create_character_name.js

import { format } from "./string_utils.js";
import { logger } from "./utils.js";
import { mapLoader } from "./data_loaders.js";
import { test, random } from "./random_utils.js";
import CharacterName from "./models/character_name.js";

const map = await mapLoader("names.data");

const NAMES = {
  "anglo male": map.get("names.anglo.male"),
  "anglo female": map.get("names.anglo.female"),
  "latino male": map.get("names.latino.male"),
  "latino female": map.get("names.latino.female"),
  "anglo": map.get("names.anglo"),
  "latino": map.get("names.latino"),
};

function getGivenName(gender, heritage) {
  gender = gender.toLowerCase();
  heritage = heritage.toLowerCase();
  // 35% of Latinx folks have an anglo given name.
  let str = heritage === "latino" && test(35) ? "anglo {0}" : "{1} {0}";
  return random(NAMES[format(str, gender, heritage)]);
}

const getFamilyName = (heritage) => random(NAMES[heritage.toLowerCase()]);

/**
 * Generate a random name for a mid-century American, of the kind that would be
 * wandering around an atomic era apocalypse. Does not add a nickname.
 *
 * @example
 * createCharacterName({gender: 'female', heritage: 'latino'})
 * => {"given": "Elena", "family": "Silva", "gender": "female", "heritage": "latino"}
 * let girl = createCharacterName({gender: 'female'})
 * girl.toString()
 * => "Ada King"
 *
 * @param params {Object}
 *   @param params.gender {String} 'male' or 'female' name. Optional. If not specified, gender is 50/50.
 *   @param params.heritage {String} 'anglo' or 'latino' (Optional. If not specified, 20% of names are Latino).
 *   @param params.given {String} set the given name to this name
 *   @param params.family {String} set the family name to this name
 * @return {CharacterName}
 */
export function createCharacterName({
  gender = test(50, "male", "female"),
  heritage = test(20, "latino", "anglo"),
  given = getGivenName(gender, heritage),
  family = getFamilyName(heritage),
} = {}) {
  logger.start("createCharacterName", { gender, heritage, given, family });
  let cn = new CharacterName({ given, family, heritage, gender });
  return logger.end(cn);
}