Match replays
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- javascript, typescript
Research direction
Start with server/src/api/arena.ts and server/src/types/environment.ts to trace emitted events and current live event access, then read ui/src/util/playbackBuffer.ts, playbackClock.ts, and arenaReducer.ts for replay playback. The implementation notes also point to ReplayService.ts, mcp.ts, and tests for environments, services, reducers, and playback. Done means finished matches can be persisted, listed and fetched, then replayed with scrubbing and slow motion; the notes flag retention, storage growth, and #142 as planning concerns.
Written by the indexing model from the issue text.
Description
The arena is already an event stream — persist a match's events and add a replay player (scrub, slow-mo). Hugely shareable.
Effort: M–L
Migrated from ENHANCEMENTS.md (§2 Gameplay & fun).
Implementation notes
Priority: medium — Valuable analysis/spectator feature reusing existing SSE and playback machinery, but purely additive (no stability/security impact) and not on the core play-a-match path.
Purpose
Match replays let users (and spectators/MCP tooling) review a finished battle after the fact — currently once Environment restarts or is disposed (30-min idle GC in EnvironmentService), the SSE event history is gone. This adds durable value beyond live viewing and gives bot authors a debugging/analysis tool without needing to catch a match live.
Implementation approach
- Capture: hook the same
Environment.emit('event', ...)path already consumed byGET /api/user/:userId/arena/events(server/src/api/arena.ts) — add a recorder alongside the existingrecentLogs/recentFaultsring buffers inserver/src/types/environment.ts(MAX_RECENT_LOGSpattern) that appends every emitted event plusclock.timeto a per-match buffer, flushed/persisted onrestart()/match end (mirrors howrecentFaultsis reset at line ~570). - Persistence: new
ReplayService.ts(services singleton, same shape asArenaService.ts/AppService.ts:CREATE TABLE IF NOT EXISTSat import time, no framework migrations yet — see #142) storing{matchId, arenaId, seed, events JSONB/blob, startedAt, summary}. Event volume is significant (~10 ticks/s × up to 5 tanks × several event types for potentially minutes) — worth gzipping the JSON blob or storing to a blob column rather than one row per event. - Playback (UI): reuse
ui/src/util/playbackBuffer.tsandplaybackClock.tsalmost unmodified — they already decouple "when events arrive" from "when they're applied" and expose a playhead; a replay is just a buffer fed from a fetched array instead of a live SSE connection. Feed events through the existingui/src/util/arenaReducer.tsandui/src/util/simulate.tsunchanged — replay is only a different event source, not a different state machine, so no risk of drifting the client physics mirror fromserver/src/util/simulation.ts. - New endpoints:
GET .../arena/replays(list),GET .../arena/replays/:matchId(fetch full event log) inarena.ts; expose read-only via MCP (mcp.ts) alongsidematch_summary/recent_logsfor parity. No bot-facingcompiler.tschanges — this is spectator/analysis surface only. - Scrub/slow-mo: add a scrub bar + speed control on top of
playbackBuffer's existingtickMs/depth mechanics; scrubbing means re-seeding the reducer from event index 0 (or periodic snapshots) since state is derived by folding events, not stored per-frame.
Key details to plan
- Determinism: since
Environmentseeds a PRNG (util/random.ts), a storedseedplus event log gives two replay strategies — pure event replay (store every emitted event, simplest, robust to future physics changes) vs. re-simulation from seed (cheaper storage, but breaks ifsimulation.tschanges) — choose the former for correctness. - DB growth/retention: needs a size cap or TTL policy per arena/user; tie into
MAX_APPS_PER_USER-style caps to avoid unbounded storage abuse. - Testing: extend
environmenttests and addReplayServicetests followingservices.test.tsconventions (mockutil/db); add reducer/playback tests followingarenaReducer.test.tsand a newplaybackBuffer-from-static-array test. - Dependencies: benefits from #142 (DB migrations) landing first given a new table; otherwise standalone.
- Effort/risk: M–L as filed — mostly additive, low security risk (read-only, owner/spectator-gated like existing
/arena/events), main risk is storage/perf at scale.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 8m
- Merged PRs (30d)
- 8
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from LeeAdcock/robocodeJs.com
-
priority: medium tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
LeeAdcock/robocodeJs.com#411 ·
Maintainers usually reply within 1 day
-
enhancement priority: medium
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
LeeAdcock/robocodeJs.com#254 ·
Maintainers usually reply within 1 day
-
good first issue priority: low tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
LeeAdcock/robocodeJs.com#146 ·
Maintainers usually reply within 1 day
-
dependencies priority: low tech-debt
Difficulty 1/5 Under an hour Newbie friendliness 15/100
LeeAdcock/robocodeJs.com#413 ·
Maintainers usually reply within 1 day
-
priority: low tech-debt
Difficulty 3/5 Half a day Newbie friendliness 32/100
LeeAdcock/robocodeJs.com#412 ·
Maintainers usually reply within 1 day
All issues in LeeAdcock/robocodeJs.com
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
homarr-labs/homarr#7191 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
AvaProtocol/ava-sdk-js#276 ·
Maintainers usually reply within 1 day
-
useFragment does not require `variables` when the fragment's variables type has required fieldsOpen
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
apollographql/apollo-client#13493 ·
Maintainers usually reply within 1 day