Sweep of the remaining four twinbee_*.go flavor files (gm, resource,
ambient, housing). Every 'TwinBee [verb]' / 'TwinBee says' / 'TwinBee
notes' rewritten into first-person or implicit-subject voice. Jokes,
references, and pacing preserved; a few lines got slightly sharper
punchlines on the way through.
Files touched:
- twinbee_gm_flavor.go (~270 lines, all narration pools)
- twinbee_resource_flavor.go (~100 lines, harvest/fish/loot pools)
- twinbee_ambient_flavor.go (~40 lines, between-day ticker)
- twinbee_housing_flavor.go (7 lines; Thom Krooke 3rd-person and
Pastel 1st-person voices preserved)
twinbee_npc_flavor.go intentionally untouched: those are Pete
announcements referring to TwinBee, which is correctly third-person
(different speaker).
DO-NOT-REWRITE headers replaced with voice-convention notes covering
future additions.
Every 'TwinBee [verb]' / 'TwinBee says' / 'TwinBee notes' rewritten
into first-person or implicit-subject voice. Header DO-NOT-REWRITE
prohibition retired (it predated the realization that the third-person
voice was actively annoying); replaced with a voice-convention note
covering future additions.
Sibling twinbee_*.go files still carry third-person references; sweep
to follow.
Active expeditions now tick on a 3-hour cadence between the 06:00
briefing and 21:00 recap. Each fire DMs the player a short TwinBee
moment — mostly pure flavor (dripping sounds, polite possums,
diplomatic moths) with a 50/50 chance of a small mechanical nudge
(±SU, +threat, 1d4 coins from a found purse, +1 HP if camped).
The dungeon is now louder while you're offline without being
balance-relevant. Multi-day expeditions feel populated by something
other than the player's calendar.
Mechanics:
- new last_ambient_at column with CAS idempotency (mirrors
briefing/recap pattern in dnd_expedition_cycle.go)
- ambientCooldown=3h, skipped if in turn-based combat session
- 60min politeness window around scheduled briefing/recap so we
don't pile DMs on the daily messages
- weighted event pool with per-event eligibility (camp_visitor
requires camped, pack_rat requires SU>=1, faction_whisper
requires threat>=30 and not siege)
- effects: applyThreatDelta, updateSupplies, euro.Credit +
coins_earned bump, SaveDnDCharacter HP nudge (clipped at max)
Files:
- internal/db/db.go: ALTER TABLE + CREATE TABLE update
- internal/flavor/twinbee_ambient_flavor.go: 7 humor-heavy pools
- internal/plugin/expedition_ambient.go: ticker + resolver
- internal/plugin/expedition_ambient_test.go: 8 pure-logic tests
- internal/plugin/adventure.go: wire goroutine in Start()
Bundle of uncommitted working-tree edits across combat engine, expedition
cycle, flavor pools, and TwinBee/zone narration. Includes new files:
combat_debug.go, dnd_boss_consumables.go, dnd_dex_floor.go, plus
CHANGES_24H.md and REBALANCE_NOTES.md scratch notes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GM→DM rename across docs and code (GMNarrationType→DMNarrationType,
GMState→DMState, narration constants, comments) so the system reads as
"Dungeon Master" everywhere. Player-visible "GM mood" wording stays
where it appears in flavor.
Streamed zone/expedition combat: zone advance now stages patrol →
patrol play-by-play → patrol resolution → room intro → room play-by-play
→ final outcome through sendZoneCombatMessages with 2–3s pacing
(arena keeps its 5–8s window). Combat narrative lines pick up a compact
d20-vs-AC roll annotation for hit/crit/miss/block events.
Combat outcome polish: dndHPSnapshot lets narration show sheet HP
rather than legacy combat-engine HP, and markAdventureDead clears the
zombie state where hp_current was 0 but the legacy alive flag stayed
true after a D&D-layer KO.
Adv 2.0 announcement (ADVENTURE_2.0_ANNOUNCEMENT.md), README rewrite
covering the new layer, and adv2_scenario_test.go — a full
zone-run + expedition + harvest playthrough against a copy of the prod
DB asserting persisted state end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expand under-populated TwinBee expedition pools (singletons → 3, pairs →
4) for: morning briefings (Day1/3/14/21), evening recaps (boss/close-call/
quiet), all four threat clock bands, every zone temporal event narration,
supply depletion, and every milestone narration. Add MilestoneCartographer
and MilestoneSurvivalist pools (spec §13). Wire MilestoneSurvivalist into
AwardCompletionMilestones (was inline string).
All additions in TwinBee voice, no existing entries altered.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spec §11.3. New !region command surface:
!region — list regions w/ status (▶ current, ✓ cleared,
· visited, ★ zone boss, ⛺ base camp)
!region travel — move to next region in order
Travel burns one day of supplies via applyDailyBurn (so harsh / siege
multipliers stack normally), advances current_day +1, fires one
transit wandering check (resolveTransitWanderingCheck — same buckets
as the night check but campMod = 0 since you're not bedded down),
then writes region-transition narration on both ends.
Two new flavor pools (RegionTransitDeparture / RegionTransitArrival)
with [REGION_NEXT] interpolation. Travel rejected when camped, and
when already in the final (zone-boss) region.
Tests cover the campMod=0 invariant, the day/supply/region delta on
travel, and the marker rendering in renderRegionList.
§8.3 siege economics:
- applyDailyBurn now takes an explicit siege flag and enforces a 2× floor
on supply burn even when HarshMod is below 2 (tier-1 zones still get
starved out per spec).
- currentBurn mirrors the same precedence so status/briefing readouts
stay consistent.
- Briefing rollover passes e.SiegeMode through, decoupling siege from
the harsh-conditions composite.
§8.3 threat-70 warning: applyDailyThreatDrift emits a one-time
appendApproachingSiegeLog when the level crosses 70 (prevLevel<70 and
new level≥70). Pulls from a new flavor.ThreatClockApproachingSiege pool
seeded with the spec's verbatim warning beat plus two voice-matched
alternates.
Other siege effects (boss +20 HP / Legendary Resistance, cleared-room
respawn, no-short-rest enforcement) stay deferred to the combat-link
phase — ThreatBandInfo already exposes the flags that engine will read.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a TwinBee aside on room entry when GM mood sits at the extreme
bands (≤19 hostile, ≥80 effusive). Mid-bands stay silent — the aside is
strictly extra flavor, never replacing core narration. Two new pools
(MoodAsidesHostile, MoodAsidesEffusive) live alongside the existing
TwinBee voice in twinbee_gm_flavor.go. Wired into zoneCmdEnter and
zoneCmdAdvance; the advance path reloads the run so post-combat
nat20/nat1 deltas are reflected before band lookup.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds zone_underdark, zone_feywild_crossing, zone_dragons_lair, and
zone_abyss_portal flavor files with elite-room intros, boss-entry
pools (where canonical twinbee_gm_flavor.go didn't already ship one),
boss ability callouts, and zone-specific lore. Wires the four pools
into zoneRoomEntryPool / bossEntryPool / bossSignaturePool /
eliteRoomEntryPool / zoneLorePool, and replaces the now-obsolete
"unflavored zone" assertions with Tier 4-5 positive routing tests.
RoomEntryUnderdark, RoomEntryDragonsLair, BossEntryInfernax, and
BossEntryBelaxath are reused verbatim from twinbee_gm_flavor.go per
the canonical-flavor-first rule.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New additive flavor files (zone_manor_blackspire_flavor.go,
zone_underforge_flavor.go) with elite-room intros, boss ability
callouts, and zone lore. Manor reuses RoomEntryHauntedManor from
twinbee_gm_flavor.go; Underforge had no canonical RoomEntry/BossEntry
pools yet, so both are defined in the new zone file.
Aldric Blackspire: Multiattack (life drain) / Charm / Children of the
Night / Mist Form / Phase Two
Emberlord Thyrak: Molten Strike / Forge Breath / Living Forge /
Construct Resilience / Phase Two
Wires zoneRoomEntryPool, bossEntryPool, zoneLorePool,
bossSignaturePool, and eliteRoomEntryPool to the new tier-3 pools.
Adds Tier 3 routing tests for boss-entry, elite line, lore, and
room-entry overlays.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New additive flavor files (zone_forest_shadows_flavor.go,
zone_sunken_temple_flavor.go) with elite-room intros, boss ability
callouts, and zone lore. Reuses existing RoomEntryForestShadows and
BossEntryHollowKing from twinbee_gm_flavor.go. The Sunken Temple had
no canonical RoomEntry/BossEntry pools yet, so both are defined in the
new zone file.
Hollow King: Corrupting Aura / Root Surge / Devour Light / Phase Two
Dreaming Aboleth: Tentacle Multiattack / Enslave / Mucus Cloud /
Legendary Actions
Wires zoneRoomEntryPool, bossEntryPool, zoneLorePool,
bossSignaturePool, and eliteRoomEntryPool to the new tier-2 pools.
Updates the D2b "no callout pool" test to use Dragon's Lair (still
unflavored) and adds Tier 2 routing tests for boss-entry, elite line,
lore, and room-entry overlays.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New additive flavor files (zone_goblin_warrens_flavor.go,
zone_crypt_valdris_flavor.go) with elite-room intros, boss ability
callouts (Grol: Surprise Attack / Heart of Hruggek / Terrifying Roar;
Valdris: Corrupting Touch / Legendary Resistance / Call of the Grave /
Phase Two), and zone-specific lore deep-dives. Existing
twinbee_gm_flavor.go is untouched per the protected-files contract.
Wires three narration helpers in dnd_zone_narration.go:
composeBossEntry — boss-entry render plus a one-line ability callout
eliteRoomEntryLine — elite-room atmospheric prefix
zoneLorePool — zone-specific !lore pool with generic fallback
Boss-entry callsite in dnd_zone_cmd.go now uses composeBossEntry; the
elite branch of resolveCombatRoom prefixes with the zone's elite line.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>