Commit graph

1161 commits

Author SHA1 Message Date
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