Lateania: Hearth & Hereafter — classes, archetypes, death & resurrection, pets & housing#374
Open
hardlygospel wants to merge 8 commits into
Open
Lateania: Hearth & Hereafter — classes, archetypes, death & resurrection, pets & housing#374hardlygospel wants to merge 8 commits into
hardlygospel wants to merge 8 commits into
Conversation
added 7 commits
June 21, 2026 16:04
First slice of the Hearth & Hereafter expansion (mpiorowski#363): the playable roster grows from five to seven. - Druid (WIS, Spirit): a hybrid bruiser-healer of the wild. Trait "Nature's Renewal" mends a little health every tick. Kit of thorns, roots, moonfire, barkskin, regrowth and a Force of Nature capstone. - Necromancer (INT, Souls): a hardy shadow caster. Trait "Soul Harvest" restores health and Souls on every kill. Kit of shadow bolts, decay, bone shields, life-drain and a Soul Reaping capstone. Two new Resource variants (Spirit, Souls) and full match arms across classes.rs; ability rosters in abilities.rs (ids 800/900, each with a level-1 opener, a level-50 capstone, and 8+ unlocks by 50); class-select keys 6 and 7 in input.rs. The only runtime additions are the two trait hooks: Druid regen in the per-player upkeep loop and Necromancer harvest in kill_mob - no combat-engine changes, all effects reuse existing AbilityEffect kinds. Adds class round-trip/coverage and trait tests; the existing ability-roster invariants now cover both new classes. 103 lateania tests green; clippy/fmt clean. CONTEXT.md updated. Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
Completes the dozen-class roster for the Hearth & Hereafter expansion (mpiorowski#363), building on the Druid/Necromancer slice. - Bard (CHA, Tempo): support battle-singer. Trait "Battle Hymn" returns Tempo faster. Songs that mend, hearten, and unstring the foe. - Monk (DEX, Ki): martial ascetic. Trait "Iron Body" blunts physical blows. Flurries, stuns, and a Touch of Death capstone. - Paladin (STR, Mana): holy bulwark. Trait "Aura of Devotion" mends a little each tick. Smites, shields, and Avenging Wrath. - Warlock (CHA, Mana): pact caster. Trait "Pact of Souls" restores Mana on a kill. Curses, drains, and Cataclysm. - Berserker (STR, Rage): reckless juggernaut. Trait "Frenzy" scales damage up to +50% as health falls past half. Biggest HP pool. New Resource variants Tempo and Ki; full match arms across classes.rs; rosters in abilities.rs (ids 1000-1408, each a level-1 opener, level-50 capstone, 9 unlocks). Five small trait hooks in svc.rs reusing existing sites - no combat-engine changes. Class select reworked to a cursor list (w/s + Enter, 1-9 quick-pick) since twelve classes no longer fit single number keys; one compact row each plus a detail block for the highlight. Adds an all-twelve integration test; the ability invariants now cover every class. 104 lateania tests green; clippy/fmt clean. CONTEXT.md updated. Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
Third slice of the character-depth pillar (Hearth & Hereafter, mpiorowski#363). Leveling already grew stats every level via the formula curve, but the gains were invisible - non-ability levels just said "You reach level N". - check_level_up now announces, for each level gained, the concrete reward: the +max HP / +attack / +resource the curve granted, the new ability when one unlocks, and a named milestone at every fifth level. - New milestones (Blooded, Toughened, ... Ascended) land at levels 5/10/.../50 and grant a permanent +5 HP each, folded into max_hp via milestone_hp_bonus - a pure function of level, so no new save state. - The character sheet shows the current milestone rank under the level. No dead levels: a test asserts every level for every class either grows a stat or hits a milestone. Adds milestone + level-up-feedback tests. 106 lateania tests green; clippy/fmt clean. CONTEXT.md updated. Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
Add the archetype layer that completes the character-depth pillar. At level 10 every class chooses one of two permanent paths (the ARCHETYPES data table in classes.rs), each carrying a role stance — Tank, Healer, or DPS — expressed as four percent modifiers: outgoing damage, incoming mitigation, healing received, and max HP. The modifiers ride existing combat hooks, so there are no engine changes: DPS amplifies attack() and spell_damage(), Tank reduces the blow in strike_player(), Healer boosts heal_player(), and the max-HP bonus folds into max_hp(). The chosen path is held on PlayerState as a &'static ArchetypeDef and persisted by stable key (schema 7 -> 8, defaulting gracefully for older saves and validated against the class on load). A new level-10 selection screen (draw_archetype_select, gated on a non-empty archetype_choices in the snapshot) takes over until the player commits with 1/2, mirroring the class-select flow; the character sheet shows the chosen path and role. Tests cover the level gate, immediate stat effect, persistence round-trip, and tank mitigation. cargo test/clippy/fmt all green. Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
Death used to blink a fallen player back to the temple after an 8s rest. Now falling leaves a real CORPSE where you stand: hp 0, target and buffs cleared, 20% carried gold and any escort lost (banked gold still safe), and your spirit lingers awaiting rescue. From the corpse you choose your fate: - wait for a resurrection, or - release to the temple now (r / Enter while dead). If neither happens before the linger deadline (CORPSE_LINGER_SECS) the tick auto-releases you, so no one is ever stuck. The temple trip is now a shared send_to_temple helper used by both the auto-release and the manual release. Resurrection becomes a rite of the holy and life-attuned callings (Class::can_resurrect -> Cleric, Paladin, Druid). A living caster in the same room spends resource (g key) to raise the nearest corpse in place at a fraction of full vitality (resurrect_nearest) rather than sending them to the temple. The snapshot now carries dead / can_resurrect / corpse_here and a per-occupant alive flag, so the UI shows a "You have fallen" overlay with the release hint, tags corpses as (fallen) in the room roster, and prompts capable players to resurrect. The dead state is transient and not persisted (a reload returns the character alive at a safe room), so there is no save-schema change. Tests cover the lingering corpse (not an instant temple trip), release-to-temple, and a healer resurrecting a corpse in place while an incapable class cannot. cargo test (111) / clippy / fmt all green. Stacked on the character-depth expansion (PR mpiorowski#370, The Twelvefold Path). Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
Add beasts of war that fight at your side - the next Hearth & Hereafter pillar after death & resurrection. Each capital gains a Stable (new FeatureKind), the companion vendor. Open it with `p`, browse five species (the new pets.rs PetSpecies table - War Hound, Dire Wolf, Moor Hawk, Cave Bear, Emberdrake), and buy one with gold (Enter); `x` feeds and tends the one you have. You keep one companion at a time; a new purchase sets the old one loose. A pet rides on PlayerState, so it is always at your side. In the combat round it bites your target after your own strike (and the kill is yours if its bite finishes the foe). When you are struck, a share of the blow (PET_WOUND_PCT) splashes onto it - but only on blows you survive, since combat is over once you fall. A pet beaten to zero is downed and stops fighting until you feed it at a stable, which revives it, heals it to full, and raises its loyalty. Loyalty drives its level (more HP and attack) via a pure function, so only the species key and loyalty are persisted (schema 8 -> 9; it reloads at full health). The snapshot carries the live pet (glyph, level, HP, downed, loyalty) and the stable catalogue, so the room panel shows your companion, the character sheet and Stable panel show its state, and a hint points to the vendor. Tests cover buying (gold spent / unaffordable refused), the pet piling onto your target, being downed by a barrage, feeding to revive and strengthen, and every capital having a stable - plus the pets.rs growth maths and the save round-trip. A pre-existing bank test that found a feature by hardcoded index is fixed to find it by kind, since adding the stable shifts feature indices. cargo test (119) / clippy / fmt green. Stacked on the death & resurrection PR (mpiorowski#371). Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
The final Hearth & Hereafter pillar: true-Ultima-Online-style homes you buy, own, furnish, and let others visit. Hearthward Close is a public courtyard off Embergate's Market Row, ringed with one home of each of five tiers - Wattle Hut, Thatched Cottage, Timber Longhouse, Stone Manor, and Wizard's Tower - the grander ones adding upper floors reached by a stair. A housing clerk keeps the ledger (open it with `n`): buy a deed to claim a free home of that tier (one home to a name), then, standing inside it, furnish it from a catalogue of over fifty pieces, each with its own flavour - from an oak milking stool to a brass orrery. Placed furnishings become part of the room everyone sees. The key design choice keeps this tractable: homes are NOT dynamic rooms. They are pre-built static rooms (housing.rs data + world.rs extend_housing), so all the movement, snapshot, minimap, and visiting machinery works unchanged - and because the close and every door are public, anyone can walk up and visit, exactly the UO shared-world feel. Only ownership (plot_owner) and furnishings (house_furniture) are dynamic side-state on the service, the same static-rooms-plus-side-map pattern that made the mazes, mob behaviours, and wildlife tractable. Ownership and placed furniture persist (schema 9 -> 10); on load they are re-registered into the service side-maps. The snapshot carries a context-sensitive housing ledger (deeds at the clerk, the furniture catalogue inside a home you own) and the room description lists whatever has been set down. Tests cover claiming a deed (gold spent, one-home-per-name), furnishing only a home you own while a visitor in the same room cannot, the 50+-piece catalogue and non-overlapping plot address maths, the housing room count, and the save round-trip. cargo test (123) / clippy / fmt green. Stacked on the combat-pets PR (mpiorowski#373). Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
This was referenced Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thanks @mpiorowski! This is Hearth & Hereafter (#363) — a character-and-home expansion for Lateania, bundled here as one release. Seven reviewable commits, lock-free / snapshot-only, every stage
cargo test/clippy/fmtgreen (123 lateania tests).🎭 Twelve classes, archetypes & every level
The roster grows from five to twelve — Druid, Necromancer, Bard, Monk, Paladin, Warlock, Berserker join the originals, each with its own resource, trait, and full 1–50 ability roster. Every level now grants a visible reward and a named milestone (Blooded…Ascended). At level 10 each class picks one of two archetype paths, each a Tank / Healer / DPS stance expressed as percent modifiers on the existing combat hooks — no engine changes.
💀 Death & resurrection
A real dead state: when you fall you become a corpse where you stand, not an instant temple trip. Wait for rescue or release (
r); if no one comes by the linger deadline you're drawn home automatically. Resurrection is a rite of the holy/nature callings (Cleric/Paladin/Druid) — a living caster (g) raises the nearest corpse in place.🐺 Combat companions
Buy a beast at a capital Stable (
p) — War Hound, Dire Wolf, Moor Hawk, Cave Bear, Emberdrake. It fights at your side (bites your target, kill credited to you), shares the blows you survive and can be downed, and grows by feeding (loyalty → levels). Persisted across sessions.🏠 Player housing (true Ultima Online)
Hearthward Close, a public courtyard off Embergate's Market Row, is ringed with one home of each of five tiers — Wattle Hut → Thatched Cottage → Timber Longhouse → Stone Manor → Wizard's Tower (the grand ones add upper floors up a stair). Buy a deed at the clerk (
n) to claim a home, then furnish it from a catalogue of 50+ pieces, each with its own description, that everyone in the room can see. The homes are shared-world — public rooms anyone can walk into.The trick that made housing tractable (and the through-line of this whole expansion): static rooms + dynamic side-maps. Homes are pre-built rooms; only ownership and furnishings are runtime side-state, so all the movement/visiting/snapshot machinery — and the UO "walk into someone's house" feel — comes for free. The same pattern carries the archetype/pet/corpse layers.
The seven commits
Tests
New coverage for all four pillars: the twelve-class/ability invariants and milestones, archetype gating + tuning, the corpse/release/resurrect flow, companion combat/downing/feeding, and housing deeds/furnishing/visiting + the save round-trips.
P.S. — @mpiorowski this completes the roadmap from #363. Happy to split it back into the separate PRs if you'd rather review them piecemeal — just say the word. And the offer on a fresh late.sh banner still stands. 🙂