Commit Graph
4 Commits
Author SHA1 Message Date
adminandClaude Opus 5.5 9ef360ba1b Let the game view show the picture at a chosen scale (#225)
game-maker / gate (push) Successful in 2m57s
game-maker / suite (push) Failing after 9m28s
The game view always stretched the camera picture to fit the pane.
Pixel art came out blurred at odd factors, and there was no way to
see the game at its real size. The view now has a header with a
scale drop-down, and 100 % is the default.

- The header of the new GamePane offers Auto, Fit, 25 %, 50 %,
  100 %, 200 % and 400 %. Auto and Fit show the factor they land
  on, e.g. "Auto · 100%", and follow the pane when it resizes.
- 100 % means one screen pixel per pixel of the camera resolution
  (width x height). The camera zoom scales the world on top of
  that, so a zoomed camera still fills the same frame.
- Auto takes the largest fixed step that fits the whole picture
  and falls back to 25 % when nothing fits. Fit keeps the old
  behaviour.
- A picture larger than the pane is cropped around the camera
  centre. Fixed steps start on a whole pixel so pixel art stays
  sharp at 100 %.
- The choice is kept in the browser like "Play starts". Nothing
  is written into the project.

Found on the way: the first draft applied the step to the world
instead of the camera resolution. The camera zoom then had no
effect at 100 %, which the existing check 12c caught (zoom 1.37
measured as scale 1).

The CI smokes were not run locally, because that would reseed
projects the user works in. All three smoke cameras are 640x360
and fit the 670x383 harness view at 100 %.

Tests:
- ./check.sh: 156 files, 2298 tests, CHECK EXIT 0 (before 2290).
- 8 unit tests in tests/viewport/view.test.ts for whole-pixel
  steps, cropping, Auto and Fit with fallback, and zoomed cameras.
- 7 e2e checks in 03g. e2e 1-17,28,30,38-40: ALL PASSED, 727
  checks.
- Counter-checks: no cropping, no rounding, no factor reported to
  the header, and no zoom share each fail their own tests.
- Check total: 1367 (CI at c1a702b) + 7 = 1374, computed only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 07:02:48 +02:00
adminandClaude Opus 5.5 d444b27fae Let behaviors read and set tilemap cells while the game runs (#135)
game-maker / gate (push) Successful in 2m59s
game-maker / suite (push) Successful in 9m22s
A behavior could move sprites around but had no way to look at or
change the tilemap it was standing on. Doors, breakable blocks and
"is there ground ahead?" checks all need that.

- New nodes Tile at, Set tile, World to cell and Cell to world. The
  conversion honours position, rotation, scale and mirroring of the
  placed map. A small Tile literal node lets a graph compare what it
  read against a fixed tile.
- The layer is picked by name from all tilemap layers in the project
  through a new field kind. "First layer" takes the map's first one.
  Because layer is an input, a text can also be wired in.
- Each placement keeps only its edited cells in liveTilemap.ts,
  layered over the asset's cells. A second placement of the same map
  stays untouched, and the asset itself is never written.
- A read sees a Set tile from earlier in the same flow. Drawing picks
  up the edit at once and neighbouring autotile edges adapt.
- Solids see the edits straight away, so a Move in the same frame
  already hits the new cell. Rapier rebuilds its shapes on the next
  step.
- After Stop the map is back to what was painted. The editor run shows
  the edit in the scene view while it lasts and does not touch the
  project.
- An unwired tilemap input means no map, like Get position. Cells
  outside the grid are refused and done reports false.

Tests:
- ./check.sh: 155 files, 2271 tests, CHECK EXIT 0 (before 2245).
- tests/core/tile-access.test.ts (14), one physics test for a floor
  set at runtime, catalog entries for the five nodes.
- e2e 39,40: all passed, 86 checks (before 81), five new in 40s.
- Counter-checks: collision ignoring edits fails 3 unit tests, the
  solids cache missing same-tick edits fails only the "at once" test,
  drawing ignoring edits fails the 2 drawing checks, the editor run
  not reporting a new tile fails only its check.
- 40s uses a still tile. The animated fixture tile redraws every frame
  and hid the last counter-check at first.
- Check total 1351 + 5 = 1356, computed. CI confirmed 1351 at cb32b4b.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 20:45:29 +02:00
adminandClaude Opus 5 28b1afa7af Panning the scene view no longer redraws the whole scene
game-maker / gate (push) Successful in 2m22s
game-maker / suite (push) Successful in 8m38s
A middle-mouse pan used to run the full redraw on every frame. It
collected every object from the project, cleared and redrew every
shape, re-sorted all children and made Pixi re-upload every buffer,
although only the camera had moved. The user saw the frame rate drop
while panning.

- WorldViewport gets moveCamera(). When zoom and view size are
  unchanged it only moves the world and redraws the overlays drawn in
  screen pixels. collectFrame, the shape redraw and the re-sort drop
  out of a pan frame.
- Every full redraw remembers the box each object is culled by. A pan
  that moves an object across the edge of the view still takes the
  full redraw, so objects appear and vanish as before.
- Grid, selection outlines, rays and the container origin mark move
  into a shared drawOnScreen hook. It runs after every full redraw and
  after every pan. The parent links stay in afterItems because they
  are drawn in world units.
- Wheel zoom keeps the full redraw, because line widths follow the
  zoom. A cache for collectFrame was left out: it would save about
  1 ms and risk stale data.
- debugInfo() reports redraws and cameraMoves, and __gm gets a hook
  that forces a full redraw, so a check can compare against it.

Findings:
- Chrome already coalesces mouse moves to one per frame (500 moves
  gave 183 redraws in 189 frames). A throttle was tried and removed
  again, because its counter-check did not fail.
- A check in module 03 compared the whole gameInfo() object and broke
  on the new counters. It now compares camera, objects and rendering.
- The stall without ?vsync most likely comes from the desynchronized
  context in src/main.ts. It cannot be reproduced headless.

Tests:
- Measured on Jump and Run, main-thread time per frame, 3 runs of 240
  moves: pan 5.7-7.4 ms before, 3.8-4.8 ms after. Plain mouse moves
  stay at 2.1-2.4 ms. 208 of 240 moves took the fast path.
- ./check.sh: 141 files, 2080 tests, exit 0.
- GM_STEPS=1-16,29,42,43: 535 checks, 1 failed (the module 03 test
  above). After the fix GM_STEPS=1-5: all passed, 130 checks.
- 3 new e2e checks in 5d: 12 pan steps give 12 camera moves and 0
  full redraws, pixel rows after the pan match a fresh redraw, a box
  panned out of view and back is drawn again.
- Counter-checks: overlays not redrawn on pan gives "3 of 3 rows
  differ". Edge test disabled keeps the box visible with 0 redraws.
- Check total 1285 (1282 confirmed by CI task 229, plus 3).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 15:38:05 +02:00
rootandClaude Opus 5 11981b40d0 Give the three asset tabs one base, and move the viewports into the editor
src/viewport/ held three classes only src/editor/ ever used, and framing.ts sat
under graph/ although the scene view wants the same bounds sum. The graph, the
texture and the container tab repeated the same header, subscription and
disposal code with two silent divergences: the graph tab said "nothing shown"
with null instead of '', and the texture tab refell back to the first asset on
a selection change but not on a project event.

These arrive together because GraphCanvas ties them: it reads framing from its
new home, hands its fold marks to folding.ts, and its '' change is what
GraphEditor must agree with.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 07:14:38 +02:00