Skip to content

feat(hq): the game's sky at dusk and night, Chunky's sun by day, fitted lanterns; 0.2.0 publishes the command - #39

Merged
stellarfeline merged 15 commits into
mainfrom
feat/lw-game-sky
Oct 21, 2026
Merged

stellarfeline merged 15 commits into
mainfrom
feat/lw-game-sky

Conversation

@stellarfeline

Copy link
Copy Markdown
Owner

HQ mode's dusk was Chunky's Preetham sky, which at a low sun reads yellow where the game's sunset is orange. This ports the method Delvewright's Chunky scenes use (the pinned client's day timeline at the tick), keeps Chunky's sun and shadows by day, fits the lanterns, and prepares 0.2.0.

Sky by time of day (--sky auto, the default)

  • Game sky (--sky game): light from the client's lightmap.fsh sky light at the tick (visual/sky_light_factor, visual/sky_light_color), the lens seeing the client's own sky (sky disc, fog, sunrise fan, sun, moon, stars) as an equirectangular map; no directional sun light (the game has none); Hable with the mid-grey gain k = 1.463761 (--tonemap filmic-mid-grey). Ported from Delvewright (GPL-3.0), attributed in ACKNOWLEDGEMENTS.
  • By time: Chunky's look weighted by (factor − night) / (day − night), both read from the jar's timeline (day plateau ticks 730–11270). Weight 1 by day, 0 by night, linear between (≤ 1/1870 per tick); dusk tick 12800 is 0.1818. The mix is Lumenwright's own rule over a client quantity. One tick across the plateau edge moves the camp frame 0.067/255; a hard switch would jump 28.7/255 (a test reds on it). Ticks 6000 and 18000 are byte-identical to --sky chunky and --sky game.
  • Day default is byte-identical to the approved frames.

Lanterns

The game look's emitter intensity is 137.9628 (13 × 10.6125), authored by Lumenwright: fitted so lantern-lit pixels at dusk match the engine's Chunky reference in mean display luma (41.993), by bisection over exact linear interpolation of two renders, cross-checked by a direct render (6.75e-7). Quarter-frame fits spread 112.6–118.5. Chunky's look keeps 13; --emitter-intensity takes any value.

Measured (CUDA, 16384 spp, four bounces, against the engine's Chunky reference)

frame display mean SSIM
dusk, main (Chunky sky) 18.68 0.7799
dusk, new default 8.06 0.8162

The remaining sky difference is the engine's own: a veil in the lens (Chunky feeds one map to lens and light) and a clear-colour lean that departs from the client's Mth.clampedLerp (pinned here by a test). Renders: the two dusk HQ frames change; day frames are byte-identical; re-rendered twice, byte-identical.

Also

  • Benchmark redesigned before measuring (docs/benchmark.md): same frame, spp and machine per question. PC: Chunky CPU 78.60 s, LW CUDA 6.14 s (12.8×), LW CPU 54.84 s (1.43×).
  • README: front page is renders, Install and a Quick start; the rest moved to docs/ pages, every old anchor resolving (66 links, 0 broken). lumenwright-kernel declared rust-version 1.85, which its let-chains do not build on; it is 1.88.
  • 0.2.0 plumbing: lumenwright-cli is published (kernel, library, command in order; the workflow refuses unless all three are absent); Install is cargo install lumenwright-cli; CHANGELOG [0.2.0] - Unreleased. cargo publish --dry-run --workspace passes; the command's package builds standalone against the packaged two.
  • Parity: a mid-blend case (showcase-auto-mid) on Metal and CUDA against the CPU; a perturbation that skips the half-weight sun reds each.

Gates: fmt, clippy -D warnings (with and without cuda), cargo test --workspace (146 passed), build-ptx.sh, CUDA and Metal parity tests, publish dry-run: all 0.

🤖 Generated with Claude Code

https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2

stellarfeline and others added 15 commits October 20, 2026 14:34
`--tonemap filmic-mid-grey` (`Tonemap::FilmicMidGrey`): Chunky's Hable curve
(`HableToneMappingFilter`, `FILMIC_WORLDS` preset) read brighter by the gain
that holds linear 0.18 at 0.18 before the display gamma, so 0.18 shows at
0.18^(1/2.2) = 0.458656, the value the game's transfer gives a decoded colour.
At the preset it shows at 0.393285.

The gain is closed form: with y = 2km and q = m / whiteScale + E/F,
h(y) = m / whiteScale is a quadratic in y whose positive root gives
k = 1.463761. A curve read k times brighter is the curve with A k^2, B k and
W / k (the white held), so exposure 1 still means the light as measured.

`HableCurve` (`white_scale`, `h`, `before_gamma`, `brightened`,
`mid_grey_gain`) is ported from Delvewright's engine (GPL-3.0,
stellarfeline/delvewright at 0fd300da7,
`crates/delvec/src/compiler/view/scene.rs`), which writes this curve into
every Chunky scene. `Tonemap::Filmic` now evaluates through the same
`HableCurve` at the preset (the parameter products in float, the rest in
double, as Chunky's `processPixel`), so there is one Hable implementation.

Test `the_game_tone_curve_shows_mid_grey_as_the_game`: k within 1e-6 of
1.463761; the curve holds 0.18 within 1e-6; its seven floats are the
engine's 0.32138956, 0.7318806, 0.1, 0.2, 0.02, 0.3, 7.651521; it equals the
preset at k times the light within 1e-5 relative over 1e-4..7e2; 0.18 shows
at the gamma filter's 8-bit level; the preset shows it at 0.393285; W is
white. Log:
test render::post::tests::downsample_averages ... ok
test render::post::tests::tonemap_endpoints ... ok
test render::post::tests::the_game_tone_curve_shows_mid_grey_as_the_game ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 75 filtered out; finished in 0.00s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
A new HQ sky model, `HqSkyModel::Game` (`--sky game`), beside Chunky's
(`HqSkyModel::Chunky`, `--sky chunky`, still the default in this commit).
It ports the method Delvewright's engine lights its Chunky scenes with
(GPL-3.0, stellarfeline/delvewright at 0fd300da7:
`crates/delvec/src/compiler/view/scene.rs` `lightmap_sky` and `sky_cell`,
`crates/delvec/src/compiler/view/sky_image.rs` `sky_map`):

- The sun casts no light. The game has no directional light; nothing in its
  lightmap depends on the sun's direction. A sun of colour 0 now draws no
  next-event sample in the kernel (CPU, CUDA) and in pathtrace.wgsl.
- The sky casts the lightmap's colour for a cell open to it: the 1.21.11
  client's `lightmap.fsh` at sky light 15 with `SkyFactor` and
  `SkyLightColor` the `visual/sky_light_factor` and `visual/sky_light_color`
  attributes (now read from the jar's timeline, `EnvironmentState`), read at
  the 8-bit level of the RGBA8 lightmap and decoded with x^2.2. The light keeps
  the client's sky's directions: it is the client's sky with nothing drawn in
  it, scaled, plus the least uniform veil that makes its cosine-weighted mean
  over the upper hemisphere exactly that colour (scale up to Chunky's
  `Sky.MAX_INTENSITY` 50, the engine's rule).
- The lens sees the client's own sky at the tick: the quick-mode sky (the
  client's `SkyRenderer` and `AtmosphericFogEnvironment.getBaseColor`
  evaluated per direction) with its disc, fog, sunrise fan, sun, moon and
  stars, drawn on the host into a 2048 x 1024 equirectangular map.

Both maps go to every backend in the existing `sky` buffer;
`Params::sky_map` (a new vec4, 416 bytes) carries their sizes. The kernel
reads the lens's map before a path's first diffuse bounce and the light's
after (`integrator::sky_lens`, `sky_light`, a bilinear `map_lookup`,
mirrored line for line in pathtrace.wgsl; CUDA runs the Rust kernel).

Two departures from the engine, both because Lumenwright owns its kernel or
read the client again:
- Chunky feeds one map to the lens and to the light, so the engine's lens
  sees the veil too (a pale noon zenith). Here only the light carries it.
- The engine's clear colour leans toward the sky colour by
  1 - clamp(min(512/16, 12)/32, 0.25, 1)^0.25 = 0.218. The client's
  `getBaseColor` calls `Mth.clampedLerp(x/32, 0.25, 1)`, and clampedLerp's
  bytecode is (delta, start, end): the weight is 1 - 0.53125^0.25 = 0.146,
  as Lumenwright's quick sky already had. A test now pins it.
The sun is drawn at every altitude, as the client's `renderSunMoonAndStars`
draws it (no altitude test in its bytecode); the engine draws it from -4.29°.

A jar without environment attributes (before 1.21.11) is refused under the
game's sky, naming `--sky chunky`.

Tests: kernel `the_sky_maps_are_read_bilinearly` (texel centres, the seam,
the poles, the second map), `the_lens_sees_one_map_and_a_bounce_is_lit_by_the_other`
(a white top face under a light map of 0.3 shows 0.3 whatever the lens's map
holds; a lit sun lights it, a black one does not); host
`the_sky_light_is_the_clients_lightmap` (30 points against an f64
transcription of lightmap.fsh within half an 8-bit level; the engine's
0.374446 at tick 12782 within its level), `the_game_sky_casts_the_lightmaps_light`
(the cosine-weighted mean of the light's map, integrated a second way through
the kernel's lookup on a 720 x 180 grid, is the target within 2e-3),
`the_clear_colour_leans_to_the_sky_as_the_client_does`,
`day_cycle_layers_dimension_and_timeline` (the two new attributes); Metal
parity `gpu_draws_the_game_sky_as_the_cpu_does` and two game-sky cases in
`gpu_matches_cpu_in_hq_mode` and `cuda_matches_cpu_in_hq_mode`. Perturbation:
pathtrace.wgsl's `sky_light` reading the lens's map reds both Metal tests
(26/255 in the sky frame, 13.889% mean luminance on the game day case).

Local log (M2 Pro):
test tests::the_sky_maps_are_read_bilinearly ... ok
test tests::the_lens_sees_one_map_and_a_bounce_is_lit_by_the_other ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test assets::environment::tests::colour_helpers_match_argb ... ok
test assets::environment::tests::no_attributes_is_none ... ok
test render::sky::tests::the_sky_light_is_the_clients_lightmap ... ok
test request::tests::the_clear_colour_leans_to_the_sky_as_the_client_does ... ok
test assets::environment::tests::day_cycle_layers_dimension_and_timeline ... ok
test scene::mesh::tests::lightmap_extremes ... ok
game sky at dusk: light [0.13035227, 0.13035227, 0.36859095] cast [0.13037985821113043, 0.13035929900481383, 0.3685891005453283] (scale 2.107643, mean [0.06184742, 0.058470804, 0.10664413], veil [0, 0.0033766143, 0.06823889])
test render::sky::tests::the_game_sky_casts_the_lightmaps_light ... ok
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 74 filtered out; finished in 0.05s
hq sky: largest channel difference 0/255 between CPU and GPU (mean blue 136.5)
test gpu_draws_the_sky_as_the_cpu_does ... ok
hq game sky: largest channel difference 0/255 between CPU and GPU (mean red 167.1)
test gpu_draws_the_game_sky_as_the_cpu_does ... ok
hq showcase: mean luminance differs by 0.001% between CPU and GPU
hq showcase: 0.000% of pixels differ by more than 16/255 between CPU and GPU
hq showcase-dusk: mean luminance differs by 0.000% between CPU and GPU
hq showcase-dusk: 0.000% of pixels differ by more than 16/255 between CPU and GPU
hq showcase-sun: mean luminance differs by 0.000% between CPU and GPU
hq showcase-sun: 0.000% of pixels differ by more than 16/255 between CPU and GPU
test gpu_matches_cpu_in_quick_mode ... ok
hq showcase-game-day: mean luminance differs by 0.000% between CPU and GPU
hq showcase-game-day: 0.000% of pixels differ by more than 16/255 between CPU and GPU
hq showcase-game-dusk: mean luminance differs by 0.000% between CPU and GPU
hq showcase-game-dusk: 0.000% of pixels differ by more than 16/255 between CPU and GPU
hq block-entities: mean luminance differs by 0.000% between CPU and GPU
hq block-entities: 0.000% of pixels differ by more than 16/255 between CPU and GPU
hq items: mean luminance differs by 0.000% between CPU and GPU
hq items: 0.000% of pixels differ by more than 16/255 between CPU and GPU
test gpu_matches_cpu_in_hq_mode ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 10 filtered out; finished in 8.90s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
…at shows mid-grey as the game does

`--mode hq` now draws `--sky game` unless told `--sky chunky`, and its tone
curve defaults by the sky: `filmic-mid-grey` under the game's sky, `gamma`
(Chunky's default) under Chunky's. In the library `HqSkyModel::default()` is
`Game` (render distance 192, the client's 12 chunks) and
`HqOptions::default().tonemap` is `FilmicMidGrey`.

Why the default: HQ mode's `--time` is a Minecraft tick, and the game's sky is
the only sky that is a function of it. Chunky has no time of day: its
Preetham sky keeps a sunset at any sun below the horizon, and the fade to
night Lumenwright put under it was Lumenwright's own rule. The game's sky
takes every value from the client jar at the tick (the timeline, the
lightmap shader, the client's sky drawing), so it holds from noon through
dusk to the night plateau with nothing authored but the veil's rule. It is
also the look Delvewright's engine renders its Chunky scenes with, which is
the standard these renders are compared with.

Why Chunky's stays: it is the frame Chunky renders (the speed benchmark and
the parity tests compare against Chunky's own scene, a Preetham sky and a sun
at 45 degrees), and it is the sky with a sun that casts light and shadow,
which a caller who wants Chunky's look, or states a sun direction for its
shadows, asks for. Under the game's sky `--sun-intensity` and
`--sky-intensity` are refused by name (the game's sun casts no light);
`--sun-altitude` still moves the sun drawn in the sky.

Tests: the parity tests' Chunky cases (`DAY_SUN`, `DUSK_SUN`, `SUN_IN_VIEW`,
the sky-cache frame) now say `--sky chunky`; `cli_png_equals_library_pixels`
compares the CLI's default and the library's game sky; new
`chunky_scales_are_refused_under_the_game_sky`. Local render tests (M2 Pro):
test every_item_definition_in_the_jar_resolves ... ok
test cli_info_and_render ... ok
test hq_cpu_produces_a_lit_image ... ok
test gpu_draws_the_sky_as_the_cpu_does ... ok
test gpu_draws_the_game_sky_as_the_cpu_does ... ok
test quick_mode_draws_entities ... ok
test chunky_scales_are_refused_under_the_game_sky ... ok
test quick_top_down_colours_match_terrain ... ok
test block_entities_render_in_both_modes ... ok
test items_draw_in_both_modes ... ok
test mipmaps_calm_distant_textures ... ok
test gpu_matches_cpu_in_quick_mode ... ok
test sign_text_reads_in_both_modes ... ok
test renders_are_deterministic ... ok
test gpu_matches_cpu_in_hq_mode ... ok
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.85s

The treehouse camp at dusk (tick 12800, 1280 x 720, four bounces, the
engine's emitter settings: intensity 159.003, sampling NONE), Metal at 1024
spp, against the engine's Chunky reference (Chunky 2.5.0-SNAPSHOT.474,
2048 spp, the scene's light and tone written by the engine's own functions
at 0fd300da7). SSIM here is held down by the frames' emitter noise at this
budget; the converged table is in docs/research/game-sky.md:
reference ref/chunky-camp-dusk-2048.png: luma 54.2; sun-band (178, 97, 98) 359° (n=4208); sun-upper (166, 96, 103) 354° (n=7004); away-upper (151, 95, 110) 344° (n=7908)
out/base-dusk.png: disp mean 19.87 p90 124 p99 156 SSIM 0.6807 luma 72.8 (ref 54.2); sun-band (249, 221, 123) 47° (n=4208); sun-upper (230, 217, 147) 51° (n=7004); away-upper (147, 145, 115) 56° (n=7908)
out/c2-dusk-gamma.png: disp mean 14.45 p90 41 p99 126 SSIM 0.6749 luma 52.1 (ref 54.2); sun-band (205, 94, 57) 15° (n=4208); sun-upper (186, 92, 66) 13° (n=7004); away-upper (168, 92, 76) 10° (n=7908)
out/c2-dusk-hable.png: disp mean 11.23 p90 36 p99 86 SSIM 0.6764 luma 51.5 (ref 54.2); sun-band (180, 96, 60) 18° (n=4208); sun-upper (168, 95, 69) 16° (n=7004); away-upper (157, 94, 78) 12° (n=7908)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
… its measurements

docs/research/game-sky.md (new): the method HQ mode's default sky ports from
Delvewright's engine, each value cited or authored, the five places
Lumenwright departs from it, and the comparison with the engine's Chunky
renders. chunky-parity.md now says it covers `--sky chunky`. The README's
HQ description, flag table (`--sky`, `--tonemap filmic-mid-grey`, the
Chunky-only scales) and limitations, CHANGELOG [Unreleased], and
ACKNOWLEDGEMENTS (Delvewright's engine; the grey card) follow.

Measured: the treehouse camp camera, CUDA 16384 spp, four bounces, the
engine's emitter settings, against Chunky 2.5.0-SNAPSHOT.474 at 2048 spp
under the light and tone the engine's own functions (0fd300da7) write.
Tool output, cmp2.py:
== dusk
reference ref/chunky-camp-dusk-2048.png: luma 54.2; sun-band (178, 97, 98) 359° (n=4208); sun-upper (166, 96, 103) 354° (n=7004); away-upper (151, 95, 110) 344° (n=7908)
base-dusk.png: disp mean 18.68 p90 124 p99 156 SSIM 0.7799 luma 73.5 (ref 54.2); sun-band (249, 221, 123) 47° (n=4208); sun-upper (230, 217, 147) 51° (n=7004); away-upper (147, 145, 115) 56° (n=7908)
base-dusk-midgrey.png: disp mean 14.25 p90 90 p99 106 SSIM 0.7946 luma 68.7 (ref 54.2); sun-band (202, 188, 122) 50° (n=4208); sun-upper (193, 186, 141) 52° (n=7004); away-upper (142, 140, 115) 56° (n=7908)
game-dusk-gamma.png: disp mean 9.72 p90 40 p99 126 SSIM 0.8103 luma 56.4 (ref 54.2); sun-band (205, 94, 57) 15° (n=4208); sun-upper (186, 92, 66) 13° (n=7004); away-upper (168, 92, 76) 10° (n=7908)
game-dusk.png: disp mean 7.12 p90 35 p99 86 SSIM 0.8125 luma 56.0 (ref 54.2); sun-band (180, 96, 60) 18° (n=4208); sun-upper (168, 95, 69) 16° (n=7004); away-upper (157, 94, 78) 12° (n=7908)
== day
reference ref/chunky-camp-day-2048.png: luma 105.8; sun-band (213, 212, 204) 53° (n=4208); sun-upper (210, 210, 204) 60° (n=7004); away-upper (212, 211, 204) 52° (n=7908)
base-day.png: disp mean 30.84 p90 65 p99 77 SSIM 0.7267 luma 113.4 (ref 105.8); sun-band (154, 172, 185) 205° (n=4208); sun-upper (139, 172, 196) 205° (n=7004); away-upper (147, 175, 195) 205° (n=7908)
base-day-midgrey.png: disp mean 33.17 p90 68 p99 75 SSIM 0.7416 luma 110.3 (ref 105.8); sun-band (147, 159, 168) 206° (n=4208); sun-upper (135, 159, 174) 203° (n=7004); away-upper (142, 161, 174) 204° (n=7908)
game-day-gamma.png: disp mean 9.67 p90 51 p99 51 SSIM 0.9348 luma 102.4 (ref 105.8); sun-band (182, 208, 255) 219° (n=4208); sun-upper (167, 196, 255) 220° (n=7004); away-upper (176, 203, 255) 219° (n=7908)
game-day.png: disp mean 8.37 p90 47 p99 55 SSIM 0.9321 luma 98.3 (ref 105.8); sun-band (166, 181, 204) 216° (n=4208); sun-upper (156, 175, 204) 216° (n=7004); away-upper (162, 179, 204) 216° (n=7908)
== the engine's choices put back (a86e929 + veil in the lens + clamp(x,0.25,1)), Metal 256 spp
enginelike-dusk.png: disp mean 6.34 p90 30 p99 92 SSIM 0.6631 luma 55.3 (ref 54.2); sun-band (178, 99, 100) 359° (n=4208); sun-upper (166, 97, 105) 353° (n=7004); away-upper (151, 96, 111) 344° (n=7908)
enginelike-day.png: disp mean 3.38 p90 13 p99 42 SSIM 0.8351 luma 106.0 (ref 105.8); sun-band (213, 213, 204) 60° (n=4208); sun-upper (210, 210, 204) 60° (n=7004); away-upper (211, 212, 204) 68° (n=7908)
== noise floor
game-dusk-seed1.png: disp mean 1.45 p90 7 p99 14 SSIM 0.9327 luma 56.0 (ref 56.0); sun-band (180, 96, 60) 18° (n=4208); sun-upper (168, 95, 69) 16° (n=7004); away-upper (157, 94, 78) 12° (n=7908)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
The README's speed table had no controlled variables: quick mode was timed
only on Metal and HQ only on CUDA, day ran at 4096 spp and dusk at 16384,
and Chunky was absent. docs/benchmark.md now holds a design written before
any run (the design section), the tables measured to it, and
the instruments by revision; the README links it in one line, and its two
"Measured on" sections and "HQ mode and Chunky on one frame" move there
(the anchors resolve on the new page; the old speed table, measured at
0b39f8f, is replaced by this one).

# Benchmark design

Written before any run of this benchmark. Every number in the tables comes from this design;
a cell that cannot be measured is marked n/a with its reason.

## Instruments

- Lumenwright: the `lumenwright` command built from `f291590` (the code head of
  `feat/lw-game-sky`; later commits on the branch are documentation), `--release`; on the PC
  with `--features cuda` and the PTX from `scripts/build-ptx.sh` at the same revision.
- Chunky: `chunky-core-2.5.0-SNAPSHOT.474.g156e2bb.jar` (sha256
  `79ea46233cfa4929e738c6074ff8aabf4f8a2e59cfe9925abc3888a782bad15c`) and its libraries,
  run headless (`-render <scene> -f`), the client jar 1.21.11 (sha1
  `ba2df812c2d12e0219c489c4cd9a5e1f0760f5bd`) as its resources. JDK 17 on the Mac, JDK 21 on
  the PC (what each machine has).
- World: the Treehouse Camp save the README's renders use (region files' sha256 list hashes
  to `526fa9df…`, the same on both machines).
- Machines: Mac = Apple M2 Pro (10 CPU cores, 16 GPU cores), macOS; PC = AMD Ryzen 7 7800X3D
  (16 threads) and RTX 4070 Ti SUPER, Linux under WSL2.
- Timers, both recorded for every run: the renderer's own (Chunky's `renderTime`;
  Lumenwright's `render` stage) and the whole command's wall clock (Python `time.time()` on
  the Mac, `/proc/uptime` on the PC), which includes reading the world and, for Chunky,
  starting the JVM and building its octree.
- Runs: three per cell, the median reported with the three values. In question 1 the
  renderers alternate run by run (Chunky, then each Lumenwright backend, three rounds), so a
  load change falls on all of them alike.
- Load: the one-minute load average and the three busiest processes are recorded before every
  run. Other workers share the Mac; a run is not discarded for load, it is reported with it.

## The frames

- **F-chunky**: the whole-camp view, camera 140, 118, 14 looking at 56, 82, 58, vertical
  field of view 60°, 1280 × 720, 625 chunks (`--render-distance 12`), four bounces (Chunky
  `rayDepth` 5), Chunky's Preetham sky and a sun at altitude 45° from the south-east (Chunky
  altitude π/4, azimuth π/4), emitters at intensity 13 sampled `ONE`, gamma tone map,
  250 samples per pixel. Lumenwright: `--sky chunky --tonemap gamma --time 4000
  --sun-altitude 45 --sun-azimuth 135 --spp 250 --max-bounces 4`. Chunky:
  `docs/bench/treehouse-camp-bench.json`. It is the one frame both renderers draw by the same
  algorithm (Chunky cannot draw the game's sky with two maps).
- **F-game**: the same camera, resolution, chunks and bounces under Lumenwright's defaults
  (the game's sky, the mid-grey tone curve, emitters 13 `ONE`), at tick 4000 (day) and
  12800 (dusk).
- **F-quick**: the same camera, resolution and chunks in quick mode at tick 4000.

## Questions

1. **Lumenwright against Chunky on the same machine.** Changes: the renderer (Chunky on the
   CPU; Lumenwright on each backend the machine has). Fixed: F-chunky (frame, camera,
   resolution, 250 spp, four bounces, sky mode, world), the machine; load recorded.
   Mac: Chunky CPU, Lumenwright Metal, Lumenwright CPU. PC: Chunky CPU, Lumenwright CUDA,
   Lumenwright CPU, Lumenwright Vulkan if WSL2 offers a hardware Vulkan adapter.
2. **Lumenwright's backends against each other.** Changes: the backend. Fixed: the frame
   (F-chunky for HQ, the runs of question 1; F-quick for quick mode), the machine; load
   recorded. HQ: as question 1. Quick: Mac CPU and Metal; PC CPU (the CUDA backend has no
   rasterizer and uses the CPU's).
3. **How cost scales with samples.** Changes: spp, at 64, 256 and 1024. Fixed: F-game
   (camera, resolution, bounces, sky mode), the backend (Metal on the Mac, CUDA on the PC),
   the machine; day and dusk each run at every spp, so they compare at the same spp; load
   recorded. The renders' quality budgets (4096 and 16384 spp in the README) are not speed
   cells.

## Tables (bench-table.py over the run logs)

Session 1:
### Q1 and Q2 (HQ): F-chunky, 1280 x 720, 250 spp, four bounces

| machine | renderer | own timer, median (runs) s | whole command, median (runs) s | 1-min load before each run |
|---|---|---|---|---|
| Mac | Chunky, CPU | 267.56 (289.74, 209.34, 267.56) | 275.55 (301.44, 213.62, 275.55) | 21.73, 123.60, 142.03 |
| Mac | Lumenwright, Metal | 33.54 (33.54, 33.81, 32.03) | 33.98 (33.98, 34.86, 32.52) | 156.00, 99.89, 251.06 |
| Mac | Lumenwright, CPU | 211.37 (211.37, 227.01, 146.87) | 211.83 (211.83, 227.35, 147.24) | 149.96, 96.09, 233.06 |
| PC | Chunky, CPU | 78.60 (93.18, 77.60, 78.60) | 82.03 (97.69, 81.50, 82.03) | 8.01, 14.40, 14.38 |
| PC | Lumenwright, CUDA | 6.14 (6.15, 6.05, 6.14) | 6.74 (6.74, 6.64, 6.74) | 13.98, 15.35, 15.66 |
| PC | Lumenwright, CPU | 54.84 (54.67, 54.84, 55.05) | 55.14 (54.97, 55.14, 55.34) | 11.98, 13.14, 13.40 |

Ratios (Chunky's median over Lumenwright's, own timer / whole command):

- Mac, hq-metal: 7.98x / 8.11x
- Mac, hq-cpu: 1.27x / 1.30x
- PC, hq-cuda: 12.80x / 12.17x
- PC, hq-cpu: 1.43x / 1.49x

### Q2 (quick): F-quick, 1280 x 720

| machine | backend | own timer, median (runs) s | whole command, median (runs) s | 1-min load |
|---|---|---|---|---|
| Mac | Metal | 0.05 (0.06, 0.04, 0.05) | 0.33 (0.36, 0.33, 0.33) | 204.90, 204.90, 204.90 |
| Mac | CPU | 0.11 (0.12, 0.11, 0.09) | 0.39 (0.39, 0.40, 0.37) | 204.90, 204.90, 204.90 |
| PC | CPU | 0.14 (0.14, 0.14, 0.13) | 0.48 (0.47, 0.48, 0.48) | 13.84, 13.84, 13.84 |

### Q3: F-game, 1280 x 720, four bounces, own timer (whole command), medians of three, s

| spp | Mac Metal, day | Mac Metal, dusk | PC CUDA, day | PC CUDA, dusk |
|---|---|---|---|---|
| 64 | 5.21 (5.53) | 5.21 (5.54) | 1.07 (1.67) | 1.07 (1.69) |
| 256 | 21.29 (22.24) | 21.50 (21.89) | 4.12 (4.73) | 4.12 (4.74) |
| 1024 | 83.11 (83.45) | 83.50 (83.86) | 16.31 (16.91) | 16.48 (17.10) |

Mac session 2 (Q1 again):
| Mac | Chunky, CPU | 208.31 (179.02, 208.31, 277.95) | 212.33 (183.00, 212.33, 285.99) | 16.37, 74.67, 96.94 |
| Mac | Lumenwright, Metal | 32.61 (32.34, 32.61, 32.93) | 33.08 (32.70, 33.08, 33.47) | 86.59, 84.84, 77.58 |
| Mac | Lumenwright, CPU | 212.86 (131.59, 229.03, 212.86) | 213.39 (132.02, 229.58, 213.39) | 73.67, 75.15, 67.34 |

Mac load (one-minute average) was 16 to 251 across both sessions from other
work on the machine, so the Mac's CPU rows are reported and not used for a
CPU comparison; the PC's load was 8 to 16 on 16 threads. Vulkan on the PC:
n/a (WSL2 gives only a software adapter). The F-chunky Metal frame is
byte-identical to the frame measured at 0b39f8f: display mean 1.66/255,
SSIM 0.9594 against Chunky converged at 4000 spp (Chunky 250 spp: 1.99,
0.9575).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
…s on

lumenwright-kernel 0.1.0 declares rust-version 1.85, but its `if let`
chains (integrator.rs) are stable from 1.88. Measured with
`cargo +<tc> check -p lumenwright-kernel --ignore-rust-version`:
kernel on 1.87: exit=101
error[E0658]: `let` expressions in this position are unstable
kernel on 1.88: exit=0
(and on 1.85, on the PC: exit=101, the same error). The library and the
command declare 1.90: `cargo +1.90 check` passes for both, and 1.89 is
refused (a dependency's own rust-version). The CI comment that said the
crates carry no rust-version now says what they carry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
…t; the rest has its own pages

The README keeps the Treehouse Camp renders and their image licence,
Install, a Quick start (one render command and one library snippet), a
list of the documentation, and the licence. Everything else moved, its
heading text unchanged so its anchor resolves on the page that now holds
it: docs/renders.md (how the renders are drawn, each command and time,
Get the camp, Render), docs/cli.md, docs/library.md (Using the crate,
Library), docs/textures.md, docs/architecture.md, docs/backends.md,
docs/testing.md, docs/limitations.md, docs/releasing.md; the benchmark
moved to docs/benchmark.md in the previous commit.

Install now states only what was checked:
- Rust: `cargo +<tc> check` passes for lumenwright-cli (at v0.1.0, which the
  install command names, and at f291590) and lumenwright on 1.90, and both
  are refused on 1.89; lumenwright-kernel builds on 1.88 and not 1.87 (its
  manifest is fixed in the previous commit). Stated per crate.
- C compiler: `cargo tree -e normal,build` shows `cc` and `ring` under
  lumenwright-cli only; none under lumenwright with or without its default
  features, nor under the kernel.
- WSL2 Vulkan: the old text said wgpu reaches the GPU through dzn with
  WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER=1. On the PC the benchmark ran
  on, `lumenwright backends` reports "vulkan: unavailable (only a software
  Vulkan adapter is available)" with and without the flag, so Install says
  that instead.
The library snippet in docs/library.md had lost the `unifont` field the
Request carries; it has it again. cli install from the tag is kept; the
cli's crates.io publishing is untouched.

Every anchor the old README had resolves (linkcheck over the repository's
Markdown, code blocks skipped):
66 local links in 17 files, 0 broken
#the-treehouse-camp-by-day-and-at-dusk: README.md
#image-licence: README.md
#install: README.md
#using-the-crate: docs/library.md
#quick-start: README.md
#get-the-camp: docs/renders.md
#render: docs/renders.md
#textures-the-chunky-approach: docs/textures.md
#command-line-render: docs/cli.md
#library: docs/library.md
#architecture: docs/architecture.md
#backends: docs/backends.md
#testing: docs/testing.md
#measured-on-an-m2-pro-10-cpu-cores-16-gpu-cores: docs/benchmark.md
#hq-mode-and-chunky-on-one-frame: docs/benchmark.md
#measured-on-an-rtx-4070-ti-super-driver-61692-wsl2: docs/benchmark.md
#known-limitations-v01: docs/limitations.md
#releasing: docs/releasing.md
#license: README.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
The README's commands, unchanged, rendered by f291590 on CUDA (RTX 4070 Ti
SUPER, WSL2), now under HQ mode's defaults: the game's sky lit as the client
lights the tick and the mid-grey tone curve. Each frame was rendered twice
and the two PNGs are byte-identical. The four quick frames, re-rendered by
f291590 on Metal, are byte-identical to the committed ones, so they are not
in this commit. Held for the owner's look; the contact sheet (main / new /
the engine's Chunky reference) is outside the repository.

Run log (hq-showcase.sh):
load 0.95 1.06 3.08 2/325 3453189
treehouse-camp-day-hq a exit=0 monotonic_wall=66.18
  render               65.461s
  total                66.073s
treehouse-camp-day-hq b exit=0 monotonic_wall=66.09
  render               65.494s
  total                65.989s
treehouse-camp-day-hq identical
treehouse-bridge-day-hq a exit=0 monotonic_wall=90.66
  render               90.054s
  total                90.550s
treehouse-bridge-day-hq b exit=0 monotonic_wall=90.64
  render               90.046s
  total                90.541s
treehouse-bridge-day-hq identical
treehouse-camp-dusk-hq a exit=0 monotonic_wall=262.45
  render              261.823s
  total               262.342s
treehouse-camp-dusk-hq b exit=0 monotonic_wall=262.51
  render              261.899s
  total               262.410s
treehouse-camp-dusk-hq identical
treehouse-bridge-dusk-hq a exit=0 monotonic_wall=360.92
  render              360.297s
  total               360.808s
treehouse-bridge-dusk-hq b exit=0 monotonic_wall=360.86
  render              360.238s
  total               360.755s
treehouse-bridge-dusk-hq identical
ALLDONE
exit=0

Quick frames (quick.sh):
treehouse-camp-day-quick a exit=0   total                 1.003s
treehouse-camp-day-quick b exit=0   total                 0.494s
treehouse-camp-day-quick: the two runs are byte-identical
treehouse-camp-day-quick: byte-identical to main's docs/renders/treehouse-camp-day-quick.png
treehouse-camp-dusk-quick a exit=0   total                 0.409s
treehouse-camp-dusk-quick b exit=0   total                 0.490s
treehouse-camp-dusk-quick: the two runs are byte-identical
treehouse-camp-dusk-quick: byte-identical to main's docs/renders/treehouse-camp-dusk-quick.png
treehouse-bridge-day-quick a exit=0   total                 0.497s
treehouse-bridge-day-quick b exit=0   total                 0.398s
treehouse-bridge-day-quick: the two runs are byte-identical
treehouse-bridge-day-quick: byte-identical to main's docs/renders/treehouse-bridge-day-quick.png
treehouse-bridge-dusk-quick a exit=0   total                 0.328s
treehouse-bridge-dusk-quick b exit=0   total                 0.428s
treehouse-bridge-dusk-quick: the two runs are byte-identical
treehouse-bridge-dusk-quick: byte-identical to main's docs/renders/treehouse-bridge-dusk-quick.png

sha1 of the committed frames:
b95b689c5af298b299c3f9621a025842843c9c0a  docs/renders/treehouse-bridge-day-hq.png
876be3b7201f32b33bff0ad3ccf2e0cb606117bb  docs/renders/treehouse-bridge-dusk-hq.png
6df75b35196a258954639c49617092dd11b6f41d  docs/renders/treehouse-camp-day-hq.png
138a00071454425e9908a185f0107bd974b0ea61  docs/renders/treehouse-camp-dusk-hq.png

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
…d the game's at dusk and night

The owner's ruling: daytime keeps Chunky's sun light and shadows, the look
approved before; dusk and night use the game's sky. Both stay selectable.

`SkyLook::ByTime` (`--sky auto`, the default) weighs the two looks by where
the client's `visual/sky_light_factor` at the tick stands between its night
and day values over the day timeline (`sky::day_weight`;
`environment::sky_light_factor_range` samples the track at its keyframes).
The client's 1.21.11 day timeline marks the day plateau itself:
sky_light_factor and sky_light_color hold their day values, and
sunrise_sunset_color its zero alpha, from tick 730 to 11270; the factor
then falls linearly to 0.24 at 13140, holds it to 22860 and rises back by
730. So the weight is 1 (Chunky's look, byte for byte) on that plateau, 0
(the game's) on the night plateau, and linear in ticks on the ramps. At the
camp's dusk tick 12800 it is 0.181818. The mix is authored; its quantity is
the client's.

The mix is one render: Chunky's sky, read through its cache, is weighted
into both of the game's maps (`sky::blend_chunky_sky`), and Chunky's sun
lights and is drawn at the same weight. Light transport is linear in the
sky's and the sun's radiance, so the frame's radiance is the weighted mix of
the two looks'. Each look keeps its own tone curve and emitter intensity
when the caller states none (`HqOptions::tonemap` and `emitter_intensity`
are now `Option`): gamma and 13 for Chunky's, filmic-mid-grey and the game
look's intensity for the game's, the curves mixed in display values
(`post::tonemap_mix`) and the intensities linearly. `--sky chunky` and
`--sky game` force either look; `--sun-intensity`/`--sky-intensity` are
refused only under `--sky game`. `HqSkyModel` is now a struct (look,
render distance, Chunky's sun and sky scales).

No kernel change. Tests: `the_default_sky_follows_the_day_without_a_jump`
(tick 6000 is `--sky chunky` byte for byte, 18000 is `--sky game`; one tick
across either edge of the ramp moves a frame no more than one tick inside a
look does; mid-ramp is neither), `the_day_weight_follows_the_sky_light_factor`,
`the_tone_mix_is_each_curve_at_its_ends`, the range in
`day_cycle_layers_dimension_and_timeline`. Perturbation: a hard switch at
the plateau's edge reds the first (28.673/255 at the edge). Log:
sky by time: one tick moves a frame by 0.040/255 inside Chunky's look, 0.057 at the day plateau's edge and 0.067 at the night's

On the camp (Metal, 64 spp, one tick apart, mean / max / p99 of the 8-bit
difference): 11269->11270 0.059/16/2 (both Chunky's), 11270->11271
0.067/10/2 (across the edge), 13139->13140 0.025/86/1, 13140->13141
0.022/44/1 (both the game's). The day frame at tick 4000 is byte-identical
to main's (38ef002) at 32 spp on Metal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
…at dusk

The owner's ruling: a tunable emitter scale whose default matches the
engine's reference at dusk. `GAME_EMITTER_INTENSITY` = 137.9628 (Chunky's 13
times 10.6125) is the emitter intensity of the game's look, authored by
Lumenwright: neither a vanilla nor a Chunky value. Under the default sky the
intensity is the looks' mixed by the day weight (Chunky's 13 by day), and
`--emitter-intensity` (`HqOptions::emitter_intensity`) takes any value over
it.

Method (fit.py): two CUDA renders of the camp's whole-camp view at tick
12800 under the default sky (day weight 0.181818), 16384 spp, four bounces
(Chunky rayDepth 5, the reference's), emitters sampled ONE (Lumenwright's
default), at intensities 13 and 26 with the same seed, which draw the same
random numbers, so the frame at any intensity k is HDR(13) + (k - 13)/13 x
(HDR(26) - HDR(13)) in radiance. Lantern-lit pixels are those where the
emitters' light at the engine's intensity 159.003 outshines the sky's (Rec.
709 luminance). Objective: their mean display luma under the default tone
mix equals the reference's (Chunky at 2048 spp under the engine's light and
lantern scale, as in docs/research/game-sky.md); bisection.

Log:
lantern-lit pixels: 128564 of 921600 (13.95%)
reference mean display luma on them: 41.993
Lumenwright at 13: 28.622; at 159.003: 45.956
fitted emitter intensity at day weight 0.181818: k = 115.2423 (luma 41.993)
the game look's intensity: (k - w * 13) / (1 - w) = 137.9628 = 13 x 10.6125
lit pixels at k: mean |error| 7.33, rms 9.29 luma
per quarter of the frame (k): 118.5, 114.6, 116.6, 112.6
cross-check: a direct render at k=115.2423 (its own PNG, the default tone mix) reads lit-pixel luma 41.993; reference 41.993
linear model vs direct render, radiance: mean |diff| 6.75e-07, mean radiance 0.1174

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
…its kernel

The owner's ruling for the next release:
- lumenwright-cli loses `publish = false`; README Install is
  `cargo install lumenwright-cli`, with no git-tag install.
- release.yml refuses unless all three crates are at the version, none is
  marked publish = false, and none has the version on crates.io; it
  publishes lumenwright-kernel, lumenwright and lumenwright-cli in that
  order, each once the index serves the one before.
- The workspace is 0.2.0 (lumenwright's pin on the kernel `=0.2.0`, the
  command's on the library `0.2.0`, the PTX crate's lock follows);
  CHANGELOG's section is `[0.2.0] - Unreleased`, dated at release time,
  which the workflow refuses until then.
Nothing is published here. `cargo publish --dry-run --workspace` is run on
this commit and its result is reported with the round.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
…ts' measurements

game-sky.md gains "By the time of day" (the client's day plateau, ticks
730-11270 on sky_light_factor, sky_light_color and the sunset glow's alpha;
the weight; the one-render mix; the continuity measured) and "Lanterns" (the
fit and its method, authored by Lumenwright), and a table of the defaults
against the engine's reference. The README's HQ description, renders.md,
cli.md (`--sky auto|game|chunky`, each look's tone curve and emitter
intensity), the CHANGELOG and a note on the benchmark's F-game follow.

The defaults at 0cd2b54, CUDA 16384 spp, four bounces, cmp2.py:
default-dusk.png: disp mean 8.06 p90 33 p99 86 SSIM 0.8162 luma 59.6 (ref 54.2); sun-band (190, 127, 77) 27° (n=4208); sun-upper (178, 125, 90) 24° (n=7004); away-upper (156, 105, 87) 16° (n=7908)
default-day.png: disp mean 31.46 p90 65 p99 79 SSIM 0.7161 luma 111.8 (ref 105.8); sun-band (154, 172, 185) 205° (n=4208); sun-upper (139, 172, 196) 205° (n=7004); away-upper (147, 175, 195) 205° (n=7908)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
… time of day

The README's commands, unchanged, rendered by 0cd2b54 on CUDA (RTX 4070 Ti
SUPER, WSL2) under the round-2 defaults; each frame rendered twice gave
byte-identical PNGs. The two day frames are Chunky's look and are
byte-identical to main's approved frames (38ef002), so against main only the
two dusk frames change: the game's sky at day weight 0.181818 with the
lanterns at the fitted intensity (115.2423 at that weight). Held for the
owner's look; contact-sheet-2.png is outside the repository.

Run log (hq-showcase.sh):
load 1.96 4.73 5.93 3/329 1293547
treehouse-camp-day-hq a exit=0 monotonic_wall=91.10
  render               90.492s
  total                91.001s
treehouse-camp-day-hq b exit=0 monotonic_wall=91.03
  render               90.453s
  total                90.925s
treehouse-camp-day-hq identical
treehouse-bridge-day-hq a exit=0 monotonic_wall=122.20
  render              121.565s
  total               122.064s
treehouse-bridge-day-hq b exit=0 monotonic_wall=122.17
  render              121.583s
  total               122.066s
treehouse-bridge-day-hq identical
treehouse-camp-dusk-hq a exit=0 monotonic_wall=332.83
  render              332.138s
  total               332.688s
treehouse-camp-dusk-hq b exit=0 monotonic_wall=333.09
  render              332.420s
  total               332.946s
treehouse-camp-dusk-hq identical
treehouse-bridge-dusk-hq a exit=0 monotonic_wall=450.00
  render              448.040s
  total               448.692s
treehouse-bridge-dusk-hq b exit=0 monotonic_wall=447.07
  render              446.319s
  total               446.937s
treehouse-bridge-dusk-hq identical
ALLDONE
exit=0

against main:
treehouse-camp-day-hq.png: byte-identical to 38ef002's
treehouse-bridge-day-hq.png: byte-identical to 38ef002's

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
A third game-sky case in gpu_matches_cpu_in_hq_mode and
cuda_matches_cpu_in_hq_mode: the default sky at tick 12205 (day weight
0.5), where Chunky's sky is mixed into the maps and Chunky's sun lights
and is drawn at half weight, under the same tolerances as the other cases
(mean luminance within 3%, under 2% of pixels off by more than 16/255).

Perturbation, Metal: pathtrace.wgsl drawing no sun sample whenever the
sky's maps are on (the blend's sun skipped on the GPU) passes every earlier
case and reds the new one:
hq showcase-game-dusk: mean luminance differs by 0.000% between CPU and GPU
hq showcase-game-dusk: 0.000% of pixels differ by more than 16/255 between CPU and GPU
hq showcase-auto-mid: mean luminance differs by 3.655% between CPU and GPU
thread 'gpu_matches_cpu_in_hq_mode' (7095725) panicked at crates/lumenwright-cli/tests/render.rs:608:9:
test gpu_matches_cpu_in_hq_mode ... FAILED
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 15 filtered out; finished in 3.89s
perturbed metal exit=101

Local Metal run on the head (M2 Pro):
test gpu_draws_the_game_sky_as_the_cpu_does ... ok
test gpu_draws_the_sky_as_the_cpu_does ... ok
test gpu_matches_cpu_in_quick_mode ... ok
hq showcase-auto-mid: mean luminance differs by 0.001% between CPU and GPU
hq showcase-auto-mid: 0.000% of pixels differ by more than 16/255 between CPU and GPU
test gpu_matches_cpu_in_hq_mode ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 12 filtered out; finished in 9.04s
metal parity exit=0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
`HqSkyModel` became a struct when the sky went by the time of day, so the
intra-doc link `HqSkyModel::Game` no longer resolved and CI's doc job
(`cargo doc --no-deps` with RUSTDOCFLAGS=-Dwarnings) failed. It now links
`SkyLook::Game`. The same command passes locally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ba8LkuKW2bd5C5HCDo7p2
@stellarfeline
stellarfeline merged commit ab4536c into main Oct 21, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant