Chapter 27 — Character Creation
Part VII — Systems
How the engine handles player identity through archetypes, backgrounds, traits, and multiclassing.
Package
Section titled “Package”@ai-rpg-engine/character-creation — standalone, depends only on @ai-rpg-engine/core for type imports. No engine runtime dependency.
npm install @ai-rpg-engine/character-creationConcepts
Section titled “Concepts”| Concept | Description |
|---|---|
| Archetype | Primary class — base stats, starting tags, progression tree |
| Background | Origin story — stat modifiers, starting tags, optional inventory |
| Trait | Perk or flaw — stat/resource/tag/verb/faction effects |
| Discipline | Secondary class — 1 granted verb, 1 passive, 1 drawback |
| Cross-Title | Synthesized identity from archetype + discipline combo |
| Entanglement | Friction effect from certain archetype + discipline combos |
| Build Catalog | Pack-specific menu of all character options |
| Character Build | Player’s choices (archetype, background, traits, discipline) |
Multiclassing
Section titled “Multiclassing”The system uses structured identity fusion, not additive spreadsheet stacking:
- Primary archetype sets the character’s core identity (base stats, progression tree, starting tags)
- Secondary discipline is compact: 1 verb, 1 passive effect, 1 drawback
- Each archetype + discipline combo produces a cross-discipline title that synthesizes the identity (e.g., “Grave Warden”, “Hex Pistol”, “Synapse Surgeon”)
- Some combos create entanglements — friction effects that reflect narrative tension (e.g., a divine scholar who smuggles attracts unwanted attention)
Build Catalog
Section titled “Build Catalog”Each starter pack exports a buildCatalog: BuildCatalog alongside its content. The catalog defines:
- 3 archetypes with stat priorities and starting tags
- 3 backgrounds with stat modifiers
- 4 traits (2 perks, 2 flaws)
- 2 disciplines with granted verbs
- 6 cross-discipline titles (3 archetypes x 2 disciplines)
- Optional entanglements
All catalogs share the same budget: statBudget: 3, maxTraits: 3, requiredFlaws: 1.
Validation
Section titled “Validation”validateBuild(build, catalog, ruleset) checks:
- Archetype, background, traits, discipline all exist in catalog
- No incompatible traits selected
- Trait count within limit
- Required flaw count met
- Discipline required tags satisfied
- Stat budget not exceeded
- Stats clamped to ruleset bounds
Returns BuildValidationResult with computed final stats, final resources, resolved title, resolved tags, errors, and entanglement warnings.
Entity Resolution
Section titled “Entity Resolution”resolveEntity(build, catalog, ruleset) produces a full EntityState:
id: 'player',type: 'player'blueprintIdset to archetype ID- Computed stats = archetype base + background modifiers + trait effects + discipline effects + allocations
- Computed resources = ruleset defaults + archetype overrides + trait effects + discipline effects
- Tags merged from archetype, background, traits, title, entanglements
- Inventory merged from archetype, background
- Custom metadata:
archetypeId,backgroundId,disciplineId,portraitRef,title
Trait Effects
Section titled “Trait Effects”Traits produce one or more TraitEffect:
| Type | Example |
|---|---|
stat-modifier | { stat: 'dex', amount: 1 } |
resource-modifier | { resource: 'hp', amount: -3 } |
grant-tag | { tag: 'curse-touched' } |
verb-access | { verb: 'steal' } |
faction-modifier | { faction: 'guard', amount: -10 } |
Option Helpers
Section titled “Option Helpers”For building character creation UIs:
getAvailableArchetypes(catalog)— all archetypesgetAvailableBackgrounds(catalog)— all backgroundsgetAvailableTraits(catalog, selectedIds)— filters out incompatible traitsgetAvailableDisciplines(catalog, archetypeId, tags)— filters by required tagsgetStatBudgetRemaining(build, catalog)— remaining allocatable points
Serialization
Section titled “Serialization”Builds serialize to compact JSON for save files:
import { serializeBuild, deserializeBuild } from '@ai-rpg-engine/character-creation';
const json = serializeBuild(build);const restored = deserializeBuild(json);validateSerializedBuild(json) validates structure without needing a catalog.
Example
Section titled “Example”import { validateBuild, resolveEntity } from '@ai-rpg-engine/character-creation';import { content, buildCatalog } from '@ai-rpg-engine/starter-fantasy';
const build = { name: 'Aldric', archetypeId: 'penitent-knight', backgroundId: 'oath-breaker', traitIds: ['iron-frame', 'cursed-blood'], disciplineId: 'occultist', statAllocations: { vigor: 2, instinct: 1 },};
const result = validateBuild(build, buildCatalog, content.ruleset);// result.ok === true// result.resolvedTitle === 'Grave Warden'// result.finalStats === { vigor: 8, instinct: 6, will: 1 }
const entity = resolveEntity(build, buildCatalog, content.ruleset);// entity.id === 'player'// entity.tags includes 'martial', 'oath-broken', 'curse-touched', 'grave-warden'