2026 10 13 equipment rules design - xopherdeep/do-it-for-the-xp GitHub Wiki

Equipment rules: in-game tools, earned in order, held in the hands

Date: 2026-10-13. Status: design approved in chat by the owner, section by section; this spec awaits review.

Why

The owner: "our equipment needs better thought ... some of the rules so the items need to change. they feel like they break the game more than help it." What was found (code read 2026-10-13):

  1. MP is free. MyHome.restInBed refills HP and MP at no cost, any number of times; the Hotel is 10 GP (Lodging.ROOM_COST). Every item is priced in MP, so every item is unlimited.
  2. Items bend real chores (ItemEffects.ts): the Silver Arrow snoozes a quest to tomorrow (daily, forever), the Ice Wand adds 24 h to a deadline and stacks on itself, the Fire Wand adds 12 h, Gale's Wind is a no-chores day every 7 days, Tesla's Bolt skips approval, X's Invisibility stops ambushes. These are privileges, and by the owner's rule privileges are Powers the Game Master prices. Gale's Wind (300 MP, every 7 days, the hero picks the day) undercuts the Day of Rest Power (1000 AP a month, the Game Master picks the day).
  3. Rule zero is broken in a fight. The Silver Arrow and the Rewind Power (recall) take a chore out of the fight (BattleService.postponeTask splices it); it goes nowhere, and the victory logs the whole quest done with full rewards (useBattleOutcome). recall and stun are not once per fight.
  4. Items lie. On the board Bombs, Thor's Hammer, Sol's Flare and Gaia's Quake take MP and only print a line; the catalogue (EquipmentItems.ts) still promises "completes 50% of any single task", "instant task completion".
  5. The hands do not matter. In a fight any unlocked item works from the bag.
  6. Getting items is thin. Five items come from temple chests; four temple relics (Trident of Tides, Flame Shield, Dawnbreaker Bow, Void Dagger) unlock nothing; the rest come only from the Game Master. MP prices (25-300) ignore the pools: a Warrior starts at 10 MP (+2 a level), a Mage at 40 (+8).

Owner decisions (2026-10-13)

  • In-game only. Items work in temples and fights. Anything that bends a real chore or house rule is a Power.
  • MP comes back from the bed once per real day, from chores finished in fights, and from paid or found refills.
  • Hands only. In a temple or a fight only the two held tools can be used; potions, food and Powers still come from the bag. Swap anywhere except during a fight.
  • "A & B": the Zelda structure (tools earned in order from temples, one clear job each) with the full list: no item is cut or merged; every name stays and gets its own in-game job.
  • No data is removed.

1. Core rules

  1. No quest-board effects. applyBoardEffect loses snooze, extend, pull-in, pause, day off, bedtime lift, trusted hour, no-encounters, shuffle and the Bottles board drink. Tapping a tool in the portal (outside a temple or a fight) opens its card: its temple use, its fight use, its MP. One exception: the Lantern on the board still lists the hero's overdue quests, free; it reads and never writes.
  2. Real-life effects are Powers (section 4).
  3. MP costs something (section 3).
  4. Hands only. In a fight the Goods bag still opens Bottles (potions and food) and the Book Of Spells (Powers). A tool that is not in a hand shows the reason "Hold it in a hand before a fight." In a temple the footer's two hand slots are the only way to use a tool (as today). The hands can be changed anywhere (the equipment modal, temples included) except during a fight, where the dock is already read-only.
  5. Every tool and Power fight effect is once per fight, counted per effect whatever cast it (as today: Chronos' Clock and the Stop Power share one Time Stop).
  6. recall is retired. Run Away already keeps the day's progress (restoreCompletedTasks restores chores finished earlier today), so a chore that cannot be done now still waits on the board.
  7. Honest text. Each item's description names its temple use and fight use; the docs are rewritten (section 6).
  8. No data removed. Heroes keep their unlockedItems (profiles without the list keep everything, as today). Quest effects the old items already wrote are all timed and run out.

2. The item list

One table, src/lib/services/items/ItemRules.ts (new, pure), is the source of truth: per item name mp, temple?: TempleUseId, fight?: BattleEffectId, consumes?: string (the pack item a use spends), source (for the unlock hint) and the two lines its card shows. BattleItems.ts, ItemUse.ts, the item card and unlockHintOf read it.

Stored copies. Profiles keep plain copies of catalogue entries, old descriptions included, and mpCostOf reads the cost off the stored description ("50MP | ..."). Costs and text now come from ItemRules by name; the stored desc is never read for a rule. A hero holding an old Ice Wand pays 10 MP, not 50.

Item Earned MP Temple Fight
Lantern start 5 map and compass for this temple (as today) —
Bottles start 0 bottle a spring: at a health or mana spring, keep it as a pack potion instead of drinking now opens potions and food (as today)
Bombs chests, temple shops; later crafted one Bomb blow open a locked door (as today, never a fight seal) stun
Wind Whistle Wind Temple chest (as today) 0 — (fast travel) —
Pegasus Boots free Aura, Wind Temple (as today) 0 — (menu style) —
Gaia's Quake Earth Temple chest, Gaia's Hammer (as today) 10 hidden rooms on this floor appear on the map —
Hook Shot Water Temple chest, Trident of Tides 5 swing over a pit or void to the room beyond (as today) —
X's Invisibility Swamp Temple chest, Void Dagger 15 slip out of a free-fight monster room without its fight; a quest room cannot be skipped vanish
Fire Wand Fire Temple chest, Flame Shield 10 — kindle
Thor's Hammer free Ignis, Fire Temple 15 — stun
Silver Arrow Sun Temple chest, Dawnbreaker Bow 25 — pin
Sol's Flare free Sol, Sun Temple 20 — weaken
Ice Wand Ice Temple chest, Frost Wand (as today) 10 freeze a trap: walk through it unharmed this visit frost
Tesla's Bolt Storm Temple chest, Lightning Rod (as today) 5 — charge
Gale's Wind free Ventus, Storm Temple 15 — gust
Night's Light Moon Temple chest, Lunar Pendant (as today) 10 moonlight on the glyphs: one wrong answer of the riddle fades moonlight
Chronos' Clock free Umbra, Moon Temple 20 — time-stop

Correction to the chat design: Ventus is the Storm Temple's Pegasus (clouds), not the Wind Temple's; the Wind Temple frees Aura. Gale's Wind therefore comes from the Storm Temple.

The navigation items (My Quests, Book Of Spells, Goods, Wallet, Portal Home) are unchanged.

Unlock sources (ItemEffects.ts lock helpers, ChestLoot.ts):

  • CHEST_ALIASES gains Trident of Tides → Hook Shot, Flame Shield → Fire Wand, Dawnbreaker Bow → Silver Arrow, Void Dagger → X's Invisibility; CHEST_TEMPLE names their temples; CHEST_BLURBS gets "A relic of the {Temple}. Equip it as the {Item}." for the four.
  • PEGASUS_INDEX gains Ventus 0 → Gale's Wind, Ignis 1 → Thor's Hammer, Sol 2 → Sol's Flare, Umbra 8 → Chronos' Clock (Aura 3 → Pegasus Boots stays). The Wind Whistle rule is unchanged (chest only).
  • ALWAYS_UNLOCKED is unchanged (it already holds Lantern and Bottles). unlockableItemNames (the Compendium's unlock list) reads the ItemRules names instead of the old board table.
  • Bombs are a pack item (Bomb, the registry's stackable dungeon item). Every temple shop sells Bombs at 20 GP beside the Potion of Vigor (shopWares). The crafting spec's Bomb recipe adds a third source later. Holding Bombs with none in the pack: "Out of bombs."

3. MP economy

  • The bed, once per real day. Lodging.ts gets quoteBedRest(stats, lastBedRestOn, now); the hero stores lastBedRestOn (a dayKeyOf day key). A second rest the same day: "You're not sleepy yet. Come back tomorrow." Old profiles have no stamp and may rest once. The Hospital bench (a free quarter of HP once a day) is unchanged, so a broke hero is never stuck.
  • The Hotel price grows with level: roomCost(level) = 10 + 5 × level GP (ROOM_COST becomes the base). HotelHub quotes and charges it.
  • Chores give MP back in quest fights: each chore finished in a fight that holds a quest restores 10 % of max MP (at least 1), charge doubles it for the rest of that fight. Free fights restore none (their moves are not real chores and could be farmed). Rule in src/lib/services/battle/choreGains.ts (new, pure).
  • Potions, temple springs, camps and the class win regen are unchanged.

4. Real-life Powers with a quest-board effect

  • Ability.boardEffect?: 'snooze' | 'extra-time' | 'quiet-day' | 'trusted-hour' | 'none' in src/types/abilities.ts. Real-life Powers only.
  • src/lib/services/abilities/PowerBoardEffects.ts (new, pure apart from the store and the quest engine) holds the effects lifted from ItemEffects.ts, writing questEffects exactly as today:
    • snooze: one open quest moves to tomorrow (snoozedOn). Refused when that quest is already snoozed today.
    • extra-time: +24 h on one open quest's deadline (extendedUntil). Refused when the quest already has an extension that has not passed. No stacking.
    • quiet-day: no ambushes for 24 h (noEncountersUntil).
    • trusted-hour: for one hour, claims skip approval (trustedUntil); refused unless the family setting trustedHour is on.
  • Order: check (powerBoardEffectBlocked, plus the quest pick for snooze and extra-time) → the normal cast (AbilityService.useAbility: frequency, MP, cast log, Town Crier, adult note) → apply. A cancelled pick or a refusal charges nothing and logs nothing.
  • Limits are the Power's own frequency and AP requirement, set by the Game Master.
  • Presets (AbilityPresets.ts, the library; nothing is added to a family automatically):
Power Description Frequency MP AP
Snooze Move one quest to tomorrow. Weekly 10 150 a week
Extra Time 24 more hours on one quest's deadline. Weekly 10 150 a week
Quiet Day No ambushes for 24 hours. Weekly 15 200 a week
Trusted Hour For one hour, your claims skip the approval queue. Weekly 20 300 a week
  • Day of Rest and Night Owl stay ledger-only (no boardEffect): Day of Rest says the Game Master picks the day; the app's bedtime setting locks nothing (isBedtimeNow has no caller), so there is nothing to lift.
  • Dropped: Chronos' 1 h deadline pause (Extra Time covers it), the Hook Shot pull-in, Gaia's shuffle (it never shuffled). The family setting dayOffBroadcast is hidden in the settings screen (its only user was Gale's Wind; a Day of Rest cast already tells the adults); its stored value stays.
  • UI: My Powers' Cast opens the existing quest picker for snooze and extra-time first. The Compendium editor (XpCreateUpdateAbility.vue) shows an On the quest board select (None, Snooze, Extra Time, Quiet Day, Trusted Hour) for real-life Powers, beside the In battle select in-game Powers already have.

5. Fight and temple effects

Battle effects (BattleEffects.ts): every effect becomes oncePerFight: true. recall leaves BATTLE_EFFECT_IDS; isBattleEffectId('recall') stays false and battleEffectOf reads a stored recall as gust. The Rewind preset becomes gust.

Effect Label Engine Line on success
frost +10 minutes on the clock extendClock(ICE_WAND_MS) (as today) Ice creeps over the clock: +10 minutes!
time-stop Pauses the clock for 15 minutes freezeClock (as today) Time stands still for 15 minutes!
kindle Chores earn 1.5x the minutes scaleCooldown (as today) The fuse burns slow: every chore earns 1.5x the minutes!
stun The beast misses its next strike skipNextStrike() (as today) {Beast} is stunned! It will miss its next strike.
weaken Halves the beast's attack weakenEnemy (as today) The sun blazes! {Beast}'s attack is halved.
heal Heals 25% of max HP store (as today; Powers only) +{n} HP
gust Refills the clock to full new refillClock(): the running countdown restarts at its full length; refused when the clock is not running A gust blows the beast back: the clock is full again!
pin The beast misses its next two strikes skipNextStrike() twice {Beast} is pinned! It will miss its next two strikes.
vanish Run away with no parting strike new vanishNextRun() sets a flag; the page then runs Run Away, and handleRun dodges the parting strike with a new PartingDodge 'vanish'; the grudge mark and the quest stay as for any run {Hero} vanishes into the shadows...
charge Chores give back double MP a charged flag the chore gains read (section 3) Lightning crackles: every chore gives back double MP!
moonlight Each chore heals 5% of max HP a moonlit flag the chore gains read: +5 % max HP (at least 1) per chore finished Moonlight settles on you: every chore heals you!

charge and moonlight live in choreGains.ts: choreGains({ maxHp, maxMp, questFight, charged, moonlit }) → { hp, mp }; the page applies them when a chore completes (finishCombatTask).

Temple uses (ItemUse.ts; once per room per visit unless noted, through visitMemory):

  • Ice Wand: traps bite on entering, so the wand is used from the room before: every trap room next to the hero (any open side) is frozen for this visit, and onEnterRoom skips a frozen trap's damage and its sheet. No trap next to the hero: "No trap nearby to freeze." (nothing charged).
  • Gaia's Quake: the floor's secret rooms are revealed (TempleSystem.revealSecrets(templeId, level); the visibility rule's isHiddenSecret is false for a revealed floor). Once per floor per visit.
  • Night's Light: in an unsolved puzzle room, the room's riddle sheet shows two choices instead of three (one wrong one fades) every time it opens this visit.
  • X's Invisibility: in a free-fight monster room sealed by its fight (lockOnEnter, not isQuestRoom), the seal opens without the fight; the room stays uncleared. A quest room: "This beast holds a quest. It sees you."
  • Bottles: tapped in a room with an unused health or mana spring, it adds one Spring Water (+10 HP) or one Silver Water (+10 MP), new rows in BattlePotions.POTIONS, to the pack and uses the spring up (a 10 HP spring must not become a 50 HP Potion). The old "drink from the bottles: 25 % HP" use goes.
  • Bombs: spend one Bomb from the pack instead of MP.
  • A fight-only tool in a temple: "{Item} is for fights." The Pegasus items keep their clicks.

6. Contracts and docs

  • docs/Items-And-Classes-Contract.md: sections A and B rewritten from sections 1-5; rule zero kept.
  • docs/Equipment-Mechanics.md: rewritten as the item table of section 2.
  • docs/Battle-Field-Contract-v2.md section H: hands only, the five new effects, recall and the checklist's postpone mode gone.
  • docs/Temple-Interactions-Contract.md: the equipment section follows section 5.

Edge cases

  • MP is checked before anything runs; nothing is charged on a refusal or a cancelled pick.
  • A Power and an item with the same fight effect share its once-per-fight use.
  • gust with the clock frozen or stopped is refused ("The clock is not running.").
  • vanish in a free fight behaves like Run Away there (no parting strike anyway); it still uses the effect.
  • Bombs and Thor's Hammer share stun: one of them per fight.
  • Holding a tool whose temple or fight use is "—" is allowed; its card says where it works.
  • A hero who unlocked everything before the locks keeps everything.

Testing

  • Jest, pure modules first: ItemRules.spec (every item has a temple or fight job or is a travel/menu item; every MP cost is 0-25; stored descriptions never change a cost), BattleEffects.spec (the five new effects, every effect once per fight, recall read as gust), BattleItems.spec (hands only, Bombs spend one, costs from the table), ItemUse.spec (each temple use and refusal), choreGains.spec (quest vs free fight, charge, moonlight), Lodging.spec (bed once a day, hotel price by level), PowerBoardEffects.spec (each effect, no stacking, trusted-hour setting, refusals charge nothing), ItemEffects.spec (only the Lantern list is left; aliases and Pegasus gifts), BattlePowers.spec (Rewind is gust).
  • Component specs: the battle bag's hands-only reason, XpCreateUpdateAbility On the quest board select, My Powers cast opening the picker.
  • E2E tests/e2e/specs/battle.spec.js: the fixture hero holds the Ice Wand; the spec uses it, sees a tool that is not held refused with "Hold it in a hand before a fight.", drinks a Health Potion and casts Stop.
  • Gate: chemx verify (--build when .vue files change).

Out of scope

  • Crafting (its own spec): Bombs' recipe, Hook Shot drops.
  • New temple mechanics (cracked walls, dark rooms).
  • Powers Phase 2 (durations, caps beyond frequency).
  • Rebalancing class MP pools.

Work units (for the board)

# Unit Effort Depends on Owns
W1 ItemRules table, catalogue text, unlock sources standard none ItemRules.ts, EquipmentItems.ts, ItemEffects.ts (lock helpers only), ChestLoot.ts, specs
W2 Fight effects (gust, pin, vanish, charge, moonlight; recall retired; all once per fight) and the engine verbs deep W1 BattleEffects.ts, BattleService.ts, battleService/strikeMath.ts, battleService/types.ts, BattlePowers.ts, specs
W3 Fight items: hands only, table costs, Bombs spend one standard W1, W2 BattleItems.ts, spec
W4 Temple uses, temple shops sell Bombs deep W1 ItemUse.ts, roomInteractions/*, TempleSystem (+ templeSystem/visibility.ts), specs
W5 MP economy: bed, hotel, choreGains standard none Lodging.ts, MyHome.ts, HotelHub.ts, choreGains.ts, specs
W6 Board stripped, boardEffect, PowerBoardEffects, presets (the four new ones and Rewind → gust), cast order deep W1 ItemEffects.ts (board part), PowerBoardEffects.ts, AbilityService.ts, AbilityPresets.ts, src/types/abilities.ts, specs
W7 Powers UI: picker on cast, Compendium select, settings toggle hidden standard W6 My Powers page, XpCreateUpdateAbility.vue, family settings view, specs
W8 Battle page: bag reasons, vanish run, postpone mode removed, chore gains wired deep W2, W3, W5 BattleField.ts, BattleField.vue, XpBattleTaskMenu.vue, specs
W9 Docs and e2e light W8 the four docs, battle.spec.js, battle-backup.json

Waves: W1 + W5; then W2 + W4 + W6; then W3 + W7; then W8; then W9. Every file has one owner: W6 owns AbilityPresets.ts (Rewind included), W1 owns the lock half of ItemEffects.ts and W6 the board half, so W1 lands before W6 starts.

⚠️ **GitHub.com Fallback** ⚠️