fix(streaming-duel): harden duel lifecycle, oracle revenue path, and cinematic camera#1177
Open
binkyfishai wants to merge 1 commit into
Open
fix(streaming-duel): harden duel lifecycle, oracle revenue path, and cinematic camera#1177binkyfishai wants to merge 1 commit into
binkyfishai wants to merge 1 commit into
Conversation
…cinematic camera **Duel lifecycle / agent behaviour (DuelOrchestrator.ts + DuelCombatAI.ts)** - Draw-path cleanup: `endFightByTimeout()` draw now routes through `startResolution()` so `stopCombatAIs()` runs; previously arena bounds stayed clamped and autonomous behaviour stayed disabled until the next duel started. - `startCombatAIs()` rollback: the fire-and-forget catch now calls `stopCombatAIs()` to release any services that had bounds set before the constructor threw. - Positioning fix: agents spawn 0.5 units apart (tileDistance=1) instead of 16, so `startCombat` succeeds on the first try. Every duel was hitting the retry limit as a draw before this. - Weapon picker `>= 0` gate: melee/ranged/mage pickers previously kept the equipped item when every score was -1 (wrong type). A ranged agent ended up holding a longsword + 500 arrows; now the gate forces a valid weapon for the role. - Trash-talk IIFE guard: pending LLM calls respect `isRunning` so post-stop chat doesn't land on an agent back in the overworld. - Perf: hoisted PROTECTION_PRAYER_MAP to module scope, added sync short-circuit in `maybeActivateProtectionPrayer`, memoised `detectOpponentAttackType` by weapon id (removes per-tick allocations). **Oracle / hyperbet publish path (DuelArenaOraclePublisher.ts + main.ts)** - Bounded exponential-backoff retry (1s → 2.5s → 6s → 15s → 30s) on publish failure, per (duelId, targetKey), with `setTimeout.unref()` and `destroy()` cancellation. Gives up with a clear "manual intervention required" log after 6 total attempts. - Boot re-enqueue: on `init()`, records with `chainState[target].lastError` set are re-published via the full retry schedule. Stranded records from a mid-retry crash now resume automatically. - Startup warning: if `STREAMING_DUEL_ENABLED=true` but `DUEL_ARENA_ORACLE_ENABLED=false`, log a clear⚠️ so operators know on-chain settlement is disabled. **Operator triage (admin-routes.ts)** - `GET /admin/duels/oracle/stuck` — list records with any failed target. - `POST /admin/duels/oracle/clear/:duelId` — clear lastError; with `{forceRetry:true}` also re-fires publish with the full retry budget. **Cinematic camera (ClientCameraSystem.ts)** - FIGHTING: wider FOV (46→54), higher angle (phi 0.27π→0.30π), wider radius band (4–7.5 → 5–10), more orbit drift. - RESOLUTION: closer hero framing (radius 5.5–8 → 4.5–7), less top-down (phi 0.44π→0.35π), winner-weighted focusBias 0.5→0.7. - COUNTDOWN push-in: dynamic smoothstep shrink from radiusMax to radiusMin over 4s to replace the frozen pre-fight frame. - RESOLUTION hero push-in: dynamic 1.5s shrink to (radiusMin + 0.3) timed with the 600ms victory-emote delay. **Tests (+14 regressions, all verified failing when the fix is reverted)** - `DuelOrchestrator.test.ts` (new): draw-path arena cleanup, hp_advantage smoke test, phase-guard. - `DuelArenaOraclePublisher.test.ts`: retry-then-succeed, exhaust-retries, destroy cancels timers, boot re-enqueue, getStuckRecords, clearStuckRecord with/without forceRetry, not_found handling. Typecheck: no new errors (2 pre-existing DuelCombatRole errors already on main). Oracle + scheduler suites: all 48 tests green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardens the streaming duel arena end-to-end — duels now actually run, finish cleanly, publish results on-chain reliably, and look better. Verified live against a deployed
+ "DuelOutcomeOracle" +on local anvil. Adds 14 regression tests, all validated by temporary rollback.Changes
Duel lifecycle (DuelOrchestrator.ts, DuelCombatAI.ts)
+ "startResolution()" +, so arena bounds clear and autonomy restores (previously stuck until next duel).+ "startCombatAIs()" +rollback on failure.+ "startCombat" +now succeeds first try.+ ">= 0" +gate: previously kept any equipped item (wrong type included) when all scores tied at -1; ranged agents ended up holding swords + arrows.+ "maybeActivateProtectionPrayer" +, memoised+ "detectOpponentAttackType" +.+ "stop()" +.Oracle / hyperbet path (DuelArenaOraclePublisher.ts, main.ts)
+ "setTimeout.unref()" +and+ "destroy()" +cancellation. Gives up cleanly after 6 attempts.+ "lastError" +set from a mid-retry crash resume publishing on startup.+ "STREAMING_DUEL_ENABLED=true" +but oracle disabled.Operator triage (admin-routes.ts)
+ "GET /admin/duels/oracle/stuck" +— list records with any failed target.+ "POST /admin/duels/oracle/clear/:duelId" +— clear+ "lastError" +;+ "{forceRetry:true}" +refires with full retry budget.Cinematic camera (ClientCameraSystem.ts)
+ "radiusMax" +→+ "radiusMin" +(replaces frozen pre-fight frame).+ "radiusMin + 0.3" +timed with the victory emote.Test plan
+ "bun x vitest run tests/unit/oracle src/systems/StreamingDuelScheduler" +— 48 pass (34 existing + 14 new)+ "bun run typecheck" +— no new errors (2 pre-existing DuelCombatRole errors unchanged)+ "DuelOutcomeOracle" +to local anvil, ran server, observed UPSERT(BETTING_OPEN) → UPSERT(LOCKED) → RESOLVE txs on block 17, 19, 37, 39; verified via+ "cast receipt" ++ "node build/index.js" +directly (bypassing+ "scripts/dev.mjs" +) requires+ "PUBLIC_CDN_URL=http://localhost:5555/game-assets`" +in the env, or the client has no assets.+ "dev.mjs" + ` normally handles this via a health-check fallback.