Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Match replays

Open
#116 0 comments 0 reactions 0 assignees View on GitHub

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

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

enhancement priority: medium

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 by GET /api/user/:userId/arena/events (server/src/api/arena.ts) — add a recorder alongside the existing recentLogs/recentFaults ring buffers in server/src/types/environment.ts (MAX_RECENT_LOGS pattern) that appends every emitted event plus clock.time to a per-match buffer, flushed/persisted on restart()/match end (mirrors how recentFaults is reset at line ~570).
  • Persistence: new ReplayService.ts (services singleton, same shape as ArenaService.ts/AppService.ts: CREATE TABLE IF NOT EXISTS at 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.ts and playbackClock.ts almost 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 existing ui/src/util/arenaReducer.ts and ui/src/util/simulate.ts unchanged — replay is only a different event source, not a different state machine, so no risk of drifting the client physics mirror from server/src/util/simulation.ts.
  • New endpoints: GET .../arena/replays (list), GET .../arena/replays/:matchId (fetch full event log) in arena.ts; expose read-only via MCP (mcp.ts) alongside match_summary/recent_logs for parity. No bot-facing compiler.ts changes — this is spectator/analysis surface only.
  • Scrub/slow-mo: add a scrub bar + speed control on top of playbackBuffer's existing tickMs/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 Environment seeds a PRNG (util/random.ts), a stored seed plus 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 if simulation.ts changes) — 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 environment tests and add ReplayService tests following services.test.ts conventions (mock util/db); add reducer/playback tests following arenaReducer.test.ts and a new playbackBuffer-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

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from LeeAdcock/robocodeJs.com

All issues in LeeAdcock/robocodeJs.com

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.