Skip to content

v1.1.12: Awakening rework, Team Corner overhaul, and playtest fixes - #153

Merged
binary-knight merged 30 commits into
mainfrom
release-1.1.12
Sep 24, 2026
Merged

binary-knight merged 30 commits into
mainfrom
release-1.1.12

Conversation

@binary-knight

Copy link
Copy Markdown
Owner

Version 1.1.12. Release notes: DOCS/release-notes/RELEASE_NOTES_1.1.12.md; Steam text: DOCS/release-notes/steam/STEAM_RELEASE_NOTES_1.1.12.txt.

Changes

  • Awakening:
    • Stages are reached by points: moments 3, Wave Fragments 2, distinct insights 1. The thresholds are 4/12/22/34/48/62; stage 7 also needs all seals or the revelation.
    • Insight ids are saved. The seven moments that were never recorded now are, and MemoriesRecovered is reachable (4).
    • A framed AWAKENING screen shows each rise at the location loop's safe point. There is a first-login line and a one-time hint.
    • [P] Progress shows the stage out of 7, and [J] opens the Ocean Journal.
    • Stage gifts are derived from the stage at run time, never saved:
      • Wisdom, max HP and max mana through the stat recalculation;
      • damage dealt, damage taken and combat XP through the same sites as the Team HQ bonuses.
    • The stage is stamped on the character at run time, so grouped followers keep their own. A duel defender is stamped from its own saved story data (the maintainer's design choice).
    • Story chapter 1 is "The Drowning".
  • Team Corner:
    • A shared paged picker (BaseLocation.PickFromList) for Info, Join, Examine, Sack, Equip, Specialize and Resurrect.
    • The rankings read the saves in one pass (about 6 s down to 0.1 s on a copy of the live data), with real power and levels, mixed teams, and empty teams hidden.
    • Fixes: the password hash (leader only), dissolve clearing upgrades and vault, create clearing leftovers, case- and accent-insensitive names, stale NPC re-lookups after a roster reload, war expiry and guarded settlement, vault deposit ordering and capacity, guarded upgrades, the gear-move save order, and a five-member limit with dead members holding their place.
  • Playtest fixes: the world event reward label, cursed item tags and confirmation, the one rest per floor (saved with the floor), a lives hint, the stamina bar for casters, gear comparison for dungeon finds and the merchant, and the training, auto-combat and world-events texts.
  • Other:
    • NPC teammates no longer attack their sleeping player (the team path was $.Player.Team).
    • Gold transfers are delivered to the playing character's save key, so an alt's wires and refunds reach it.
    • The admin deletes read a banned character's Name2.
    • The delete purge keeps mail to a name another character goes by, and drops the deleted payer's claim on an unfinished war refund.

Known and unchanged

  • Two simultaneous joins can take a team to six (membership lives in the saves).
  • Two processes recovering the same NPC's gear at once (the shared NPC record has no owner process).
  • A crash mid-deposit loses rather than duplicates the gold.
  • A fought war whose completion fails is abandoned with nothing paid.
  • Existing case-variant team names stay separate.
  • The es/fr/hu/it Awakening text awaits a native speaker's review.

Listed for 1.1.13

  • Equip Best removes the first same-name backpack item while giving the stronger one.
  • The delete purge's sender mail clause removes mail sent by a living character whose display name equals the deleted account's username.
  • The Home and Inn character equipment screens and the Dungeon party equip menu lack the take/give save order.
  • The throne challenge looks a player king up by display name as a save key and falls back to a stand-in.
  • Deferred from 1.1.11: NPC grudge and marriage clean-up on deletion, and a stale save restoring a deleted king; both need an owner-process design for shared records.

Tests

1,731 passing, up from 1,568.

binary-knight and others added 30 commits September 24, 2026 05:29
The rankings counted each team's members with its own scan of every
player save, so 66 teams parsed about 2.4 GB of save JSON per view
(about 6 s on a copy of the live data, now 0.1 s): one pass now reads
each save once. Player-only teams showed power 50 per member and an
average level of 0; the real levels and stats are used. A team with NPC
and player members counted the NPCs and the viewer only; it now counts
every member once. Teams with no members are not listed.

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

- The world event bonus line shows only the world event's share; it was
  printed on ordinary kills with the early-game and team bonuses in it.
- Cursed items are tagged in the backpack (identified ones only), the drop
  hint names the Magic Shop, and equipping one warns it cannot come off.
- A sanctuary rest and the camp say you can rest once per floor.
- A one-time hint explains lives when you first enter the dungeon.
- Spellcasters see the stamina bar only when they can spend stamina.
- The training points hint names the Level Master's key; the auto-combat
  notice says what it does; Main Street's menus show the world events key.
- Gear found in the dungeon and the merchant's wares are compared with
  what you wear, as monster drops are.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- The awakening level comes from points: 3 per moment, 2 per Wave
  Fragment, 1 per distinct insight. Stages 1-6 need 4, 12, 22, 34, 48
  and 62 points; stage 7 needs the stage 6 points and all seals, and
  the true identity still grants 7 at once.
- Every insight source passes a stable id (dream, vision, discovery,
  room feature, riddle, song, story stage, paradox choice, dialogue
  node, betrayal, the Dark Alley void); the same insight counts once.
- Insight ids are saved with the story systems. A restore replays
  fragments, moments and insights without announcing them and keeps at
  least the saved level, so no existing character loses a level.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- SparedAnEnemy: sparing an NPC who begs for mercy in a duel.
- MetManwe: the Creator's dialogue starts.
- LetGoOfPower: accepting Manwe's Offer and lowering your weapon; also
  the refuse_power choice, which is in a paradox never presented.
- RejectedParadise and AbsorbedDarkness: the floor 95 choices.
- HeardOldGodLoreSong: the first Old God lore song at the Music Shop.
- AcceptedGrief: a grief, companion or NPC, reaching Acceptance.
- MemoriesRecovered needs 4 memories: only the four floor memories and
  the full truth can be recovered.
- The Manwe alliance granted "CreatorsRest", which is not a fragment;
  it grants The Choice.
- The moment recorded when a companion joins has text that says so.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- A stage rise is queued on the session's awakening and shown once at
  the top of the next location loop, which a fight returns to when it
  ends; never mid-fight or mid-dialogue. Rises before that point fold
  into one screen.
- The screen names the stage, gives four lines of its lore (the Old
  Gods as drops of the same water by stage 4; only stage 7 names
  Manwe), the boon each stage adds and what it opens.
- A new character's opening dream ends with a line that something
  within them is asleep and that loss, mercy and wonder wake it.
- The status screen's awakening line points to [P] Progress, and a
  one-time hint explains the awakening the first time the line is
  shown or the stage first rises.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- The awakening section shows the stage out of 7 with the status
  screen's names, the points toward the next stage, the Wave Fragments
  found out of 10, the moments lived and the active boons.
- [J] on that screen opens the Journal's pages: the lore of each
  fragment found and the moments lived.
- Fragment titles and lore, and a line for each moment, are localized.
- The old /5 scale and its keys, the unused story_awakening keys and
  the uncalled English GetFragmentLore are removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- Stage 1 +3 Wisdom, 2 +5% max mana, 3 +5% combat XP, 4 +5% max HP,
  5 +3% damage dealt, 6 3% less damage taken; stage 7 adds 5 more to
  each percentage and the title the Awakened. Cumulative, computed from
  the stage at run time, never stored on the character.
- Wisdom, max HP and max mana are added in RecalculateStats (Wisdom
  beside gear, so it feeds mana; HP and mana beside the divine boons).
- Damage, damage taken and combat XP ride on TeamHQBonus.ApplyAttack,
  ApplyDefense and ApplyXP, at the same sites and in the same order as
  the Armory, Barracks and Training, rounded once.
- Only the session's own player gets them; companions, NPCs and other
  players' characters do not.
- A load recalculates once the story systems are restored and gives
  back the saved HP and mana the earlier pass clamped.
- The status screen and the Journal list the active boons.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
The first chapter and its opening banner were both called The
Awakening, the name of the awakening meter. They are now The Drowning
in all five languages, after the opening dream.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Lists instead of typed names: Info, Join, Examine, Sack, Equip,
Specialize and Resurrect use one paged picker (a number, a name or the
start of one). Examine lists player members too.

- Changing the team password updates the stored password; leader only.
- A dissolved team takes its upgrades and vault with it.
- Quitting keeps the team protected while any player is still in it.
- Create charges only when the team is made; names are trimmed and
  compared ignoring case.
- Sack, Resurrect and Specialize act on the current NPC after a world
  reload; Resurrect saves the shared state.
- A war left running by a disconnect is abandoned after 10 minutes and
  its wager refunded if no round was fought; a war with no rounds costs
  nothing; the wager and result are saved.
- Vault deposits save before crediting and respect the capacity;
  upgrades cannot be bought twice at once or past level 10.
- Equip saves the player before the team and equips nothing that was
  not taken.
- Teams hold 5 members, players and NPCs, dead ones keeping their slot.
- View inventories is on every menu; rankings and war history page;
  Resurrect and withdraw confirm; Sack offers to take the gear first;
  the menu's text is translated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
A stage can rise inside a fight (a companion's death, a spared foe).
The Wisdom, max HP and max mana boons are now recalculated when the
AWAKENING screen shows at the top of the location loop, which every
dungeon room action and every fight returns to, instead of at the
moment of the rise. The test pins the screen inside that loop.

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
- A team war with no rounds is refunded only when it is closed; if the
  close does not land, the stale-war cleanup refunds it once.
- Join checks the five-member limit again after the password.
- Sack takes the gear only while the NPC is still on the team.
- A cursed item asks before it is equipped, into an empty slot too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
The rest flag lived in memory and was cleared on every floor entry, so
logging out and back in allowed another rest. It is saved with the
floor's state and cleared only when the floor respawns.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- A won or lost team war pays or charges only when its result is saved;
  otherwise the player is told the war was closed or its result is
  pending, and the stale-war cleanup settles it once.
- Gold transfers are delivered to the character they were sent to, so an
  alt's refund or wire no longer goes to the main character.
- A team founded by an NPC can change its password again.
- Examining a player teammate shows their saved health, mana and age.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- A player's awakening stage is kept on the character at run time
  (never saved), so a grouped follower acting in the leader's session
  keeps its boons. The follower's own session stamps its character on
  load and on every rise; joining a group hands the leader that same
  object, and the join stamps it again in the follower's session.
  Unstamped characters fall back to the session's stage.
- Existing teams whose names differ only in case are listed, ranked and
  joined by their exact name; a new case variant is still refused.
- Examining a player shows the saved health and mana maxima.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- Sack saves the recovered gear the moment it moves, then strips it from
  the NPC found again by ID (a reloaded copy wears it under a new item
  ID, so the slot and name are matched too): the gear is in one place.
- New team names are compared with Unicode case folding on every
  connection, so an accented case variant is refused. Variants already
  in the tables stay separate teams, joinable by their exact name.
- Design choice (the maintainer's): a player loaded from their save as a
  duel defender gets the awakening boons of their own saved stage, as
  they already get their own team's HQ levels. The stage is computed
  from the save's story data with the same points function, never from
  the attacker's session; the loader stamps it before its one
  recalculation. An echo gets none. An unstamped character that is not
  the session's player still reads 0.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
A war left active with no round played is refunded later by the stale
cleanup to the key that paid; after a delete and a recreate on the same
key, the new character collected the old one's wager. The purge clears
the payer key on the deleted character's active wars, so the cleanup
abandons them without a refund.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
The quit path counted living NPC members only, so the last player
leaving while the NPCs were dead dissolved the team with its vault and
upgrades, and the NPCs respawned on a team that no longer existed. A
dead NPC member counts, as it does for the five-member limit; a
permanently dead one does not.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Both admin deletes read the character's Name2 through ReadGameData,
which skips banned accounts, so a banned married character was purged
under the married display name: its children, recorded under Name2,
were not disowned and passed to a later character of that name. The
Name2 is read from the row itself, banned or not.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Death by age is permanent, so, as in the five-member count, it holds no
place when the last player quits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
The joiner was left out of the member count by display name, which also
dropped an existing member of the same (married) display name, so a
full team could take a sixth. The joiner is left out by save key.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- Quitting does not dissolve a team while the NPC roster is being
  rebuilt; a rebuilt roster could show none of its NPC members. The
  empty-team sweep removes a team that really is empty.
- Recruit and Resurrect run the team size query before looking the NPC
  up again, so no await falls between that lookup and the change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Both left the viewer out by display name, which also hid a teammate of
the same (married) display name: that teammate could not be examined or
picked, and got no team mail.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- The delete purge removed mail addressed to the character's display
  name even when another character goes by that name (a married
  "Bob Smith" beside a player "Bob Smith"); that mail is kept.
- The team status list, the player-ally recruit list and the siege
  force leave the viewer out by save key, not display name, so a
  teammate of the same name is shown.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- Every Team Corner gear move is saved at once in the order that cannot
  copy an item: gear taken from an NPC saves the shared state first,
  gear given to one saves the player first (shared helpers, also used by
  Sack and Equip Best).
- The delete purge keeps mail to the deleted account's username when
  another character goes by that name.
- A recruited player echo is stored and loaded by its save key, never
  the viewer's own save; old entries holding a name still load.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
- A recruited echo is matched by its save key, and an older entry by
  display name only; an NPC's name is never compared with a save key, so
  an echo whose key equals an NPC's name still loads and stays recruited.
- Equip Best offers gear displaced earlier in the pass to the remaining
  slots again, keeping the save order that cannot copy an item.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
Before this release, a team dissolved by its last member left its HQ
upgrades and vault under its name, and the next team of that name got
them back. Creating a team now clears any rows left under the name in
the same transaction as the insert; a refused create touches nothing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CT1VB81uLs5VNysGendLKY
The world sim leaves a sleeper's NPC teammates out of the attackers by
the sleeper's team, read from their save as '$.Player.Team'. The save's
keys are camelCase, so the path never matched, the team came back empty
and any Dark or Evil teammate could attack. It reads '$.player.team'.

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
@binary-knight
binary-knight merged commit fb69b1e into main Sep 24, 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