Names without the AI: a built-in name generator with extensive lists (hybrid) #1257

Closed
opened 2026-10-28 04:57:53 +00:00 by claude-bot · 9 comments
Collaborator

Owner's decision, 2026-10-28: build a list-based name generator, in the style of fantasynamegenerators.com, into Prep → Names. Hybrid: names always come from the generator, and an AI (when configured) only writes a description of a name the GM picks. For v4.7.0.

Why:

  1. Repetition. AI models surface the same names over and over; the owner has been offered the same names many times. A disallow list sent to the AI would only add token cost.
  2. Cost. No tokens per draw, which matters for the hosted service (AI priced by usage, #642).
  3. It works with no AI at all. Today Prep → Names fails when no LLM is configured.

Today: generation_service tool names → audio_service.generate_name_options() (LLM, JSON schema, names plus a 1–2 sentence description per kind), pre-fetched into a Redis pool by planning_tasks.prefetch_name_options. The UI is pages/prep/tools/Names.jsx, with kinds from ENTRY_TYPE_LABELS and an optional "feel". Instant NPC (instant_npc) is separate and out of scope here.

Requirements:

  • Extensive lists. Variety is the point. Each person style needs enough pieces that the combinations run to hundreds of thousands, plus curated whole-name lists, so the same name practically never comes back.
  • Never offer the same name twice in a campaign. Remember (cheaply: hashes in the DB or Redis, no tokens) every name shown in a campaign, and skip it and anything already a wiki entry title or alias there. This is the "disallow list", free.
  • Variety within a set: no two options in one set share a first letter, ending or length band where avoidable.
  • Styles for people: several human flavours, plus elf, dwarf, halfling, gnome, orc, goblin and more. Offered by game system where it fits (PF2e ancestries, 5e species), and all styles are always available.
  • Other kinds, by pattern: settlements, taverns and inns, organisations, geography, countries, ships, items…, mapped to the wiki's entry types.
  • A filter: never a real English word on its own where a name is wanted, and never anything offensive or slur-like, including across syllable joins.
  • Our own lists. fantasynamegenerators.com's lists are its author's copyrighted work and its terms forbid reuse. The technique (pieces plus rules) is free; every list is written for Quest Board.
  • Description, hybrid: the existing per-name "describe" action asks the AI for a description of a chosen name, only when an AI is configured. Without one, names alone (later, maybe, a description built from tables).
  • Deterministic tests: seeded generation, no duplicates in a set, the filter, and the campaign memory.

Plan:

  1. Draft two or three styles as samples for the owner to judge by ear, before the rest are written.
  2. Draw the drawer change (a style choice) before building.
  3. Engine, campaign memory, API and drawer; then the remaining lists, each style reviewed by sample.

The prefetch pool for names can go once names stop needing the LLM.

**Owner's decision, 2026-10-28:** build a list-based name generator, in the style of fantasynamegenerators.com, into Prep → Names. Hybrid: names always come from the generator, and an AI (when configured) only writes a description of a name the GM picks. For v4.7.0. **Why:** 1. **Repetition.** AI models surface the same names over and over; the owner has been offered the same names many times. A disallow list sent to the AI would only add token cost. 2. **Cost.** No tokens per draw, which matters for the hosted service (AI priced by usage, #642). 3. **It works with no AI at all.** Today Prep → Names fails when no LLM is configured. **Today:** `generation_service` tool `names` → `audio_service.generate_name_options()` (LLM, JSON schema, names plus a 1–2 sentence description per kind), pre-fetched into a Redis pool by `planning_tasks.prefetch_name_options`. The UI is `pages/prep/tools/Names.jsx`, with kinds from `ENTRY_TYPE_LABELS` and an optional "feel". Instant NPC (`instant_npc`) is separate and out of scope here. **Requirements:** - **Extensive lists.** Variety is the point. Each person style needs enough pieces that the combinations run to hundreds of thousands, plus curated whole-name lists, so the same name practically never comes back. - **Never offer the same name twice in a campaign.** Remember (cheaply: hashes in the DB or Redis, no tokens) every name shown in a campaign, and skip it and anything already a wiki entry title or alias there. This is the "disallow list", free. - **Variety within a set:** no two options in one set share a first letter, ending or length band where avoidable. - **Styles for people:** several human flavours, plus elf, dwarf, halfling, gnome, orc, goblin and more. Offered by game system where it fits (PF2e ancestries, 5e species), and all styles are always available. - **Other kinds, by pattern:** settlements, taverns and inns, organisations, geography, countries, ships, items…, mapped to the wiki's entry types. - **A filter:** never a real English word on its own where a name is wanted, and never anything offensive or slur-like, including across syllable joins. - **Our own lists.** fantasynamegenerators.com's lists are its author's copyrighted work and its terms forbid reuse. The technique (pieces plus rules) is free; every list is written for Quest Board. - **Description, hybrid:** the existing per-name "describe" action asks the AI for a description of a chosen name, only when an AI is configured. Without one, names alone (later, maybe, a description built from tables). - **Deterministic tests:** seeded generation, no duplicates in a set, the filter, and the campaign memory. **Plan:** 1. Draft two or three styles as samples for the owner to judge by ear, before the rest are written. 2. Draw the drawer change (a style choice) before building. 3. Engine, campaign memory, API and drawer; then the remaining lists, each style reviewed by sample. The prefetch pool for names can go once names stop needing the LLM.
Author
Collaborator

Plan step 1: a sampler for the owner to judge by ear. Name Sampler artifact: https://claude.ai/artifact/QTWCeFLowhFfgxwPCFGuKh (private to the owner). It's a JS prototype of the engine with five styles, all lists original:

Style Possible names (pieces multiplied out)
Human: Hearthland (two old name elements, plus a place or trade surname) about 3.4 million
Elvish (invented syllables, plus a house name or "of the …" epithet) about 39 million
Dwarvish (hard syllables, plus a two-word forge clan name) about 46 million
Settlements (first part plus ending; "Upper …", "…-on-river") about 230,000
Taverns & inns (signboard patterns) about 29,000

In the sampler:

  • No repeats within a visit, and variety within a set (a new first letter and a new ending where possible).
  • Filters: a famous-name block (Tolkien and other well-known fantasy characters), and a rude-word filter checked per word. The short words match only as whole words or word starts, so Spicer, Sedgelow and Nightingale pass, and "Arse…" doesn't.
  • The owner marks 👍/👎 per name and leaves notes per style. Collections: votes (doc <style>~<slug>) and notes/<style>.

Next: read the marks and notes, tune these lists, then draw the drawer and build the real engine (Python, seeded, plus the campaign memory).

Plan step 1: a sampler for the owner to judge by ear. Name Sampler artifact: https://claude.ai/artifact/QTWCeFLowhFfgxwPCFGuKh (private to the owner). It's a JS prototype of the engine with five styles, all lists original: | Style | Possible names (pieces multiplied out) | |---|---| | Human: Hearthland (two old name elements, plus a place or trade surname) | about 3.4 million | | Elvish (invented syllables, plus a house name or "of the …" epithet) | about 39 million | | Dwarvish (hard syllables, plus a two-word forge clan name) | about 46 million | | Settlements (first part plus ending; "Upper …", "…-on-river") | about 230,000 | | Taverns & inns (signboard patterns) | about 29,000 | In the sampler: - **No repeats** within a visit, and variety within a set (a new first letter and a new ending where possible). - **Filters:** a famous-name block (Tolkien and other well-known fantasy characters), and a rude-word filter checked per word. The short words match only as whole words or word starts, so Spicer, Sedgelow and Nightingale pass, and "Arse…" doesn't. - The owner marks 👍/👎 per name and leaves notes per style. Collections: `votes` (doc `<style>~<slug>`) and `notes/<style>`. Next: read the marks and notes, tune these lists, then draw the drawer and build the real engine (Python, seeded, plus the campaign memory).
Author
Collaborator

Owner's criterion (2026-10-28): a name must flow off the tongue. Their one 👎 so far, "Godgyth Linshaw", was "very awkward to say", not a problem with any single piece. So the real engine needs flow rules applied at every join, beyond curating lists. A draw that breaks one is thrown away and redrawn:

  • Consonant clusters across a join: reject hard clusters formed where two pieces meet (e.g. d|g, th|g, t|ch, k|g, three or more consonants running across a join), using an allow-list of easy joins (l|w, n|d, r|th…).
  • Repetition: no echo of the same consonant or syllable on either side of a join or across the space (-gyth Lin- is fine; -wyn Wyn- is not).
  • Length: a cap on syllables per given name and for the full name; a long family name pairs with a short given name and vice versa.
  • Stress and rhythm: prefer alternating stressed and unstressed syllables in the human styles; avoid two heavy closed syllables in a row (God|gyth).

The same criterion should be stated to testers: "👍 if it fits the style and is easy to say". This is a candidate change to step 3 on the Names page, pending the owner.

**Owner's criterion (2026-10-28): a name must flow off the tongue.** Their one 👎 so far, "Godgyth Linshaw", was "very awkward to say", not a problem with any single piece. So the real engine needs **flow rules applied at every join**, beyond curating lists. A draw that breaks one is thrown away and redrawn: - **Consonant clusters across a join:** reject hard clusters formed where two pieces meet (e.g. `d|g`, `th|g`, `t|ch`, `k|g`, three or more consonants running across a join), using an allow-list of easy joins (`l|w`, `n|d`, `r|th`…). - **Repetition:** no echo of the same consonant or syllable on either side of a join or across the space (`-gyth Lin-` is fine; `-wyn Wyn-` is not). - **Length:** a cap on syllables per given name and for the full name; a long family name pairs with a short given name and vice versa. - **Stress and rhythm:** prefer alternating stressed and unstressed syllables in the human styles; avoid two heavy closed syllables in a row (`God|gyth`). The same criterion should be stated to testers: "👍 if it fits the style and is easy to say". This is a candidate change to step 3 on the Names page, pending the owner.
Author
Collaborator

At the owner's request (2 Nov), the scoring page now offers ten more kinds, 15 in all:

  • People: Sunreach and Northmarch humans, halfling, gnome, orc and goblin.
  • Places: landscape, and countries & realms.
  • Other: organisations and ships.

Every person style also has a flow check at its joins, following the owner's note on "Godgyth". It's live at the same link, with the PR in #1314. The marks feed the lists the real generator will use.

At the owner's request (2 Nov), the scoring page now offers ten more kinds, 15 in all: - **People:** Sunreach and Northmarch humans, halfling, gnome, orc and goblin. - **Places:** landscape, and countries & realms. - **Other:** organisations and ships. Every person style also has a flow check at its joins, following the owner's note on "Godgyth". It's live at the same link, with the PR in #1314. The marks feed the lists the real generator will use.
Author
Collaborator

The owner's notes after a first pass through every section of the names page (2026-11-03), and what changes on the feedback site:

  • Organisations leaned towards orders and secret societies, with few guilds and almost no companies. It's split into three:
    • Guilds
    • Companies, expected to be the most used, so it gets the most patterns: family firms, trading and shipping houses, workshops and shops, inns' and mills' owners, banks and chartered companies
    • Orders & secret societies
  • Taverns & inns produced mostly taverns. It's split into Taverns (signboard names) and Inns & lodgings (a rest, a lodge, a waystation, a coaching inn).
  • Ships split by class: Small boats (fishing, river and ferry boats), Merchant ships and Warships.
  • Landscape split by kind: Forests & woods, Mountains & hills, Caves & the deep, Rivers, lakes & falls, Coasts & seas, and Marshes, moors & plains. The owner gave the split as an example only.
  • Settlements split by size: Hamlets & villages, Towns and Cities. The difference is real but modest:
    • villages get plain two-part names, often after the land (Ashford, Nettlecombe);
    • towns add the market, the bridge or the river (Market Harrow, Wexford-on-Esk);
    • cities get shorter, older or grander names (Port Calder, Kingsreach) and are drawn more often from older roots.

Votes already cast stay valid. The old ids (org, inn, ship, geo, town) remain accepted on the server, so no rater's saved document is refused. The page no longer offers them, and the admin readout lists them as retired with their counts.

The flow rules at piece joins apply to every new style. A "whole company" generator (size, trade, owner and staff, all offline) is a later enhancement, filed separately.

**The owner's notes after a first pass through every section of the names page (2026-11-03), and what changes on the feedback site:** - **Organisations** leaned towards orders and secret societies, with few guilds and almost no companies. It's split into three: - **Guilds** - **Companies**, expected to be the most used, so it gets the most patterns: family firms, trading and shipping houses, workshops and shops, inns' and mills' owners, banks and chartered companies - **Orders & secret societies** - **Taverns & inns** produced mostly taverns. It's split into **Taverns** (signboard names) and **Inns & lodgings** (a rest, a lodge, a waystation, a coaching inn). - **Ships** split by class: **Small boats** (fishing, river and ferry boats), **Merchant ships** and **Warships**. - **Landscape** split by kind: **Forests & woods**, **Mountains & hills**, **Caves & the deep**, **Rivers, lakes & falls**, **Coasts & seas**, and **Marshes, moors & plains**. The owner gave the split as an example only. - **Settlements** split by size: **Hamlets & villages**, **Towns** and **Cities**. The difference is real but modest: - villages get plain two-part names, often after the land (Ashford, Nettlecombe); - towns add the market, the bridge or the river (Market Harrow, Wexford-on-Esk); - cities get shorter, older or grander names (Port Calder, Kingsreach) and are drawn more often from older roots. **Votes already cast stay valid.** The old ids (`org`, `inn`, `ship`, `geo`, `town`) remain accepted on the server, so no rater's saved document is refused. The page no longer offers them, and the admin readout lists them as retired with their counts. The flow rules at piece joins apply to every new style. A **"whole company"** generator (size, trade, owner and staff, all offline) is a later enhancement, filed separately.
Author
Collaborator

The owner's answer to Q219 (2026-11-03): all of them. These kinds join the names page in the same change as the splits, for rating:

  • Ancestries: Kobold, Leshy, Catfolk, Ratfolk, Kitsune and Tengu (PF2e), and Dragonborn and Tiefling (5e)
  • Noble houses (with seat and motto)
  • Deities & saints
  • Streets, districts & landmarks
  • Temples & shrines
  • Books, scrolls & documents
  • Magic items & named weapons
  • Horses & animals
  • Battles & historical events
  • Festivals & holidays
**The owner's answer to Q219 (2026-11-03): all of them.** These kinds join the names page in the same change as the splits, for rating: - Ancestries: Kobold, Leshy, Catfolk, Ratfolk, Kitsune and Tengu (PF2e), and Dragonborn and Tiefling (5e) - Noble houses (with seat and motto) - Deities & saints - Streets, districts & landmarks - Temples & shrines - Books, scrolls & documents - Magic items & named weapons - Horses & animals - Battles & historical events - Festivals & holidays
Author
Collaborator

The ratings so far (read-only tally of the feedback data, 2026-11-03; two raters):

  • Well approved (12–60 votes each, almost all up): every people style, caves, mountains, marshes and moors, streets, temples, villages, towns, cities, inns, and the retired organisations, ships, settlements and landscapes.
  • Down-votes with a clear cause:
    • Forests (18 up, 27 down): old English woodland words (Chase, Hanger, Holt, Brake, Weald, Thicket, Copse, Wilds) and plain tree names (Yew Copse, Elm Grove).
    • Rivers & lakes (26 up, 10 down): the northern waterfall words Force, Foss, Leap and Spout, and "The Heron Lake".
    • Coasts: too many "The …" names, and Ness.
    • Realms: too many "The …" names. Reach and Marches don't fit a country, and no realm calls itself "Old", though "New" is fine.
    • Landscape (owner's note): fewer "The ".
    • Human (Hearthland): heavy Old English parts (Cyn-, Leod-, -swith, Bald-, Mild-).
    • Elvish: drop the "of the …" titles, which the owner noted are the only title instead of a family name, and the vowel pile-ups (Caeraor, Ulanenae).
    • Taverns: "Snug". Mountains: "Heights" on a place name.
  • Not yet rated: most of the 18 newest kinds.

Next:

  1. Apply those fixes on the feedback site for the owner to confirm by ear.
  2. Draw the Prep → Names drawer with its style choice (the original plan's step 2).
  3. Build: the engine in the backend, ported from the names page, with campaign memory, the filters, seeded tests, and AI only for "describe".

Q228 asks whether the unrated kinds go into the first build.

**The ratings so far (read-only tally of the feedback data, 2026-11-03; two raters):** - **Well approved** (12–60 votes each, almost all up): every people style, caves, mountains, marshes and moors, streets, temples, villages, towns, cities, inns, and the retired organisations, ships, settlements and landscapes. - **Down-votes with a clear cause:** - **Forests** (18 up, 27 down): old English woodland words (Chase, Hanger, Holt, Brake, Weald, Thicket, Copse, Wilds) and plain tree names (Yew Copse, Elm Grove). - **Rivers & lakes** (26 up, 10 down): the northern waterfall words Force, Foss, Leap and Spout, and "The Heron Lake". - **Coasts:** too many "The …" names, and Ness. - **Realms:** too many "The …" names. Reach and Marches don't fit a country, and no realm calls itself "Old", though "New" is fine. - **Landscape** (owner's note): fewer "The <adj> <noun>". - **Human (Hearthland):** heavy Old English parts (Cyn-, Leod-, -swith, Bald-, Mild-). - **Elvish:** drop the "of the …" titles, which the owner noted are the only title instead of a family name, and the vowel pile-ups (Caeraor, Ulanenae). - **Taverns:** "Snug". **Mountains:** "Heights" on a place name. - **Not yet rated:** most of the 18 newest kinds. **Next:** 1. Apply those fixes on the feedback site for the owner to confirm by ear. 2. Draw the Prep → Names drawer with its style choice (the original plan's step 2). 3. Build: the engine in the backend, ported from the names page, with campaign memory, the filters, seeded tests, and AI only for "describe". Q228 asks whether the unrated kinds go into the first build.
Author
Collaborator

The owner's answer to Q228 (2026-11-03): (a). Every kind goes in the first build, including the ones not yet rated. Ratings keep tuning them afterwards as list edits.

Engine requirement from the owner's follow-up: company, guild, church and noble names often include their town or region. Build every pattern with a place slot (a guild's town, a house's seat, a company's region, a temple's parish) so the slot can be filled from outside with a real place in the campaign, falling back to a generated name. Using it ("for: Kettlebridge" in the drawer; "roll up Kettlebridge" in #1328) is a later enhancement, but the slot is in the engine from the start, so it needs no rewrite.

**The owner's answer to Q228 (2026-11-03): (a).** Every kind goes in the first build, including the ones not yet rated. Ratings keep tuning them afterwards as list edits. **Engine requirement from the owner's follow-up:** company, guild, church and noble names often include their town or region. Build every pattern with a place slot (a guild's town, a house's seat, a company's region, a temple's parish) so the slot can be **filled from outside** with a real place in the campaign, falling back to a generated name. Using it ("for: Kettlebridge" in the drawer; "roll up Kettlebridge" in #1328) is a later enhancement, but the slot is in the engine from the start, so it needs no rewrite.
Author
Collaborator

The owner's answers to Q229–Q231 (2026-11-03), recorded as D331 (D327–D330 cover #1328 and Q228; commit 7abcca14):

  • Q229: the style order as drawn: the campaign's own system's peoples first, places smallest to largest.
  • Q230: the "feel" box is gone; the style does that job.
  • Q231: ten names a set.

Building now on feat/1257-names-in-prep, with the server and the drawer built in parallel from one spec.

  • The engine: a faithful Python port of the 44 rated styles from the names page, with its filters and flow rules and the place slot in every pattern that names a place.
  • Campaign memory: a name is never offered twice, and never one that's already a page's title or alias.
  • Runs: sets are still names runs, so Insert, the shelf and History keep working.
  • AI: used only for Describe, when one is configured.
  • Removed: the names prefetch pool.
**The owner's answers to Q229–Q231 (2026-11-03), recorded as D331** (D327–D330 cover #1328 and Q228; commit 7abcca14): - **Q229:** the style order as drawn: the campaign's own system's peoples first, places smallest to largest. - **Q230:** the "feel" box is gone; the style does that job. - **Q231:** ten names a set. **Building now** on `feat/1257-names-in-prep`, with the server and the drawer built in parallel from one spec. - **The engine:** a faithful Python port of the 44 rated styles from the names page, with its filters and flow rules and the place slot in every pattern that names a place. - **Campaign memory:** a name is never offered twice, and never one that's already a page's title or alias. - **Runs:** sets are still `names` runs, so Insert, the shelf and History keep working. - **AI:** used only for Describe, when one is configured. - **Removed:** the names prefetch pool.
rbrooks referenced this issue from a commit 2026-11-03 22:00:21 +00:00
Author
Collaborator

Done: merged in #1331 (D330, D331; lane 6l).

  • Prep → Names: the drawer draws from Quest Board's own lists, all 44 rated styles, ported by script from the names page. Ten names a set, by Kind and a Style that follows it. Save to the wiki; Describe only with an AI (409 without); Another set.
  • Never twice: names are never offered twice in a campaign (name_offers), and never one that's an existing page title or alias.
  • No AI for names: sets are still names runs, so Insert, the shelf and History work. The prefetch pool is gone.
  • The place slot is in every pattern that names a place, ready for "names that use their place" (#1328).
  • Checks:
    • The render check was clean: 57 shots, axe clean, 460 names with no repeats.
    • The owner approved the wording (part v).
    • The full backend suite passed on the dev host (10,721), and then CI passed.
    • CI found two guard collisions (.title, .body) and one slow-runner test race, all fixed.

Follow-ups, not filed yet:

  • Remove the now-unused AI name code in audio_service.
  • Keep only names runs that are inserted, shelved or saved, so History doesn't fill up with every draw.

Ratings on the feedback site keep tuning the lists.

**Done:** merged in #1331 (D330, D331; lane 6l). - **Prep → Names:** the drawer draws from Quest Board's own lists, all 44 rated styles, ported by script from the names page. Ten names a set, by Kind and a Style that follows it. Save to the wiki; Describe only with an AI (409 without); Another set. - **Never twice:** names are never offered twice in a campaign (`name_offers`), and never one that's an existing page title or alias. - **No AI for names:** sets are still `names` runs, so Insert, the shelf and History work. The prefetch pool is gone. - **The place slot** is in every pattern that names a place, ready for "names that use their place" (#1328). - **Checks:** - The render check was clean: 57 shots, axe clean, 460 names with no repeats. - The owner approved the wording (part v). - The full backend suite passed on the dev host (10,721), and then CI passed. - CI found two guard collisions (`.title`, `.body`) and one slow-runner test race, all fixed. **Follow-ups, not filed yet:** - Remove the now-unused AI name code in `audio_service`. - Keep only names runs that are inserted, shelved or saved, so History doesn't fill up with every draw. Ratings on the feedback site keep tuning the lists.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#1257
No description provided.