jurnalis-engine v0.27.0
What's Changed
New Features
- All 9 SRD species — Dragonborn (Draconic Ancestry, Breath Weapon, Draconic Flight), Gnome (Gnomish Cunning, Forest/Rock lineages), Goliath (Giant Ancestry, Large Form, Powerful Build), Halfling (Brave, Luck, Halfling Nimbleness, Naturally Stealthy), Orc (Adrenaline Rush, Relentless Endurance), Tiefling (Fiendish Legacy — Abyssal/Chthonic/Infernal). Existing species corrected to 2024 SRD: ability bonuses moved to backgrounds, Elven Lineage subraces, Dwarven Toughness.
- Subrace selection step — A new
ChooseSubracecreation step routes players through lineage/ancestry selection for species that have variants (Elf, Dragonborn, Gnome, Tiefling). Subrace traits and speed overrides are applied during character finalization.
Bug Fixes
- Shield spell is now reaction-only —
cast shieldon your turn is rejected; Shield triggers automatically via thePendingReactionsystem when the player is hit, per SRD 5.1. - NPC attacks after moving —
resolve_npc_turn()now correctly uses movement and action as independent per-turn resources. NPCs that close distance will also attack in the same turn. - Quest objective completion — Defeating the target NPC now correctly marks the objective complete. The
seed_objectives → combat → end_combat → check_defeat_npc_objectivespath is covered by regression tests. - Quest objective room name —
seed_objectives()was readingboss.locationbefore deterministic NPC placement. Sortinglocation_idsand all HashMap iterations ingenerate_world()makes world generation fully deterministic for a given seed. - Equip/unequip uses free object interaction — Drawing or sheathing a weapon in combat costs the free object interaction (one per turn) instead of the action, per SRD 2024. A second interaction costs the Utilize action; further attempts are blocked.
- No action consumed on equip disambiguation — When
equip <partial>triggered a disambiguation prompt, the combat handler was unconditionally markingaction_used = truebefore the player resolved the prompt. The flag is now only set after the command actually resolves. - Map command no longer leaks internal IDs —
render_map()was including the numericLocationIdin brackets (e.g.* Shrine [0] -> north). Output now reads* Shrine -> north.
Other
- World generation is fully deterministic for a given seed (sorted NPC, item, and trigger placement order).
Full Changelog: 0.25.0...0.27.0
Full Changelog: 0.25.0...0.27.0