bab9462409
Merge r3d/cb-warm into main (gathering every branch; main's side kept on conflicts)
...
bootstrap / cfree-fixpoint (push) Failing after 26s
ci / build-and-test (push) Failing after 17s
commit-lint / conventional-commits (push) Failing after 10s
docs / build-and-deploy (push) Failing after 9s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:21:21 +03:00
5370507859
Merge r3d/cb-cap into main (gathering every branch; main's side kept on conflicts)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:21:21 +03:00
eeb7a3d5fb
Merge lang/png-jobs into main (gathering every branch; main's side kept on conflicts)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:21:21 +03:00
e72a4d0a13
Merge grass/far into main (gathering every branch; main's side kept on conflicts)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:21:20 +03:00
737d6e1859
wip: uncommitted work gathered before the branch is merged into main
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:18:48 +03:00
8a997fd7ce
ludic.wildlife pins: a tie between thirst and hunger sets off for water (GO_DRINK), as the package does
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:15:54 +03:00
67d477af77
ludic.wildlife: pin every transition of the 15 WILD_* states and the dice each draws (phase 27.2a)
...
Sixteen test programs under tests/*_pins_test.ludic, on today's code, each one tick from a set
state through the public step (wildlife_tick_ground / _bird / wildlife_tick, wildlife_release,
wildlife_new): the state it goes to, its timer, and how many of the package's rolls it took and
which (the next roll is read off a newborn's yaw, compared with a stream of the same seed). IDLE,
WANDER, ALERT, WARY, FLEE, CHARGE, GO_DRINK, GO_FEED, DRINK, APPROACH, EAT, TRAPPED, FLY, LAND,
PERCH; the droppings' roll before them; the newborn's seven (eight for a bird); what the step
leaves alone. tests/pin/ holds the shared step, the dice reader and two species of its own (a tame
horse, a crow that never lands on its own). Compiled, not run here: 27.2 holds to them unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:57:15 +03:00
ab0b84b87e
feat(lang): 27.3 - a reducer on a table's row: reducer T in S.table on A, @Target, Row<T>, @RowVerb, @Column
...
An action names one row of a ludic.base Table<T> by its handle, in a field marked @Target, and
`reducer Deer in Herd.deer on Spook(r: mut Row<Deer>, n: Noise, a: Spook)` runs once, for that row
alone (the table may sit down a path, S.w.tab). The drain resolves the handle (tb_row) and hands the
reducer a Row<T> - new in ludic.base: tb, row, h, rec - that the queue keeps, one per row reducer,
filled in place, so a targeted action allocates nothing; a stale handle runs nothing, and
LUDIC_ACTIONS_LOG=1 prints a line for it (@alloc_ok). Row reducers order among an action's by their
state's name, then the table's path.
Checked at compile time (actions_rows.ludic): the row reaches r.rec and r.h only - r.tb / r.row
refused, the view never assigned, stored, copied or handed on except to a @RowVerb (a function of
the record's own module taking Row<T> first; any other function taking a row is refused); a field
marked @Column (a table column mirrors it) is not written through r.rec; only the module owning the
state declares a row reducer; one @Target, an int, per action; the states between the row and the
action are read. `mut` is allowed on a Row<T> parameter.
ludic schema's code section gains row_reducers (record, table, state, action, target, predicted,
net, module, at) and row_verbs (name, record, module, at), and every action its target; row
reducers are left out of `reducers`. ludic deps and ludic-lsp name a row reducer
`reducer Deer in Herd.deer on Spook`. vocab: @Target, @Column, @RowVerb; docs/language pages;
LANGUAGE.md "A reducer on a row"; examples actions/rows and ten rejects; test.ludic feat, reject and
schema cases (not run); changes/row-reducers.md. Reseeded; bootstrap-cfree fixpoint holds (307497
lines); Maroon Lake's `ludic build --check` is clean against this tree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:14:59 +03:00
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
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
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
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
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
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
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
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
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
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
47ba741f6d
Merge commit ' 1ab5ca14' into lang/foundations
2026-09-30 00:43:24 +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
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
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
f0cf85943f
ludic.i18n: an English value in a key's hole gets the old English lookup (exact, pattern, sentence) while the game still hands English into holes - until its code and data are keys (phase 26.9), where it does nothing; keys_test holds it (exact, a pattern, no line, a number untouched)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:19:46 +03:00
11447b8650
ludic.i18n: tr / trf / trn take the compiler's Key (k"...", kn"..." for trn), built from string(k); keys_test with key literals
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:56:05 +03:00
12e2816480
Merge commit ' 92530c5' into lang/foundations
2026-09-29 23:21:08 +03:00
92530c5db7
render3d: gpu_tex_read_all and gpu_tex_write_all flush the frame first - the read-back is a submit of its own and took the image before the draws that fill it (the sky bake's BRDF table was all zeros at one width in three)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:18:05 +03:00
2fd01d0c9f
Merge commit ' f0096ae' into lang/foundations
2026-09-29 23:17:27 +03:00
f0096aec87
ludic.i18n: keys (phase 26.1) - en.po as the base, tr/trf/trn marked strings made into text by L, keyed plurals, the fallback to English then the key ([[key]] loud in a dev build), the English form beside it
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:16:12 +03:00
b5b3edc6ec
ludic.ui: t(key, holes...) in a template - the key marked (byte 1, a marked key kept as it is) and each hole's value after a byte 31, the text the translator decodes at draw time; joined through the text memo, so nothing is made while it reads the same (phase 26)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:16:05 +03:00
82c652ca31
ludic.ui: an override's path is compared normalised, and an absolute path matches the relative one it ends with - a lab build registers its components as lab/../src/ui/..., so the studio's src/ui/... (or absolute) path matched nothing and the override changed nothing; nothing is normalised while no override stands; examples/library/ui_override_up registers under a .. path as the lab does
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:00:12 +03:00