Commit Graph

8 Commits

Author SHA1 Message Date
Ludovic Marie d271176f23 Tools and harnesses start the game in scratch folders, not a player's
The game logs into HORIZON_HOME and falls back to the player's own game folder when it is unset. Harnesses
that set only HORIZON_NO_AUDIO (and test_native_client, which set nothing) wrote logs, and on a world run
advancements, into ~/Library/Application Support/horizon.

lab.game_env gives every game a fresh HORIZON_HOME, HORIZON_LAUNCHER_HOME, XDG_DATA_HOME and XDG_CONFIG_HOME,
no audio and no launcher self-update; a folder the caller passes is kept. Every launcher of the game uses it,
parity.py gives each harness its own HORIZON_HOME, and tests/test_game_home.py fails for a script in tools/
that starts the game without it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 18:34:32 +02:00
Ludovic Marie be16401f90 Telemetry: send to telemetry.playhorizon.dev, a benchmarks summary, the Railway config
- DEFAULT_ENDPOINT is https://telemetry.playhorizon.dev. The heartbeat, the launcher's live count and the
  outbox upload all go there; HORIZON_TELEMETRY_URL still names another server, and HORIZON_TELEMETRY_URL=off
  sends nothing at all. CI workflows and the harnesses that start the game or the launcher set off. Consent
  is unchanged: the four switches stay opt-in, only the anonymous ping is always on.
- GET /v1/benchmarks/summary: players' benchmark uploads grouped by GPU, CPU, render distance and game, groups
  of 3+ installs only, medians per install then across installs, no install ID, day, OS version, driver,
  memory or screen. Cached 10 minutes, CORS for the website. Same rules as website/scripts/benchmarks.mjs,
  tested on the same fixtures; a deleted install leaves its groups at once.
- /v1/aggregate no longer lists the newest 50 raw benchmark reports (hardware, driver, day, one install each):
  uploads are published only through the summary.
- Behind Railway's proxy the rate limit counts X-Real-IP, else the last X-Forwarded-For entry (the one the
  proxy adds; a client could choose the first). Still in memory only, never stored or logged.
- crates/horizon-telemetry-server/railway.json: Dockerfile build from the repository root, health check
  /healthz, one replica in europe-west4 (one SQLite file on the /data volume).
- Docs: docs/telemetry.md, the server README (the summary's shape, Railway setup), the privacy page (the ping
  is on, where the data lives, how benchmark uploads are shown).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 21:46:32 +02:00
Ludovic Marie ce87bfb8c7 Tools read the pinned Minecraft version from research-lock.json
lab.VERSION, lab.GAME (.local/minecraft/<version>) and lab.RESOURCES
(.local/horizon-client/<version>) come from the lock, and lab.version_info()
reads the pinned client jar's version.json. Every harness, generator and
tool that named 26.3 (resource folders, jar and source paths, result
records, the vanilla client's --version and asset index, the bare login
client's protocol, the benchmark's options.txt data version, the packet id
table's header) uses them, so a candidate worktree pinned to another version
runs them unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:22:20 +02:00
Ludovic Marie 9dc0803a24 Graphics benchmark: games run with HORIZON_NO_AUDIO=1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 17:12:30 +02:00
Ludovic Marie 7f1e197428 Section arena in pages; graphics docs and benchmark comparison
At render distance 32 the single section arena grew past the 4 GiB buffer
limit and the renderer panicked. Sections now live in pages of at most
256 MiB (or the device's buffer limit); draws keep their order and bind each
page once per run of consecutive draws in it, so translucent sections stay
back to front. docs/graphics.md describes the settings, the benchmark and
what changed; graphics_bench.py --compare prints a before/after table and
keeps each game's log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 17:10:07 +02:00
Ludovic Marie ad701d73d9 Fewer stalls: region writes on a writer thread, culled entities, villager POI scans skip empty sections
- Unloaded chunks and entity chunks are encoded and written by a background
  region writer, in order; loads see queued records first, and synchronous
  saves wait for the queue. Deleting entity chunks a region doesn't hold no
  longer rewrites the region file.
- Mobs render within Entity.shouldRenderAtSqrDistance (64 x bounding-box size
  x entity distance) and inside the view frustum (EntityRenderer.shouldRender);
  block entities outside the frustum are skipped, beams and structure blocks
  excepted.
- Minecarts and dropped items tick only in entity-ticking chunks, like mobs.
- Villager POI searches skip sections whose palette has no POI block.
- Streaming bookkeeping uses the Fx hash and checks a column's light
  readiness once per frame instead of once per dirty section.
- HORIZON_SPIKES=MS prints the timed spans of slow frames; frame summaries
  give the phase split of the slowest 1%.

RD 32 village flight on the 4080: 81 -> 230 fps; 1% low 5.8 -> 18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:14:57 +02:00
Ludovic Marie 45bd1a7be8 Renderer and tick performance: section arena with indirect multi-draw, dense occlusion graph, entity ticking within the simulation distance, fast chunk-map hashing
- Terrain sections live in one vertex arena (first-fit free list, grown on the
  GPU) and draw with one multi_draw_indexed_indirect per pass instead of a
  buffer bind and draw per section; per-frame scratch vectors are reused.
- The SectionOcclusionGraph search runs over dense arrays around the camera
  instead of hash sets, with per-column visibility.
- Mobs outside the entity-ticking chunks (Chebyshev distance of the
  simulation distance, DistanceManager.inEntityTickingRange) only check
  despawning, as in ServerLevel.tick; before, every loaded mob ticked.
- World chunks use the Fx hash; sky darkening is sampled once per time and
  weather instead of once per mob; creaking-heart scans compare state ids.
- Horizon-only graphics settings (horizon-graphics.txt): frame pacing without
  spinning, present mode, animated textures, worker threads.

RD 32 village flight on the 4080: 3.1 -> 81 fps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:34:48 +02:00
Ludovic Marie c982fadaf5 Graphics benchmark: scripted flights over four scenes at render distances 8/16/32, with CPU and GPU frame times
horizon-ctl gains 'fly' (a constant-speed camera path that replies with the
frame summary); frame summaries add CPU time per frame (waits for the GPU,
display and limiter excluded), per-phase averages and GPU time from timestamp
queries. --offscreen renders into a texture on the discrete GPU so the 4080
can be measured under the headless compositor. Baselines: lavapipe on vscreen
and the RTX 4080 offscreen, seed 1234.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:04:23 +02:00