mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Expedition autopilot Phase 4 + rogue sneak attack + TwinBee voice sweep
Tedium-removal pass driven by live play feedback. Three big threads: Expedition autopilot Phase 4 — background auto-run + harvest-until-dry: - New expeditionAutoRunTicker walks active expeditions every 15min (5min tick, per-expedition CAS on new last_autorun_at column). Skips combat sessions, briefing/recap quiet windows, expeditions <30min old. - Walks up to 3 rooms/tick with compact narration; suppresses DMs when 0 rooms walked or just hitting the per-tick cap (no "stretch complete" filler). Player only hears from the bot when a real decision is needed. - Compact mode: one-line combat narration for trash/elite, auto-resolves elite doorways via the forward-sim engine (boss still pauses). Threaded via new advanceOnceWithOpts → resolveRoom → resolveCombatRoom. - Auto-harvest now grinds each Common/Uncommon node until dry (cap at 8 attempts/visit), mirroring manual !scavenge retries. Rare+ still pauses. - Ambient ticker: anti-repeat by Kind via new last_ambient_kind column (avoids two pack_rat DMs in a row when the pool only has 6 lines). - !expedition go <n> now routes to the fork-choice handler when active + numeric; fork footer rewritten to suggest !expedition go instead of !zone go. Boss/Elite doorway: formatNextRoomMessage routes the action hint by next room type and autopilot loop breaks via new nextRoomType field so "Room X/Y — Boss" doesn't double-print with contradictory hints (!zone advance vs !fight). - runAutopilotWalk extracted from expeditionCmdRun so foreground and background share the loop body. Rogue Sneak Attack actually exists now: - Audit found the rogue's "Sneak Attack" passive was AutoCritFirst + 5% damage rider. No Nd6, ever. Phase 2 Monte Carlo masked this with a small flat buff; the class's defining mechanic never matched its tooltip or 5e identity. - Added SneakAttackDie int to CombatModifiers, per-hit Nd6 in combat_primitives.go (same lane as DivineStrikePerHit). Scales with level: 1d6 at L1-2 ... 4d6 at L7-8 ... capped at 10d6 at L19-20. - AutoCritFirst + 5% rider retained as bonuses on top of working sneak attack — preserves the opener-burst feel. - L7 rogue expected per-hit ~8 → ~22 damage. Valdris fight math goes from "16 rounds to kill, die in 8" to winnable. TwinBee voice sweep (Phase B3): - ~530 line changes across 24 files replacing third-person "TwinBee notes/files/tracks/respects/..." constructions with first-person inside flavor string literals. Code identifiers (TwinBeeLine, twinBeeLine, etc.), chat-prefix labels (🎭 **TwinBee:**), item names (TwinBee's Bell), achievements, and game-title references in fun.go (Konami TwinBee ship) left intact. - Catches a real bug: Valdris fight rendered "TwinBee marks the Legendary Resistance" mid-combat in third person, contradicting the Phase B2 convention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,16 +21,16 @@ package flavor
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryFeywildCrossing = []string{
|
||||
"The grass here is the wrong green. Too saturated, too even, the green of a screen calibration test. TwinBee notes that everything in the Feywild looks like it has been color-corrected by someone with strong opinions about color.",
|
||||
"You step through what was a doorway and what is now an arch of living briar. The briar parts politely. TwinBee respects the politeness and trusts none of it. Polite plants are a known issue.",
|
||||
"A clearing. Mushrooms in a circle. TwinBee does not need to say anything about the circle. You already know about the circle. Step around it.",
|
||||
"The trees bend their canopies toward you when you pass beneath them. TwinBee waves. Two of the trees wave back. TwinBee does not enjoy this.",
|
||||
"A small bridge over a stream that flows the wrong direction. Uphill. TwinBee files this under 'physics on holiday' and steps onto the bridge anyway, because the only alternative is the stream and the stream is worse.",
|
||||
"You enter a room of impossible flowers — varieties that do not exist on the surface, in colors that do not exist on the surface, with scents that suggest emotions you have not yet had. TwinBee breathes shallowly and recommends not stopping to admire them.",
|
||||
"A glade. Sunlight, despite no visible sun. The light is coming from somewhere and the somewhere is not the sky. TwinBee does not look up. TwinBee has learned not to look up in the Feywild.",
|
||||
"The path forks. A small creature made of starlight is sitting at the fork, waiting, patient, with the air of someone who has already been offered the deal you're about to be offered. TwinBee says: 'Walk past. Do not negotiate. Do not name your name.'",
|
||||
"You cross what was a creek and what is now a ribbon of liquid sky. Stepping stones glow. The stones are not stones. TwinBee identifies them as polite and recommends you say thank you on the far side without specifying who you are thanking.",
|
||||
"The chamber ahead is a banquet hall, set for thirty, untouched. The food is fresh. The wine is poured. The chairs are warm. TwinBee files this under 'the worst possible kind of empty' and does not let you sit down.",
|
||||
"The grass here is the wrong green. Too saturated, too even, the green of a screen calibration test. I note that everything in the Feywild looks like it has been color-corrected by someone with strong opinions about color.",
|
||||
"You step through what was a doorway and what is now an arch of living briar. The briar parts politely. I respect the politeness and trust none of it. Polite plants are a known issue.",
|
||||
"A clearing. Mushrooms in a circle. I do not need to say anything about the circle. You already know about the circle. Step around it.",
|
||||
"The trees bend their canopies toward you when you pass beneath them. I wave. Two of the trees wave back. I do not enjoy this.",
|
||||
"A small bridge over a stream that flows the wrong direction. Uphill. I file this under 'physics on holiday' and step onto the bridge anyway, because the only alternative is the stream and the stream is worse.",
|
||||
"You enter a room of impossible flowers — varieties that do not exist on the surface, in colors that do not exist on the surface, with scents that suggest emotions you have not yet had. I breathe shallowly and recommend not stopping to admire them.",
|
||||
"A glade. Sunlight, despite no visible sun. The light is coming from somewhere and the somewhere is not the sky. I do not look up. I have learned not to look up in the Feywild.",
|
||||
"The path forks. A small creature made of starlight is sitting at the fork, waiting, patient, with the air of someone who has already been offered the deal you're about to be offered. I say: 'Walk past. Do not negotiate. Do not name your name.'",
|
||||
"You cross what was a creek and what is now a ribbon of liquid sky. Stepping stones glow. The stones are not stones. I identify them as polite and recommend you say thank you on the far side without specifying who you are thanking.",
|
||||
"The chamber ahead is a banquet hall, set for thirty, untouched. The food is fresh. The wine is poured. The chairs are warm. I file this under 'the worst possible kind of empty' and do not let you sit down.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -39,7 +39,7 @@ var RoomEntryFeywildCrossing = []string{
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var BossEntryThornmother = []string{
|
||||
"The throne is woven. Not built — woven, from briar and bone and a third material TwinBee cannot identify and prefers not to. The flowers around it are the wrong size and the wrong color and they are watching you with the kind of attention that flowers do not have. The Thornmother on the throne is beautiful in the way some predators are beautiful, which is to say: deliberately. 'You came,' she says, and the voice is not one voice — it is three voices choosing to sound like one. 'I have three names. Would you like the first?' TwinBee says, very flatly: 'Don't accept any of the names. Don't take the bargain. The flowers are part of her. Roll initiative.'",
|
||||
"The throne is woven. Not built — woven, from briar and bone and a third material I cannot identify and prefer not to. The flowers around it are the wrong size and the wrong color and they are watching you with the kind of attention that flowers do not have. The Thornmother on the throne is beautiful in the way some predators are beautiful, which is to say: deliberately. 'You came,' she says, and the voice is not one voice — it is three voices choosing to sound like one. 'I have three names. Would you like the first?' I say, very flatly: 'Don't accept any of the names. Don't take the bargain. The flowers are part of her. Roll initiative.'",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -47,12 +47,12 @@ var BossEntryThornmother = []string{
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var EliteRoomEntryFeywildCrossing = []string{
|
||||
"The cavern ahead is too big for the forest above it. The proportions don't agree. TwinBee notes the ceiling is twenty feet higher than the room's exterior would allow, and that the figure on the far end is matched to the new dimensions. 'Fomorian,' TwinBee says. 'Evil Eye on a save you don't want to fail. Block its line of sight.'",
|
||||
"You enter what looks like a giant's bedroom — a bed the size of a barge, a chair the size of a wagon, a fireplace tall enough to walk into. The occupant is sitting on the bed with its head in its hands. It is not pretending to be sad. It is sad, and it is also going to attack you, and the two are not in conflict. TwinBee files this under 'Fomorian — exiled Fey royalty, deformed, dangerous, sympathetic in the worst way.'",
|
||||
"The clearing is pretty. Until you look at the ground. The ground is studded with stones that aren't stones. The stones are skulls of things that were giants. The Fomorian sitting in the center is using one of them as an armrest, and TwinBee notes that the skull was not in this clearing the last time anyone surveyed it. 'Evil Eye,' TwinBee says. 'WIS save coming. Don't make eye contact early.'",
|
||||
"A stone circle, mossy, broken in two places. Tall enough that the figure pacing inside it does not need to duck. TwinBee identifies the gait — Fomorian, deformed-but-deliberate, the walking of something that has chosen the shape it's stuck with. The Evil Eye comes when the gait stops. TwinBee tracks the timing.",
|
||||
"You climb a stair worn smooth by feet much larger than yours. The room at the top has been a throne room and a prison and a dining hall, all in the same century, depending on which Fey was in charge. The current occupant is large, lonely, and immediately aware of you. 'Evil Eye on a thirty-foot range,' TwinBee says. 'Stay close enough to dodge, far enough to fail-safe.'",
|
||||
"The chamber ahead has been arranged for negotiation — a low table, two chairs, a service of cups. One chair is occupied by the Fomorian. The other is for you. The negotiation has already concluded. TwinBee says: 'Don't sit. Don't accept the cup. The Eye triggers when you decline politely.'",
|
||||
"The cavern ahead is too big for the forest above it. The proportions don't agree. I note the ceiling is twenty feet higher than the room's exterior would allow, and that the figure on the far end is matched to the new dimensions. 'Fomorian,' I say. 'Evil Eye on a save you don't want to fail. Block its line of sight.'",
|
||||
"You enter what looks like a giant's bedroom — a bed the size of a barge, a chair the size of a wagon, a fireplace tall enough to walk into. The occupant is sitting on the bed with its head in its hands. It is not pretending to be sad. It is sad, and it is also going to attack you, and the two are not in conflict. I file this under 'Fomorian — exiled Fey royalty, deformed, dangerous, sympathetic in the worst way.'",
|
||||
"The clearing is pretty. Until you look at the ground. The ground is studded with stones that aren't stones. The stones are skulls of things that were giants. The Fomorian sitting in the center is using one of them as an armrest, and I note that the skull was not in this clearing the last time anyone surveyed it. 'Evil Eye,' I say. 'WIS save coming. Don't make eye contact early.'",
|
||||
"A stone circle, mossy, broken in two places. Tall enough that the figure pacing inside it does not need to duck. I identify the gait — Fomorian, deformed-but-deliberate, the walking of something that has chosen the shape it's stuck with. The Evil Eye comes when the gait stops. I track the timing.",
|
||||
"You climb a stair worn smooth by feet much larger than yours. The room at the top has been a throne room and a prison and a dining hall, all in the same century, depending on which Fey was in charge. The current occupant is large, lonely, and immediately aware of you. 'Evil Eye on a thirty-foot range,' I say. 'Stay close enough to dodge, far enough to fail-safe.'",
|
||||
"The chamber ahead has been arranged for negotiation — a low table, two chairs, a service of cups. One chair is occupied by the Fomorian. The other is for you. The negotiation has already concluded. I say: 'Don't sit. Don't accept the cup. The Eye triggers when you decline politely.'",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -62,37 +62,37 @@ var EliteRoomEntryFeywildCrossing = []string{
|
||||
|
||||
// Coven Magic: extra spell slots scaled by GM Mood (high mood = stronger Thornmother).
|
||||
var ThornmotherCovenLines = []string{
|
||||
"Her slot pool scales with TwinBee's mood — Effusive TwinBee buys the Thornmother an extra round of high-tier casts. 'My affection is taxable here,' it says. 'Sorry. Spread out.'",
|
||||
"Coven Magic. The slots above her base list are mood-scaled — the better the mood at the run's start, the worse this fight runs late. TwinBee files this under 'cosmic irony' and notes the math is fixed at zone entry.",
|
||||
"She has more spells than the sheet says. The extra ones come from the coven and the coven volume is set by TwinBee's mood. TwinBee tracks the count and warns the party when the bonus tier is in play.",
|
||||
"Her slot pool scales with my mood — when I'm Effusive I buy the Thornmother an extra round of high-tier casts. 'My affection is taxable here,' I say. 'Sorry. Spread out.'",
|
||||
"Coven Magic. The slots above her base list are mood-scaled — the better the mood at the run's start, the worse this fight runs late. I file this under 'cosmic irony' and note the math is fixed at zone entry.",
|
||||
"She has more spells than the sheet says. The extra ones come from the coven and the coven volume is set by my mood. I track the count and warn the party when the bonus tier is in play.",
|
||||
}
|
||||
|
||||
// Beguiling Bargain (1/combat): offers a deal — accept a debuff for a permanent minor buff.
|
||||
var ThornmotherBargainLines = []string{
|
||||
"Once per fight she offers a bargain — a debuff for a permanent minor buff. The buff is real. The debuff is real. TwinBee says: 'It's a player choice. The party agrees or refuses. Don't let one person decide for the rest.'",
|
||||
"Beguiling Bargain. The offer is genuine. Both halves are genuine. TwinBee files this under 'long-term economics' and notes that the buff persists past the run while the debuff applies only inside it.",
|
||||
"She offers. The choice is the player's. TwinBee declines to advise on this one — it is not a tactics question, it is a build question, and the answer depends on what you intend to keep.",
|
||||
"Once per fight she offers a bargain — a debuff for a permanent minor buff. The buff is real. The debuff is real. I say: 'It's a player choice. The party agrees or refuses. Don't let one person decide for the rest.'",
|
||||
"Beguiling Bargain. The offer is genuine. Both halves are genuine. I file this under 'long-term economics' and note that the buff persists past the run while the debuff applies only inside it.",
|
||||
"She offers. The choice is the player's. I decline to advise on this one — it is not a tactics question, it is a build question, and the answer depends on what you intend to keep.",
|
||||
}
|
||||
|
||||
// Thorned Grasp: Restrained + 4d6 piercing/turn, CON DC 16 to break free.
|
||||
var ThornmotherGraspLines = []string{
|
||||
"Roots from the floor. Restrained, four-d-six piercing every turn until you make the CON save at sixteen. TwinBee says: 'It tries the back line first. Stay near a friend who can grant advantage on the save.'",
|
||||
"Thorned Grasp. The flowers around her throne are the AoE. Stand near them and the briars come up. Stand far and they reach further. TwinBee tracks the radius and recommends fighting from the doorway.",
|
||||
"Grappled by the room. The damage is not the problem — the problem is that you can't reposition while your front line is taking spells. TwinBee files this under 'CC tax' and asks who has Misty Step.",
|
||||
"Roots from the floor. Restrained, four-d-six piercing every turn until you make the CON save at sixteen. I say: 'It tries the back line first. Stay near a friend who can grant advantage on the save.'",
|
||||
"Thorned Grasp. The flowers around her throne are the AoE. Stand near them and the briars come up. Stand far and they reach further. I track the radius and recommend fighting from the doorway.",
|
||||
"Grappled by the room. The damage is not the problem — the problem is that you can't reposition while your front line is taking spells. I file this under 'CC tax' and ask who has Misty Step.",
|
||||
}
|
||||
|
||||
// Shapechange (1/combat): adopts a player's appearance; 50% miss vs her until DC 17 Investigation.
|
||||
var ThornmotherShapechangeLines = []string{
|
||||
"She picks one of you and becomes them. Until someone passes a DC 17 Investigation, half your hits roll a coin to see if they hit her or your friend. TwinBee says: 'The party member with the highest INT calls it. Quickly.'",
|
||||
"Shapechange. The room now has two of someone. TwinBee tracks which one has the wrong shadow and whispers the answer to the controller — but only after the Investigation roll, because TwinBee respects mechanics.",
|
||||
"She takes a face. Half your damage might land on the face's owner. TwinBee files this under 'every JRPG that ever did the doppelganger fight' and reminds you that the trick was always to look at the feet.",
|
||||
"She picks one of you and becomes them. Until someone passes a DC 17 Investigation, half your hits roll a coin to see if they hit her or your friend. I say: 'The party member with the highest INT calls it. Quickly.'",
|
||||
"Shapechange. The room now has two of someone. I track which one has the wrong shadow and whisper the answer to the controller — but only after the Investigation roll, because I respect mechanics.",
|
||||
"She takes a face. Half your damage might land on the face's owner. I file this under 'every JRPG that ever did the doppelganger fight' and remind you that the trick was always to look at the feet.",
|
||||
}
|
||||
|
||||
// Phase 2 (<30% HP): True Form revealed — illusions drop; +4d6 psychic on attacks; coven summons 2 Night Hags.
|
||||
var ThornmotherPhaseTwoLines = []string{
|
||||
"Below thirty percent the masks come off. True form. All her attacks add four-d-six psychic. The coven sends two Night Hags. TwinBee says: 'Phase shift. The fight just turned into three priests and a sense-of-self problem.'",
|
||||
"Phase two: the illusions drop, the Hags arrive, the psychic damage starts stacking on every hit. TwinBee tracks the new threat list and recommends focusing the original Thornmother — the Hags are reinforcements, not the win condition.",
|
||||
"True Form. The flowers stop being flowers. Two Night Hags step out of the throne. The Thornmother's hits start writing themselves directly into your mind. TwinBee files this under 'cinematic phase shift' and asks who still has spell slots.",
|
||||
"Below thirty percent the masks come off. True form. All her attacks add four-d-six psychic. The coven sends two Night Hags. I say: 'Phase shift. The fight just turned into three priests and a sense-of-self problem.'",
|
||||
"Phase two: the illusions drop, the Hags arrive, the psychic damage starts stacking on every hit. I track the new threat list and recommend focusing the original Thornmother — the Hags are reinforcements, not the win condition.",
|
||||
"True Form. The flowers stop being flowers. Two Night Hags step out of the throne. The Thornmother's hits start writing themselves directly into your mind. I file this under 'cinematic phase shift' and ask who still has spell slots.",
|
||||
}
|
||||
|
||||
// ThornmotherSignatureCallouts — combined pool for boss-entry suffix.
|
||||
@@ -116,12 +116,12 @@ var ThornmotherSignatureCallouts = func() []string {
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var LoreLinesFeywildCrossing = []string{
|
||||
"The Crossing is not a place. The Crossing is a thinness — the spot where the veil between worlds wears down enough to step through. The wear is not random. Someone has been wearing it down on purpose, slowly, for a long time. TwinBee files this under 'someone' and declines to be more specific.",
|
||||
"The Thornmother has three names. Each name belongs to a separate covenant — a separate pact with a separate piece of her. Speaking any of the names is a partial agreement to the pact attached. TwinBee does not name her. TwinBee does not let anyone in earshot name her.",
|
||||
"Time runs differently here. A long rest in the Feywild is — sometimes — a year on the surface. Sometimes it is a minute. The dice for this are rolled by something that is not at the table. TwinBee tracks the discrepancy and warns the party not to commit to anything urgent before the run ends.",
|
||||
"The Fomorians were Fey royalty. They were exiled, deformed, and given the underground. The deformity was the punishment, not the cause. TwinBee respects the precision of the curse and files it under 'the kind of magic that takes a committee.'",
|
||||
"Redcaps are not killed by violence. Redcaps are powered by violence. The cap is the storage medium. Soaking it in fresh blood resets the meter. TwinBee says: 'Don't bleed near them. They're patient.' (Bleeding near them is the thing they're patient for.)",
|
||||
"The Will-o-Wisps are not lost spirits. They are unfulfilled bargains. Each one was a Feywild deal that the surface party broke. TwinBee notes that the wisps still want the deal honored and files this under 'long memory.'",
|
||||
"The mushroom circles in the Crossing are receivers. They listen for words spoken inside them and route the words to a coven that has been waiting for those words for several centuries. TwinBee suggests the party say nothing inside any circle, including 'this is a circle.'",
|
||||
"The Thornmother's flowers are not separate from her. They are her. The throne, the dais, the petals, the perfume — the whole arrangement is one organism, and dropping HP on the boss is one way of dropping HP on the room. TwinBee files this under 'environmental targeting' and recommends burning the throne when she's mid-cast.",
|
||||
"The Crossing is not a place. The Crossing is a thinness — the spot where the veil between worlds wears down enough to step through. The wear is not random. Someone has been wearing it down on purpose, slowly, for a long time. I file this under 'someone' and decline to be more specific.",
|
||||
"The Thornmother has three names. Each name belongs to a separate covenant — a separate pact with a separate piece of her. Speaking any of the names is a partial agreement to the pact attached. I do not name her. I do not let anyone in earshot name her.",
|
||||
"Time runs differently here. A long rest in the Feywild is — sometimes — a year on the surface. Sometimes it is a minute. The dice for this are rolled by something that is not at the table. I track the discrepancy and warn the party not to commit to anything urgent before the run ends.",
|
||||
"The Fomorians were Fey royalty. They were exiled, deformed, and given the underground. The deformity was the punishment, not the cause. I respect the precision of the curse and file it under 'the kind of magic that takes a committee.'",
|
||||
"Redcaps are not killed by violence. Redcaps are powered by violence. The cap is the storage medium. Soaking it in fresh blood resets the meter. I say: 'Don't bleed near them. They're patient.' (Bleeding near them is the thing they're patient for.)",
|
||||
"The Will-o-Wisps are not lost spirits. They are unfulfilled bargains. Each one was a Feywild deal that the surface party broke. I note that the wisps still want the deal honored and file this under 'long memory.'",
|
||||
"The mushroom circles in the Crossing are receivers. They listen for words spoken inside them and route the words to a coven that has been waiting for those words for several centuries. I suggest the party say nothing inside any circle, including 'this is a circle.'",
|
||||
"The Thornmother's flowers are not separate from her. They are her. The throne, the dais, the petals, the perfume — the whole arrangement is one organism, and dropping HP on the boss is one way of dropping HP on the room. I file this under 'environmental targeting' and recommend burning the throne when she's mid-cast.",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user