Commit Graph

4 Commits

Author SHA1 Message Date
prosolis
6386161402 UX S6: race truth-up — wire Tiefling fire resist + best-fit hints
R22: replace race copy that promised mechanics the engine doesn't deliver.
- Tiefling: wire FireResist as a CombatModifier. Enemy main attack is
  halved when monster is FireAttacker-tagged; aoe_fire abilities are
  halved unconditionally; fire-tagged traps deal half damage to Tieflings.
  DnDMonsterTemplate carries FireAttacker; toCombatStats propagates it.
  Hand-authored fire entries tagged in dnd_bestiary.go (flameskull,
  magmin, azer, salamander, fire_elemental, emberlord_thyrak,
  young_red_dragon, infernax, belaxath).
- Open5e tuned generator derives FireAttacker from the highest-AvgDamage
  attack's DamageType (threshold AvgDamage>=5). 19 tuned monsters tag.
  Regenerated bestiary_tuned_data.go.
- Elf: drop "immune to sleep" (no sleep mechanic); reframe as keen
  senses + trance flavor.
- Half-Elf: drop "two bonus skill proficiencies" (no skill system);
  reframe as adaptable cross-cultural know-how.
- Tiefling copy: drop "bonus on CHA checks" (no checks); keep fire
  resistance with flavor framing.

R23: DnDRaceInfo grows a BestFit field; renderRaceMenu emits an
"_best with: …_" hint per race so spiky stat spreads (Orc -1/-1/-1)
read as specialist picks rather than a brick of penalties.

R24: dnd.go header comment for the caster classes now reflects the
shipped state (Playable=true, spell lists populated) instead of the
pre-Open5e scaffold language.

Tests: TestApplyRacePassives gains a FireResist column; new
TestTieflingFireResistance asserts ~0.5x ratio over a 300-trial sweep
against a FireAttacker enemy. Full suite green.
2026-05-14 22:06:31 -07:00
prosolis
1512f6cc50 UX S3: SRD copy-edit pass — sanitize jargon + curated overrides
Plumbed through the open5e importer so regen stays safe:

- New cmd/open5e-import/desc_overrides.go holds two per-ID override
  maps (spellDescOverride, magicItemDescOverride) and a regex-driven
  cleanDesc sanitizer. Override wins outright; otherwise the SRD
  first-sentence runs through cleanDesc, which strips the phrases
  the S3 acceptance criteria forbid (saving throw[s], spell slot,
  within range, 5-foot, DC <n>, "(save DC X)" parentheticals,
  "constitution score is N", "out to a range of N feet"). A small
  post-pass repairs the orphan stubs the strippers leave behind
  (" and." trailers, "must make." after the saving-throw object
  is gone).

- gen.go (spells) + magicitems.go now call spellDescription /
  magicItemDescription instead of raw firstSentence; same hand-
  authored override pattern, same cleanDesc fallthrough.

- Override coverage: the 19 SRD-only spells that show up in
  defaultKnownSpells (call_lightning, charm_person, vicious_mockery,
  …) plus ~35 high-visibility magic items (Amulet of Health, every
  Belt of Giant Strength variant, Cloak of Displacement, etc.).
  Tone is outcome-first second-person with bite — these surface
  in the spellbook and the curio shop, so they get to be funny.

- tuned.go (R21) + magicitems.go strip "(...)" from emitted Names
  via stripNameParenthetical. Slug keeps the variant; only the
  display text loses the qualifier. Two bestiary entries
  (giant_rat_diseased, deep_gnome_svirfneblin) and stone_of_good_luck
  affected.

- Regenerated all three data files. Acceptance grep is clean:
  zero hits for any banned phrase in Description/Desc fields.

- New cmd/open5e-import/desc_overrides_test.go covers the
  sanitizer regressions, orphan-repair, name-strip, and the
  override-wins-but-fallthrough-still-sanitizes path.

Conflicts: none. S4 (magic-item UX) wanted this in first so the
new curio renderer consumes clean text — ready for it now.
2026-05-14 21:53:06 -07:00
prosolis
297ce3d786 D&D: wire monster abilities from SRD traits in the tuning pass
The tuned bestiary previously left every generated entry with a nil
Ability. abilityFromTraits now classifies each creature's SRD trait
names against a priority-ordered rule table, mapping the most
combat-defining trait onto a MonsterAbility effect (death_aoe,
regenerate, spell_resist, evade, enrage, ...). Creatures whose traits
are all non-combat stay nil. 165 of 322 entries get an ability.
2026-05-14 18:00:29 -07:00
prosolis
908e2b0855 D&D: codified bestiary tuning pass — derive tuned roster from SRD staging
Adds `gen tuned` to cmd/open5e-import: a deterministic formula that scales
every raw SRD stat block down to an engine-ready DnDMonsterTemplate. HP/AC/
AttackBonus are verbatim SRD (AC clamped to the engine min 10); the Attack
stat is interpolated from attackByCRPoints, a CR→Attack anchor table lifted
from the hand-tuned dndBestiary (CR is the calibration axis the 2026-05-10
rebalance used — raw SRD per-hit damage is ignored). Speed/BlockRate are
coarse baselines from SpeedWalk/AC.

bestiary_tuned.go merges the 322 generated templates into dndBestiary, but
hand-authored roster entries win — the merge only fills IDs the roster does
not already define, so playtested numbers and wired abilities are untouched.

Abilities are deliberately not wired: every generated entry has a nil
Ability, with the SRD multiattack/trait text parked in Notes as raw material
for the follow-up ability-wiring pass.
2026-05-14 16:45:09 -07:00