740ac2a879
Merge lang/i18n-data-fill 5d9f9cf2: ludic.audio has one aud_play holding the only Audio.play_at
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:31:17 +03:00
5d9f9cf284
ludic.audio: one call into the runtime's playback - aud_play holds the only Audio.play_at (the one float -> Q16.16 crossing), and aud_emit and aud_ui both go through it; aud_ui had its own play_at since the interface channel, which the game's guard (one play, one play_at) could not hold. README and the module's words follow.
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:24:36 +03:00
a6ce456c60
Merge r3d/tiles-open-fix c18579f7: tiles_open_test asks for what a device would have made, not the frame counter
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:24:13 +03:00
c18579f777
tiles_open_test: "nothing on a device" asks what terrain_from_baked would have made - the coarse height and normal textures and the page pool - not gvk_frame_no, whose default is 1 (env.ludic), not 0: the open path ticks no frame
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:23:36 +03:00
ad7cbd8e2e
Merge r3d/tiles-open-file 42147937: terrain_tiles_open_file - a map's terrain bake opened for questions with no device
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:19:33 +03:00
69adbddb46
Merge lang/i18nhandlers 56762050: the key check walks @On listeners, hooks, tests, computed fields and scenes; reseeded
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:19:33 +03:00
42147937b2
render3d: terrain_tiles_open_file(path, key, version, half, ox, oz) - a map's baked tiles opened for the CPU questions alone (terrain_height, _file, _smooth, terrain_ortho), with no device and no renderer booted: terrain_from_baked's opening without its coarse level on the GPU. False and nothing changed for another bake's key or version, a missing file, or a whole copy already kept (it answers first). tests/tiles_open_test: a bake written with LBAK's header answers its heights and photograph at a map origin of (300, -120), nothing on a device; the refusals leave no file open, and a bake opened after them answers. The hand-written tiles move to tests/fakes/tiles_file.ludic (payload, raw file, bake, the expected answer at an origin, the cache's snapshot), shared with height_file_test
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:13:18 +03:00
56762050fb
i18n: a key used only in a listener counts as used - the key check walked prog but not the bodies kept beside it (@On listeners, the lifecycle hooks, tests, computed fields, scenes), so their keys were never checked against en.po and ludic schema listed them unused (the game's 15 itemuse.* keys, emitted through ItemPlace); they are walked now as privates.ludic walks them. examples/lang/i18n_listen and its schema case (added, not run); reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:12:25 +03:00
744a03bdfa
Merge lang/i18n-data-fill 88823314: L is keys only - a plain string is drawn as it is in every language
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 03:11:16 +03:00
8882331421
ludic.i18n: the English path is out of L (26.9) - a plain string is drawn as it is in every language (a player named Settings stays Settings), a key, a key glued into text and a bracketed line are made as before. The pattern tables, the sentence and padding lookups, Ln, i18n_pattern_count and kr_words' English-argument lookup are gone; a language's .po is read for keys and plurals. Tests move to keys; README and a changeset say so.
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:58:13 +03:00
e2aa928e95
Merge lang/i18nerror 25a57c09: English left is an error under a lang line; ludic.ui's own words are keys; reseeded
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:49:43 +03:00
25a57c099b
i18n 26.9, error mode: English left is an error under a lang line (a template's words, a text attribute's, a choice that reads as words, a @Text row's English), ludic deps still counting english_left; hole counts and undescribed splits stay warnings. ludic.ui's own words are keys - ui_tk(ui_st, k"ui.right_click", plain) for the key field's Right / Middle / Left click and press a key..., its plain text for a program with no translator; the examples' en.po / tr.po carry ui.*, i18n_ui checks clean, rejected/i18n_keys/english_left holds the error, data_missing counts 2; LANGUAGE.md and the changeset; on lang/foundations 2288feeb; reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:45:15 +03:00
490dc0f563
Merge r3d/height-askers 130b9091: only the loaders page; every other terrain question reads the whole copy, a resident slot or the file
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:43:39 +03:00
130b9091d1
render3d: the terrain's questions never page - ter_h and ter_o read a resident tile in place and any other through the file scratch (heights and now the photograph, four tiles each, sized when the tiles open, forgotten when they close), so terrain_height, _smooth, terrain_ortho, the chunk heightfields, ground_fill, grass, water and shadow no longer take slots or move the clock. Only the loaders page: tp_fill reads through tt_h_load / tt_n_load / tt_o_load, and terrain_tiles_prefetch as before. terrain_height_file is now terrain_height, kept as the name callers wrote against. No answer changes: every read was already the whole copy's texel. tests/height_file_test: heights and photograph equal the texels written, resident or not; a whole-map sweep of the questions, and a ground layer's fill over the map (a one-layer LGD2 written in the test), leave the slots, their contents, the clock and the read counts unchanged
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:43:17 +03:00
2288feeb59
Merge lang/i18n-data-fill 96798c0f: ludic.anim transitions go via a one-shot
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:38:41 +03:00
96798c0fbb
ludic.anim: a transition may name a via one-shot - a request from from (the state last asked, or "*") to to goes by it when the rig carries its clip, and the one-shot's next hands on. The game's hiker picked sit_down / stand_up / board_boat / leave_boat in code; the set says it now. A via edge is not an edge for a request's own fade. animset_test holds it, with a via the rig has and one it has not.
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:34:07 +03:00
9a1cae1d52
Merge r3d/height-file c2fc8f78: terrain_height_file - the exact height without touching the tile cache
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:30:26 +03:00
c2fc8f78f2
render3d: terrain_height_file - terrain_height's exact bilinear that never pages: a resident tile is read in place, any other from tt_file into four tiles of scratch of its own (in the state's defaults, forgotten when the file closes), so no slot is taken and no recency bumped - a sweep at boot no longer changes which tiles the cache holds, and so what is drawn from it. With the whole copy it is terrain_height. tests/height_file_test: equal to terrain_height over a grid across many tiles, resident and not, at tile corners and past the edge; a whole-map sweep leaves slot_of, tile_in, ref, the heights, the hand and the read counts unchanged
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:29:55 +03:00
12553edb26
Merge 7c4e6870
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:07:11 +03:00
ea451dfda2
Merge 986fba3586
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:07:11 +03:00
7c4e6870b3
render3d: the blades' density window filled apart from its upload - gb_window_fill (the tiles round the camera's, zeros off the map, the corner) and gb_frame sends it; the same bytes, now readable by a test without a GPU
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:03:43 +03:00
986fba3586
ludic.i18n: inside a bracket an argument's bytes ride raw - trf escapes a 27 or 31 only outside brackets, and the decoder unescapes only there, so a bracketed line carrying a key with holes (Ada's brief: its legend line's escaped arguments) keeps its own escapes whichever way it was put in (a game's txt_key raw, or trf). 81e1f7d8 unescaped inside the bracket and split the legend's arguments out of the brief. nest_test holds a key whose hole holds a key with two holes: bare, bracketed raw, bracketed through trf, and escaped.
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:00:20 +03:00
00b45742d1
Merge lang/i18n-data-fill 81e1f7d8: ludic.i18n's L makes bracketed lines (29/30) itself, outermost first
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 01:48:18 +03:00
81e1f7d8e6
ludic.i18n: a line bracketed inside another (bytes 29 .. 30) is made by L itself - each bracket outermost in, a key whole through keyed() so its escaped arguments stay whole, and a split on 31 never inside a bracket (a game's txt_key puts its nested line raw); a stray bracket draws nothing. The game's tx_L did this alone, so L in a test or anywhere else drew the brackets (26.9's move, made now). nest_test holds it.
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 01:39:44 +03:00
3bf07ce606
Merge lang/builtinnames d4df925b (attrs before export 26b986de + the builtin-name refusal); reseeded, fixpoint 300381
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 01:15:05 +03:00
d4df925b8f
checker: a function named like a built-in a call always takes is refused at its declaration - function words(st, k) compiled and every call became words(n) with a pointer for n (invalid IR, far from the cause); the table is selfhost/check/check_builtins.ludic, emit_call's built-ins no find_fn guard lets a declared function take, and ludic-dev syntax --check holds it to emit_call both ways; every other built-in (buffer, floats, double, ...) yields to a declared function in the checker as it already did in codegen. string_temps' keep and cross_heap_test's keep renamed (hand, keep_cell); rejected/builtin_call_name and functions/builtin_yield with their cases (added, not run); reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 01:10:24 +03:00
26b986de5b
parser: an attribute before export is kept - @ToClients export event E was a local event (the attributes read in front of export were dropped when the declaration was parsed afresh one call down), as were @Sync / @Owned / @Server / @On / @Public ... before export; and export @ToClients event was refused. Attributes and export now read in either order into one declaration, and a wrapper marks what it added exported (g_at_keep goes); examples/networking/net_export and three schema cases (added, not run); reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 01:03:44 +03:00
64adb052b4
Merge commit ' d703d79feb' into lang/foundations
2026-09-30 00:56:43 +03:00
d703d79feb
ludic.i18n: a glued key's name is a-z, 0-9, _ and . only (every key en.po holds), so a word glued on after it is not read as part of it; keys_test: "Not owned. " + a key, and a capital straight after one
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:52:49 +03:00
96c6e27d98
ludic.i18n: a key's text glued into an English line is made where it sits - L decodes each marked name inside a line that is not a key of its own ("A {1}, {2} cm." given a name that is a key, name + "\n" + blurb), in the language in use, then the line takes its old English lookup; kept in the keyed cache. Interim until every such line is a key (26.9). keys_test covers the stop at a sentence's full stop, a key at the head with words after, a mixed argument in a key's hole, and a key whole left alone.
...
Since the data's text became keys (26.4), a game's English patterns that take a table's name (Notify, txt_pat, a concatenation) drew the raw mark and key.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:50:53 +03:00
a3377215e9
ludic.i18n: tr and key_text lose their @alloc_ok - string(k) of a Key is no allocation to the escape analysis now, and key_text's slice is not one either, so both pass arena strict as they stand (trf / trn keep theirs: they make a line)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:48:29 +03:00
01df9b9d77
runtime (macOS): with a layer asked for, the loader is pinned to our MoltenVK whatever the shell set - the SDK's setup-env.sh exports VK_DRIVER_FILES and VK_ICD_FILENAMES at its own, and the one left set loaded a second MoltenVK; VK_DRIVER_FILES overwritten, VK_ICD_FILENAMES cleared, R3D_VK_ANY_DRIVER=1 to keep the shell's
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:47:07 +03:00
47ba741f6d
Merge commit ' 1ab5ca14' into lang/foundations
2026-09-30 00:43:24 +03:00
c3a37bf76c
Merge commit ' 10a394ae' into lang/foundations (nested and list @Text keys derived, trf's trailing "" padding not counted, string(k) no escape site); reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:43:11 +03:00
c9cf202721
Merge commit ' 10a394ae' into lang/i18n-data-fill
2026-09-30 00:41:34 +03:00
1ab5ca14fb
runtime (macOS): MoltenVK opened first, so a process holds one - the SDK's loader in /usr/local/lib loaded its own MoltenVK beside the linked one and the program drew through it; the loader only when a layer is asked for, pinned to ours (VK_DRIVER_FILES, lib/macos-arm64/MoltenVK_icd.json) unless a driver is named. steady's stream round: a 300-cell warm-up, then the least of three 150-cell windows
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:41:27 +03:00
10a394ae6c
compiler: text keys below a row, trf padding and tr's cast (ECS's 26.4 gaps) - a @Text Key in a record nested in a row, or in each item of a list of them, is filled with its derived key <registry>.<row>.<field>.<i>.<field> as a top-level one is, and a @Text []Key a row leaves out takes <...>.0, .1, ... for as many as en.po has (so no .lres spells a key; the manifest and en.po are now read before the parse that fills the rows); field: null is no text; trf / trn's trailing "" literals are padding, not counted against the English's holes; and string(x) of a string or a Key is x itself to the escape analysis, no allocation site, so tr(key) passes arena strict (a template's lone hole still copies); examples/lang/i18n_nested and its feat_case (added, not run); LANGUAGE.md and the changeset; reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:41:05 +03:00
a1419cdd1f
Merge commit ' 603a5bd6' into lang/foundations
2026-09-30 00:40:12 +03:00
2e0a7f0031
Merge commit ' bdda22c' into lang/foundations
2026-09-30 00:39:29 +03:00
da78010281
Merge commit ' 9a0011c' into lang/foundations (a test program holding a phase handler compiles: rt_init called only when the runtime defines it); reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:39:20 +03:00
603a5bd63f
Merge commit ' bdda22c' into lang/i18n-data
2026-09-30 00:35:57 +03:00
9f1273fb32
Merge branch 'lang/foundations' into lang/i18n-data
2026-09-30 00:35:56 +03:00
9a0011c38f
compiler: a test program may hold a phase handler - the test runner called @rt_init whenever the program had systems, and a handler alone makes none (LLVM: use of undefined value '@rt_init'); it calls it only when it exists, as an entry program's main does; a ludic test case with a handler (added, not run); reseeded, bootstrap-cfree fixpoint holds
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:34:34 +03:00
bdda22cb2e
ludic.i18n: a key with holes inside another key's hole survives - an argument's own 31s and 27s are escaped with 27 and the decoder splits on the unescaped ones (trf(k"a", trf(k"b", x))); keys_test holds it
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:32:23 +03:00
86644e6533
packages: the registry text a game fills is keys (Maroon Lake's phase 26.4) - ThingKind.name, GearKind blurb/howto/names, HintCard's words, JobDef title/text/how, NpcLine and NpcChoice text, WeatherKind.name are @Text Key fields (a compiled row that leaves one out takes its derived key, the English is the game's en.po); what a package hands back as text is the key's marked text, "" for none; NpcName.name, NpcChoice.line and SettingDef.text are not text and lose @Text; ludic.i18n's tr/trf/trn/key_text say @alloc_ok (tr is a cast); the packages' tests with key literals (built, not run); changes/text-keys-data.md
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:29:03 +03:00
eaeadc6a52
Merge commit ' f0cf859' into lang/foundations
2026-09-30 00:28:24 +03:00
eb0d3b1846
Merge lang/schemacode (R7, d39a27a) into lang/editortools, so R9 lands after R7 with nothing to resolve: no conflicts (LANGUAGE.md and test.ludic merged), selfhost/ is R7's (its seeds; bootstrap-cfree fixpoint holds)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:27:16 +03:00
50333571d7
Merge lang/foundations ( 9391695) into lang/editortools: no conflicts, selfhost/ identical to lang/foundations (the seeds unchanged; bootstrap-cfree fixpoint holds at 289532 lines), the help lists R10's --stdin-file, R8's syntax and R9's fmt / remove lines together
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:26:26 +03:00
320ce42626
ludic remove <module> and ludic get --json (R9)
...
remove is the inverse of add: the require line leaves package.ludic; the lock keeps exactly what the
remaining requires still reach, read from the store's copy of each locked package.ludic (no
network), so a package another still requires stays locked and what only the removed one brought in
leaves with it; each leaving package loses the ludic_modules/ symlink add made, never the shared
store entry. Refused (exit 1) when package.ludic does not require the module; source still
importing a removed package is a warning. With no store copy to read, only the named module leaves.
get --json diffs the lock before and after in memory and prints {added, removed, changed,
unchanged} on stdout (an entry as the lock records it: name, version, hash, kind, provides; a change
as name, from, to, from_hash, to_hash), the resolver's lines on stderr. Cases added to test-pkg,
not run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:24:49 +03:00
047bdf4189
ludic fmt for editors: --lint --json, and a buffer on stdin (R9)
...
ludic-fmt --lint --json prints the violations --lint reports as one JSON array on stdout,
[{file, line, col, rule, message}] ordered by file, line and column (col where the rule knows it),
the summary on stderr, --lint's exit status, and never rewrites the baseline. ludic-fmt - refuses a
buffer that does not read as Ludic (a string/template/key literal left open, a bracket never closed
or closed by the wrong one) with exit 2 and name:line:col on stderr; - --lint judges a buffer as the
file --stdin-name names (--stdin-rel: that path relative to the project), against its baseline and
lint paths. ludic fmt --lint and ludic fmt - run it from the nearest package.ludic upwards (from
--stdin-name's directory when given). Hooks read nothing and write to stderr under --json or -.
Regression cases added to test-tools and ludic-dev test (fmt_editor_cases), not run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:24:43 +03:00