bd2d62ddca
ludic.ui: a select matches a number as a number (its text was made every frame per select); the fired-event queue's lists made with room; ludic.inventory: the counts made at full length at once
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 21:09:08 +03:00
179dd60536
ludic.ui: parsing at load gives back what it does not keep - tpl_words written once into bytes of its own (a string a character before), a stylesheet's stripped text, its error list and each reader freed once read, ex_text's joining node freed when it collapses to one piece or none
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 20:06:25 +03:00
4df15eacfb
ludic.ui: a fired event, a press, a hold and a native's events make nothing - a ring of 16 event objects and one hold object made with the state with their keys, and every ui_fire with no value carries the kept null
...
The last kept bytes of the leak gate's pack, shop and journal screens (memory_final, count mode).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 19:20:01 +03:00
fc22c3f250
ludic.ui: a bar's min, max and value read without ui_attr's new null for a miss (ui_attr_float), and the action answer ring made full with the state - craft's bar kept a block a frame, pack/shop/journal kept one frame filling the ring
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 18:56:10 +03:00
ab6b666fd6
ludic.ui: a scroll box without scroll-top asks ui_attr_has first - ui_attr's miss made a new null every frame on every screen that scrolls (the gate's one kept block a frame on map, shop, journal and craft)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 18:26:46 +03:00
ac8c7b0c0b
ludic.clock: clock_hhmm reads a table of the day's times made with the state; ludic.minimap: minimap_pin past the end is one kept empty mark; ludic.ui: ev_text's memo miss is its own declared function
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:57:30 +03:00
7d85ea3432
@max on the bounded lists: TextRing's slots, the pack's counts and change ring, the net's fact ring, the compass pools, ludic.ui's memo (its 3/4 of MM_CAP), screen pools, answer and pointer rings; ludic.base's intern test holds the table to its cap now that past it is Mem.over
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:48:53 +03:00
54c0feafc2
Merge lang/foundations 6fb5118 into lang/ecs
2026-09-28 16:46:20 +03:00
f8825dc55a
ludic.ui, ludic.i18n: frame_keeps and birth_leaks to 0 - :nth-child's a and b read once per argument, a border-image's miss its own function; typing, the dev dump, parsing, the pointer ring's making, Ln's counted line and the plural header declared
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:46:00 +03:00
6fb5118afd
capacities (25.5a): @max(n) on a list field, and a full table is a failure
...
'@max(64) boxes: []Box' on a property's or a state's field is a promise: the grow path of a push to
that field (only the grow path, so nothing is paid until it doubles) checks it, and growing past n is
reported by the fence - 'PoolState.boxes grew past its @max(16) (it holds 16)' - counted under
count, said under warn, and under fail (a headless or dev build's default) the run ends with exit 87.
Mem.over("what") is the same for a package's own table: ludic.base's StrTable past its most
(sb_intern) and ludic.ui's memo past three quarters of MM_CAP no longer quietly copy per call. The
census counts overflows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:43:02 +03:00
429e419327
ludic.ui, ludic.i18n: frame_allocs to 0 - a wrap, an ellipsis, a tooltip's lines, a text-shadow's colour and a range's value kept by what made them; pointer events from a ring; inline text joined through the memo; the pool's and the state's lists through ui_kept; parse, memo miss, pool miss, lazy start and template errors declared; the translation cache clears in place
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:41:47 +03:00
0f534731a6
ludic.ui: nothing a frame on the pack screen - a key's down/up carry one kept null, scroll asks filtered in place, a shadow's colour joined through the memo, numbers to 65536 made once each
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:22:21 +03:00
6cdef20cc2
ludic.ui: an unmounted component is mounted again rather than made again - its record renewed (a generated renew), its props and model kept; an action's call answers into a ring
...
A prompt that comes and goes as a player walks (co-op's netleak: in_get, cmp_*_new, bd_class, value_slot/put)
made a new record, props and model on every mount, and an action's call answered into a new Val (ev_call_with).
examples/library/ui_remount: two thousand comings and goings hold the heap at 0, and the counter starts at 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:25:55 +03:00
5d71892b7c
ludic.ui: every bar percentage (0% .. 100% to a tenth) made once when the memo starts, so a bar moving never makes its text in play
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:46:47 +03:00
0068411946
ludic.ui: a float in a text's hole written to one decimal from kept texts (its whole part from mm_int, its tenth a literal) - a bar's width moving every frame made a new string every frame, and read 7.470598e-07%
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:29:11 +03:00
50f255eea4
ludic.ui, runtime: the last per-frame allocations in the interface - the top popover found without a list, the popover draw list and the clip stack kept, a select's options in a list the node keeps (and matched to its value without writing the index), a number's text kept on its Value until it changes (value_num_set / Value.num_text), a key's label kept per key code until the layout changes it
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:11:48 +03:00
706c7abc55
ludic.ui: no number made text to be read back - a style handler returns before any text for a key not its own, grow/alpha/animations/scroll read numbers as numbers, el_secs split once per text, a tooltip translated when its title changes
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:43:44 +03:00
4d8526ad7e
ludic.ui, runtime, compiler: a component call's answer is written into a pooled record while the screen is built (call(p, name, args, into); value_into_*), a component root's passes pooled, an icon's atlas and name read in place; reseeded
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 01:51:56 +03:00
ea5eedb5a5
ludic.ui: a hole's text found by its pieces in the memo (built only when it first reads that way), avals left for the attributes read as text, a class's [root] made once, and a dev build's reload lets go of every file it read only to compare
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 01:29:02 +03:00
fa119d234b
ludic.ui, runtime, compiler: an expression's Value comes from the screen's pool while it is built (never a state's start or an action's), true and false shared, calc() terms pooled and read in place, a model's list fields filled in place (value_set_ints/strs/floats/bools); reseeded
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 01:05:35 +03:00
429eeb7754
ludic.ui, compiler: a component's model is filled in place into an object its instance keeps (value_set_*); colours, border-images and a class screen's stub made once; object-fit into a kept list - benchmark 20 -> 10 KB a frame
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:17:47 +03:00
08ac2f1125
ludic.ui: var() values found by their pieces, tpl_words/url/border-image by their text, nine-slices, picking, lifecycle, focus, hover, the event queue and input without a list or record made a frame
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:10:56 +03:00
51a5e06f5c
ludic.ui: props kept an instance, a call's arguments a depth, a loop's index shared, an absent attribute's text without a Value; runtime Value.clear - benchmark 36 -> 20 KB a frame
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:46:18 +03:00
46888b6716
runtime, ludic.ui: a scalar Value is one allocation, not three (lists only for a list or an object); layout and cascade lists kept a depth; small numbers' text made once - benchmark 63 -> 36 KB a frame
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:43:25 +03:00
1d40f6d95a
ludic.ui: splits, words, gradients and keys are made once per text (a bounded memo), sides without a list - benchmark 110 -> 63 KB a frame
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:38:57 +03:00
d1c9359e96
ludic.ui: a screen's nodes and envs are pooled and used again - two generations a screen, reset in place, their own lists emptied not replaced; a tree is good until its screen is built twice more (benchmark 256 -> 110 KB a frame)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:33:48 +03:00
83200a453b
ludic.ui: string matching compares in place - at_alias, lk_in, colours and every s[a..b] == p made a string per position tried, per rule, per element, per frame (a benchmark page: ~3 MB -> 256 KB a frame)
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:27:02 +03:00
9862ec82e3
refactor(packages): 0.R5 - a question no longer starts its state - 64 lazy starts ('if st.x == null { st.x = ... }' inside a getter) are the state's defaults, gear__ensure is gone, and ludic migrate state --tighten took mut off 208 package parameters: things_all, thing_find, gear_charge, gear_level, jobs_state and the rest read
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 00:51:03 +03:00
40a91f39ed
fix(ui): the pointer in the renderer's pixels - macOS reports it in window points, so on Retina every hit landed at half the cursor's position
...
The old kit read Input.mouse_x() * gl_scale; ludic.ui read it raw against a layout sized in
drawable pixels. A backend says how many screen pixels one pointer unit is (pointer_scale);
render3d's is gl_pixel_scale(), 1 on Windows and headless.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 23:31:47 +03:00
259b4d9b35
fix(ui): 0.R4 - an action a UI button dispatches is reduced before the frame is presented
...
ludic.ui runs a frame's presses after drawing it, and what they dispatched waited for the end of the
phase - after the host had presented - so a button's change showed a frame late. Decided: drain, not a
phase per action. ui_show and ui_press drain the queue once the presses have run, so the code after
them and the frame presented next see the change; a host that runs presses some other way calls
drain_actions() before it presents.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 07:08:26 +03:00
d46f0adb5e
fix(lang): 0.R4 - ludic.ui's UiAct is its own, and a name that meets a package's export says whose it is
...
A game's exported UiAct collided with ludic.ui's, which nothing outside ludic.ui uses: it is private
to ludic.ui now, and a private record of one spelling in two modules never clashed. A real clash - a
type named like one a package exports - is still refused, and the message names the package and the
way out (`ludic_ui exports it, and exported names are one namespace - rename this one, or declare it
without export inside a module of your own`).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 06:57:35 +03:00
3a87d02696
packages: ludic.ui's render3d backend threads Render3dState; render3d's settable vars (r3d_dem_path, post_*, grass_*, wt_wade_*, ...) are Render3dState's fields again, not lets
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:11:15 +03:00
7b17b4a1b9
wip(0.S3): outside the runtime, its drawable size, scale, screen and tile size are read and set through its functions; a migration reports such a reference instead of threading the runtime's state
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:47:21 +03:00
19fcf60599
wip(0.S3): packages and examples migrated again from their pre-0.S sources in one run
...
ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic
1804 vars into 126 states, 64 into lets; 23498 edits in 460 files
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:31:34 +03:00
5ffe50ed02
wip(0.S2): migrate - a var nothing writes becomes a let; a state is keyed by its module, directory or program, so every program's plan agrees; paths normalized; program states named SceneDemoState / scene_demo_st; the LSP reads state, mut and entry/handler parameters
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:31:34 +03:00
3eda72e8c2
wip(0.S3): packages and examples migrated in one run - ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:02:45 +03:00
253d8d3632
ui: a renderer installs itself through the UiRenderers registry, not a global's initializer
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:31:48 +03:00
ec9a650e65
feat(ui): ui_scale and ui_box, on-submit, zoom (and a length over a length in calc), on-hold
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 03:31:38 +03:00
077b38e684
feat(ui): a title shows for the keyboard's focus as well as the pointer
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:06:27 +03:00
d15cc79822
feat(ui): a key field takes a mouse button, and is :capturing while it listens
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:04:47 +03:00
6bd3228990
feat(ui): translate="no", and a title of several lines translated whole or line by line
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:03:49 +03:00
7605a0253c
feat(ui): linear-gradient backgrounds, object-fit and aspect-ratio
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:02:49 +03:00
abf45ef9db
feat(ui): scroll-top holds a scroll box at an offset, on-scroll, and ui_scroll_set
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:00:21 +03:00
cf8b9e425e
feat(ui): nine-slice corners clamped to half the box in each direction, cut on whole pixels
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:59:26 +03:00
12f4ba8431
feat(ui): min(), max() and clamp(); insets as percentages of the containing block
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:53:44 +03:00
355201f094
feat(ui): text-fit, line-height, and ems against the font size an element ends with
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:51:41 +03:00
d163bad406
feat(ui): a popover's align along its side, and within= for the bounds it flips against
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:48:58 +03:00
0aad2294ec
feat(ui): pointer events for natives and elements, with capture; on-down and on-up; hits in painting order
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:48:02 +03:00
d2b0413c30
feat(ui): the gamepad moves the focus, presses and goes back; a held direction repeats on the clock
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:42:32 +03:00
a4c7a756f0
feat(ui): a scrollbar held where it was taken, a popover that keeps the mouse, easing that lands
...
- the scrollbar is .ui-scrollbar with a .ui-thumb, styled by the default sheet or a theme; a press
on the thumb holds it at the point it was taken and the pointer moves it in proportion, a press on
the track jumps the thumb's middle there and holds it, and neither presses what is under the bar
(it used to centre the thumb on the pointer and press the row beneath as well);
- while a popover is up only scroll boxes inside it take the pointer, and a press outside it that
closes it forgets any press in progress;
- a transition ends exactly on its value (it stopped a rounding error short, at every frame rate).
Tests: ui_popover_mouse, ui_scrollbar, ui_ease (60/120/180/240 Hz).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:39:28 +03:00