## Context The existing SCUM player intelligence projection owns server-local identities and sessions, while the game-client bridge owns declared Companion snapshots and commands. Neither layer presents movement. The map must remain an explainable, bounded operational view and may not turn the browser into a route to raw logs, Run, game databases, or Companion sockets. ## Goals / Non-Goals **Goals:** - Collect only declared semantic position/vehicle transition events from a platform-managed Companion or accepted log projection. - Convert plugin-declared world coordinates into safe normalized map coordinates and retain only a sampled, bounded trail per server/entity. - Return a fixed bounded window with player/vehicle filters, vehicle-riding segments, data source, collection time, map version, and precision. - Enforce existing server authorization before resolving map status or trajectory data; preserve server isolation. - Render readable point and line trails with explicit empty and missing-map states and detail navigation contracts. **Non-Goals:** - OCR, screenshot parsing, mouse/keyboard injection, desktop automation, direct game-window access, direct sockets, direct database access, raw coordinate/database querying, indefinite retention, real-time all-server heatmaps, or raw log/browser delivery. ## Decisions 1. **A small typed event catalog is the only collector contract.** The SCUM manifest declares four semantic events: `player.position`, `vehicle.position`, `player.vehicle.enter`, and `player.vehicle.leave`. Every event includes a bounded entity ID, occurred time, collection time, source (`companion` or `log-projection`), and a plugin map ID/version. Position events carry only finite world X/Y values. They enter through the existing durable log/Companion snapshot channel, never browser-to-game traffic. 2. **Plugin map declaration defines the safe projection.** `mapTrajectories` in the manifest declares map ID/version, world bounds, image dimensions, axis orientation, sampling distance/time, and retention seconds. Platform validates it once, converts world coordinates to normalized 0–1000 map units, rounds to declared precision, and rejects mismatched map metadata or points outside declared bounds. The frontend receives no host path, original world coordinate, Companion endpoint, or raw record body. 3. **Project by server/entity/time with event identity and compression.** `GameMapTrackPoint` is unique by accepted event ID and is scoped by server plus entity kind/ID. Projection sorts logically by event time; duplicates are ignored, late points remain ordered in query results, and a point is retained only when it advances the declared sampling interval or distance (transitions are always retained). The repository filters time on server/entity indexes and prunes expired points and ride segments during projection and query. 4. **Derive riding intervals from enter/leave events.** A player enter opens one vehicle segment; entering a different vehicle closes the prior segment at the new event time. A leave closes only the matching active vehicle. Out-of-order and duplicate transitions cannot produce overlapping active segments. The map response projects these segments as player-associated vehicle trail intervals, not inferred ownership. 5. **Use a bounded read model instead of arbitrary map queries.** The API accepts a maximum 24-hour time window and at most 20 known player IDs plus 20 known vehicle IDs. It authorizes server access before lookup, verifies player IDs belong to that server, limits output points per entity, and returns map metadata plus empty/missing-map statuses. Vehicle IDs are only accepted if observed in the same server's declared vehicle snapshots or trajectory records. 6. **Keep detail linking as explicit identifiers.** Player trail summaries provide the existing `gamePlayerRecordId`; vehicles provide their safe vehicle ID and link intent. The frontend may navigate to the existing player selection/detail endpoint or invoke the pre-existing vehicle lookup context. It does not receive a route to Run, a raw query template, or vehicle storage details. ## Risks / Trade-offs - [Companion cannot provide typed position events] → the map shows a clear collection-unavailable/empty state; no substitute screen or input automation is attempted. - [Map version changes] → points are queried only for the declared map version; mismatched events are rejected and the response explains the missing compatible map. - [High event volume] → server-side sampling, per-entity output caps, and retention pruning bound storage and response size. - [Late events] → query sorting and identity deduplication keep trails deterministic; transition rules avoid reopened or cross-vehicle overlap. ## Migration Plan 1. Add model-first track/segment records, memory/file/MySQL persistence, projection, retention, and test coverage. 2. Register the plugin map declaration and typed schemas; unsupported deployments remain visibly empty. 3. Deploy the authorized API and console map. Existing player and vehicle views remain unchanged. 4. Roll back by removing the map panel/declaration; expired projected records are pruned normally and no raw data needs migration.