Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .github/workflows/playwright-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,42 +71,42 @@ jobs:
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-shard-1
server_set: seeded
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue --project=lap-replay
shard: 1/7
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-shard-2
server_set: seeded
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue --project=lap-replay
shard: 2/7
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-shard-3
server_set: seeded
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue --project=lap-replay
shard: 3/7
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-shard-4
server_set: seeded
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue --project=lap-replay
shard: 4/7
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-shard-5
server_set: seeded
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue --project=lap-replay
shard: 5/7
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-shard-6
server_set: seeded
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue --project=lap-replay
shard: 6/7
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-shard-7
server_set: seeded
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue
projects: --project=seeded-e2e --project=seeded-routes --project=seeded-imports --project=tracks-catalogue --project=cars-catalogue --project=lap-replay
shard: 7/7
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
- name: seeded-webgpu
- name: lap-replay-webgpu
server_set: seeded
projects: --project=seeded-webgpu
projects: --project=lap-replay-webgpu
runs_on: '["mars-ubuntu-2vcpu-6g", "mars-retry-3"]'
uses: ./.github/workflows/playwright.yml
with:
Expand Down
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
## Unreleased

### Features
- Show clickable circuit-overview sector markers on desktop only while hovering or using keyboard focus; keep them visible on touch screens.
- Group LMU state of charge, virtual energy and regenerative power in a separate table below the main Replay and Compare → Spectate metrics.
- Use dashed track edges in Replay and Compare → Spectate to provide fixed-distance speed cues.
- Show plain TC and ABS indicators in the Replay and Compare → Spectate center dashboard only when native activation telemetry was recorded, lighting them green during activation and keeping inactive or temporarily unavailable readings neutral.
- Show color-coded per-wheel traction status in the center dashboard for single-lap Replay and Compare → Spectate, with separate A/B readings and unavailable telemetry marked clearly.
- Keep Sessions actions in a bottom-center floating bar with a selection count and Deselect all. Keep Compare visible and enable it only for two compatible laps; filter comparison laps by Mine, Others, or All inside the lap-picker dropdown.
- Show separate LMU player energy, engine, electric motor, steering feedback, weather and race-control readings in live telemetry and recorded-lap analysis when provided by the game.
- Show separate LMU player energy, engine, electric motor, steering feedback, weather and race-control readings in live telemetry when provided by the game.
- Show read-only LMU setup, forecast and condition snapshots with source age and availability, without waiting for network requests before displaying live telemetry.
- Compare laps in Spectate with synchronized 3D replay, configurable cameras and overlays, live A/B instruments, sector deltas, and telemetry, car, AI, Focus View, and lap-statistics panels.
- Inspect recorded telemetry in Compare → Spectate with a Data panel and switch between lap A and B without showing both panels at once.
- Bring Compare → Spectate's scene, playback, telemetry and Insights to single-lap Replay, with saved 3D settings, grouped wheel graphs, stable ERS bands, chassis/tire-info rendering and independently resizable, horizontally scrollable panels.
- Show LMU traction-control and ABS settings and activation, traction-control cut level, motor map, battery state of charge, virtual energy and signed regen power in Replay's existing Data panel instead of a separate Player telemetry section; show brake migration beside brake bias in Dynamics.
- Restore the single-lap Replay segment-time list in a collapsible Segments panel, with active-segment highlighting and a saved open state.
- Use Replay on phones with a compact horizontal dashboard, larger touch controls, an opaque circuit overview you can close, and one panel at a time beneath the playback tabs. Read colored sector labels closer to the timeline on phones and desktops, and scroll track and lap pickers out of view while keeping navigation visible.
- Manage Replay AI analysis from its tab without a duplicate panel header.
- Open desktop Replay and Spectate panels within half the workspace, then drag them wider—including a single panel—to give charts more room. Resize each panel without shrinking its neighbors.
- Drag Replay and Spectate tabs to reorder them, or use Alt+Left/Right; keep the saved tab order when reopening the page.
- Choose a 50–100 Hz recording frequency for ACC, AC Evo, iRacing, or LMU during setup to reduce recording size. Live UDP recording is unchanged.
- Downsample saved recordings manually or with an opt-in age policy in Storage settings; measure the first 1,000 frame timestamps per stream and skip recordings already at or below the target. Track progress and retry failed files. Favorites and MoTeC imports stay unchanged.
- Split recordings into individual, lossless per-lap `.bin` files so lap 60 loads as fast as lap 1.
Expand All @@ -14,6 +27,10 @@
- Provide a Linux x86_64 AppImage for Ubuntu 22.04 and newer, with AppImageUpdate-compatible GitHub release deltas.

### Fixes
- Correct the LMU steering indicator direction in the Replay and Compare → Spectate center dashboard without changing recorded steering values.
- Show active TC and ABS readings in green in Replay's Data panel, while keeping inactive and unavailable readings neutral.
- Use reported traction-control activity in Replay and lap insights when the game's telemetry provides it; infer activation only when that channel is unavailable.
- Hide Y-axis labels on telemetry charts while keeping chart legends and data visible.
- Keep recording splitting and background processing available when the UDP telemetry port is already in use.
- Report inconclusive historical lap classification as limited without requesting attention, and correct earlier results.
- Center Le Mans Ultimate track outlines within catalogue cards.
Expand Down Expand Up @@ -81,6 +98,7 @@
- Skip LMU outline requests when stored track names do not identify one layout.

### Internal
- Cover Replay extraction invariants with regressions for bounded track ribbons, seek-aware tire labels, cold frame capture, keyboard frame stepping, position-only segment timings and native AC Evo TC evidence.
- Ignore terminal color codes when waiting for compiler startup in the Paraglide lifecycle CI test.
- Generate Paraglide declarations with the installed native TypeScript compiler and stop abandoned translation watchers from consuming CPU after development exits.
- Use Ubuntu instead of macOS for CI runners and cap Mars memory requests at 6 GB.
Expand Down
25 changes: 25 additions & 0 deletions advisor-plans/lap-replay-backend-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Lap replay server implementation

Contract: [shared integration contract](lap-replay-contract.md). Reciprocal UI work: [UI plan](lap-replay-ui-plan.md).

## Scope and ownership

Own replay/Insights handlers currently in `apps/backend/src/routes/laps/resource-routes.ts`, feature semantic DTOs under `packages/lap-replay/contracts/replay.ts`, package-owned server implementation and focused endpoint tests. Preserve shared DB/capture/analysis services, middleware and application lifetime ownership. The coordinator owns package manifests, public barrels, app registration and final test discovery.

## Tasks

1. Move `SemanticReplayFrame` and `SemanticLapTelemetry` definitions from the client hook into browser-safe contracts; reuse authoritative LMU wire, insight and coverage types. Preserve the wire format; strengthen the existing unknown findings array to `LapInsight[]` only where the real handler already guarantees it.
2. Extract actual Hono handlers for semantic telemetry, Insights reads and Insights rerun into `server/`, preserving existing source/artifact selection, native replay, frame-index restoration, serialization and errors. Export real routes through `/server`; remove old handlers rather than wrap them (C4/C5).
3. Compose routes in the existing app with inherited auth/CSRF/origin behavior and inferred RPC typing. Move exclusively owned server tests if found; keep shared cross-feature tests centrally owned and migrate their public imports (C4/C5).

## Acceptance and verification

Server acceptance is C4 and server/contracts ownership in C5; C1/C2 depend on the unchanged real backend integration. Reuse all shared E2E scenario definitions. Validate shared-ID/header failures, wrong-game/missing laps, parsing failures and uncommitted live-capture states against existing source fixtures. Follow the shared contract's authoritative distinction between ordinary unavailable capture results and the later publication-race guard. Preserve current handling rather than invent new fallback data, clocks, indices, auth or persistence behavior.

The coordinator runs feature server/unit gates, real API error/recording scenarios, full UI/backend replay/Insights integration, public typing, boundary rejection and production browser build. Record passing results and any unavailable environment explicitly. Server and UI implementations proceed independently after the shared contract; final completion depends on integrated E2E evidence.

## Implementation outcome

The package owns the three real Hono handlers, semantic DTOs and focused route integration suite; application registration preserves the typed route chain and shared middleware. Existing mixed comparison/AI route coverage remains centrally owned.

Executed outcomes are linked from the [shared verification record](lap-replay-contract.md#recorded-verification). Real compiled HTTP coverage includes ordinary errors, rerun persistence and both unavailable-capture states. The unchanged later publication-disappearance race and generic replay-failure catch were not fault-injected; their handling was preserved, not claimed as independently exercised.
Loading
Loading