fix: add runId to seed calculations and use seeded random for treasure loot
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m19s

Fixes #299: Seed calculation now includes runId component per spec (seed = floor × 12345 + runId)
Fixes #298: Treasure loot now uses seeded random instead of Math.random()

Changes:
- Added runId field to CombatState type
- Generated random runId on spire entry in createEnterSpireMode
- Updated getRoomsForFloor, generateSpireRoomType, generateSpireFloorState, generateTreasureLoot to accept and use runId
- Updated all call sites in combat-descent-actions.ts and combatStore.ts
- Treasure loot item count now uses seeded RNG instead of Math.random()
This commit is contained in:
2026-06-08 14:54:37 +02:00
parent 7f5493f4d8
commit 83f835ccb0
6 changed files with 47 additions and 31 deletions
+10 -4
View File
@@ -47,6 +47,9 @@ export const useCombatStore = create<CombatStore>()(
currentRoomIndex: 0,
roomsPerFloor: 1,
// ─── Spec: Run identity (climbing spec §4.2, §7) ────────────────────
runId: 0,
// ─── Spec: Descent tracking state ─────────────────────────────────────
descentPeak: null,
roomResetState: {},
@@ -166,8 +169,9 @@ export const useCombatStore = create<CombatStore>()(
set((s) => {
if (s.currentFloor <= 1) return s;
const newFloor = s.currentFloor - 1;
const rooms = getRoomsForFloor(newFloor, newFloor * 12345);
const newRoom = generateSpireFloorState(newFloor, 0, rooms);
const seed = newFloor * 12345 + s.runId;
const rooms = getRoomsForFloor(newFloor, seed);
const newRoom = generateSpireFloorState(newFloor, 0, rooms, s.runId);
return {
currentFloor: newFloor,
currentRoom: newRoom,
@@ -180,7 +184,8 @@ export const useCombatStore = create<CombatStore>()(
exitSpireMode: () => {
set((s) => {
const rooms = getRoomsForFloor(s.exitFloor, s.exitFloor * 12345);
const seed = s.exitFloor * 12345 + s.runId;
const rooms = getRoomsForFloor(s.exitFloor, seed);
return {
spireMode: false,
currentAction: 'meditate',
@@ -189,7 +194,7 @@ export const useCombatStore = create<CombatStore>()(
currentFloor: s.exitFloor,
floorHP: getFloorMaxHP(s.exitFloor),
floorMaxHP: getFloorMaxHP(s.exitFloor),
currentRoom: generateSpireFloorState(s.exitFloor, 0, rooms),
currentRoom: generateSpireFloorState(s.exitFloor, 0, rooms, s.runId),
castProgress: 0,
clearedFloors: {},
clearedRooms: {},
@@ -362,6 +367,7 @@ export const useCombatStore = create<CombatStore>()(
guardianBarrier: state.guardianBarrier,
guardianBarrierMax: state.guardianBarrierMax,
meleeSwordProgress: state.meleeSwordProgress,
runId: state.runId,
}),
}
)