d22abae476
render3d: gf_hash's comment says what it is - a 64-bit mix (the big constants lex as longs, & 0xFFFFFFFF is & -1); deterministic, and narrowing it would move every painted thing
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:38:39 +03:00
9ce51c2d49
Merge r3d/golden-json 7918103b: the ground_fill golden is valid JSON, and its test fails a file that is not one whole object
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:36:59 +03:00
7918103b8b
render3d: ground_fill_golden.json is valid JSON (the cover and solid blocks each closed one brace too many)
...
gg_cover_json and gg_solid_json ended in plain strings with "}}", which only a template literal reads as one
brace: the cover's closed the top-level object before "solid", and the solid's left a stray "}" at the end.
The committed golden is fixed by hand to what the generator now writes.
ground_fill_test also checks the golden as JSON: one value with nothing after it (Json.parse reads the
first value and ignores the rest, so it alone would not have caught this), an object, its eleven sections
in order. The generator notes what the studio asked: past the density patch an empty tile reads 0 for R and
G (only past the map's edge does a texel clamp), and several clearings multiply.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:36:08 +03:00
176dc79b49
Merge r3d/painted-zones: ground_fill's candidate as a pure function, solid layers with stable ids, clearings as data, and a conformance golden the studio shares
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:25:43 +03:00
87b95625ff
render3d: ground_fill's golden conformance data, generated by tests/gen/ground_fill_golden.ludic (two runs byte-identical)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:25:43 +03:00
530956889b
render3d: a README note on painted ground layers, and the changeset
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:24:23 +03:00
54e267dfa6
render3d: ground_fill's conformance test and the generator of its golden
...
tests/ground_fill_test.ludic compares gg_json (gf_hash over fixed inputs, Math.lerp cases whose order
matters, the yaw as model.vert turns by it, a hand-written density, one cover chunk with a clearing and
one solid chunk) line for line with tests/ground_fill_golden.json, and checks ground_fill draws exactly
the candidates and a solid layer's far bands a subset of band 0. The golden is written by
tests/gen/ground_fill_golden.ludic, run from the repository root; it is not committed here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:24:23 +03:00
e535879262
render3d: ground_fill's candidate is a function of its own; solid layers with stable ids; the trample as clearing discs
...
ground_candidate answers (layer, chunk, band, cell) -> keep, x, z, scale, yaw, seed, wind from pure gf_*
steps and the density read between them; ground_fill draws its answers with the same operations in the
same order. A solid layer fills at step0 and band 0 whatever the camera, a far band drawing a stable
subset (draw 7 under (step0/step_b)^2), each thing an int id from (layer, chunk, cell), listed per chunk
into a caller's GroundSolids or answered by id. r3d_ground_clearing hands the trample over as discs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:23:53 +03:00
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