Commit Graph
9 Commits
Author SHA1 Message Date
prosolis ca2d1a8ea3 pets: earn XP from combat wins again
petGrantXP has been dead code since R1 deleted the legacy daily activity
loop it used to ride. Nothing replaced the call, so for the whole life of
Adventure 2.0 the only pet XP in the game came from a paid babysitter.
Prod bears it out: the one player who never subscribed has a pet sitting
at level 1 with 0 XP after months of play.

That is not cosmetic. DerivePlayerStats scales PetAttackProc,
PetDeflectProc and PetAttackDmg off pet level, so a frozen pet is a
permanently dead combat slot that the player has no way to revive.

Wire it into postCombatBookkeeping — the one seam all four combat
close-outs already meet, so a pet cannot level differently depending on
whether the fight auto-resolved or was played a round at a time. Both
slots earn on the same win, matching the babysit trickle: combat only
reads the two pets' averaged procs, so leveling both is not a spike.

Writes go through the narrow per-slot pet upserts rather than
saveAdvCharacter, because this runs on a path that does not hold the
per-user lock and a full-row write could clobber a concurrent save.

Verified against the sim: a level-3 pet finishes one L10 expedition at
level 4 with carryover, where before it finished exactly where it started.
2026-07-20 23:51:49 -07:00
prosolis 57a0ea90f2 N4/E1: second pet slot for the Tier-4 Estate
An Established (Tier-4) home can draw a second companion. Both pets show up on
the sheet and the town showcase, level via babysitting, and wear their own
barding (!thom pet2buy <tier>).

Combat: both pets contribute their attack/deflect/whiff procs at half weight —
DerivePlayerStats now averages over the active pets, so a pair reads as roughly
one full pet (flavor-forward, not a stat spike; difficulty-neutral). The average
reduces to identity over a single pet (x/1==x, 0.0+x==x, 3+(2L+1)/2==3+L), and
the engines still roll one proc per channel per round, so the single-pet path
and TestCombatCharacterization golden stay byte-identical. Pinned by
TestDerivePlayerStats_OnePetIsByteIdentical + the golden.

Scope kept deliberately flavor-forward: pet 2 carries identity/level/barding and
the three combat procs only. The morning-defense buff, death/ditch-recovery
save, and the level-10 supply-shop unlock stay pet-1 mechanics — no second
defensive multiplier stacks, and the one-pet path is untouched by construction.

Storage: parallel pet2_* columns on player_meta + Pet2* mirror on
AdventureCharacter (absent == no second pet, DEFAULT '' correct for every
pre-existing row, no backfill — the N2-temper / P4-party precedent). Pet-1 code
paths are untouched. Arrival reuses the chase/feed/type/name DM flow, slot-aware,
gated HouseTier>=4 with an established first pet.

Review fixes folded in (high-effort /code-review, 3 angles): pet-2 barding block
no longer hidden when pet-1 is chased away; showcase tie-break restored
(level desc, then name); petGrantXP collapsed onto the shared level-up helper;
dead-param armor-buy wrappers inlined; pet-2 barding tagged with its own euro
ledger reason.

Claude-Session: https://claude.ai/code/session_017mEwUmmS7aQTP2NQXj6rUa
2026-07-10 15:03:57 -07:00
prosolis 7dbfa0b56f Pet adoption: stop double-deleting pending, pass interaction to resolvePetName
resolvePendingInteraction deletes the pending entry before dispatch, but
resolvePetName then re-ran LoadAndDelete to recover the carried PetType.
That second lookup always missed, so the if !ok branch returned nil: the
save never ran and no pet was ever persisted (adoption was 100% broken).

Pass the already-loaded interaction in, matching every other handler.
Add a regression test driving the real dispatcher path.
2026-05-22 08:42:47 -07:00
prosolis 3ed2e1d8e0 Pets: roll arrival on expedition emergence, not the 08:00 morning DM
The pet-arrival roll only ran in sendMorningDMs (the 08:00 overworld
morning DM), which is skipped for anyone underground. Expedition players
are almost never in the overworld at 08:00, so the roll never reached
them — the encounter never fired despite the conditions being met.

Move the roll onto the emergence seam via a shared helper
maybeRollPetArrivalOnEmerge, called when a player surfaces alive
(voluntary extract, abandon, survived forced extraction) and on respawn
for underground deaths. Remove the now-dead morning-DM arrival roll.
Story-wise: while the player was out, an animal wandered into the empty
house looking for food.

The 25% morning pet event still rolls only in the overworld DM and has
the same reachability gap; left for a follow-up.
2026-05-21 22:51:00 -07:00
prosolisandClaude Opus 4.7 0ca17628d4 WIP: DM window tiers, expedition activity dedup, harvest gating
- Split advDMResponseWindow into a 12h low-priority tier for passive
  overnight-tolerant prompts (pet arrival/type/name); bump pet arrival
  chance 15% -> 30%.
- Skip zone_run activity lines for runs that belong to an active
  expedition — the expedition rollup is the source of truth.
- Loosen currentRoomCleared: Entry/Exploration/Trap allow harvest
  unconditionally (risk is the combat-interrupt roll); Elite/Boss stay
  gated on RoomsCleared.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:53:58 -07:00
prosolisandClaude Opus 4.7 81cce0169f Adv 2.0 L4d reader flip: pet helpers off AdvCharacter to PetState
All ten helpers in adventure_pets.go now take PetState (or *PetState
for petGrantXP) instead of *AdventureCharacter. mistyHousingHint takes
raw NPC counters since Misty fields stay on AdvCharacter for a later
phase. mistyReactivatePet returns bool; caller flips both stores.

DeathTransitionParams gained Pet PetState so combat_bridge no longer
touches the DB; arena caller loads PetState. PetState.HasPet() mirrors
AdvCharacter's. petMidnightCheck loads PetState per char.

L4 grep-empty exit criterion now holds for adventure_pets.go.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:25:22 -07:00
prosolisandClaude Opus 4.7 0004a2e35c Adv 2.0 L4e reader flip (read-only sites): house state via loadHouseState
dnd_rest long-rest eligibility, dnd_sheet housing display, and
petShouldArrive / mistyHousingHint now source house state from
player_meta via loadHouseState(userID) instead of *AdventureCharacter.
petShouldArrive, mistyHousingHint, and renderDnDSheet gained a
HouseState parameter; scheduler and Misty NPC callers load it.
Reader flip inside adventure_housing.go itself stays deferred — its
mutation paths bundle with cutting AdvCharacter writes post-soak.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:25:22 -07:00
prosolisandClaude Opus 4.7 690817f2ed Adv 2.0 L4d: pets dual-write pet_* off AdvCharacter to player_meta
Eight pet_* columns added to player_meta (flags packed into pet_flags_json).
PetState + load/upsert/backfill helpers; dual-writes wired at every pet
mutation site (arrival, naming, supply-shop unlock, babysit trickle,
morning defense, misty reactivation). Backfill idempotent, runs on Init.

L4 grep-empty exit criterion intentionally NOT met for adventure_pets.go:
helpers still take *AdventureCharacter because external callers (babysit,
scheduler, npcs, combat_bridge, combat_stats, dnd_sheet, arena, character)
read pet fields directly. Cross-file signature flip belongs after the
dual-write soak.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:25:22 -07:00
prosolisandClaude Opus 4.6 76110f61ca Add housing/pets/Thom Krooke, wordle overhaul, boost system, backup strategy
Part 3 (Housing, Thom Krooke & Pets):
- Housing system with tiered upgrades, mortgage loans, FRED API rates
- Thom Krooke realtor NPC with !thom commands and !thom pay extra principal
- Pet system with arrival, naming, leveling, combat, morning defense
- Pet ditch recovery scales with level, name validation

Wordle overhaul:
- Remove daily expiration — puzzles persist until solved/failed
- Auto-start new puzzle after solve, fail, or skip
- Sequential puzzle IDs instead of date-based
- Auto-create puzzle on first guess if none active

Adventure fixes:
- Double XP/money boost toggle (!adv boost, admin only)
- Fix ensureCharacter wiping existing data on query errors
- Fix rival RPS format string bug
- Fix daily summary empty data (load today+yesterday logs)
- Fix holdem DM-to-room reply routing
- Fix Robbie payout to 25% of item value
- Add fishing to leaderboard and TwinBee calculations
- Add Thom to morning menu
- Persist mortgage rate across restarts via db.CacheGet/Set

Infrastructure:
- Daily database backup via VACUUM INTO with 7-day retention
- Admin DM notification on backup failure (async)
- Daily NPC house balance reset for holdem

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 16:50:49 -07:00