Repository navigation
Art pass slices 5-6: minimap, Inter, hit feedback, art checks, screenshots and streaming guide (close) - #54
Merged
Merged
Conversation
Owner decision 15 (2026-10-28): the Mangonel alone flies a smaller banner, scale 450 (1.25 m, 123 permille), centred on the engine, and inspect_gltf check lowers only the Mangonel's floor to 120 permille; every other unit keeps 200. check now prints a unit banner's reach from the unit's centre and notes one past the unit's radius (0.60 m against 0.5 m here, 1.32 m before). Owner decision 16 accepts the Seat flag's placement rule in place of the 1.4x height ratio. ART_STYLE, the visuals.ron comment and the ROADMAP review note record both answers.
fonts.rs installs assets/fonts/InterVariable.ttf over Bevy's built-in Fira Mono at AssetId::default() in Startup, read with std::fs before the first PostUpdate registers fonts; a missing file is a warning and Fira Mono stays. The HUD fit tests drop the 0.6 em monospace helpers and measure every line with Inter's real advance widths through skrifa 0.42.1, a game dev-dependency on the copy parley already locks (no new package in Cargo.lock; one dependency edge on game).
…l-input check Owner decision 7: a 192 px minimap bottom-left over the bottom bar, north up, one texel per tile: terrain, territory and borders (rebuilt in the FixedUpdate step that changed the field's border sources), buildings, every unit (no fog yet), the selection, Town outlines (amber while annexed) and the camera's view trapezoid. It repaints only when the tick, camera, window, selection or territory changed and prints frame_stats: minimap repaints/paint_us on exit. A press or drag moves the camera; a right click issues orders::ground_order, extracted from the right click's ground branch (Move, or SetRally for an own building); a click with attack-move armed issues AttackMove. --minimap-check prints four steps for a real-input driver and judges them. Unit dots are brightened 45% rather than the plan's 15%, which left them unreadable on their own territory.
combat_fx.rs reads SimEvent::Hit after the step and never writes to the sim. The attacker's data picks the look: a building or a unit kind with a range over one tile looses an arrow, the Siege class lobs a stone on a 2 m arc, anything else lunges 0.2 m toward its target and back. Arrows and stones are two shared meshes with two unlit materials from a pool of 256 entities, flown in 0.25 s on the fixed clock the units are interpolated with. Arrows take a low 0.8 m arc: flown straight at chest height they stayed inside the figures between archer and target and did not show in the fight shots. Docs and the ROADMAP slice 5 note record what landed; no acceptance line is ticked.
scripts/art_checks.sh (just art-checks) runs the art pass's local proxies: data-check, the Yeoman swap walkthrough on a scratch copy of data/ (AP2), inspect_gltf check (AP3), check_assets and its self-test (AP1), and five background-mode runs at 1280x720 under lavapipe that save the four sign-off screenshots and the dev panel's, each run's draw calls gated under 500 and its replay verified. scripts/art_drive.sh (just art-drive) takes over the slice 4 and 5 scratch drivers: xdotool clicks every unit of --click-check and performs --minimap-check's four steps. scripts/check_draws.sh is the shared gate on a `frame_stats: draws` line. CI's game-linux job renders art_bench too (tick 200, a 120 s deadline: tick 300 came 76 to 87 s in on the VM) and gates every render smoke's draws under 500.
docs/STREAMING.md is the stream set-up for the dev Mac: the two commands (a match against the Standard bot with --skip-menu, and --spectate --seed 1, the m5_first_match setup decided at tick 26012), why 1280x720, why --draw-stats, the occlusion and focus settings that change what is presented, OBS on Apple Silicon, a five-minute pre-flight that reads the frame_stats exit lines and verifies the replay, and what to keep after the stream. Every flag, path and number was checked against the code: the camera's 35 m default zoom, --fast-forward-to's refusal and --spectate requirement, the replay directory and file name, WinitSettings::game() in Bevy 0.19.1, and the exit lines' names.
…hecklist The five 1280x720 screenshots come from just art-checks under lavapipe, re-encoded losslessly: art-units-40m, art-town-40m, art-battle-60m and art-match-minimap for the owner's sign-off (AP8), and art-dev-panel for the counter (AP7). PLAYTEST gains the art pass's proxies with their observed output, the owner's Mac checklist (AP5's fps and headroom runs, the dev panel, the four shots on the P3 display and as sRGB, the minimap by hand, M3b and M4b line 2 with the models) and the screenshots table. BUILD_TIMES records the slice's measurements, ART_STYLE the measured checklist row and the art pass's milestone row, ui.md the draw-call gate, ARCHITECTURE the scripts and the art pass, and HANDOFF that the pass is ready for the owner's Mac sign-off and the first stream. ROADMAP gains the slice 6 note, the art pass's three good first issues with how to verify them, notes on M3b and M4b line 2 and on M7's minimap, fps and screenshot lines, M7's pulled deliverables and its estimate of 2-3 sessions. No acceptance line is ticked: each tick names the PR that observes it.
install_ui_font now registers the file's bytes in a throwaway FontCx, the way load_font_assets_into_font_collection will, before it replaces Fira Mono at the default font id. Font::from_bytes never parses, so an empty, truncated or garbage InterVariable.ttf used to replace Fira Mono with a font Bevy then registered no family for, and every HUD, menu and overlay text drew nothing with no warning. Such a file is now a warn! and Fira Mono stays (an_unparsable_font_file_keeps_fira_mono). Inter's default figures are proportional, so with FiraMono gone every stock, rate, pop count and countdown that changed by a digit moved the readouts beside it. fonts::hud_font gives every HUD, overlay and menu text Inter's tabular figures (OpenType tnum). every_hud_text_uses_tabular_figures checks the spawned texts' TextFont, and readouts_hold_their_place_when_a_number_changes lays the top bar out with Bevy's own text measure and UI layout (the new test-only ui_test module) and checks that no readout moves when the stocks go from 111 to 444. The fit tests measure figures in their tabular form, read from Inter's GSUB tnum lookups.
…the plugin's schedule minimap_overlaps_no_hud_text rebuilt the message line, the annexation readout and the minimap frame from constants and assumed centred text, so a change to any of those nodes (FlexStart on the message line, say) went unseen. It now spawns the real HUD, message line, readout and minimap at 1280x800 and lays them out with Bevy's text measure and UI layout (ui_test), writing every text each line can show at its longest into the real text node and comparing the laid-out rects. a_new_border_source_repaints_territory_in_the_same_update ran its own Update chain, not MinimapPlugin's. The new the_plugin_shows_a_new_border_in_the_update_of_its_tick runs SimPlugin and MinimapPlugin on their own schedule with a Watchtower placed by the scenario stream and checks, in the very update whose tick gives the tower its land, that the territory layer was rebuilt once and the image shows the won tiles; ordering sync_territory_layer before SimSystems::Step now fails it. The module doc and the right-click test claimed the minimap moves the camera after the outcome. The outcome overlay covers the minimap and takes its presses, so the doc now says so and the test only claims that the handler does not gate camera moves on MatchOver.
…n's processes check_draws.sh --fight accepted fight_max=0, which the game prints when no counted frame fell inside the fight window, and fight_max is never above max, so the flag added no check: a run whose armies never fought passed AP4's fight clause in CI and art_checks. With --fight the field must now be non-zero and the run's `frame_stats: fight` line must show fight frames and its ticks (not `none`). art_checks.sh step 10 matched `pgrep -x eonmark`, which never sees the step 9 dev binary (eonmark-dev), and both scripts matched any Xvfb or eonmark on the machine, so another session's display failed them. art_checks now finds its own games by their `--replay-dir <out>` argument and its own Xvfb by the auth file it gives xvfb-run; art_drive keeps the id and name of each game and Xvfb it starts and checks those.
…abular figures PLAYTEST's caption for art-battle-60m.png named both Towns' buildings, but the shot holds P0's Seat, its eleven buildings and three sites; P1's mirrored Town is off-screen, on the minimap only. The match shot's minimap outlines four Towns, two a player. The sign-off note pointed the owner at the blue buildings' terracotta wood only; the blue Mangonel and Supply Wain are mostly the same wood, and on art-units-40m.png their saturated pixels count more red than blue (343 against 121, 227 against 54), so the note now names them with the same lever. Owner decision 15 also reads "no crowd clipping": scale 450 still reaches 0.10 m past the Mangonel's radius and a banner inside it would miss the 120 permille floor, so ROADMAP, ART_STYLE, inspect_gltf's comment and the sign-off note record that and ask the owner to confirm. ART_STYLE called the scale-450 pole half as thick; it is 450/700, about two-thirds. fog.md now cites the plugin-driven border test for AP6's "within one frame", ROADMAP gains the review's note, and PLAYTEST's proxy rows the re-run evidence, including one art-checks run whose minimap paint p95 read 575 us and art_drive's ungated short-run p95. The five screenshots are retaken by just art-checks at b5f7154 (lossless re-encode), so the HUD shows Inter's tabular figures.
AP1, AP2, AP3, AP7, AP9 and AP10, and M7's check_assets and data-check lines (owner decision 8), each with the evidence observed at the review fix round's head. AP4 and AP6 wait for their Mac clauses, and AP5 and AP8 are the owner's; a Notes line says so.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
The last two slices of the pre-stream art pass (ROADMAP "Art pass (pre-stream)"). After this the game is ready for the owner's Mac sign-off and the first gameplay stream.
Slice 5
orders::ground_order, the same path as a world right click; attack-move works from it too.--minimap-checkplus a real-input xdotool drive.paint_usp95 is 290 to 400 µs on lavapipe.skrifa, a dev-dependency that adds no package to Cargo.lock.combat_fx.rs): arrows on a low arc, Mangonel stones and melee lunges. It is presentation only and runs on the fixed clock.Slice 6
scripts/art_checks.sh(just art-checks) andscripts/art_drive.sh(just art-drive):click_check: ok 16/16andminimap_check: okwith real X input.art_benchandscripts/check_draws.sh --fightgates it below 500 draws. The gate also needs a measured fight window.docs/screenshots/art-*.png, checked row by row against the ART_STYLE checklist.docs/STREAMING.md: a runbook for the owner's stream, with every flag, path and number checked against the code. It covers:--spectate;Review: four lenses (game, visual, tests and CI, docs and rules) raised 18 findings: 15 confirmed and fixed in four commits, 3 refuted.
Determinism: no fixture or
.hashmoved.rules_versionstays 25 andSIM_VERSION17.git diff --stat 15f1616..HEAD -- crates/sim/tests/fixturesis empty.ROADMAP ticks come in one follow-up commit on this PR, naming it:
check_assetsanddata-checklines (owner decision 8), each with its pasted evidence.mode=" clause;Tier
Code PR
just ci: "ci: all steps passed", 849 passed, 21 ignored. machete and deny are not installed locally and nextest fell back tocargo test; CI runs all three.check_drawsfails closed onfight_max=0;f32/f64/HashMap/HashSet/Instantin sim, rules or ai, and no engine dependency outsidecrates/game.Docs PR
typosandscripts/check_trademark.shpass; links are relative.Data PR
data-check:OK rules_version=25 rules_hash=0xfb0d0b8986fc8865 ... models=36.cargo test -p sim: 313 passed, warm 8.7 to 9.1 s.Licensing and disclosure
How to verify
Then on the Mac: PLAYTEST "Owner's Mac checklist (art pass)", which covers the AP5 fps run, the AP8 sign-off, the AP4
mode=re-read and the AP6 minimap by hand. After that,docs/STREAMING.md.Known variance: one
just art-checksrun failed the minimap paint gate with p95 575 µs, and the next passed at 304 µs with no code change. This is VM timing noise, recorded in PLAYTEST, and the Mac reading decides.Generated by Claude Code