ludic/tools/ludic-cli
Orkuncakilkaya ce5bf0fe0e feat(pack): asset packs, so a built game is a thing you can hand someone
A Ludic game opened its assets by a path relative to the working directory, so
`build/mygame` ran only from the project root and there was nothing to give
anyone but "the binary, and also this whole tree". A game is not one file, but
shipping it has to be.

`ludic pack` writes a .lpak: a header, a name-sorted entry table, a name heap
and the blobs, 16-byte aligned. Entries are stored rather than compressed - PNG,
JPEG and glTF binary arrive compressed already, and a decompressor on the load
path would spend CPU to make the file no smaller.

The reader is spliced into the compiler at the one place every asset in a Ludic
program comes through: file_open. gltf_load, tex_load, Audio.load, Fs.read_text
and the renderer's own shader loads all bottom out there, so routing it through
@lp_pak_open reaches every one of them without any of them knowing. A read of a
packed path becomes an fmemopen over the mapped bytes; everything else is the
fopen it always was. Fs.exists and Fs.size consult the packs too, so a game that
guards a load with Fs.exists keeps finding its assets once they are packed.

The pack is mmap'd rather than read: 165 MB of textures costs one syscall at
boot and pages in only what is touched. @lp_pak_boot runs from
@llvm.global_ctors, before main, so a pack is mounted before the game's first
line - and it reads packs.index, a plain list, so the mount order is explicit
and a later pack shadows an earlier one.

Without a packs.index nothing mounts and every open goes to the filesystem
exactly as before, which is every `ludic run` during development. Packing is a
shipping step and is invisible until you ship.

The compiler reproduces itself byte-exactly and the C-free bootstrap from the
seed still holds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 16:37:23 +03:00
..
assets.ludic feat(gl): OpenGL 4.1 and the ludic.render3d renderer 2026-09-10 03:31:12 +03:00
build.ludic feat(gl): OpenGL 4.1 and the ludic.render3d renderer 2026-09-10 03:31:12 +03:00
checks.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
dev.ludic feat(gl): OpenGL 4.1 and the ludic.render3d renderer 2026-09-10 03:31:12 +03:00
docgen.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
docgen_check.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
docgen_gen.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
forgejo.ludic feat(cli): install in one command, and call the CLI ludic 2026-09-05 22:01:52 +03:00
glgen.ludic feat(gl): OpenGL 4.1 and the ludic.render3d renderer 2026-09-10 03:31:12 +03:00
json.ludic feat(cli): install in one command, and call the CLI ludic 2026-09-05 22:01:52 +03:00
lsp_test.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
main.ludic feat(pack): asset packs, so a built game is a thing you can hand someone 2026-09-10 16:37:23 +03:00
pack.ludic feat(pack): asset packs, so a built game is a thing you can hand someone 2026-09-10 16:37:23 +03:00
pkg.ludic feat(pack): asset packs, so a built game is a thing you can hand someone 2026-09-10 16:37:23 +03:00
pkg_test.ludic feat(cli): install in one command, and call the CLI ludic 2026-09-05 22:01:52 +03:00
prelude.ludic feat(gl): OpenGL 4.1 and the ludic.render3d renderer 2026-09-10 03:31:12 +03:00
project.ludic feat(gl): OpenGL 4.1 and the ludic.render3d renderer 2026-09-10 03:31:12 +03:00
release.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
selfhost.ludic feat(pack): asset packs, so a built game is a thing you can hand someone 2026-09-10 16:37:23 +03:00
selfhost_test.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
test.ludic feat(pack): asset packs, so a built game is a thing you can hand someone 2026-09-10 16:37:23 +03:00
toolchain.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
tools.ludic refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00