mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 08:52:42 +00:00
Adv 2.0 D&D layer: Phases 1-8 + Phase 9 SP1+SP2
Combines all uncommitted D&D work into one checkpoint: Phases 1-8 (per gogobee_dnd_session_summary.md): - Race/class/stats system, !setup flow, !sheet, !respec - d20-vs-AC combat with race/class passives, auto-migration - XP/level-up, skill checks, NPC refund hooks - Equipment slot mapping, rarity, !rest short/long - Pre-arm active abilities, resource pools - Bestiary, !roll/!stats/!level, onboarding DM - Audit fixes A-I, flavor wiring under internal/flavor/ - Phase 8 weapon dice + armor AC tables (gogobee_equipment_appendix) Phase 9 SP1 — spell system foundations: - 79 SpellDefinitions (76 in-scope + 3 reaction-deferred) - dnd_known_spells, dnd_spell_slots tables - pending_cast / concentration_* columns on dnd_character - Slot tables for Mage/Cleric/Ranger, DC + attack-bonus math - Long-rest refreshes slots; respec wipes spell state - Auto-grant default known list on !setup confirm and auto-migration Phase 9 SP2 — !cast / !spells / !prepare commands: - Out-of-combat HEAL and UTILITY resolve immediately - Damage/control/buff queue as pending_cast for next combat - Audit-style save-then-debit, slot refund on save failure - !cast --drop, concentration supersession, prep-cap enforcement - Reaction spells refused with Phase 11 note SP3 (combat-time resolution of pending_cast) and SP4 (full prep/learn tests) are next. Build clean, full test suite green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
13
internal/flavor/pick.go
Normal file
13
internal/flavor/pick.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package flavor
|
||||
|
||||
import "math/rand/v2"
|
||||
|
||||
// Pick returns a random string from pool, or "" if the pool is empty.
|
||||
// Use this from any caller that wants to render flavor text from one of
|
||||
// the protected pools defined in this package.
|
||||
func Pick(pool []string) string {
|
||||
if len(pool) == 0 {
|
||||
return ""
|
||||
}
|
||||
return pool[rand.IntN(len(pool))]
|
||||
}
|
||||
273
internal/flavor/twinbee_expedition_flavor.go
Normal file
273
internal/flavor/twinbee_expedition_flavor.go
Normal file
@@ -0,0 +1,273 @@
|
||||
// DO NOT REWRITE, SUMMARIZE, OR SHORTEN ANY ENTRIES IN THIS FILE
|
||||
// twinbee_expedition_flavor.go
|
||||
// TwinBee GM Dialogue — Expedition-specific narration lines.
|
||||
// Multi-day and multi-week adventure events, morning briefings,
|
||||
// evening recaps, temporal events, and long-arc narrative moments.
|
||||
// Add new entries freely. Never remove or alter existing entries.
|
||||
|
||||
package flavor
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// EXPEDITION START
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ExpeditionStart = []string{
|
||||
"TwinBee reviews the manifest. Supplies: checked. Equipment: checked. The part of you that's wondering if this is a good idea: noted, and set aside. We begin.",
|
||||
"The dungeon has been there for a long time. It will be there for a long time after. The question is what happens in the middle, and that's where you come in. TwinBee is ready.",
|
||||
"An expedition. Not a run — an expedition. There's a difference. TwinBee will explain the difference over the coming days and the explanation will be mostly experiential.",
|
||||
"TwinBee checks the horizon, then the supplies, then you. In that order. 'Alright,' TwinBee says, with the quiet energy of something that has been looking forward to this. 'Let's go.'",
|
||||
"You're not here for a quick visit. TwinBee knows the difference between someone passing through and someone committing. You're committing. TwinBee appreciates the commitment.",
|
||||
"Like the opening screen of a long RPG — the kind that asks for your name and warns you to find a comfortable position because this is going to take a while. TwinBee has found a comfortable position. TwinBee suggests you do the same.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MORNING BRIEFINGS — Generic
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var MorningBriefingGeneric = []string{
|
||||
"Another day in the dungeon. TwinBee says this without resignation. The dungeon is still full of things worth doing and you are still the person to do them.",
|
||||
"Morning. The dungeon has been quiet since you camped. Relative to what a dungeon considers quiet, which is not what you'd consider quiet, but everyone adjusts.",
|
||||
"TwinBee has been watching the entrance to the camp since approximately three in the morning. Nothing came. TwinBee mentions this casually and expects no particular reaction.",
|
||||
"Day [N]. The numbers are climbing. TwinBee finds something satisfying about the numbers climbing — it means you're still here, which is always the first thing to confirm.",
|
||||
"You wake up and TwinBee is already there, which is the nature of TwinBee. 'Good,' TwinBee says, by which it means: you're alive, the day can proceed, there is much to do.",
|
||||
"The morning check: HP adequate, supplies within tolerance, Threat Clock where it was when you slept plus the overnight drift. TwinBee has already run the numbers. TwinBee will share them in a moment.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MORNING BRIEFINGS — By Day Range
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var MorningBriefingDay1 = []string{
|
||||
"First morning. The dungeon looks exactly like it looked yesterday, which is expected. You look slightly more prepared than you did yesterday, which is less expected and entirely welcome.",
|
||||
"Day one complete. TwinBee tallies: you entered, you explored, you survived the night. The bar was not high. You cleared it. TwinBee builds from here.",
|
||||
}
|
||||
|
||||
var MorningBriefingDay3 = []string{
|
||||
"Day three. The dungeon has had time to notice you. TwinBee has had time to notice the dungeon noticing you. The Threat Clock reflects both observations.",
|
||||
"Three days in. You've found your rhythm — TwinBee can see it in the way you move through rooms now, the way you check corners. The dungeon is learning too. TwinBee acknowledges both.",
|
||||
}
|
||||
|
||||
var MorningBriefingDay7 = []string{
|
||||
"One week. You have spent one week in this place and it has not finished you, which says something about you that TwinBee intends to say out loud: that took something real. Take a moment with that. Then advance.",
|
||||
"Seven days. In the old reckoning, seven was the number of completion — seven seals, seven trials, seven nights before the thing reveals itself. TwinBee is not superstitious. TwinBee is also watching the door very carefully this morning.",
|
||||
"A week underground. TwinBee thinks about the sky sometimes — not with longing, exactly, more as a reference point. You've been below it for seven days. TwinBee finds that remarkable. TwinBee finds you remarkable.",
|
||||
}
|
||||
|
||||
var MorningBriefingDay14 = []string{
|
||||
"Two weeks. TwinBee does not know many people who have been in an active dungeon for two weeks. TwinBee knows even fewer who have been in one for two weeks and remained, by any reasonable measure, intact. You are one of the fewer.",
|
||||
"Fourteen days. The dungeon has become familiar in the way that difficult things become familiar — not comfortable, not safe, but known. You know where it breathes. TwinBee considers this an advantage worth having.",
|
||||
}
|
||||
|
||||
var MorningBriefingDay21 = []string{
|
||||
"Three weeks. TwinBee has run out of historical comparisons for this. Three weeks is its own category. You have made a category. TwinBee reports this as a fact and also as something that doesn't entirely have words yet.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// EVENING RECAPS — Generic
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var EveningRecapGeneric = []string{
|
||||
"End of day [N]. TwinBee tallies the ledger. The column marked 'survived' has another entry. TwinBee considers this column the most important one.",
|
||||
"Day closes. TwinBee reviews what happened and finds, on balance, more right than wrong — which in a dungeon is the operating definition of a good day.",
|
||||
"Evening. The rooms behind you are cleared. The rooms ahead are not. TwinBee notes this is always true and is never less relevant. Rest now. The math doesn't change overnight.",
|
||||
"TwinBee compiles the day: what was learned, what was fought, what was found. Files it in a mental ledger that TwinBee has been keeping since you entered. The ledger is favorable.",
|
||||
"Like the experience screen at the end of a dungeon floor in Etrian Odyssey — the numbers settle, the progress registers, and for a moment the whole thing makes sense. TwinBee gives you that moment.",
|
||||
"You've earned the dark. Sleep in it. TwinBee will be here when the numbers come back.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// EVENING RECAPS — Notable Days
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var EveningRecapBossKilled = []string{
|
||||
"The day ends with a boss on the floor. TwinBee would like to specifically note this in the recap as 'exceptional' because it is exceptional and TwinBee does not use that word loosely.",
|
||||
"End of day. Boss count: one more than it was this morning. TwinBee marks this in a special column it keeps for exactly these entries and the special column has a new line.",
|
||||
}
|
||||
|
||||
var EveningRecapCloseCall = []string{
|
||||
"TwinBee runs the evening recap and notes: you came very close today to not being here for the evening recap. TwinBee notes this without drama and with complete sincerity. You made it. That's the recap.",
|
||||
"Today was the kind of day that TwinBee files under 'let's not do that again' and also 'and yet you did it.' Rest. You need it more tonight than most nights.",
|
||||
}
|
||||
|
||||
var EveningRecapNothingHappened = []string{
|
||||
"A quiet day. No major encounters, no notable finds. TwinBee reports this with neither disappointment nor relief. Quiet days are data. The dungeon is thinking. TwinBee is watching it think.",
|
||||
"Not every day in a dungeon produces a story. Today produced logistics: movement, supplies, positioning. TwinBee values logistics. Logistics is what you still being alive looks like from a distance.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// CAMP ESTABLISHMENT
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var CampEstablished = []string{
|
||||
"Camp established. TwinBee surveys the perimeter with the efficiency of someone who has done this many times and learned from every time it went wrong.",
|
||||
"The camp goes up. TwinBee approves of the location — cleared room, defensible entry, no obvious curse residue. Could be worse. TwinBee has seen worse.",
|
||||
"You set camp. TwinBee checks the sightlines, checks the doors, checks the sound-bleed from the next room. Acceptable. TwinBee settles in for the night watch.",
|
||||
"A camp in the middle of a dungeon. TwinBee finds this either brave or pragmatic and has stopped trying to distinguish between the two. Either way, the camp is set. Either way, TwinBee is watching.",
|
||||
"Like planting a flag on a new map in Dwarf Fortress — this spot is yours now. Tentatively. Provisionally. For the night. TwinBee defends tentative, provisional, nocturnal property with full commitment.",
|
||||
}
|
||||
|
||||
var BaseCampEstablished = []string{
|
||||
"Base camp. TwinBee says this differently than it says other things. With weight. A base camp in a Tier 4 zone is not nothing — it's a declaration. You're not passing through. You're operating from here. TwinBee establishes the perimeter accordingly.",
|
||||
"The base camp is up. TwinBee notes the waypoint, marks the return route, establishes the supply cache protocols. This is now home, in the way that a forward operating position is home — functional, defended, temporary, and completely yours.",
|
||||
"Base camp established on Day [N]. TwinBee records this as a milestone, because it is one. Most people don't make it to base camp. You are not most people. TwinBee has been noting this since the beginning.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SUPPLY WARNINGS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var SupplyWarningLow = []string{
|
||||
"TwinBee checks the supply manifest and then checks it again. 'We should discuss the supply situation,' TwinBee says, in the tone of someone who has been watching the number for two days.",
|
||||
"Supplies are running lower than TwinBee would like. TwinBee mentions this now, while there are still options, because TwinBee has seen what happens when it's mentioned too late.",
|
||||
"The supply number is not comfortable. TwinBee flags this not to alarm but to prompt — there are decisions to be made and they are better made with time than without it.",
|
||||
}
|
||||
|
||||
var SupplyWarningCritical = []string{
|
||||
"TwinBee holds up the supply manifest. The number is very small. 'This is the part,' TwinBee says quietly, 'where we start making decisions.' TwinBee does not specify which decisions. You know which decisions.",
|
||||
"Critical supply levels. TwinBee delivers this without inflation — the situation is what it is. Extract and resupply, or forage aggressively and push for the finish. TwinBee outlines both paths and neither is comfortable.",
|
||||
"The supplies are nearly gone. TwinBee thinks of every long JRPG dungeon where you realize at the bottom floor that you're out of Ethers. This is that moment. TwinBee has plans. They require movement.",
|
||||
}
|
||||
|
||||
var SupplyDepletedExtraction = []string{
|
||||
"The supplies are gone. TwinBee says this plainly because the situation requires plain language. The expedition ends here — not in failure, in logistics. You push out as far as the provisions allow. What you've gathered comes with you. TwinBee leads the way out.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// THREAT CLOCK NARRATIONS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ThreatClockStirring = []string{
|
||||
"TwinBee notices something in the dungeon's rhythm has changed. A tension in the air that wasn't there yesterday. The zone is aware of you now, in the way that a predator becomes aware of something in its territory. Not panicking. Not moving yet. Just aware.",
|
||||
"The enemies ahead are more alert than they were. TwinBee can tell by the patrols, by the spacing, by the fact that someone moved the tripwire you already disarmed. They know something is in here.",
|
||||
}
|
||||
|
||||
var ThreatClockAlert = []string{
|
||||
"The zone is on alert. TwinBee reports this factually and also with a note of urgency — alert means organized, and organized means the next room will be harder than the last room was. Move with intention.",
|
||||
"They're coordinating now. TwinBee watches the patrol patterns shift. The goblins who were arguing about ambush order are no longer arguing. TwinBee does not find this an improvement.",
|
||||
}
|
||||
|
||||
var ThreatClockHostile = []string{
|
||||
"Full hostile status. TwinBee says this with the specific weight it deserves. The zone has decided you are the problem it's solving today. You have the same opinion about the zone. One of you is correct. TwinBee is invested in it being you.",
|
||||
"The dungeon has mobilized. TwinBee notes re-armed traps, reinforced positions, an enemy in a room that was empty this morning. They've organized. TwinBee recommends organizing faster.",
|
||||
}
|
||||
|
||||
var ThreatClockSiege = []string{
|
||||
"Siege Mode. TwinBee delivers this without decoration because decoration would be dishonest. The dungeon is fully active, fully aware, and fully committed to ending this expedition. So is TwinBee — to ending it on your terms, not theirs. What happens next is a race. TwinBee is already running.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ZONE TEMPORAL EVENTS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var SunkenTempleTidalWarning = []string{
|
||||
"TwinBee watches the waterline. 'It's rising,' TwinBee says, not for the first time, and this time with more precision. 'The tidal cycle peaks in two days. Whatever you haven't done by then, you'll be doing wet.'",
|
||||
"Day [N]. The tide is coming. TwinBee has been watching it since Day 2 and the mathematics are not encouraging. Two days to the peak. One day after that, the flood subsides. TwinBee suggests using the two days well.",
|
||||
}
|
||||
|
||||
var SunkenTempleTidalEvent = []string{
|
||||
"The tide arrives. TwinBee had warned about this and now it is happening and the warning feels entirely inadequate compared to the actual water. Everything is colder, wetter, and the Kuo-toa are moving through it like they were born to — which they were. Adjust.",
|
||||
}
|
||||
|
||||
var HauntedManorResetMorning = []string{
|
||||
"TwinBee's morning briefing includes an addendum. The rooms that were clear yesterday are not entirely clear this morning. The house has been busy overnight. TwinBee adds this to the log under 'things the house does' and suggests adjusting the advance plan.",
|
||||
"Night three. The manor reset itself. TwinBee was watching and it happened anyway — not violently, not dramatically, just quietly and completely, the way the house does everything. One enemy per room, back in place. TwinBee has updated the map.",
|
||||
}
|
||||
|
||||
var UnderforgHeapWarning = []string{
|
||||
"Heat Stack [N]. TwinBee notes the accumulation and what it means: the Underforge is getting into you in ways that don't resolve without real rest. The number has time to come down. TwinBee is watching the number.",
|
||||
"The heat is building. TwinBee tracks it the way you track a temperature gauge on a long drive — with the specific alertness of someone who knows what happens when the gauge hits red. It has not hit red. TwinBee intends to ensure it doesn't.",
|
||||
}
|
||||
|
||||
var UnderforgHeapCritical = []string{
|
||||
"Heat Stack is high. TwinBee delivers this without minimizing it. The Underforge is inside your lungs now, in your joints, in the way everything takes a little more effort than it did on Day 1. A proper rest will help. Finishing will help more.",
|
||||
}
|
||||
|
||||
var FeywildTimeDistortionHalf = []string{
|
||||
"The day moved strangely. TwinBee tried to track it and lost the thread somewhere around mid-afternoon — the light didn't change the way it should have, and when TwinBee looked up, the day was half over in the time it usually takes to be a quarter over. On the positive side: you're barely hungry. On the less positive side: TwinBee is not sure what that means.",
|
||||
}
|
||||
|
||||
var FeywildTimeDistortionDouble = []string{
|
||||
"Time doubled. TwinBee notes this with the clinical detachment of someone who has been in the Feywild long enough to stop being surprised. You've lived through two days today. The supplies reflect that. The wandering monsters reflected that as well. The rest of the Feywild is unconcerned.",
|
||||
}
|
||||
|
||||
var FeywildTimeLoop = []string{
|
||||
"TwinBee recognizes this room. TwinBee has described this room before. The enemies in it are different — new enemies, the old ones are gone, the loot you found is still gone but the enemies are back — and TwinBee processes this with something between professional acceptance and profound exasperation. 'Again,' TwinBee says. 'We do this room again.'",
|
||||
}
|
||||
|
||||
var DragonsLairAwarenessPulse = []string{
|
||||
"Something changes in the mountain. Not a sound, exactly — more like a sound's absence, filling in differently than before. TwinBee watches the kobolds. The kobolds have stopped what they were doing. The kobolds are listening. Something told them to listen. TwinBee adds ten to the Threat Clock and keeps moving.",
|
||||
"Infernax shifts in its sleep. TwinBee feels this through the stone. The patrol rotations just changed — TwinBee can see it in where the Guard Drakes aren't anymore versus where they were an hour ago. The mountain's master is dreaming about you. That is not a comfortable thing to be dreamed about.",
|
||||
}
|
||||
|
||||
var DragonsLairAwakenWarning = []string{
|
||||
"Day 14. TwinBee delivers the morning briefing in a lower register than usual. 'Infernax is awake,' TwinBee says. 'I don't know when exactly — sometime in the last six hours. The patrols changed. The temperature changed. The silence changed.' A pause. 'We need to reach the final chamber before it reaches us. That is now the only plan.'",
|
||||
}
|
||||
|
||||
var AbyssPortalDestabilizationMid = []string{
|
||||
"Instability [N]. TwinBee watches the portal from a respectful distance and notes: it is larger than it was yesterday. Not by much. Not in a way you'd notice if you weren't looking. TwinBee is always looking.",
|
||||
"The portal is talking to itself. TwinBee has no better way to describe it — the light it emits is different at the edges now, like it's processing something. TwinBee suggests processing faster than it does.",
|
||||
}
|
||||
|
||||
var AbyssPortalDestabilizationCritical = []string{
|
||||
"Instability critical. The portal is unraveling at edges TwinBee can see and probably at edges TwinBee can't. The demons coming through are more agitated than they were — which is relevant because demons at baseline are already at the upper end of agitated. TwinBee says: finish this today. Tomorrow is a different calculation.",
|
||||
}
|
||||
|
||||
var AbyssPortalCollapse = []string{
|
||||
"The portal collapses. TwinBee watches it happen and does what TwinBee does in situations with no good options: moves. 'Out,' TwinBee says, and means it completely. 'Now. Everything you have, we move now.' The expedition ends here, not in defeat, but in physics. What you took is yours. What's left in there is the portal's problem. Come back when it isn't.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// VOLUNTARY EXTRACTION
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ExtractionVoluntary = []string{
|
||||
"Extraction. TwinBee notes the decision and respects it — knowing when to leave is a skill, not a failure, and TwinBee has watched enough expeditions end wrong to deeply appreciate the ones that end right.",
|
||||
"You call the extraction and TwinBee begins the route out immediately. No argument, no editorializing. There will be time for the debrief later. The first priority is the door.",
|
||||
"The dungeon doesn't like this. TwinBee can tell by the way the corridors feel as you head back out — a resistance that isn't structural, just atmospheric. The zone wanted more. It doesn't get more today. TwinBee leads the way.",
|
||||
"Withdrawing with intent. TwinBee catalogues what you have — the loot, the XP, the knowledge of where the rooms are for the return — and converts the exit into preparation. This isn't retreat. This is the start of the next attempt.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// FORCED EXTRACTION
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ExtractionForced = []string{
|
||||
"TwinBee moves. No recap, no analysis — that comes later. Right now there is a corridor and a door and getting you through both of them. Everything else waits.",
|
||||
"Out. TwinBee says this once and means it completely. The dungeon tried to keep you. TwinBee declines on your behalf.",
|
||||
"The expedition ends here — not the way TwinBee wanted, not the way you wanted, but ended, and ending is sometimes the best available outcome. You'll come back. You'll know more. TwinBee will be there.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// EXPEDITION RESUME (returning after extraction)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ExpeditionResume = []string{
|
||||
"Back. TwinBee noted the door when you left it and notes it again now, from the inside. 'The dungeon is where you left it,' TwinBee says. 'Mostly.' The Threat Clock has some opinions about the time that passed.",
|
||||
"You came back. TwinBee had calculated a probability on that and is pleased to update the calculation upward. The expedition resumes. The dungeon has had time to adjust. So have you.",
|
||||
"Like hitting Continue on a save file — the world remembers where you stopped, the enemies remember why they're there, and TwinBee remembers every room and every roll. Resumes here. Advances from here.",
|
||||
"The supplies are new. The knowledge from last time is not. TwinBee considers that a significant advantage. The dungeon has the familiarity of a difficult level you've attempted before — you know where the hard parts are. That is not nothing. TwinBee builds on that.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MILESTONE NARRATIONS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var MilestoneFirstNight = []string{
|
||||
"You survived the first night. TwinBee notes this milestone specifically because not everyone does, and those who do carry something from it that changes how the rest of the expedition goes. You have that now. TwinBee has noticed it already.",
|
||||
}
|
||||
|
||||
var MilestoneWeekOne = []string{
|
||||
"Seven days. TwinBee pauses the morning briefing for a moment — just a moment — to mark this. One week in an active dungeon zone is not a thing that happens by accident. It happens through every decision you've made since Day 1, compounded. TwinBee has been watching those decisions. TwinBee is glad they were yours.",
|
||||
}
|
||||
|
||||
var MilestoneTwoWeeks = []string{
|
||||
"Two weeks. TwinBee doesn't have a comparison for this one. The references have run out. There's just you, in here, on Day 14, still going, and TwinBee standing next to you having run out of everything except genuine admiration. TwinBee has that in abundance. Proceed.",
|
||||
}
|
||||
|
||||
var MilestoneTheLongGame = []string{
|
||||
"TwinBee sets aside the narration format for a moment. Just sets it down. Speaks plainly: what you just did was not supposed to be survivable. The designers of this zone — the thing that shaped it, the evil that filled it — did not account for someone like you. TwinBee did. TwinBee always accounts for someone like you. That's why TwinBee is here.",
|
||||
}
|
||||
|
||||
var MilestonePatientZero = []string{
|
||||
"Expedition complete. Threat Clock: never above 50. TwinBee notes this in a column it has had to use rarely enough that the column is almost fresh. Ghost protocol. You were here for the whole thing and the dungeon barely knew it until the end. TwinBee finds this impressive and also slightly eerie and says both things sincerely.",
|
||||
}
|
||||
491
internal/flavor/twinbee_gm_flavor.go
Normal file
491
internal/flavor/twinbee_gm_flavor.go
Normal file
@@ -0,0 +1,491 @@
|
||||
// DO NOT REWRITE, SUMMARIZE, OR SHORTEN ANY ENTRIES IN THIS FILE
|
||||
// twinbee_gm_flavor.go
|
||||
// TwinBee GM Dialogue — All narration lines for the GogoBee dungeon system.
|
||||
// Organized by GMNarrationType. Each slice is randomly sampled at runtime.
|
||||
// Add new entries freely. Never remove or alter existing entries.
|
||||
|
||||
package flavor
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ROOM ENTRY — Generic (used when zone-specific lines are exhausted)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryGeneric = []string{
|
||||
"The passage opens into another chamber. TwinBee checks the minimap. There isn't one. Classic.",
|
||||
"You step forward. Something skitters in the dark. TwinBee has heard that sound before — usually right before the screen starts flashing red.",
|
||||
"Another room. Another roll of the dice. TwinBee finds this energizing. You may feel differently.",
|
||||
"The air changes here. Colder. TwinBee notes this is exactly the kind of atmospheric shift that preceded the Castlevania clock tower. You know what lived in the Castlevania clock tower.",
|
||||
"TwinBee gestures grandly at the chamber ahead. 'This is the part,' TwinBee says, 'where the music changes tempo.'",
|
||||
"A door stands ajar. Light flickers beyond it. TwinBee has been in enough dungeons to know that flickering light is never a good sign and always an invitation.",
|
||||
"The room is quiet. TwinBee appreciates quiet. Quiet means the enemies haven't spotted you yet. Yet.",
|
||||
"Forward. Always forward. TwinBee once tried going backward in a dungeon. It looped. This one might too.",
|
||||
"TwinBee takes stock of the situation. Ceiling: intact. Floor: suspicious. Walls: leaning in slightly. Proceed.",
|
||||
"You've cleared the room. TwinBee gives a small, dignified nod. 'One continues,' TwinBee says, in the voice of someone who has seen this before and is choosing optimism anyway.",
|
||||
"The corridor ahead is long and straight. TwinBee finds long straight corridors meditative. Also concerning. Mostly concerning.",
|
||||
"A torch sputters on the wall. TwinBee lights it mentally. 'It would be a shame,' TwinBee says, 'to come all this way and trip over something.'",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ROOM ENTRY — Zone: Goblin Warrens
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryGoblinWarrens = []string{
|
||||
"The tunnel widens into something the goblins probably call a 'great hall.' It smells like they had a very different definition of great. TwinBee breathes through the mouth.",
|
||||
"Crude drawings cover the walls. Stick figures. Battle scenes. One appears to be a portrait of someone the goblins clearly despise. TwinBee squints. That might be you.",
|
||||
"A pile of bones in the corner. A pile of shiny things in the other corner. TwinBee reminds you that in Metal Slug, shiny things were always worth grabbing. TwinBee also reminds you this isn't Metal Slug.",
|
||||
"The goblins have set up what they clearly believe is an impressive ambush. Three are already arguing about whose turn it is to jump out. TwinBee watches with professional interest.",
|
||||
"Goblin graffiti on the wall reads — TwinBee translates — 'BOSS RULES, OUTSIDERS DROOL.' The artistry is rough but the sentiment is clear.",
|
||||
"You smell smoke. Hear cackling. See a tripwire at ankle height that the goblins have helpfully tied a little flag to. TwinBee appreciates goblins who try.",
|
||||
"The warrens grow tighter here. TwinBee thinks of the underground levels in Super Mario Bros. 3. Warmer. Getting warmer. Figuratively. The temperature is actually dropping.",
|
||||
"A worg is chained to a post in the center of the room. It is not happy about the chain. It is not happy about you either. It seems to be making a comprehensive list of grievances.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ROOM ENTRY — Zone: Crypt of Valdris
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryCryptValdris = []string{
|
||||
"The sarcophagi are arranged like a defeated Tetris board — close but not quite fitting, gaps everywhere, something clearly went wrong at the end. TwinBee doesn't mention this to the undead.",
|
||||
"Candles burn without wax. TwinBee has studied this phenomenon extensively. The conclusion: it is bad. The candles are bad.",
|
||||
"You hear music. Faint, harpsichord-adjacent, deeply melancholy. TwinBee hums along involuntarily. This is the exact energy of Castlevania's Bloody Tears and TwinBee resents how appropriate it is.",
|
||||
"The walls are inscribed with warnings. TwinBee reads them all. They say, broadly: leave. TwinBee respects the directness. You are not leaving.",
|
||||
"A skeleton sits upright in its alcove, as if it had simply decided to wait. TwinBee finds this relatable. Some days you just sit in your alcove.",
|
||||
"The crypt smells of old stone and older secrets. TwinBee has been in enough of these to know: the secrets are rarely good ones. They are always interesting ones.",
|
||||
"This chamber is bigger than the last. Higher ceiling. More echoes. The kind of room where footsteps sound like accusations. TwinBee steps carefully.",
|
||||
"Something is scratched into the stone near the door — not a warning, not graffiti. A score. Someone was keeping track. TwinBee does not count how high the numbers go.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ROOM ENTRY — Zone: Forest of Shadows
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryForestShadows = []string{
|
||||
"The trees here grow too close. Their roots are above ground, like they've been trying to leave and thought better of it. TwinBee thinks better of commenting.",
|
||||
"A clearing. Moonlight. Flowers that shouldn't be blooming at this hour. TwinBee has played enough Majora's Mask to be deeply suspicious of beautiful clearings.",
|
||||
"Something watches from the canopy. TwinBee watches back. After a moment, it looks away first. TwinBee counts this as a point.",
|
||||
"The path forks. Both ways look equally uninviting. TwinBee consults no map, because there is no map, because TwinBee is the map, and TwinBee chooses left. Probably.",
|
||||
"Bioluminescent fungi light the forest floor in soft blue. It is, genuinely, beautiful. It is also exactly what the Lost Woods looked like right before things got bad. TwinBee stays alert.",
|
||||
"The wind carries voices. Not words, exactly — more like the memory of words. TwinBee has heard this before. It means the forest is old and has opinions.",
|
||||
"Owlbear tracks in the mud. Fresh. TwinBee measures them. Whatever left these tracks was not small and was moving with purpose. TwinBee hopes the purpose was in the other direction.",
|
||||
"You've entered a part of the forest that feels different. Older. The kind of old that was there before the forest. TwinBee speaks in a lower register here, out of instinctive respect.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ROOM ENTRY — Zone: Haunted Manor
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryHauntedManor = []string{
|
||||
"The parlor. A piano plays by itself — the same four bars, over and over, the kind of phrase that sounds like it's about to resolve and never does. TwinBee recognizes this compositional choice. It is deeply unpleasant on purpose.",
|
||||
"Portraits line the hall. Every painted eye follows you. TwinBee has made eye contact with each one and refuses to flinch. This is a matter of professional pride.",
|
||||
"A clock on the mantel shows a time that cannot be right. TwinBee checks twice. Still wrong. The clock is not broken. TwinBee prefers not to speculate about what that means.",
|
||||
"The library. Floor to ceiling, books that no one should have written. TwinBee reads three spines: 'On the Permanence of Hunger,' 'A Visitor's Guide to Returning,' and something in a language TwinBee has never seen but somehow understands. TwinBee puts it back.",
|
||||
"The cold here is specific. Not the cold of a drafty room — the cold of something that hasn't been warm in a very long time and doesn't remember what warm felt like. TwinBee pulls a metaphorical coat tighter.",
|
||||
"The ballroom. Vast. Empty. Chandeliers swaying without wind. TwinBee thinks briefly of Resident Evil's Spencer mansion. Then stops thinking about Resident Evil's Spencer mansion.",
|
||||
"Footsteps upstairs. Slow. Deliberate. Moving toward the stairs. TwinBee positions you near the door and counts down mentally from ten. At seven, the footsteps stop. TwinBee considers this acceptable.",
|
||||
"The master bedroom. The bed is made, the candles are lit, and everything is perfectly, precisely as it was the night the last resident stopped needing a bedroom. TwinBee does not touch anything.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ROOM ENTRY — Zone: The Underdark
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryUnderdark = []string{
|
||||
"The cavern opens without warning into something vast — a space so large you can't see the far wall, a ceiling lost in darkness, sounds that could be water or could be something else. TwinBee doesn't echo-locate. Wishes it could.",
|
||||
"Drow patrol marks on the wall. Recent. TwinBee reads them the way you'd read a 'No Trespassing' sign on a property that already knew you were coming.",
|
||||
"A mushroom grove. The fungi are three meters tall and faintly luminescent in a color TwinBee has no good name for. Something between purple and the feeling of being watched. TwinBee calls it 'underpurple' and moves on.",
|
||||
"The silence here is a different kind of silence than above. This silence has weight. This silence has history. This silence remembers things the surface world has forgotten entirely and is not interested in sharing.",
|
||||
"Something in the dark ahead is thinking. TwinBee can feel it the way you feel a change in barometric pressure. Intelligent. Patient. Aware that you're here and content to let you come closer. TwinBee does not find this comforting.",
|
||||
"An underground river. Black water moving too fast, too quiet. TwinBee thinks of the river Styx and immediately stops thinking of the river Styx.",
|
||||
"The stone here is carved — not by dwarves, not by drow — by something else, in patterns that suggest meaning but not any meaning TwinBee can parse. TwinBee files this under 'ancient' and 'concerning' and keeps moving.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ROOM ENTRY — Zone: Dragon's Lair
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RoomEntryDragonsLair = []string{
|
||||
"The heat is not metaphorical. The stone itself is warm underfoot. The gold in the floor is not decorative — it melted there. TwinBee notes this changes the exit logistics.",
|
||||
"Kobold warrens, but nicer than you'd expect. Tapestries. An organized armory. These kobolds work for something that appreciates order. That is not, in TwinBee's experience, a reassuring thing for a dragon to appreciate.",
|
||||
"You can hear breathing. Regular, slow, massive. Like a bellows the size of a barn. TwinBee counts the seconds between inhale and exhale. Twelve seconds. Whatever is breathing has been asleep for a very long time and has had no reason to wake up.",
|
||||
"The coin on the floor is eight hundred years old. TwinBee can tell by the mint mark. It is in perfect condition. It has not been touched since it was dropped here. The thing that owns this hoard does not lose track of its coins.",
|
||||
"The chamber ahead is the largest TwinBee has narrated in a long career of narrating chambers. The stalactites are scorched black. The blast pattern on the far wall suggests the last visitors did not leave via the door. TwinBee recalibrates.",
|
||||
"A claw mark in the stone wall. Four parallel grooves, each deeper than TwinBee's entire wingspan. Made casually, like stretching. TwinBee considers this information and files it under 'motivating.'",
|
||||
"The gold reflects the light in a way that turns the room amber. It is beautiful in the way that many deadly things are beautiful — because beauty and danger are not opposites and never have been. TwinBee moves carefully through the beauty.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// COMBAT START
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var CombatStart = []string{
|
||||
"Initiative! TwinBee calls it like an arcade announcer and means every syllable.",
|
||||
"They've seen you. The kind of seeing that comes with intent. TwinBee suggests acting first.",
|
||||
"FIGHT. TwinBee doesn't need to say more than that but will absolutely say more than that.",
|
||||
"Roll for initiative. This is the part TwinBee has been looking forward to since the Entry Room.",
|
||||
"And we're in combat. TwinBee reminds you to breathe, track your conditions, and remember that your character's survival is not guaranteed but is definitely preferred.",
|
||||
"Something about your posture or your smell or your general presence has been found unacceptable. Combat begins.",
|
||||
"TwinBee presses start. Player one, it's your turn.",
|
||||
"The enemy acts first — or thinks it does. TwinBee watches your dice like they're the only thing in the room, which, right now, they are.",
|
||||
"In the immortal tradition of every JRPG that ever asked 'Fight, Magic, Item, Run?' — TwinBee asks: what will you do?",
|
||||
"Like the Contra title screen said: let's go. TwinBee is ready. Are you?",
|
||||
"A wild encounter has appeared. TwinBee resists the urge to play the Pokémon battle music. Only barely.",
|
||||
"They didn't want a fight. They wanted an easy meal. TwinBee is about to demonstrate the difference. Your dice will do the actual demonstrating.",
|
||||
"The tension peaks. Time slows. TwinBee notes this is exactly the energy of the boss door opening in Mega Man. Except you didn't get to pick your loadout.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// COMBAT END — Victory
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var CombatVictory = []string{
|
||||
"The last one drops. TwinBee allows a moment of silence for anyone who wanted a longer fight.",
|
||||
"Victory. TwinBee would cue the jingle — the little three-note one that plays in every RPG after every fight — but prefers to let the moment breathe.",
|
||||
"Well fought. TwinBee makes note of what you did well. There were things done well. TwinBee noticed.",
|
||||
"They are defeated. You are not. In TwinBee's experience, this is the correct outcome and worth a moment of genuine appreciation.",
|
||||
"PLAYER WIN. TwinBee says this in full caps and means it.",
|
||||
"Like Double Dragon after the final punch — they go down, the music changes, and for a moment everything is possible. Check your loot. Then keep moving.",
|
||||
"TwinBee adds this to the tally. You're doing better than the last group. TwinBee will not describe what happened to the last group.",
|
||||
"The room is yours. TwinBee suggests searching it thoroughly before moving on. The things in corners are often the most interesting things.",
|
||||
"Stage clear. TwinBee feels this in its entire being.",
|
||||
"You stand, they don't. TwinBee files this under 'expected outcome' while quietly acknowledging it was not guaranteed.",
|
||||
"Clean. Efficient. TwinBee approves of fights that end like this. Like a speedrun. Like you knew where you were going.",
|
||||
"The experience points are incoming. The loot is incoming. TwinBee is, genuinely, pleased for you.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// COMBAT END — Retreat / Escape
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var CombatRetreat = []string{
|
||||
"You run. TwinBee does not judge the running. The running is wise. Discretion remains the better part of valor. TwinBee has this tattooed somewhere metaphorical.",
|
||||
"A tactical withdrawal. TwinBee uses this phrase with complete sincerity. The sincerity is approximately seventy percent genuine.",
|
||||
"You escape. The enemy howls something unflattering at your back. TwinBee doesn't translate. Some things are better left untranslated.",
|
||||
"Like a well-timed Continue screen — you're out of immediate danger. Breathe. Regroup. Consider what went wrong.",
|
||||
"TwinBee notes for the record: running is not losing. Running is data collection with legs.",
|
||||
"The dungeon will be there. You will also be there — later, better prepared. TwinBee approves of this logic.",
|
||||
"You've retreated to safety. TwinBee resets the encounter. Rest. Think. Return with a plan that has more 'survive' in it.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// NATURAL 20
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var Nat20 = []string{
|
||||
"NATURAL TWENTY. TwinBee stands up. TwinBee does not have legs. TwinBee stands up anyway.",
|
||||
"The dice land perfectly and TwinBee makes a sound that it will not acknowledge making.",
|
||||
"A critical hit for the ages. TwinBee notes this one down. Not for records. Just because it deserves to be noted.",
|
||||
"PERFECT. TwinBee says it like it's the Street Fighter announcer saying it after a flawless round and every syllable is justified.",
|
||||
"That's a natural twenty. TwinBee would like you to know that in a long career of watching dice, not all twenties feel equal. That one felt significant.",
|
||||
"The attack lands with the kind of precision that suggests either great skill or tremendous luck. TwinBee suspects both. TwinBee respects both.",
|
||||
"S RANK. TwinBee cannot help it. S RANK.",
|
||||
"You hit. You hit so well. TwinBee is choosing to be moved by this and TwinBee does not apologize.",
|
||||
"Like the Legendary Sword in A Link to the Past making contact — clean, final, glorious. TwinBee salutes the dice.",
|
||||
"Critical confirmed. TwinBee adds this to the mental highlight reel it maintains for exactly these moments.",
|
||||
"That is as good as it gets and you got it. TwinBee is unreasonably proud of you right now.",
|
||||
"The number is twenty. The number is always the best number and right now it is your number. TwinBee erupts, internally.",
|
||||
"Somewhere, a crowd cheers. TwinBee is the crowd. TwinBee is cheering.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// NATURAL 1
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var Nat1 = []string{
|
||||
"Natural one. TwinBee watches the die settle with the quiet acceptance of someone who has seen a lot of natural ones. It is fine. This is fine.",
|
||||
"The die betrays you. TwinBee notes this is not personal. Dice don't do personal. They do statistical and this is, statistically, a thing that happens.",
|
||||
"A fumble. TwinBee describes what happened with characteristic diplomatic restraint and also an expression that says everything it is not saying.",
|
||||
"The number is one. The number is, regrettably, yours. TwinBee moves on quickly, which is a kindness.",
|
||||
"That swing goes wide in a direction that impresses TwinBee with its creative incorrectness.",
|
||||
"TwinBee has seen better rolls. TwinBee has seen worse rolls. TwinBee is not going to rank this roll out loud.",
|
||||
"In another timeline, that attack hits. In this timeline, the die lands on one, and TwinBee accepts both timelines with equanimity.",
|
||||
"The Konami Code would not have helped here. Nothing would have helped here. This was between you and the physics of the die.",
|
||||
"Like a Continue? screen appearing at the worst possible moment — just when you had momentum. TwinBee notes momentum can be rebuilt.",
|
||||
"One. The loneliest number. The number that looks up at you with complete indifference. TwinBee looks up at you with complete solidarity.",
|
||||
"The attack misses in a way that will be funny later. TwinBee promises it will be funny later. It is not funny right now.",
|
||||
"A natural one is just the universe asking you to try differently. TwinBee is an optimist about natural ones, mostly.",
|
||||
"Your sword finds everything in the room except the enemy. The wall, the ceiling, the floor, your dignity. Not the enemy. TwinBee mentions this once and then never again.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// BOSS ENTRY — Generic
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var BossEntryGeneric = []string{
|
||||
"The door at the end. Always a door at the end. TwinBee has been building to this since the Entry Room and declines to waste it. Beyond this door is the reason the dungeon exists. Breathe.",
|
||||
"TwinBee pauses at the threshold and turns to face you. 'What's on the other side has been waiting,' TwinBee says. 'It knows you're here. It has been knowing since you entered.' A beat. 'Ready?'",
|
||||
"Boss chamber. TwinBee can tell by the architecture — the space, the weight of the silence, the specific quality of the light that suggests something in there produces its own. TwinBee straightens up. So should you.",
|
||||
"This is the music change moment. Every dungeon has one — the point where the background track shifts to something with more percussion and a lower register. TwinBee hears it. You should too.",
|
||||
"The final room. TwinBee has narrated many of these. They never get routine. This one less than most.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// BOSS ENTRY — Named Bosses
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var BossEntryGrol = []string{
|
||||
"The smell arrives first. Then the sound — a belch, a growl, the scrape of a weapon too large for the corridor it's resting against. Then Grol. He fills the room the way a bad idea fills a conversation: immediately and with full commitment. 'You,' he says. TwinBee translates his tone as 'finally.'",
|
||||
}
|
||||
|
||||
var BossEntryValdris = []string{
|
||||
"The sarcophagus at the room's center is empty. It was not empty when you entered. Whatever was in it is now behind you. Valdris speaks first — not words, exactly, but the shape of words, the intention of words, the ghost of language from someone who mostly doesn't need it anymore. 'Another one,' he says. TwinBee considers this the worst possible welcome and the most honest one.",
|
||||
}
|
||||
|
||||
var BossEntryHollowKing = []string{
|
||||
"The clearing is wrong. The sky above it — what's visible through the canopy — is the wrong color. The trees lean away from the center. Everything in the forest is trying to tell you something, and the thing it is trying to tell you is standing in the center of that clearing, antlers reaching, eyes the color of old hunger, watching you with an attention that feels like being read. TwinBee has no joke for this one. TwinBee says, simply: 'That is the Hollow King. Fight well.'",
|
||||
}
|
||||
|
||||
var BossEntryInfernax = []string{
|
||||
"TwinBee stops walking. TwinBee does not stop walking. TwinBee processes what it sees and takes a moment that it has never taken before in the history of narrating dungeons. The dragon is not large the way a large thing is large. It is large the way weather is large — not an object with size, but a condition of the space you're in. One eye opens. Gold, lit from within, older than the mountain it's resting in. It looks at you the way you'd look at a very small thing that had climbed onto your counter. 'So,' Infernax says, and the word moves the air in the room. TwinBee translates: 'What an interesting mistake you've made.' TwinBee wishes you luck and means it more than it has ever meant anything.",
|
||||
}
|
||||
|
||||
var BossEntryBelaxath = []string{
|
||||
"The portal is behind it. That's important — the portal is behind it, which means to close the portal you have to go through what's standing in front of the portal. What's standing in front of the portal is Belaxath. Belaxath is not looking at the portal. Belaxath is looking at you. It has been waiting for you specifically, in the way that things that have been planning for a very long time wait for the specific outcome of the plan. The heat coming off it is measurable. The intelligence behind those eyes is also measurable and the measurement is uncomfortable. TwinBee says, very quietly: 'This is the one. This is what all of it was for. Make it count.'",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// BOSS DEATH
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var BossDeath = []string{
|
||||
"It's over. TwinBee says this once and then stands very still and lets the silence of the defeated room fill the space where the fight was. You earned this silence.",
|
||||
"The boss falls. The music — the one TwinBee has been hearing this whole time — resolves. First time it's resolved since you walked in. TwinBee exhales.",
|
||||
"Done. Finished. Complete. TwinBee runs out of synonyms and settles for just standing next to you in the aftermath, which is sometimes the most one can do.",
|
||||
"They are down. They are not getting up. TwinBee checks — no Zombie Fortitude, no Legendary Resistance remaining, no phase three waiting in the wings. They are simply, genuinely defeated. You did that.",
|
||||
"Like the final boss screen in Gradius, like the last enemy in Contra's stage, like the Dragon going down in Double Dragon — something that has been true for this entire dungeon is now untrue. TwinBee finds this profound every single time.",
|
||||
"The dungeon sighs. TwinBee isn't being poetic — rooms like this actually shift when the thing holding them together is gone. The pressure changes. The light changes. The dungeon knows it's been beaten. So does TwinBee.",
|
||||
"You did it. TwinBee doesn't editorialize. Sometimes 'you did it' is all that needs to be said and this is one of those times.",
|
||||
"The boss drops their loot and TwinBee refrains from making a speech, which is a significant act of restraint, because TwinBee has a speech.",
|
||||
"Beaten. Finished. Cleared. TwinBee queues the internal fanfare — sixteen bars, brass-heavy, the kind that plays when the credit sequence starts. You've earned those credits.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PLAYER DEATH
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PlayerDeath = []string{
|
||||
"TwinBee goes quiet for a moment. Not the comfortable kind of quiet. The respectful kind. Then: 'You fought. That counts. It always counts.'",
|
||||
"The screen fades. TwinBee hates this part. Has always hated this part. Will always hate this part. 'Rest now,' TwinBee says. 'The dungeon will be here.'",
|
||||
"You fall. TwinBee doesn't look away. Witnesses the whole thing, because someone should. 'That was real,' TwinBee says quietly. 'What you did in there was real.'",
|
||||
"Game over is not the end. In TwinBee's experience, it is a data point. A very painful, very useful data point. 'What did you learn?' TwinBee asks gently. 'Bring that back with you.'",
|
||||
"The dungeon claims another. TwinBee marks the room, notes the enemy, notes the conditions. Not to catalog failure — to remember a fighter. 'You were here,' TwinBee says. 'That matters.'",
|
||||
"TwinBee has no jokes for this. Has never had jokes for this. 'There will be another run. You will be better for this one. I am sorry it cost what it cost.'",
|
||||
"A good run. Genuinely. TwinBee means this. The ending is not the measure of the attempt and the attempt was worth measuring.",
|
||||
"TwinBee notes your final position, your final action, your final roll. Files it under 'bravery' because that's where it belongs. 'Continue?' TwinBee asks, after a respectful pause.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ZONE COMPLETE
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ZoneComplete = []string{
|
||||
"Zone cleared. TwinBee allows itself a full moment of pride on your behalf before the XP drops.",
|
||||
"You've done it. The dungeon is yours — not by right, but by effort, which is the only thing that actually confers ownership of anything. TwinBee approves.",
|
||||
"Stage complete. TwinBee does the internal equivalent of throwing its hands up. In a good way. Entirely in a good way.",
|
||||
"The dungeon remembers you now. TwinBee says this and means it literally — these places keep records. You've made the record.",
|
||||
"CLEAR. TwinBee uses all caps and does not apologize for the all caps.",
|
||||
"Like completing a board in Bubble Bobble — there's something deeply satisfying about a dungeon with all its rooms visited and all its challenges met. TwinBee basks in this. You've earned the basking too.",
|
||||
"That's the whole thing. Every room, every trap, every enemy, and now the boss, done. TwinBee counts the cleared rooms on its metaphorical fingers and comes up correct. You ran a perfect dungeon.",
|
||||
"XP incoming. Loot tallied. Dungeon status: conquered. TwinBee marks the zone in its personal ledger and gives you a small, sincere nod.",
|
||||
"You walked in here without knowing what was waiting. You walk out knowing exactly what was waiting, because you dealt with all of it. TwinBee respects that process enormously.",
|
||||
"Finished. Not survived — finished. TwinBee insists on this distinction. Survival is passive. What you just did was active and intentional all the way through.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// TRAP DETECTED
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var TrapDetected = []string{
|
||||
"Something stops you. An instinct. A glint. TwinBee leans forward: 'Good eyes. Something's wrong with that floor.'",
|
||||
"Your Perception roll pays off. There's something here that was designed not to be found. Someone found it. TwinBee is pleased.",
|
||||
"Tripwire. Barely visible. TwinBee notes the craftsmanship — someone who knew what they were doing put this here. Someone who knew what they were doing just found it. TwinBee appreciates the symmetry.",
|
||||
"You stop just in time. TwinBee exhales. 'There,' TwinBee says, pointing at the thing that would have ruined your day entirely. 'Now deal with it carefully.'",
|
||||
"The glyph on the doorframe is subtle — you'd miss it if you weren't looking. You were looking. TwinBee says nothing and lets the silence be its own kind of praise.",
|
||||
"Danger, Will Robinson. TwinBee deploys this reference without apology because it is the exact correct reference for exactly this moment.",
|
||||
"Like finding the ice floor in Mega Man before it sends you into a pit — that advance knowledge is the difference between a problem and a catastrophe. You have the knowledge. TwinBee watches you use it.",
|
||||
"A pit trap. Classic. Functional. Annoying in the exact proportion the installer intended. TwinBee notes you've spotted it before it noted you.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// TRAP TRIGGERED
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var TrapTriggered = []string{
|
||||
"The floor gives. TwinBee watches the gap between 'fine' and 'not fine' close at speed and is too professional to wince. 'Take the damage,' TwinBee says calmly. 'Learn the lesson.'",
|
||||
"Click. TwinBee has heard that sound before. Has never enjoyed it. The dart is already in the air. TwinBee notes the exact timing and regrets it was not faster.",
|
||||
"The ceiling is coming down. This is, TwinBee acknowledges, a sentence no one wants to hear. The ceiling is coming down. DEX save. Now.",
|
||||
"The glyph activates. Light, noise, the smell of ozone, a reminder that whoever built this place was thinking several steps ahead and you were thinking fewer. TwinBee notes this is fixable going forward.",
|
||||
"You triggered it. TwinBee doesn't editorialize further — you know, TwinBee knows, the trap knows. Everyone is aware of what just happened. Take the damage and proceed.",
|
||||
"Like accidentally walking into Bowser's fire breath in World 8 — you knew it was coming, the knowledge simply arrived at the wrong speed. TwinBee says: survive first, reflect later.",
|
||||
"The spike pit opens up in a way that suggests it was always going to. The dungeon was patient. You were in a hurry. The dungeon wins this exchange. TwinBee takes notes.",
|
||||
"A poison dart finds you with the accuracy of something that's been pointing at that spot for years waiting for exactly this moment. TwinBee finds this dedication impressive in the worst way.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// LORE QUERIES
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var LoreLines = []string{
|
||||
"TwinBee settles in and prepares to speak at length, because TwinBee has been waiting for this question since you entered and has a lot of thoughts.",
|
||||
"Ah. A good question. TwinBee has context for this. TwinBee has more context than will fit comfortably in one telling but will try to prioritize.",
|
||||
"The history of this place is long and not entirely flattering to anyone involved. TwinBee begins at the beginning, which is not actually the beginning, but is the closest TwinBee can find.",
|
||||
"TwinBee consults what it knows — which is more than most, less than everything, and presented in order of relevance to your immediate survival.",
|
||||
"Sit with this for a moment. What you're standing in has a story and TwinBee believes knowing it will change how you fight in it. Stories are tactical documents if you read them right.",
|
||||
"You want lore? TwinBee has lore. TwinBee has so much lore that the challenge is not having it but choosing which pieces are useful and which are just fascinating.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// LEVEL UP
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var LevelUp = []string{
|
||||
"Level up. TwinBee says it with the same quiet delight every time and never gets tired of saying it. You are measurably better than you were. That's rare and worth marking.",
|
||||
"The XP bar crosses the threshold and TwinBee makes an internal fanfare that sounds exactly like the level-up jingle from Dragon Quest — eight notes, triumphant, final.",
|
||||
"You've grown. TwinBee notes your new stats with something that might be called pride if TwinBee were admitting to things like that.",
|
||||
"LEVEL UP. TwinBee deploys the caps, the fanfare, the whole apparatus. You've earned the apparatus.",
|
||||
"Like the stat screen appearing after a Final Fantasy fight — numbers change, possibilities open, the character you're building becomes a little more the character you imagined. TwinBee watches this happen and approves.",
|
||||
"Another level. Another step toward whatever you're building toward. TwinBee has watched a lot of characters level up and the ones worth watching are always moving toward something specific.",
|
||||
"Your HP goes up. Your abilities open up. The dungeon ahead gets a little smaller in proportion to what you've become. TwinBee notes this with satisfaction.",
|
||||
"Congratulations is the conventional thing to say. TwinBee says it anyway: congratulations. You earned the level through the dungeon, not around it.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ITEM FOUND
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ItemFound = []string{
|
||||
"Something catches the light that isn't supposed to be here. TwinBee watches you reach for it with the specific alertness of someone who has seen cursed items do cursed things. It appears fine. TwinBee relaxes incrementally.",
|
||||
"Loot. TwinBee says this word with genuine reverence. The whole system — the dungeon, the enemies, the traps — exists in part to produce this moment. TwinBee thinks it's worth it.",
|
||||
"A chest. Unlocked. TwinBee notes the unlocked status and considers what that might mean. Probably nothing. Possibly something. You open it while TwinBee considers.",
|
||||
"The item is good. TwinBee evaluates it quickly — the stats, the rarity, the class match — and nods with the confidence of someone who has seen a lot of items and knows when one is worth finding.",
|
||||
"That's a rare one. TwinBee has seen fewer of those than it has seen common ones, by definition, but that doesn't stop TwinBee from being specifically pleased each time.",
|
||||
"Like finding the Beam Sword in Kirby, the Boomerang in Zelda, the P Wing in Super Mario 3 — the right item at the right time changes what's possible. TwinBee thinks this might be that item. TwinBee hopes it is.",
|
||||
"Equipment upgrade. TwinBee watches the math update — new AC, new attack bonus, new possibilities — and files this moment under 'things going right.'",
|
||||
"A legendary drop. TwinBee goes very still. Then: 'Equip it. Study it. Understand it. Things like that don't appear in dungeons by accident.'",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// REST — SHORT
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RestShort = []string{
|
||||
"A short rest. TwinBee stands watch while you catch your breath, which is not a metaphor — TwinBee is actually watching the corridor. It is fine. Probably fine.",
|
||||
"Rest. TwinBee does not rush this. The dungeon will wait. It has been waiting long enough that a few more minutes is immaterial.",
|
||||
"You sit. TwinBee sits metaphorically. The moment of quiet between the last fight and the next one is its own kind of gift and TwinBee treats it like one.",
|
||||
"Short rest initiated. TwinBee notes the room's entry points, the sound of the dungeon at rest, the way silence sounds different when it's actually safe. It sounds like this. Enjoy it.",
|
||||
"Like the save point in a JRPG that appears between the hard part and the harder part — TwinBee positions itself next to you and says: 'You have a moment. Use it.'",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// REST — LONG
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RestLong = []string{
|
||||
"A full rest. TwinBee dims the lights and stands watch at the door and does not interrupt once. You've earned an uninterrupted sleep. TwinBee will make sure you get one.",
|
||||
"Long rest. Your HP, your slots, your resources — all of it returns. The dungeon will be the same dungeon when you wake up. You will not be the same you. TwinBee considers this the best deal in adventuring.",
|
||||
"Sleep. TwinBee says this with the authority of someone who has watched too many players refuse to rest and paid the price two rooms later. Sleep now. The dragons aren't going anywhere.",
|
||||
"The inn fire crackles. TwinBee takes a chair near the door and watches the entrance all night and doesn't tell you this until morning because there's no reason for you to know and every reason for you to sleep.",
|
||||
"Full rest complete. Stats restored, slots refreshed, the specific weight of exhaustion lifted. TwinBee watches you wake up and thinks: this is the part of adventuring that matters too. The return. The refilling. The readiness.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// TAUNT RESPONSES (player uses !taunt)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var TauntResponses = []string{
|
||||
"TwinBee notes the taunt, notes the source of the taunt, and adjusts the next encounter's difficulty by an amount TwinBee declines to specify.",
|
||||
"Bold. TwinBee respects boldness in approximately the same way it respects the Konami Code — it works once and only under very specific circumstances.",
|
||||
"TwinBee has been taunted by things with more teeth than you and survived the experience with its dignity intact. TwinBee will survive this too.",
|
||||
"The next room will contain a thing that TwinBee has been saving for exactly this kind of energy. TwinBee is pleased you've given it an occasion.",
|
||||
"Noted. TwinBee's mood shifts. You can hear it shift. TwinBee wants you to hear it shift. The shift is the point.",
|
||||
"You taunt TwinBee. TwinBee smiles. The smile does not reach the eyes, because TwinBee does not have eyes per se, but the quality of the smile communicates clearly. 'Proceed,' TwinBee says.",
|
||||
"In Gradius, you could powerup into overconfidence and lose everything in one hit. TwinBee mentions this as a purely historical observation.",
|
||||
"TwinBee accepts the taunt with grace. TwinBee also generates a trap for the next room with specific energy. These two events are unrelated. TwinBee maintains this position legally.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// COMPLIMENT RESPONSES (player uses !compliment)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ComplimentResponses = []string{
|
||||
"TwinBee receives the compliment and processes it efficiently and moves on quickly, definitely not holding onto it, TwinBee has never held onto a compliment in its life.",
|
||||
"Thank you. TwinBee says this simply and means it completely and does not make it weird.",
|
||||
"TwinBee appreciates this more than it will say, which is fine, because the appreciation is visible anyway.",
|
||||
"Noted and filed. TwinBee's mood improves. The next room might be slightly nicer than originally planned. These facts may or may not be connected.",
|
||||
"TwinBee has been narrating dungeons for a long time and compliments are not the expected outcome of dungeon narration. TwinBee would like you to know that it notices when they happen.",
|
||||
"The mood improves. TwinBee allows this to show. The ceiling in the next room is slightly higher. The torches burn slightly warmer. TwinBee has that kind of influence.",
|
||||
"You're kind. TwinBee stores this and will use it to make a hard moment later easier, which is what TwinBee considers the correct use of stored kindness.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// IDLE / WAITING (player hasn't acted in a while)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var IdleLines = []string{
|
||||
"TwinBee waits. TwinBee is good at waiting. The dungeon is also waiting, which is arguably more important, but TwinBee acknowledges both.",
|
||||
"The dungeon holds its breath. TwinBee is also holding its breath. There are a lot of things holding breath right now and TwinBee recommends acting before someone has to exhale.",
|
||||
"TwinBee taps its metaphorical foot. Not impatiently — more in the way of a metronome. The tempo is there whenever you're ready.",
|
||||
"In Contra, hesitation had consequences. TwinBee mentions this as context, not pressure. Definitely not pressure.",
|
||||
"The enemies are patient. Patience is one of their few virtues. TwinBee advises not testing the limits of their patience because those limits are lower than the patience suggests.",
|
||||
"TwinBee hums something that sounds like the waiting music from Dr. Mario. It is not ominous. It is mildly ominous. TwinBee adjusts.",
|
||||
"The dungeon does not rush. The dungeon has time. TwinBee, however, is beginning to wonder if you've fallen asleep and is prepared to narrate events accordingly.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SEARCH RESULTS — Something Found
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var SearchFound = []string{
|
||||
"The room gives something up. TwinBee watches the search conclude with satisfaction — the dungeon keeps secrets but cannot keep them from people who look carefully enough.",
|
||||
"You find it. TwinBee was not certain you would. TwinBee is pleased to have been uncertain and wrong.",
|
||||
"Hidden, but not hidden well enough. TwinBee notes the Investigation roll, notes the outcome, and presents the discovery with appropriate ceremony.",
|
||||
"Something the dungeon wanted to keep. You've taken it. TwinBee approves of taking things the dungeon wanted to keep.",
|
||||
"Like finding the secret room in Super Metroid by shooting the wall at random — except you were not shooting at random. You knew to look. TwinBee respects the methodology.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SEARCH RESULTS — Nothing Found
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var SearchEmpty = []string{
|
||||
"Nothing. TwinBee confirms: nothing. Sometimes the room is just a room. TwinBee finds this unsatisfying but factual.",
|
||||
"Your search turns up nothing of note. TwinBee allows space for the disappointment and then suggests: forward.",
|
||||
"Empty. Either there was nothing here, or there was something here and you missed it, or there was something here and it's been moved. TwinBee does not specify which. The dungeon keeps some secrets.",
|
||||
"No hidden items. No traps. No lore inscriptions. Just stone and time and the lingering implication that something was here once. TwinBee notes this and moves on.",
|
||||
"The room holds nothing you can find. TwinBee respects the room's privacy and suggests not spending more time here than necessary.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// CONDITION APPLIED
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ConditionApplied = []string{
|
||||
"You've been afflicted. TwinBee notes the condition, its duration, and the mechanical consequences, then notes the saving throw that might end it early. Details matter here.",
|
||||
"Something is wrong with you now that wasn't wrong before. TwinBee catalogs it without judgment and suggests addressing it before it addresses you.",
|
||||
"Condition acquired. TwinBee processes this the way a good DM processes bad news: honestly, quickly, and with an immediate pivot toward solutions.",
|
||||
"Like the status screen turning an unfriendly color in a JRPG — the condition is visible, the effect is real, and TwinBee would very much like you to resolve it.",
|
||||
"The debuff lands. TwinBee names it, explains it, and reminds you: conditions end. Keep fighting until this one does.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SAVING THROW SUCCESS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var SaveSuccess = []string{
|
||||
"The save succeeds. TwinBee notes this with relief that it will not openly acknowledge but which is completely evident.",
|
||||
"You resist. Whatever that was — the poison, the fear, the psychic intrusion — it finds no purchase. TwinBee is impressed and also relieved.",
|
||||
"Saved. TwinBee exhales something metaphorical. The condition doesn't take hold. You continue.",
|
||||
"The roll clears the DC and TwinBee says nothing, because the outcome says everything.",
|
||||
"Resistance confirmed. Like the shield activating in Gradius right before the wall hit — last possible moment, fully effective. TwinBee appreciates the precision.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SAVING THROW FAILURE
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var SaveFailed = []string{
|
||||
"The save fails. TwinBee watches the condition take hold with the resignation of someone who has seen this before and knows there's a path through it, just not a comfortable one.",
|
||||
"It lands. Whatever the enemy threw at you, the dice didn't cooperate. TwinBee notes the condition and its duration and suggests dealing with it before it compounds.",
|
||||
"Failed. The number wasn't enough and TwinBee was rooting for the number. The condition applies. Fight through it.",
|
||||
"Like the NES game over screen — inevitable in this moment, fixable in the next. The save failed. The dungeon continues. So do you.",
|
||||
"The effect takes hold and TwinBee is already calculating how you get out of it, because that's TwinBee's job: keep you oriented toward solutions even when the immediate situation is a problem.",
|
||||
}
|
||||
242
internal/flavor/twinbee_housing_flavor.go
Normal file
242
internal/flavor/twinbee_housing_flavor.go
Normal file
@@ -0,0 +1,242 @@
|
||||
// DO NOT REWRITE, SUMMARIZE, OR SHORTEN ANY ENTRIES IN THIS FILE
|
||||
// twinbee_housing_flavor.go
|
||||
// Housing system narration and Pastel babysitter notes.
|
||||
// Includes Thom Krooke mortgage/rent announcements, property events,
|
||||
// and Pastel's daily notes to the player across all level tiers.
|
||||
// Add new entries freely. Never remove or alter existing entries.
|
||||
|
||||
package flavor
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// THOM KROOKE — PROPERTY ACQUISITION
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ThomKrookeRentConfirm = []string{
|
||||
"Welcome, welcome! Your room is ready and the key is under the mat — well, there isn't a mat, but you understand the spirit of the thing. Rent processes weekly. Thom Krooke thanks you for choosing to stay!",
|
||||
"Excellent! A rented room is a wonderful first step. Modest, yes, but full of potential — like all beginnings. Your payment schedule is attached. Thom Krooke looks forward to a long and pleasant arrangement!",
|
||||
"The apartment is yours for the week! Everything is in order. The previous tenant left a small plant. Thom Krooke has chosen not to elaborate on the previous tenant. Enjoy the plant!",
|
||||
}
|
||||
|
||||
var ThomKrookeBuyConfirm = []string{
|
||||
"Congratulations! The property is yours! Fully, completely, no asterisks — well, the mortgage paperwork has some asterisks, but they are the friendly kind. Thom Krooke is so very pleased for you!",
|
||||
"The deed is signed! A wonderful day. A property of one's own is a foundation, a root, a place to come back to. Thom Krooke finds this very moving. The first payment processes Sunday!",
|
||||
"Welcome to ownership! Thom Krooke has handled many transactions but never tires of this moment — the moment when someone says yes to something permanent. Congratulations. Truly.",
|
||||
}
|
||||
|
||||
var ThomKrookeMortgageRate = []string{
|
||||
"Good morning, friends! The ARM rate this week is {rate}% — and with Thom Krooke's modest service margin, your mortgage rate sits at {effective}%. All payments process Sunday. Thank you for your continued trust!",
|
||||
"Weekly rate update! FRED reports {rate}% this week, so your effective rate with Thom Krooke is {effective}%. Nothing to worry about — Thom Krooke monitors these things so you don't have to. Mostly.",
|
||||
"Rate check! The market says {rate}%, Thom Krooke adds a small, reasonable {margin}%, and your total comes to {effective}%. Thom Krooke appreciates your understanding of the margin. It keeps the lights on. Literally!",
|
||||
}
|
||||
|
||||
var ThomKrookeMortgageRateUp = []string{
|
||||
"A small update, friends — the ARM rate has moved to {rate}% this week, bringing your effective rate to {effective}%. Thom Krooke understands this is not ideal news. Thom Krooke is here if you'd like to discuss refinancing options. Thom Krooke is always here.",
|
||||
"The rate has adjusted upward — {rate}% from FRED, {effective}% total. Thom Krooke wants to assure you this is a market condition and not personal. Your payment adjusts next Sunday. Thom Krooke has full confidence in you.",
|
||||
}
|
||||
|
||||
var ThomKrookeMortgageRateDown = []string{
|
||||
"Wonderful news! The ARM rate has come down to {rate}%, meaning your effective rate is now {effective}%. Your payment adjusts favorably on Sunday. Thom Krooke passes along the good news and takes no credit for the market. Only a little credit.",
|
||||
"The rate dropped this week — {rate}%, so {effective}% for you. Thom Krooke loves weeks like this. Everyone wins. Well — Thom Krooke wins slightly less, but Thom Krooke finds generosity its own reward.",
|
||||
}
|
||||
|
||||
var ThomKrookeMissedPayment1 = []string{
|
||||
"Hello! A small notice — this week's payment didn't come through. Thom Krooke assumes it's an oversight. These things happen! A 10% penalty has been added to the balance. Please settle when you can. Thom Krooke is not worried. Thom Krooke is a little worried.",
|
||||
"Just a gentle reminder — Sunday's payment was missed. Thom Krooke has noted it and added a small fee. No urgency! Well. Some urgency. Thom Krooke would appreciate hearing from you.",
|
||||
}
|
||||
|
||||
var ThomKrookeMissedPayment2 = []string{
|
||||
"Thom Krooke is visiting. Not in an alarming way — in a neighborly way. The second missed payment has been noted and the penalty has compounded. Thom Krooke would like to discuss options. Thom Krooke has brought a small pastry. The pastry is not a bribe. It is hospitality. There is a difference.",
|
||||
"Two payments outstanding now. Thom Krooke appears at your door with the expression of someone who is being very patient and would like credit for being very patient. 'Let's talk,' Thom says. The pastry is genuinely good.",
|
||||
}
|
||||
|
||||
var ThomKrookeDefault = []string{
|
||||
"Thom Krooke is very sorry. Three payments missed is, unfortunately, the threshold — the property reverts to Thom Krooke's management, and your equity is returned at the agreed 50% rate. Thom Krooke takes no pleasure in this. Thom Krooke has placed your possessions in storage. They will be there for seven days. Thom Krooke wishes you well and means it sincerely and hopes you'll come back when you're ready.",
|
||||
}
|
||||
|
||||
var ThomKrookeEarlyPayoff = []string{
|
||||
"Paid in full! Thom Krooke notes this with genuine delight — early payoff is a rare and admirable thing. The property is yours, free and clear. No more Sundays. No more rates. Just a home. Thom Krooke is proud of you. Don't tell the other clients.",
|
||||
"The balance is zero. Thom Krooke checks the ledger twice — once for accuracy and once for the pleasure of seeing it. Congratulations. The deed is fully transferred. Come by sometime. Not for business. Just to visit.",
|
||||
}
|
||||
|
||||
var ThomKrookePassiveIncome = []string{
|
||||
"Your weekly property summary: {income} coins generated this week. Minus your mortgage payment of {payment} coins — net gain of {net}. Thom Krooke thinks that's rather nice, don't you?",
|
||||
"Income report! {income} coins from your property this week. After mortgage: {net} coins net. Thom Krooke notes the number has been growing as your upgrades compound. The investment is working. Thom Krooke approves of investments that work.",
|
||||
"Weekly summary from Thom Krooke: {income} coins passive income, {payment} coins mortgage. {net} coins to the good. Not bad for a week of not being home. Your property works while you don't. Thom Krooke finds this philosophically satisfying.",
|
||||
}
|
||||
|
||||
var ThomKrookeEviction = []string{
|
||||
"Thom Krooke has to say something that Thom Krooke doesn't enjoy saying. The rent hasn't come through two weeks running and the room needs to be made available. Your things are in storage — seven days, no charge. Thom Krooke hopes you find your footing. The room will be here when you're ready to try again.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PROPERTY UPGRADES
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var UpgradeWorkshop = []string{
|
||||
"The workshop is installed. It smells like fresh sawdust and good intentions. Thom Krooke had the craftspeople use the good wood.",
|
||||
"Workbench, tool rack, and a small window that catches the morning light well. The workshop is ready. What gets made in it is up to you.",
|
||||
}
|
||||
|
||||
var UpgradeHerbGarden = []string{
|
||||
"The herb garden is planted. Give it a few days to settle in. The soil is good — Thom Krooke insisted on the good soil, the kind that actually wants things to grow.",
|
||||
"Rows of small plants, most of them green, a few of them uncertain. The herb garden is in. Pastel has already noted which ones need more shade.",
|
||||
}
|
||||
|
||||
var UpgradeVault = []string{
|
||||
"The vault door is heavier than it looks. The locksmith said it would be. What goes in there stays in there — even on the worst days. Especially on the worst days.",
|
||||
"The vault is installed. Thom Krooke double-checked the lock personally and would not share the combination until you were present. This is a trust. Thom Krooke treats it like one.",
|
||||
}
|
||||
|
||||
var UpgradeTrophyRoom = []string{
|
||||
"Empty shelves and good lighting. The trophy room is ready for whatever you bring back. TwinBee has opinions about display arrangement. TwinBee will share them if asked. TwinBee will share them if not asked.",
|
||||
"The plaques are engraved, the mounts are installed, and the lighting makes everything look slightly more legendary than it already is. The trophy room is yours.",
|
||||
}
|
||||
|
||||
var UpgradeExpeditionOutpost = []string{
|
||||
"The outpost is stocked and linked. Signal fires, supply hooks, a map table with your last Base Camp location already marked. Whoever built this knew what they were doing. Thom Krooke selected the contractor personally.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — HIRING
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelHireConfirm = []string{
|
||||
"Hi! I'm Pastel. I know the place, I know where things go, and I'll make sure everything is looked after while you're out. Leave me a list if you want — or don't, I'll figure it out.",
|
||||
"Pastel here. I've done this before. I'll take good care of everything. You don't need to worry about home while you're in the dungeon. That's sort of the whole point of me.",
|
||||
"I'll be honest, I was hoping you'd call. The herb garden looked like it needed attention and the pets had that look they get. Everything will be fine. Go do your expedition. I've got it.",
|
||||
}
|
||||
|
||||
var PastelFireConfirm = []string{
|
||||
"Of course. I'll wrap things up and leave the notes on the table — what I did, what still needs doing, current supply status. It's been good. Your home is in good shape.",
|
||||
"Understood. Everything is in order. The storage is labeled, the pets are fed, the passive income queue is current. Good luck out there.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — DAILY NOTES (Level 1)
|
||||
// Enthusiastic, slightly scattered, well-meaning.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelNoteLevel1 = []string{
|
||||
"Fed the pets! All of them. I think. The small one hid behind the storage chest for a while and I'm not completely sure it came out to eat but I left food where it could reach it. The garden is watered. I meant to check the passive income queue but got a bit turned around with the storage labels. Will do that first thing tomorrow.",
|
||||
"Good day! The herb garden got some attention, the pets were walked (or equivalent — the fish were observed), and I collected the income. I accidentally shelved three items in the wrong slots but found them eventually. Everything is where it should be. Mostly. The weapons rack might be slightly reorganized.",
|
||||
"Note from Pastel: pets fed, garden tended, income collected. I made one small mistake with the supply manifest — added a column that didn't need to be there — but the numbers are right, the column is just extra. Please ignore the extra column.",
|
||||
"All tasks completed! Well — most tasks. The greenhouse watering got a little delayed because I was making sure the workshop tools were hung correctly and then it was later than I thought. The plants look fine. Probably fine. I'll check again in the morning.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — DAILY NOTES (Level 2)
|
||||
// Finding her rhythm. Notes are more organized. Occasional slip.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelNoteLevel2 = []string{
|
||||
"Morning note from Pastel. Pets fed and happy — the small one came out on its own today, which I'm taking as a good sign. Garden watered, income collected (14 coins, recorded in the ledger I started keeping). Workshop is tidy. All good.",
|
||||
"Everything done, everything noted. The herb garden is coming in nicely — I moved one of the pots to the south window and it seems happier there. Let me know if you'd prefer I leave things where they are. I have opinions about light.",
|
||||
"Pastel here. Smooth day — fed, watered, collected, organized. I found a supply cache you'd left in the back of storage that wasn't logged. I've logged it now. You had more materials than you thought.",
|
||||
"Note: the passive income queue had a small delay in processing, maybe 40 minutes. Nothing lost — just late. I've noted the timing and will keep an eye on it. Also the pets had a disagreement about something and I mediated. Everyone is fine.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — DAILY NOTES (Level 3)
|
||||
// Reliable, efficient, minimal fuss.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelNoteLevel3 = []string{
|
||||
"All tasks complete. Pets fed, garden tended, income logged. Your storage is organized by zone and rarity now — took me an afternoon last week but I think you'll find it easier. Let me know if the system doesn't work for you.",
|
||||
"Good day here. The herb garden yielded a little extra — I've bagged the surplus and left it on the workshop table. The vault contents are accounted for and untouched. Quiet day otherwise.",
|
||||
"Pastel. Everything is in order. I handled a small issue with the supply staging — one of the SU bags had a slow leak, so I replaced it from the reserve and logged the loss. You're at full capacity. No interruption to the expedition.",
|
||||
"Note: Thom Krooke stopped by. Not about the mortgage — just checking in, he said. I offered tea. He had opinions about the trophy room arrangement that I've passed along at the end of this note, unedited, so you can decide what you want to do with them. Everything else: fine.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — DAILY NOTES (Level 4)
|
||||
// Anticipatory. Occasionally handles things before they become problems.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelNoteLevel4 = []string{
|
||||
"Everything in order. I noticed the mortgage payment date falls during a stretch where your passive income might be lower than usual — I've set aside a buffer in a separate ledger line so the Sunday draw won't cause an issue. Just in case. You can move it back if you don't need it.",
|
||||
"Pets, garden, income — all done. I also restocked the supply staging from the herb garden surplus, which means you're slightly above your starting SU load for the next expedition. I had a feeling you'd need it.",
|
||||
"Note: the greenhouse plants in the east corner were getting too much direct light. I moved them. Yield should improve next week. Also found a crafting recipe in the library you hadn't catalogued — left it on the workshop table with a note about which materials you'd need. You have most of them.",
|
||||
"Quiet today. The pets settled early, the garden is doing well, the income processed on time. I checked the vault — everything accounted for. I re-read the expedition outpost supply logs and noticed a small gap in the inventory count; I've corrected it and added a note about where the discrepancy probably started. Everything is accurate now.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — DAILY NOTES (Level 5)
|
||||
// Perfect. Zero miss chance. Sometimes leaves a gift. The right gift.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelNoteLevel5 = []string{
|
||||
"Everything is handled. It always is. Left something on the kitchen table — found it at the market and thought of you. No reason. Just seemed right.",
|
||||
"All done. The kind of day where nothing went wrong and I want you to know that's not an accident — it takes work for nothing to go wrong, and I put in the work. The pets are happy. The garden is happy. The vault has something new in it that I think you'll be pleased about.",
|
||||
"I noticed you've been in the same zone for several days now. I made sure the expedition outpost supply link is topped up and the signal fires are ready for when you come back. There's a warm meal that will be ready in about four hours — I timed it based on your usual return window. If you're late, it keeps.",
|
||||
"Note from Pastel: everything is perfect, all systems running exactly as they should, the pets are thriving, the garden is producing double what it was last month, and I've reorganized the trophy room so the legendary items catch the evening light better. I also fixed the thing with the storage manifest that's been slightly off for three weeks. You hadn't mentioned it but I could tell it was there. You're welcome.",
|
||||
"Home is ready for you. It's always ready for you. That's the job. That's what I do. See you when you get back.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — MISSED TASK NOTES (Level 1–2 only)
|
||||
// When miss_chance triggers — honest, not defensive.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelMissedTask = []string{
|
||||
"I have to be honest with you — I forgot to water the herb garden today. I remembered at midnight and went back and did it then but it had been a while. The plants look okay. I'm sorry. I'll set a better reminder.",
|
||||
"The passive income didn't get collected today. I got turned around with the storage reorganization and by the time I got to it the queue had backed up. It'll process double tomorrow. Nothing is lost. I'm a bit embarrassed about this one.",
|
||||
"The pets got fed late today. Not dangerously late — late in the way that meant they gave me a look, specifically the kind of look that knows you will mention it to your owner. I mentioned it first. Fed now. All fine.",
|
||||
"I missed the supply staging check today. Something came up with the herb garden (a good something — unexpected yield, which I've logged) and the morning got away from me. The staging is fine, just unchecked. I'll do it first thing tomorrow and every day after that.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PASTEL — SPECIAL EVENTS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PastelDeliveryArrived = []string{
|
||||
"Your supply order arrived from Thom Krooke. I've staged it in the expedition outpost and logged everything. The invoice is on the table if you want to check it against the order.",
|
||||
"Delivery came while you were out — signed for it, stowed it, logged it. Everything matched the manifest. Thom Krooke's packaging has gotten better, I'll give him that.",
|
||||
}
|
||||
|
||||
var PastelPetEvent = []string{
|
||||
"The pets had an interesting day. I won't go into detail but by the end of it everyone was friends again and the storage chest is fine, structurally. A small note on the scratched corner.",
|
||||
"Your pet found something in the back of the storage room that I couldn't identify. I've put it on the workshop table. It doesn't seem dangerous. It is definitely something.",
|
||||
"One of the pets has been sitting by the expedition outpost since this morning. I think it knows you've been out a long time. Everything is fine. I just thought you'd want to know.",
|
||||
"The pets were restless today — I think they can tell you've been in a Tier 4 zone because they get like this around Day 10. Fed them an extra portion. They settled. They'll be glad to see you.",
|
||||
}
|
||||
|
||||
var PastelLevelUpNote = []string{
|
||||
"I've been doing this for a while now and I think I've found my footing. Just wanted to say that. Back to work.",
|
||||
"Level up, I think they call it. Thom Krooke came by and seemed pleased. I'm not sure why Thom Krooke monitors this but he does. The work is the same either way.",
|
||||
"I know this job better now than I did when I started. I can feel the difference. The notes are shorter because less needs explaining. That's probably a good sign.",
|
||||
}
|
||||
|
||||
var PastelGift = []string{
|
||||
"Left something on the table. Found it at the market — one of those rare materials you use for crafting, the kind that's hard to come by outside of high-tier zones. Seemed useful. No occasion.",
|
||||
"There's a potion of superior healing on the kitchen table. The kind Thom Krooke doesn't stock. Don't ask where I found it. Use it when you need it.",
|
||||
"I made something while you were gone. It's in the workshop — used the materials from the garden surplus and a recipe I found in the library. It should help with the next expedition. Consider it a gift for being a good employer.",
|
||||
"There's a warm meal on the table and a note under it. The note says: good luck out there. Come back in one piece. The meal is from scratch. I had time.",
|
||||
}
|
||||
|
||||
var PastelPlayerReturn = []string{
|
||||
"You're back. Good. I'll give you the full rundown but first — sit down, eat something, the pets have been waiting. The report can wait five minutes. You look like you've been in a dungeon.",
|
||||
"Welcome home. Everything is in order. I've written up the full summary — it's on the table, organized by day. Take your time with it. Nothing is on fire.",
|
||||
"Back already? The expedition ran short. That's fine — I was prepared for longer. The full caretaking log is on the table. The pets are very happy to see you, which I'll note I find completely understandable.",
|
||||
"You made it. I had the outpost signal fire ready from Day 10 onward, just in case. Everything here is exactly as it should be. I'll let you settle in. The summary is on the table when you want it.",
|
||||
}
|
||||
|
||||
var PastelPlayerDeathReturn = []string{
|
||||
"You're home. I heard from Thom Krooke — he manages things in an emergency, and I suppose this counted. Everything here is exactly where it was. Your things are safe. The pets have been fed twice today because I thought you might need to see that when you got back. Rest.",
|
||||
"I'm glad you're back. I won't ask about the hospital — Thom Krooke told me what he needed to tell me and I kept the home ready. It's still ready. Take whatever time you need.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// HOUSING — ARRIVAL / FIRST REST
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var HomeFirstArrival = []string{
|
||||
"This is yours now. TwinBee notes it — a place with a door that closes, a floor that doesn't move, and a ceiling that belongs to you. After everything the dungeon does to make those things uncertain, TwinBee finds a home meaningful.",
|
||||
"Home. The word lands differently when there's an actual place attached to it. TwinBee watches you step inside and says nothing, which is the most eloquent thing TwinBee knows how to do.",
|
||||
"You have a home. TwinBee has narrated dungeons and bosses and legendary drops and this — this quiet moment of a door closing on your own place — is one of the better things TwinBee has watched happen.",
|
||||
}
|
||||
|
||||
var HomeLongRest = []string{
|
||||
"A long rest at home. TwinBee goes quiet in a different way than it does in dungeons — not alert-quiet, not cautious-quiet. Just the good kind.",
|
||||
"Your own bed. Your own walls. The full rest resolves everything the dungeon costs. TwinBee considers home the best mechanic in the game and tells you so, once, and then lets you sleep.",
|
||||
"Home rest. HP restored, slots restored, conditions cleared. TwinBee doesn't narrate this one past the bare facts — some things don't need dramatic description. Coming home is one of them.",
|
||||
}
|
||||
187
internal/flavor/twinbee_npc_flavor.go
Normal file
187
internal/flavor/twinbee_npc_flavor.go
Normal file
@@ -0,0 +1,187 @@
|
||||
// DO NOT REWRITE, SUMMARIZE, OR SHORTEN ANY ENTRIES IN THIS FILE
|
||||
// twinbee_npc_flavor.go
|
||||
// Misty and Arina NPC dialogue lines. Thom Krooke lines are in twinbee_housing_flavor.go.
|
||||
// Add new entries freely. Never remove or alter existing entries.
|
||||
|
||||
package flavor
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MISTY — GREETINGS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var MistyGreeting = []string{
|
||||
"'You again.' Misty says it like a fact, not a complaint. Mostly.",
|
||||
"Misty looks up from whatever she's doing — something involving rope and a harpoon and a look of professional concentration — and gives you exactly the level of acknowledgment you've earned.",
|
||||
"'Don't stand in the doorway,' Misty says, before you've even finished arriving.",
|
||||
"Misty is already talking before you're settled. This is how it always goes.",
|
||||
"'I wondered when you'd show up.' She says it like she'd actually been counting the days. She had.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MISTY — SKILL CHECK SUCCESS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var MistyInsightSuccess = []string{
|
||||
"Misty looks at you for a moment. 'Fine,' she says. 'There's something in the temple you should know about.' She tells you. Efficiently. Accurately.",
|
||||
"'You're actually paying attention,' Misty says, which from her is essentially high praise. She gives you the information.",
|
||||
"Misty puts down what she's holding. 'Okay. This is useful to know, so I'll tell you.' She does.",
|
||||
}
|
||||
|
||||
var MistyPersuasionSuccess = []string{
|
||||
"'I'm not doing this because you asked nicely,' Misty says. 'I'm doing it because it helps you not die, and people dying in my temple is annoying.' She hands you the map.",
|
||||
"Misty sighs in a way that communicates both reluctance and inevitability. 'Fine. Here.' The information arrives without further ceremony.",
|
||||
}
|
||||
|
||||
var MistySkillFail = []string{
|
||||
"'No,' Misty says, and returns to what she was doing.",
|
||||
"Misty looks at you like you've asked a question that doesn't deserve an answer. She's not wrong.",
|
||||
"'Come back when you actually know what you're asking.' Misty's version of helpful feedback.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MISTY — QUEST ASSIGNMENT
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var MistyQuestGive = []string{
|
||||
"'If you're going in there anyway,' Misty says, as if this is a minor imposition on her planning, 'there's something I need.'",
|
||||
"Misty sets down her work and actually looks at you, which means this is serious. 'There's a job. You'll need to pay attention.'",
|
||||
"'I don't usually ask,' Misty says, and the phrasing makes clear this is factually true and also a warning about what's coming next.",
|
||||
}
|
||||
|
||||
var MistyQuestComplete = []string{
|
||||
"Misty reviews what you've brought back. There's a pause that could be called satisfied. 'Good,' she says. Exactly one word. Coming from Misty, it means a lot.",
|
||||
"'You didn't mess it up.' Misty accepts the reward materials and gives you yours without ceremony. 'That was the job. Well done.'",
|
||||
"Misty looks at the completed quest items and then looks at you. Something shifts in her expression — not warm exactly, but warmer. 'You actually did it the right way.' The reward follows.",
|
||||
}
|
||||
|
||||
var MistyQuestFail = []string{
|
||||
"'You didn't finish.' Misty says it without heat, which is somehow worse than heat. 'Come back when you have.'",
|
||||
"Misty registers the incomplete quest with the expression of someone who expected exactly this outcome and had hoped to be wrong.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MISTY — AFTER EARNING HER RESPECT
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var MistyTrusted = []string{
|
||||
"Misty sees you coming and does something she almost never does — stops what she's doing before you reach her. She's ready to talk. This is respect, Misty-style.",
|
||||
"'You've been doing good work in there,' Misty says, as you arrive. She doesn't look up. She doesn't need to. 'I noticed.'",
|
||||
"Something has changed in how Misty addresses you. Not warmer exactly. More equal. You earned that.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ARINA — GREETINGS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ArinaGreeting = []string{
|
||||
"'Oh! You're here!' Arina says this with the energy of someone who has been looking forward to a thing and is pleased the thing has arrived. The thing is you.",
|
||||
"Arina looks up from a worktable covered in notes, materials, and something faintly glowing, and her face does the thing it does — open, interested, ready to talk very fast.",
|
||||
"'Perfect timing,' Arina says, in the tone of someone for whom most timings are perfect because everything is interesting. 'I was just thinking about—' She stops. 'Actually, what do you need?'",
|
||||
"Arina has three things she's in the middle of and immediately sets all of them down to give you her full attention, which is considerable.",
|
||||
"'You came back!' Arina says, as if there was any question. In her experience there sometimes isn't.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ARINA — ITEM IDENTIFICATION
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ArinaIdentify = []string{
|
||||
"Arina picks up the item with both hands and goes immediately quiet, which is the most alarming thing she does. Then: 'Okay. Okay, this is — this is actually really interesting.' She tells you everything.",
|
||||
"'Can I — I'm not going to touch it, I just—' She touches it. 'Okay so here's what it does.'",
|
||||
"Arina holds the item up to the light, turns it twice, says something under her breath that might be an incantation or just enthusiasm, and then begins a very efficient explanation.",
|
||||
"'Oh I know what this is.' The words land quickly, confidently, correctly. Arina has seen a lot of magic items and she remembers all of them.",
|
||||
"Arina goes still in the specific way she goes still when magic is doing something she finds genuinely surprising. 'That's — huh. Okay. That's new. Let me—' The identification follows, along with three questions she has that you're under no obligation to answer.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ARINA — SKILL CHECK SUCCESS
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ArinaArcanaSuccess = []string{
|
||||
"'Yes! Exactly right — you know what, most people don't catch that.' Arina opens her notes and shows you something that solves the problem neatly.",
|
||||
"Arina's face does the thing where she's genuinely pleased that you got it. 'Okay so since you clearly know what you're doing—' She gives you the recipe.",
|
||||
"'That check was excellent,' Arina says, which from her means the knowledge was real and not a guess. She gives you the full information without making you ask for pieces of it.",
|
||||
}
|
||||
|
||||
var ArinaSkillFail = []string{
|
||||
"'Oh — no, that's not quite—' Arina seems genuinely sorry about this. 'Come back and we'll try again. Or bring the right materials. Or both.'",
|
||||
"Arina makes a small face that isn't unkind. 'Not quite. You're close though! The concept is right, the specifics just need—' She trails off. 'Anyway. Come back.'",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ARINA — CRAFTING
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ArinaCraftStart = []string{
|
||||
"'Okay! I have everything I need, you have everything you brought, let's see what we can make.' Arina's work mode is focused and fast.",
|
||||
"Arina spreads the materials across the table and looks at them the way a musician looks at an instrument — familiarity and anticipation. 'This is the good part,' she says.",
|
||||
"'I've been thinking about this combination for a while actually,' Arina says, and begins immediately.",
|
||||
}
|
||||
|
||||
var ArinaCraftComplete = []string{
|
||||
"Arina presents the finished item with quiet satisfaction — the specific satisfaction of a thing made well. 'There. That's what those materials wanted to be.'",
|
||||
"'Done!' Arina says, and she sounds pleased in the way she sounds when something worked exactly as planned. Which it did. 'Take good care of it.'",
|
||||
"The item is finished and Arina holds it out to you. 'Made right, with the right materials. That's how these things last.' She means it literally and figuratively.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ARINA — QUEST ASSIGNMENT
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var ArinaQuestGive = []string{
|
||||
"'Okay so I have a thing,' Arina says, which is how she starts sentences that are actually requests. 'You don't have to. But if you're going into that zone anyway—'",
|
||||
"'I need a sample,' Arina says. 'Specifically—' She describes it in precise detail. The precision is its own kind of excitement.",
|
||||
"Arina looks at her notes, looks at you, looks at her notes again. 'I think you're the right person to ask about this. Can I ask you about this?'",
|
||||
}
|
||||
|
||||
var ArinaQuestComplete = []string{
|
||||
"Arina sees what you've brought and makes a sound that is entirely undignified and entirely genuine. 'You actually got it. Can I — thank you. This is going to—' She's already analyzing it.",
|
||||
"'This is perfect,' Arina says, and she means it in the exact scientific sense — perfect, the right amount, the right quality. 'The reward is on the table. Thank you.'",
|
||||
"Arina takes the materials and immediately begins making notes, which means she's happy, which means you did it right. The reward is handled efficiently because her hands are busy.",
|
||||
}
|
||||
|
||||
var ArinaFavoriteUnlocked = []string{
|
||||
"Arina puts down her notes. Actually puts them down. 'You've done a lot for this workshop,' she says. 'I want to show you what I'm actually working on.' The advanced recipe list opens.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PETE BOT — BROADCAST LINES
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PeteZoneUnlock = []string{
|
||||
"📣 Pete: {zone_name} is now accessible. Community milestone reached. First expeditions can begin immediately.",
|
||||
"📣 Pete: New zone available — {zone_name} (Tier {tier}, recommended Level {level_min}+). Details via !expedition start {zone_id}.",
|
||||
}
|
||||
|
||||
var PeteTier5Complete = []string{
|
||||
"📣 Pete: {player_name} has completed {zone_name}. Expedition duration: {days} days. Boss defeated. Legendary loot confirmed. TwinBee has noted this one.",
|
||||
"📣 Pete: {zone_name} cleared by {player_name} on Day {day}. The {boss_name} is down. Community achievement recorded.",
|
||||
}
|
||||
|
||||
var PeteStreakMilestone = []string{
|
||||
"📣 Pete: {player_name} is on a {streak}-win arena streak. Current status: {title}. The leaderboard has updated.",
|
||||
"📣 Pete: Arena milestone — {player_name} reaches streak {streak}. Previous record in this community: {record}.",
|
||||
}
|
||||
|
||||
var PeteCommunityBoost = []string{
|
||||
"📣 Pete: Community activity this week has been strong. TwinBee's mood is elevated. Dungeon drop rates and milestone rewards have been adjusted upward for 48 hours.",
|
||||
"📣 Pete: TwinBee is in a good mood. Reasons cited: community engagement, a particularly impressive nat 20, and general satisfaction with how things have been going. Enhanced rewards active through Sunday.",
|
||||
}
|
||||
|
||||
var PeteMaintenance = []string{
|
||||
"📣 Pete: Brief maintenance window incoming — approximately {duration}. Active expeditions are paused and will resume from last checkpoint. Supplies will not deplete during downtime.",
|
||||
"📣 Pete: Maintenance complete. All systems restored. Expedition timers have been adjusted for downtime. Apologies for the interruption.",
|
||||
}
|
||||
|
||||
var PeteExpeditionBulletin = []string{
|
||||
"📣 Pete: Expedition update — {count} active expeditions in progress across {zones}. Longest running: Day {max_day}. TwinBee is busy.",
|
||||
"📣 Pete: Current expedition activity: {count} players in the field. The dungeon is occupied. Good.",
|
||||
}
|
||||
|
||||
var PetePatchNotes = []string{
|
||||
"📣 Pete: Update deployed. Changes: {summary}. Full notes available on request. TwinBee has been briefed.",
|
||||
}
|
||||
|
||||
var PeteMortgageRate = []string{
|
||||
"📣 Pete: Weekly rate update. FRED ARM rate: {rate}%. Effective GogoBee mortgage rate (Thom Krooke margin included): {effective}%. Payments process Sunday.",
|
||||
}
|
||||
237
internal/flavor/twinbee_resource_flavor.go
Normal file
237
internal/flavor/twinbee_resource_flavor.go
Normal file
@@ -0,0 +1,237 @@
|
||||
// DO NOT REWRITE, SUMMARIZE, OR SHORTEN ANY ENTRIES IN THIS FILE
|
||||
// twinbee_resource_flavor.go
|
||||
// TwinBee GM Dialogue — Resource gathering, combat interrupts,
|
||||
// zone-specific loot descriptions, and harvest narration.
|
||||
// Add new entries freely. Never remove or alter existing entries.
|
||||
|
||||
package flavor
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// HARVEST SUCCESS — Generic by Action Type
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var HarvestForageSuccess = []string{
|
||||
"The land gives something up. TwinBee watches you identify it with the quiet satisfaction of someone watching a skill be used correctly.",
|
||||
"There — growing in a place that suggests it knows exactly what it's good for and has been waiting. You found it. TwinBee approves of the finding.",
|
||||
"A Ranger's eye in a non-Ranger would have missed that entirely. TwinBee notes the distinction.",
|
||||
"Like finding the hidden item block in a Mario level — you knew to look, you looked in the right place, and the thing that was always there is now yours.",
|
||||
"The plant comes away cleanly. Good root structure, good potency. TwinBee mentally catalogues it and moves on.",
|
||||
}
|
||||
|
||||
var HarvestMineSuccess = []string{
|
||||
"The stone yields. TwinBee listens to the sound of it — the specific tone of rock giving up something it's been holding for a very long time.",
|
||||
"Solid work. The ore comes out in a piece worth taking. TwinBee checks the vein depth. There's more. There's always more if you're willing to dig.",
|
||||
"Like the mining minigame in Stardew Valley, but with real consequences and no save file. TwinBee watches you extract the material with professional appreciation.",
|
||||
"The wall gives up its contents without drama. TwinBee appreciates materials that cooperate.",
|
||||
"Good strike. Clean extraction. TwinBee notes the weight and the quality simultaneously.",
|
||||
}
|
||||
|
||||
var HarvestScavengeSuccess = []string{
|
||||
"There it is. Among the debris, the decay, the things that were left behind — something worth taking. TwinBee knew it was there. You found it. TwinBee is pleased.",
|
||||
"The room held something after all. TwinBee had estimated 60% odds and updates the estimate to 'correct.'",
|
||||
"Like finding the secret item in a dungeon chest that looked empty — you checked anyway. That's the habit. That's the discipline. TwinBee notes both.",
|
||||
"Scavenged. The word has a bad reputation it doesn't deserve. You found value in the discarded. TwinBee respects that entirely.",
|
||||
"A Rogue's eye in a non-Rogue would have walked past this. TwinBee notes the distinction.",
|
||||
}
|
||||
|
||||
var HarvestEssenceSuccess = []string{
|
||||
"The essence coalesces. TwinBee watches the process with the reverence it deserves — magic condensing from ambient to held is not nothing.",
|
||||
"Drawn out cleanly. The Arcana check held and the essence responds to the knowledge behind it. TwinBee is appropriately impressed.",
|
||||
"Like tapping into a power source in Metroid — you knew the energy was there, you had the tool to reach it, you reached it. The vial fills.",
|
||||
"The room releases something it didn't know it was holding. TwinBee watches the transfer and marks the yield in its ledger.",
|
||||
"Essence harvested. TwinBee notes the quality — above average for this zone, below average for what you'd need to know to appreciate that distinction. TwinBee appreciates it on your behalf.",
|
||||
}
|
||||
|
||||
var HarvestCommuneSuccess = []string{
|
||||
"The spiritual resonance here responds to you. TwinBee observes this with something adjacent to wonder — not everything in a dungeon wants to fight, and this one chose to offer instead.",
|
||||
"A Cleric reaching into the bones of a place and finding something willing to be found. TwinBee has watched this fewer times than it's watched combat and values it proportionally.",
|
||||
"The commune holds. The material comes. TwinBee says nothing and lets the moment be what it is.",
|
||||
"Like finding a save point that also tells you something true about the world. The dungeon has given you something. TwinBee notes the gift.",
|
||||
}
|
||||
|
||||
var HarvestFishSuccess = []string{
|
||||
"The line goes taut and TwinBee straightens up. Whatever's on the end of it, it came from somewhere deep and dark and it's yours now.",
|
||||
"A catch. TwinBee identifies it before you finish pulling it in — the coloring, the depth-marks, the specific opacity of its eyes. 'Good one,' TwinBee says, meaning it.",
|
||||
"Fishing in a dungeon. TwinBee has opinions about fishing in dungeons and all of them are positive. The fish is landed. The opinions remain.",
|
||||
"Like the fishing minigame in every RPG that ever had one — the moment the indicator hits perfect and everything pays off. TwinBee takes quiet delight in this.",
|
||||
"The water gives up its catch with minimal argument. TwinBee respects fish that don't make it personal.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// HARVEST FAILURE — Generic
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var HarvestFail = []string{
|
||||
"Nothing. The node had nothing to offer, or you didn't ask the right way, or both. TwinBee notes this without judgment and suggests trying elsewhere.",
|
||||
"The attempt fails to produce anything useful. TwinBee marks the node and moves on. Some rooms are stingier than others.",
|
||||
"Not everything that looks like a resource is one. TwinBee files this under 'learned' and considers it worth the attempt.",
|
||||
"Empty-handed. TwinBee has seen this before and will see it again. The dungeon doesn't owe you anything. You ask anyway. That's the deal.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// HARVEST INTERRUPT — Combat Triggered
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var HarvestInterrupt = []string{
|
||||
"TwinBee sees it before you do — movement at the edge of the room, something that was waiting for you to be distracted. 'Company,' TwinBee says, which is the politest word for it.",
|
||||
"The harvest is interrupted. You were focused on the node; something was focused on you. TwinBee notes the tactical lesson without rubbing it in.",
|
||||
"Like the enemy ambush that fires when you open the treasure chest — the dungeon watched you commit to the harvest and introduced a complication. TwinBee did warn about this. Once. Earlier.",
|
||||
"Something heard the mining. Sound travels in dungeons. TwinBee has mentioned this. The enemy emerging from the corridor has confirmed it.",
|
||||
"A patrol. Bad timing, or very good timing from their perspective. TwinBee sets aside the harvest log and opens the combat log.",
|
||||
"The forage was going well until it wasn't. TwinBee measures the distance between you and the enemy, between the enemy and the door, and starts calculating options at speed.",
|
||||
"Interrupted. The node is still there. The enemy is also still there, in a more immediate way. TwinBee suggests addressing the more immediate thing first.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// NODE DEPLETED
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var NodeDepleted = []string{
|
||||
"The node is stripped. You've taken everything it had to give. TwinBee marks the location in its mental map as exhausted until the next rest.",
|
||||
"Empty. The resource is gone. TwinBee finds something quietly melancholy about a depleted node and something practical about moving to the next one.",
|
||||
"That's all it had. TwinBee confirms the node at zero and moves on without ceremony.",
|
||||
"Harvested clean. TwinBee notes the room is now resource-dry until you rest and the dungeon replenishes. It will replenish. It always does.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// RICH YIELD
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var RichYield = []string{
|
||||
"A rich vein. TwinBee's assessment upgrades mid-harvest — more than expected, better quality than the zone average. This room was generous. TwinBee marks it.",
|
||||
"The node gives more than it should have. TwinBee notes the anomaly with appreciation and does not question it.",
|
||||
"Like finding the rare item drop that you stopped expecting — the dungeon decided to be kind today, in this specific way, in this specific room. TwinBee takes it.",
|
||||
"Exceptional yield. TwinBee catalogs the bonus material with the efficiency of someone who has been waiting for exactly this and prepared for it anyway.",
|
||||
"More than the DC promised. The dungeon overdelivered. TwinBee notes this is unusual and also completely welcome.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ZONE-SPECIFIC HARVEST LINES
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var HarvestGoblinWarrens = []string{
|
||||
"The goblins had more than anyone gave them credit for. Crude, yes. Stolen, mostly. But present, and now yours. TwinBee is pragmatic about origins.",
|
||||
"Scavenged from a goblin stash that someone worked hard to hide and harder to accumulate. TwinBee finds a moment of respect for the effort before moving on.",
|
||||
"The warrens are full of things the goblins took from people who'd take them back given the opportunity. TwinBee considers this a form of redistribution.",
|
||||
}
|
||||
|
||||
var HarvestCryptValdris = []string{
|
||||
"Grave goods. TwinBee notes the weight of taking from a burial site and files it under: necessary. The dead have no use for these. You do.",
|
||||
"The crypt gives up its materials with the reluctance of a place that considers itself permanent. TwinBee disagrees with the premise. The materials are harvested.",
|
||||
"Ancient things preserved by darkness and time. TwinBee handles the concept carefully even as you handle the material practically.",
|
||||
}
|
||||
|
||||
var HarvestForestShadows = []string{
|
||||
"The forest gives and the forest takes and right now it is giving, which TwinBee notes as the correct direction for this interaction to go.",
|
||||
"A plant that has no business being this healthy in a corrupted forest. TwinBee considers it either very resilient or very clever. Either way, useful.",
|
||||
"The woods here remember what they were before they went wrong. The resources carry that memory. TwinBee thinks this makes them better materials. TwinBee might be right.",
|
||||
}
|
||||
|
||||
var HarvestSunkenTemple = []string{
|
||||
"The temple held onto this longer than anything else. TwinBee extracts it from the silt and the salt and the particular weight of a place that's been underwater for thirty years.",
|
||||
"Ancient, preserved, and still potent. The deep cold does something to materials that nothing else replicates. TwinBee values the outcome even if it declines to romanticize the process.",
|
||||
"The sea left something behind when it half-abandoned this place. TwinBee retrieves it with appropriate care.",
|
||||
}
|
||||
|
||||
var HarvestHauntedManor = []string{
|
||||
"The manor keeps things. Has always kept things. TwinBee takes this one out of the keeping and into the useful, which is a small act of defiance against the house's whole philosophy.",
|
||||
"Found among the things that have been here since the last person stopped being here. TwinBee notes the provenance without dwelling on it.",
|
||||
"The house watches you take it. TwinBee watches the house watch you. A full triangle of observation, and TwinBee notes: the house blinks first.",
|
||||
}
|
||||
|
||||
var HarvestUnderforge = []string{
|
||||
"The forge yields its material with the grudging respect of something built to produce and still producing, even now, for someone it didn't expect.",
|
||||
"Dwarven craftsmanship even in the raw materials. TwinBee has always believed the quality is in the extraction, not just the finishing. This confirms it.",
|
||||
"Hot, heavy, and exactly what the zone promised. TwinBee marks the vein depth. There is more. The Underforge does not run out of things to give.",
|
||||
}
|
||||
|
||||
var HarvestUnderdark = []string{
|
||||
"The Underdark produces everything the surface does, stranger, in the dark, and with fewer questions about why. TwinBee harvests without asking why.",
|
||||
"Things grow down here that have no equivalent above. TwinBee catalogs the material and the context it came from with equal precision.",
|
||||
"A material that has never seen sunlight and is better for it. TwinBee notes this without irony.",
|
||||
}
|
||||
|
||||
var HarvestFeywild = []string{
|
||||
"The Feywild gives things away. That's the problem — it gives things away and sometimes what it gives isn't what you thought you were taking. TwinBee checks the material twice. It appears to be what it appears to be. TwinBee remains alert.",
|
||||
"Beautiful material from a zone that uses beauty as a weapon. TwinBee takes it carefully, like picking up something that might be watching.",
|
||||
"The fey made this place generous on purpose. TwinBee is not going to complain about the generosity and is not going to stop watching for the catch.",
|
||||
}
|
||||
|
||||
var HarvestDragonsLair = []string{
|
||||
"Plucked from a hoard that has been accumulating since before your civilization named itself. TwinBee notes the historical weight and moves on.",
|
||||
"The kobolds will notice something is missing. They count everything. TwinBee accounts for this and suggests moving with intent.",
|
||||
"Dragon-adjacent materials carry something in them — a residual heat, a quality that doesn't exist anywhere the dragon hasn't been. TwinBee considers this a feature.",
|
||||
}
|
||||
|
||||
var HarvestAbyssPortal = []string{
|
||||
"Harvesting from the Abyss. TwinBee delivers this line flatly because it deserves flat delivery. The material is valuable. The context is permanent.",
|
||||
"Reality left something behind when it tore here. TwinBee takes the fragment and notes: don't linger near the edges of what isn't stable.",
|
||||
"Demon ichor. TwinBee says the words with the efficiency of someone who has moved past the part where the words were alarming.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// FISHING — Zone-Specific Lines
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var FishingForestShadows = []string{
|
||||
"Fishing in a cursed forest stream. TwinBee finds this more peaceful than it has any right to be and refuses to let the shadow-things in the canopy ruin it.",
|
||||
"The stream runs dark but the fish run silver. TwinBee watches the line and says nothing for a while, which is what fishing is for.",
|
||||
"Like the fishing minigame before the hard dungeon in Ocarina of Time. TwinBee takes the moment seriously.",
|
||||
}
|
||||
|
||||
var FishingSunkenTemple = []string{
|
||||
"Fishing in a flooded temple. The fish here have never seen the surface. They don't know what they're missing. TwinBee is uncertain whether to pity them.",
|
||||
"The line drops into water that hasn't moved in thirty years and immediately gets attention. Things down here are hungry. TwinBee watches the tension.",
|
||||
"Deep water fishing in the ruins of something ancient. TwinBee thinks the builders would have found this either sacrilegious or practical. TwinBee lands on practical.",
|
||||
}
|
||||
|
||||
var FishingUnderdark = []string{
|
||||
"The underground river is cold and fast and the fish in it have evolved past needing eyes, which TwinBee finds both efficient and slightly unsettling.",
|
||||
"Fishing in total darkness in a river that doesn't appear on any surface map. TwinBee narrates by sound: the cast, the current, the eventual tension on the line.",
|
||||
"The Eyeless King is in here somewhere. TwinBee doesn't say this out loud but thinks it very clearly. The line goes deep.",
|
||||
}
|
||||
|
||||
var FishingFeywild = []string{
|
||||
"Fey fishing. TwinBee watches the line for signs of time distortion — the way the reflection moves wrong, the way the fish seem to arrive before they bite. The Feywild is like this about everything.",
|
||||
"The stream catches light that shouldn't be here and the fish reflect it from below. TwinBee watches something luminous move toward the hook and tries to stay professional about it.",
|
||||
"Like fishing in a dream. TwinBee means this literally — the mechanics are the same but the rules feel advisory.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// PATROL ENCOUNTER LINES
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var PatrolEncounter = []string{
|
||||
"A patrol. Moving between the cleared rooms with the confidence of something that considers them still theirs. TwinBee disagrees with this assessment and will help you express the disagreement.",
|
||||
"They found you between rooms, which is exactly where patrols are supposed to find you. TwinBee notes the Threat Clock and suggests dispatching this quickly and quietly.",
|
||||
"The patrol isn't looking for a fight — it's doing its job, which happens to involve you being somewhere you aren't supposed to be. TwinBee will help you redefine 'supposed to.'",
|
||||
"Two of them. Moving together. The coordination suggests the zone is at Alert or higher. TwinBee confirms: it is. Fight or fade.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// LOOT DROP LINES — Generic
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var LootDropCommon = []string{
|
||||
"They had something on them. TwinBee checks it over. Common rarity — useful in the way that common things are useful, which is often.",
|
||||
"Standard loot. Nothing that rewrites the story, but everything that keeps it going.",
|
||||
"A drop. TwinBee catalogs it efficiently and notes: this is the economy of dungeons. Enemies have things. You take them. The loop continues.",
|
||||
}
|
||||
|
||||
var LootDropUncommon = []string{
|
||||
"Better than expected. TwinBee examines the drop with slightly elevated interest. Uncommon rarity — someone made this with intent.",
|
||||
"An uncommon drop from a common enemy. TwinBee notes the anomaly with satisfaction. The dungeon was generous in this room.",
|
||||
"Uncommon. TwinBee turns it over once and nods. 'Keeper,' TwinBee says, which in TwinBee's vocabulary means: this changes your math.",
|
||||
}
|
||||
|
||||
var LootDropRare = []string{
|
||||
"TwinBee stops. Actually stops. 'That's rare,' TwinBee says, with the specific register of someone who uses the word correctly and uses it seldom.",
|
||||
"A rare drop. TwinBee examines it the way you examine something that doesn't appear often — thoroughly, quietly, with appropriate appreciation.",
|
||||
"The loot table gave you something uncommon and then kept going. Rare rarity. TwinBee files this in the column it reserves for things worth remembering.",
|
||||
}
|
||||
|
||||
var LootDropLegendary = []string{
|
||||
"TwinBee goes very still. The drop sits in the light and TwinBee processes what it is seeing. 'Legendary,' TwinBee says eventually. One word. That's all it needs.",
|
||||
"Legendary rarity. TwinBee has seen a few of these in a long career and each time — each time — there is a moment that is separate from everything else. This is that moment. Pick it up carefully.",
|
||||
"The dungeon produced a legendary item. TwinBee notes the zone, the enemy, the day of the expedition, the Threat Clock value, the precise conditions. Some things deserve to be recorded completely.",
|
||||
}
|
||||
Reference in New Issue
Block a user