ludic/tools/atlas.ludic
Orkuncakilkaya 8fed9add66 refactor(x): per-process scratch dirs, Ludic ports of the LSP test and Forgejo release
- every scratch file lives in `$TMPDIR/x_<pid>/` (tmp_dir/tmp_path in
  prelude.ludic), removed by main's new dispatch() → tmp_cleanup();
  X_KEEP_TMP=1 keeps it. `x test` and `x check-*` may now run together.
- `x test-lsp` (tools/x/lsp_test.ludic) replaces tools/test-lsp.py: the
  whole request stream is framed into one stdin file, the server runs to
  `exit`, and the response stream is parsed back by request id; adds a
  check that ludicc's own error is published on save
- tools/x/forgejo.ludic replaces tools/ci/forgejo_release.py (curl with a
  0600 header file; the token is no longer on the command line;
  LUDIC_FORGEJO_API for forks)
- `x docs-palette --check` regenerates into scratch and compares, so the
  drift guard judges the working tree rather than git HEAD; the generator
  no longer emits a trailing blank line the formatter rejects
- `x test-tools`: exit 2 from test-lsp / test-grammar.js is a visible
  skip, never a pass; the widget-prop test uses the `id: Root` syntax
- tools/test-grammar.js: current vocabulary (property/model/handler/
  prefab/scene/event/become/@Queries), LUDIC_NODE_MODULES, exit 2 on skip
- tools/atlas.ludic rewritten in the current language (it did not compile)
- operators.ludic / os.ludic registered in the suite
- json.ludic: j_quote() writer helper

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-05 01:12:26 +03:00

41 lines
1.5 KiB
Text

# atlas.ludic — render a Kenney tile pack as one index-labeled sheet, so you can
# see which sprite id is which before referring to it in a game.
#
# bin/ludicc --headless tools/atlas.ludic -o build/atlas
# ./build/atlas < /dev/null && sips -s format png build/out.ppm --out atlas.png
#
# A tool written in the language it is a tool for: one Start handler draws every
# tile with its number underneath and quits, and the headless build leaves the
# frame in build/out.ppm.
program Atlas {
const DIR: string = "assets/kenney/tiny-dungeon/Tiles"
const TILE_COUNT: int = 132 # tile_0000.png … tile_0131.png
const COLUMNS: int = 12
const CELL: int = 24
const SPRITE_INSET_X: int = 4 # centre a 16px sprite in a 24px cell
const SPRITE_INSET_Y: int = 2
const LABEL_INSET_X: int = 1
const LABEL_INSET_Y: int = 18
const BACKDROP: int = 0x101018
const LABEL_COLOR: int = 0x8090b0
# "<DIR>/tile_0007.png" — the id is the file's zero-padded number
function tile_path(i: int) -> string {
var digits = Text.from_int(i)
while Text.length(digits) < 4 { digits = "0" + digits }
return `{DIR}/tile_{digits}.png`
}
handler Sheet phase Start {
Screen.clear(BACKDROP)
for i in 0 .. TILE_COUNT {
let x = (i % COLUMNS) * CELL
let y = (i / COLUMNS) * CELL
let id = Assets.image(tile_path(i))
if id >= 0 { Screen.sprite(id, x + SPRITE_INSET_X, y + SPRITE_INSET_Y) }
Screen.draw_number(x + LABEL_INSET_X, y + LABEL_INSET_Y, i, LABEL_COLOR, 1)
}
Screen.show()
quit()
}
}