mwg API
    Preparing search index...

    Interface EntityTemplateRow

    One row of a hero or monster "file" - a core.parseCSV result, typically - turned into a fully wired entity: a StatBlock of base stats, an optional Progression against a named growth curve, an optional starting item carrying a named starting affix, and a ReactionTable already holding a low-HP rule if the row names one. The single call a game makes once per row, in place of the per-field glue code every one of those systems would otherwise need written out by hand.

    A handful of column names are reserved (id, growth, level, startingAffix, startingItem, lowHpReaction); every other column in the row becomes a base stat, so a game's own stat names (attack, speed, armor, whatever it calls them) need no declaring here. What each named growth curve, affix, and item actually is stays the game's own EntityTemplateCatalog - mwg resolves the reference, never invents the content behind it, the same boundary AffixDef.id already draws.

    Deliberately narrow: one low-HP threshold per row, not an arbitrary list of reactions - add a second column and a second ReactionRule in a game's own code the moment a second one is actually needed, rather than a general reaction-list column format speculatively built ahead of that need.

    import { parseCSV } from '@datamoc/mw_games/core';
    import { buildEntities, type EntityTemplateRow } from '@datamoc/mw_games/actors';

    const csv = `id,attack,speed,growth,startingAffix,startingItem,lowHpReaction
    fireling,10,8,steep,blazing,ember_charm,0.25`;

    const rows = parseCSV<EntityTemplateRow>(csv, {
    columns: { attack: 'number', speed: 'number', lowHpReaction: 'number' },
    });

    const monsters = buildEntities(rows, {
    growthCurves: { steep: { maxLevel: 20, experienceFor: (level) => level * level * 10 } },
    affixes: { blazing: { id: 'blazing', trigger: 'strike', weight: 1 } },
    items: { ember_charm: () => ({ id: 'ember_charm', quantity: 1 }) },
    }, (entity) => console.log(`${entity.id} panics at low hp`));

    monsters[0].reactions.check({ hp: 2, maxHp: 10 }); // fires the callback above
    interface EntityTemplateRow {
        growth?: string;
        id: string;
        level?: number;
        lowHpReaction?: number;
        startingAffix?: string;
        startingItem?: string;
        [stat: string]: unknown;
    }

    Indexable

    • [stat: string]: unknown

      any other column is a base stat by that name; must be a number

    Index
    growth?: string
    id: string
    level?: number
    lowHpReaction?: number
    startingAffix?: string
    startingItem?: string