Skip to content

v1.2.0 "Devotion": Mental Health, the Sage, the gods and the Temple - #156

Merged
binary-knight merged 218 commits into
mainfrom
release-1.1.15
Sep 29, 2026
Merged

binary-knight merged 218 commits into
mainfrom
release-1.1.15

Conversation

@binary-knight

@binary-knight binary-knight commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Version 1.2.0 "Devotion". Release notes: DOCS/release-notes/RELEASE_NOTES_1.2.0.md; Steam text: DOCS/release-notes/steam/STEAM_RELEASE_NOTES_1.2.0.txt.

Changes

  • Mental Health (MentalSystem, MentalUi): Mental 0 to 100 with bands (Stable, Strained, Shaken, Breaking, Broken). Losses from dungeon depth strain (race x class rate, saved remainder), fights, deaths, grief, witnessing, drugs (tolerance, crash, overdose, withdrawal); recovery from the daily reset, camps, the Inn, Home, prayer, confession, friends, wilderness, learning, Willow Draughts and Healer talk therapy and rehab. Addiction cap; collapse at 0 (Healer with 5% gold fee on floors 1 to 25 and in town, a death deeper; Broken until treated), checked after every fight and before entry encounters; chained fights skipped without flee text; story fights exempt. Grouped followers take their own strain. Status sheet, band tags, GMCP vitals, screen reader. Five save sites (MentalSchema, legacy load at 100).
  • Sage: new spells (Dulling Mist, Scholar's Mark, Slumber Mist, Compel, Unveil the Pattern), soft control on bosses, party wards (highest wins), Ocean's Memory and Blur end with the fight, seal and Library bonuses, Sage teammate AI, PvP mapping. Freeze, Magician Sleep and Frost Bomb share the monster hold budget; weakening counts once.
  • Gods (FaithSystem, GodBoonSystem, GodDeedSystem, GodSwitchSystem, MiracleSystem, ImmortalDeedSystem, NpcFaithSystem, WeeklyGodSystem, OldGodEchoSystem):
    • one god list (the ten Temple gods, called canon gods in the code, plus player-gods), Favor 0 to 100 with four tiers, neglect, per-source daily caps, five save sites, read-time standing from player_data;
    • a boon and a Mental ward per domain, recalculated at login, the Temple, worship changes, tier crossings and player-god changes, routed through monster, group, PvP and world boss fights;
    • deeds and taboos at their real call sites, one shared +4 deed cap a day; self-defence street kills are not murder;
    • switching costs all Favor plus wrath, once, with a saved guard; desecration standing penalty per world week (DailySystemManager.WorldWeek, 7 PM Eastern reset boundaries);
    • Miracles at Chosen, once a day (MiracleUsedToday), in monster, boss, Old God and group fights; Mortis's cheat death replaces the old divine save; not PvP or world boss;
    • player-god bless (+2 Favor, tier bonus, NPCs 10%), chastise (-5 Favor, once a day per follower), no smiting own followers; offline Favor through one SQL transaction with a failure result;
    • NPC faith (fill-once weighted pick), 5 standing per NPC follower, loosely devout NPCs recruit and convert easily, player-god boon scale compares players only;
    • god of the week (+5% XP in TeamHQBonus.ApplyXP, picked once per world week by a conditional upsert);
    • Old God echo (+10% weapon and spell damage at Zealot, lines at Zealot and Chosen).
  • Temple: rebuilt as rooms (Nave, Undercroft, Faith, Old Stones, Halls of Memory, Chapel, Deep Temple), menus from one item list per room (visual, screen reader, BBS 80 columns); Evil ward lifted (Nave refuses offerings to good gods other than the follower's own); Temple Confession removed (ConfessionsToday still read); Aurelion resolved in the Deep Temple through the dungeon's result handling (CanEncounterBoss), floor 85 points back; old keys print a pointer; 75 unused keys removed.
  • Stat rewards: player reward and penalty writes moved from derived stats to base stats so they survive the next recalculation (NPC, world and admin writes and Iron Rations hardening are left for 1.2.1); temporary effects end at rest; artifacts and the NG+ cycle bonus restored once at login (idempotent guards).
  • Input: strict yes/no prompts everywhere (AskYesNoAsync, source guard), single-player menus need Enter by default (setting E).
  • Online: "Also here" and the auction broadcast exclude the viewer by account (a family name or alt no longer lists the viewer); a session dropped before entering the world posts no departure; character creation rolls survive a disconnect (creation_rolls).
  • Secret bosses: only a win clears the chamber, pays once, group members cleared on a win.
  • Translations: every class's spell names and descriptions, god titles and descriptions, drug and prison activity messages in five languages.
  • Tooling: electron-client/generate-sprites.js reads the PixelLab key from PIXELLAB_API_KEY only; the key that was in the file remains in git history and must be revoked at PixelLab.
  • Version: GameConfig.Version 1.2.0, VersionName "Devotion", title screen tagline "The gods are watching." (banner keys in five languages, README). Player-facing text calls the ten gods the Temple's gods, since the Old Gods are the story's original divine.

Data

New tables, created at start: creation_rolls, god_standing_penalties. New world_state key: god_of_week. The short-lived god_favor table is dropped at start. Existing saves load with Mental 100 and Favor 10 with their current god.

Tests

3,735 tests pass on the head (dotnet test Tests/). Every behaviour change has a test that fails when the change is reverted.

binary-knight and others added 30 commits September 26, 2026 00:30
Character.MenuKeysNeedEnter defaults to true and rides the save
(Character, PlayerData, SerializePlayer, RestorePlayerFromSaveData,
PlayerSaveEditor). A save without the field reads true. The load, a new
character and an NG+ restart mirror it to GameConfig.MenuKeysNeedEnter.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
…d Enter

With GameConfig.MenuKeysNeedEnter on, the local console branch of
GetKeyInput reads a line and takes its first character, as the MUD, BBS
and door paths do. With it off, the one-key Console.ReadKey read stays.
Pauses (PressAnyKey) still continue on one key. The console key read is
a static seam so the branch can be driven in tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
TryHoldMonster applies a freeze or a sleep to a monster under the same rules
as a stun: refused while the monster is held in any way (stun, web, freeze,
sleep) or in its post-hold immunity; full, half, then quarter duration per
fight, then immune to freeze and sleep for the fight; capped at 3 rounds;
bosses and mini-bosses resist half the time and are held 1 round.

- Freeze and Magician Sleep (both spell handlers) and Alchemist Frost Bomb
  (both ability paths) use it. Frost Bomb rolls 75% and then the budget's
  boss resist, in place of its own 40% boss chance.
- A freeze or sleep ending starts the stun post-hold immunity (3 rounds).
- Every landed hold counts in Monster.HoldsThisFight; stuns count there too,
  and freezes and sleeps count toward the stun diminishing returns.
- TryStunMonster refuses a frozen or sleeping monster.
- Dissonant Wave's multi-target stun goes through TryStunMonster like its
  single-target twin.
- Freeze asks for 1 + rand(2) + Level/40 rounds.
- The Freeze and Sleep cast lines no longer claim the hold landed; a resisted
  or refused hold says so. Four keys in all five languages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
The visual and screen-reader preference menus list the setting under
Display on key E and show its state. It only changes single-player in a
local console, so it is hidden online, in MUD and in door play. The
toggle updates the terminal flag at once and saves. Label and message
in all five languages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
The spell weaken handlers (current and older) and the ability weaken on
the multi-monster path cut the monster's base Strength and Defence for
good and also set WeakenRounds, which Monster.GetAttackPower and
GetDefensePower already read for a timed -30% attack and -20% defence.
They now set WeakenRounds only, as the single-monster ability path has
done since 0.57.1, so the base stats are unchanged when it runs out and a
recast refreshes the timer instead of stacking another permanent cut.

Covers Wavecaller's Siren's Lament, Abysswarden's Noctura's Whisper and
the Bard's Cutting Words.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
…AskYesNoAsync

About 220 call sites read a line and test GameConfig.IsAffirmative alone, so a typo
or a stray Enter silently counts as No. Add IsNegative (N, No, Non, Nem) next to
IsAffirmative, and TerminalEmulator.AskYesNoAsync, which asks again on anything
that is neither, takes an optional default on a bare Enter, and falls back to No
after MaxInvalidChoiceAttempts or a dead connection. Route both ConfirmAsync
overloads and BBSTerminalAdapter.ConfirmAsync through the same IsAffirmative/
IsNegative pair and a new loc'd re-ask line (ui.answer_yes_no, all 5 languages)
so no caller is left on a different answer set.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
DiscoverySystem.RunRisk used IsYes (IsAffirmative or "1"), so any stray key
silently read as No and walked the player away from a dungeon discovery,
spending it for the price of one wrong keystroke. "1" is not shown in any
language's risk_confirm prompt, so drop IsYes entirely and route through
AskYesNoAsync, which re-asks on a typo instead of guessing. Tests cover
GameConfig.IsNegative, AskYesNoAsync (yes/no in every language, re-ask on
junk and on a bare Enter when strict, the default on Enter when given, the
fallback after the attempt cap), both ConfirmAsync overloads routing through
the shared helper, and the discovery risk prompt re-asking on junk instead
of walking away.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
TempleLocation, CastleLocation, DarkAlleyLocation, DungeonLocation, MagicShopLocation,
CharacterCreationSystem, TeamCornerLocation, HealerLocation and AnchorRoadLocation each
read a yes/no answer and tested GameConfig.IsAffirmative alone (or a hand rolled
StartsWith/== equivalent), so a stray key or a typo silently counted as No. Every site
now calls TerminalEmulator.AskYesNoAsync, which re-asks on anything that is neither a
localized yes nor a localized no; prompts shown as (Y/n) or (y/N) pass the matching
enterDefault so a bare Enter keeps its old default.

MagicShopLocation.IdentifyItem was synchronous (GetInputSync) and had to become async
Task to host the new read; its one caller now awaits it.

No exemptions: every site in these files was a real yes/no read. No new player facing
text; all converted prompts already existed in Localization/en.json.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Nine converted sites get behaviour coverage: CharacterCreationSystem.ConfirmChoice
(the shared helper several call sites route through), AnchorRoadLocation's gauntlet
surrender prompt (a (y/N) default site), and DungeonLocation's tutorial prompt. Each
shows a junk answer re-asks (the loc'd re-ask line appears) before a real Y or N is
honored, and the gauntlet surrender site confirms its old Enter-means-No default held.

A source check greps the nine converted files for IsAffirmative(, StartsWith("Y") or
== "Y" outside a yesno-exempt marker line, so a regression or a missed site fails loud.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Second batch of hand-rolled yes/no checks (a line read plus
GameConfig.IsAffirmative, or a StartsWith("Y")/=="Y" chain) converted to
the shared strict prompt across 34 files. Added TerminalEmulator.AskYesNoKeyAsync
as a single-key sibling of AskYesNoAsync, sharing one loop through a new
private AskYesNoCore. Seven sites are genuine menus (an extra key beyond
Y/N with its own meaning) and stay as they were, marked yesno-exempt with
a reason. OnlineAdminConsole reads through its own sanitizing ReadInput,
so it gets a small local strict-loop helper instead of calling
TerminalEmulator directly.

Tests/YesNoConvert1115BTests.cs covers a representative handful of
converted call sites, the new AskYesNoKeyAsync helper, and a source sweep
that nothing in these files still tests IsAffirmative/StartsWith("Y")/=="Y"
outside an exempt marker. Updated one pre-existing test whose assertion
depended on the exact wording of a re-ask line this batch unified.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Tests/YesNoGuard1115Tests.cs scans every Scripts/**/*.cs (excluding the
shared prompt and its plumbing) for a hand-rolled yes/no test: a bare
IsAffirmative(, a StartsWith("Y"/'Y', a =="Y"/'Y' or "Y"== read, or the
localized si/igen chain pieces. IsNegative is qualified to GameConfig.
IsNegative( because the bare name collides with StatusEffect.IsNegative()
and RelationshipManager.IsNegative(), unrelated debuff/relationship checks
called the same way six times in CombatEngine. Bare == "O"/== "I" are left
out of the chain: on the current tree they are nine common multi-way menu
letters (Info, Insult, Open, Item, Inn) unrelated to yes/no; the one real
localized chain already carries a plain == "Y" on the same line, so nothing
is lost.

A marker line counts toward ExemptSites whether or not its own code is a
hit, matching the eleven yesno-exempt markers already in the tree (three of
them on CombatEngine's multi-line spare/finish alias comment, where only
one line is itself a match). Zero unmarked hits and ExemptSites = 11 are
both asserted, so a new exemption needs a deliberate edit here.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e guard

YesNoConvert1115ATests.ConvertedFiles_HaveNoBareYesNoCheck_OutsideAnExemptLine
and YesNoConvert1115BTests.OwnedFiles_HaveNoHandRolledYesNoChecks_OutsideAnExemptMarker
each swept a fixed file list with a pattern set that is a strict subset of
YesNoGuard1115Tests: fewer files (their own batch only, versus every
non-helper Scripts file) and fewer shapes (no GameConfig-qualified
IsNegative, no "Y"==, no si/igen). Removed both; the behaviour tests in
each file are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
…weep

CastleLocation crown join, HomeLocation upgrade confirm, and MagicShopLocation
team curse removal and dark magic proceed passed English literals straight
into TerminalEmulator.AskYesNoAsync. A repo sweep for the same shape found
three more in SysOpConsoleManager (ban, unban, kick confirm). All seven now
go through Loc.Get in all 5 Localization files, reusing magic_shop.proceed_yn
where the meaning already matched.

Tests/YesNoLoc1115Tests.cs adds a source check that no AskYesNoAsync,
AskYesNoKeyAsync or ConfirmAsync call in Scripts (outside TerminalEmulator.cs
and Scripts/BBS/) takes a hardcoded English literal as its prompt, and a
check that every new key exists in all 5 languages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Label changed in all five languages; Tests/MenuAltLabel1115Tests.cs checks it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Dulling Mist (slot 5), Scholar's Mark (6), Slumber Mist (10), Compel (14) and
Unveil the Pattern (18) replace Duplicate, Roast, Giant Form, Dominate and Summon
Demon in the same slots and level gates. Psychic Scream keeps its damage and now
distracts every enemy for 2 rounds.

Slumber Mist goes through the hold budget, bosses are immune, and any damage
since it landed (a hit or a damage over time tick) wakes the monster at its turn.
Compel taunts every enemy onto the party's tank (the sturdiest member when there
is none) and weakens it; Old Gods resist. Bosses and mini-bosses resist soft
control a quarter of the time and take half the rounds; Mass Confusion holds a
boss at most 2 rounds. An area control spell that sets no damage no longer takes
the level-based fallback damage. A teammate's spell honours the Mark.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
…lls honour the Mark

SpellInfo keeps Name as the English identifier and gains DisplayName and
DisplayDescription, read from spell.<class>.<level>.name / .desc when the key
exists and the server has not overridden the text. The six reworked Sage spells
have both keys in all five languages. The cast lines, quickbar, spell library,
combat skill toggles, progression roadmap, training list and world boss spell
list show the display name.

Tests for a teammate's spell on a marked target.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
…ce for the party

Fog of War (smaller: 5 + Level/15), Shadow Cloak, Mind Blank, Noctura's Veil and
Ocean's Memory are area Buffs now and go through ApplySagePartyWard: the caster,
every living teammate, and the leader when a follower casts. Shadow Cloak and
Noctura's Veil blur each ally, Mind Blank gives each ally status immunity, Ocean's
Memory halves each ally's mana cost. Veloura's Embrace is an area Heal.

Wards follow one rule everywhere in monster combat: the highest wins, nothing
stacks (ApplyWardHighestWins), including a Cleric or Wavecaller ward and a
caster's own ward.

Ocean's Memory and a whole-fight Blur now end with the fight (they never did).
Blur makes a monster miss a teammate 20% of the time, as it does the player.
Descriptions for the six spells and two new lines in all five languages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
In a duel Slumber Mist puts the target to sleep through the duel control rules,
Dulling Mist slows it, and Psychic Scream blinds it for 2 rounds. Scholar's
Mark, Unveil the Pattern and Compel work through allies and a tank, so in a
duel they say so and do nothing. Wards and Ocean's Memory stay on the caster
in a duel (tested; the duel path never reached an ally).

Blinded did nothing in a duel. A Blinded fighter now misses 25% of weapon
swings there (GameConfig.PvPBlindedMissPercent), on both the player's swing
and the AI's. Two new lines in all five languages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
A Sage teammate now casts, before its attack spells: a party ward the
party lacks (Noctura's Veil, Mind Blank, Shadow Cloak, Fog of War,
Ocean's Memory); area control on a pack of three or more when it still
reaches two enemies and half the pack (Mass Confusion, Unveil the
Pattern, Compel, Slumber Mist, Dulling Mist); Freeze, Scholar's Mark or
Confusion on one strong target. Slumber skips bosses and held monsters,
Compel skips Old Gods, and Freeze and Slumber land through the shared
hold budget. Disabled spells are respected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
binary-knight and others added 29 commits September 29, 2026 05:16
…ayers

An NPC is loosely devout when its canon god is a weak fit for it: the
god's pick weight for its alignment and class is below the weight of a
god of its own side, so it is neither a god of its side nor its class
god (NpcFaithSystem.IsLooselyDevout). A player-god's recruit deed takes
such an NPC, or one with no god, as it takes a pagan (the pagan chance
and 150 god XP); any other NPC is a steal as before. The deed now reads
this from the target instead of its translated label. An NPC believer
can convert a loosely devout or godless NPC at its location, never a
strong fit and never one who already follows its god.

A player-god's boon scale compares players' standing only: the standing
without the NPC followers' part, on both sides of the comparison. NPC
followers still count for the rankings, the altars and the weekly god.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
…s allowance used

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
…enalties

A Zealot or Chosen's damage spells deal 10% more to the Old God their
god echoes: a single-target spell on its damage once before the hit, an
area spell per target, so only the echoed Old God gains it.

A desecration penalty written in a new week keeps the week before and
drops only older weeks, so the new week's weekly god pick still counts
the ending week's penalties when a desecration comes before the pick.
Single-player, a desecration in a week with no pick yet records the
pick first.

A test covers that an NPC follower of the week's god gets no XP bonus
online, where NPC teammates' XP passes through the same path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
…f Memory

The Temple's flat menu becomes a hall screen of rooms, one key each: the
Nave of the Gods (W worship or switch, Y pray, O offer, A the Altars
screen), the Undercroft (the dark altars and D desecrate), the Faith
(Mirael and the Cloister, the old Inner Sanctum), the Old Stones
(prophecies and the foundation stones) and the Halls of Memory (the
Fallen, the Rite of Return, the Ascended), with the Chapel and the Deep
Temple where they apply. The visual, screen reader and BBS menus come
from one item list per room.

W lists every altar, canon gods and player-gods, and folds in J and L;
O folds in C, I and $ (gold at any canon altar or your own player-god,
goods at your own god's). The Altars screen shows your Favor, tier,
boon, ward and Miracle, the one ranking by standing and this week's god;
Manwe is on no altar or ranking. The Temple Confession is removed (the
Church keeps confession; the saved counter stays). Evil players may
enter: the Nave refuses their offerings to good gods, the Undercroft
welcomes them. An old hall key prints a pointer to its new room.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
The god rank titles, Lesser Spirit to God, come from Loc in English,
Spanish, French, Hungarian and Italian wherever a player's own screen
shows them: the Temple, the Pantheon, the daily divine power line and
the who list. News lines and text built for another player's session
keep the English titles, as all news does.

The French lines for NPC faith, the weekly god and the Old God echoes
use vous, as the rest of the Temple text does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
…to it

The Deep Temple now shows only when the story's own gate lets Aurelion's
fight start (OldGodBossSystem.CanEncounterBoss: level 75 and three Old
Gods faced, or the Sunforged Blade for an awakened save), where it used
to open at level 55 and then refuse the fight. Its result goes through
the dungeon's Old God handling (artifact, alignment, God Slayer surge,
forced save, the town's reaction), and an awakened save's quest ends
there too. His floor 85 boss room points the player to the Temple
instead of fighting; an older awakened save still completes on the
floor. A resolved Aurelion is an entry in the Halls of Memory, and T at
the hall points there, never to a fight. The journal and the floor 85
hints name the Deep Temple. A room ignores a key it does not list.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
…echo

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Piece 7 moved Aurelion's fight to the Temple's Deep Temple and left the
Main Street Old Gods list, the Inn bartender's next-god rumor, the
sunforged save-quest return line and the oracle's floor list still
naming floor 85. All four now name the Deep Temple in the Temple, in
all 5 languages; the admin console's god list label follows in English.
OldGodsData.EncounterLocation for Aurelion (never displayed) is updated
for consistency.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
…ehind

The Temple Confession, the pre-rooms flat menu and its screen reader
labels, and the old believers/status counters no longer have a reader
in Scripts, Tests or web after the piece 7 room rebuild. Removed from
all 5 languages: 74 temple.confess_*, temple.menu_*, temple.sr_*,
temple.your_status and temple.believers_count keys. Kept:
temple.sr_ask_join, temple.sr_leave_prayers and temple.sr_talk_past,
still read by the Faith room's Cloister prompt.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
…led floor 85 door, and the Nave's own-god exemption

Four supervisor-verified leftovers from the piece 7 room rebuild. The
old K and V hall keys now print their Halls of Memory pointer only
while HallsOfMemoryOpen() is true, else the plain invalid-choice line
(a source guard: the permanent Pantheon statues keep the Halls open in
practice today). An offering's kind menu no longer stays silent on an
unhandled key. Floor 85's pointer to Aurelion now checks
OldGodBossSystem.CanEncounterBoss: a player not yet ready (level 75 and
three Old Gods faced) hears the Deep Temple's path is sealed instead of
being sent to a door they cannot open. The Nave now accepts an Evil
player's offering to the god they already worship; offerings to any
other good god are still refused.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
PrisonActivitySystem's player activity path (PerformActivity and its
PerformXxx helpers: pushups, yoga with the optional Agility gain,
reading, meditation, shadow boxing, stretching, planning, prayer for
guidance and prayer to darker powers, plus the rest and exhausted
messages) returned hardcoded English sentences. They now go through
Loc.Get with new prison.activity_* keys, added next to the existing
prison keys in en, es, fr, hu and it. The NPC world-simulation path
and the NewsSystem release line are unchanged by design.

A new source test asserts the player activity path never returns a
raw string literal again, and that every prison.activity_* key it
uses exists in all five languages with matching {n} placeholders.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jmfGHNHqoL1NXhfvUezQW
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
@binary-knight
binary-knight merged commit 3e0fa67 into main Sep 29, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant