Commit graph

14 commits

Author SHA1 Message Date
3ac1179440 fix(allocs): ludic.update, steps, effects and telemetry at 0 frame allocs and 0 keeps
ludic.update: whether this copy can update itself is worked out once, when the updater is configured
(the panel asked every frame, building the path to the executable each time); the notes are a list
the state keeps, filled by update_notes_for when the version or the language changes, which the
game calls from its update tick. The feed's address is declared (once, when a check starts).
ludic.steps, ludic.effects, ludic.telemetry: what is left is made on an event and declared with its
bound - an arc's tables, a chapter's columns, a step's fact, an effect's start, end and clear, the
fact pool's growth, the player id, a props record's nesting stack - and two pushes into a caller's
kept list, at most a chapter's steps and the ring's size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 20:13:06 +03:00
2fca1056c6 capacities (25.5a): @max on Physics' bounded lists - every fact pool and free list (1024), the walker slots (64), the shape and body-owner tables (262144), npc's walkers and posts (64)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:49:58 +03:00
21b828fe5c Merge branch 'lang/ecs' into lang/leaks2 2026-09-28 15:45:28 +03:00
045ab0cdf6 ludic.save save_write_tree: a tree straight to disk through Json.write_file, the backup and read-back kept; ludic.telemetry writes its id file the same way
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:42:59 +03:00
f74738a4e0 ludic.telemetry: telemetry_str_open - a named string property the caller writes into the kept buffer (a look's numbers)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:22:26 +03:00
78a70765af feat(ludic.telemetry): objects and lists inside an event's properties, an item made of numbers, and a signature of what was written - all in the kept buffer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:17:20 +03:00
d1bea7f10e fix(ludic.telemetry): nothing made per event - properties and the line written into kept buffers, the queue a ring of bytes made at the start
An event was a tree of values encoded into a new string, a dropped line was never given back, and
every batch and save joined the queue into another. Now: telemetry_props / telemetry_str / _int /
_bool write the properties as JSON into a buffer the state keeps; the line is written beside it,
its time worked out from the clock's seconds (TelemetryWorld.clock_s, was stamp); its bytes go
into one ring (ring_bytes, at most queue_max lines), the oldest overwritten past either; a batch
and the file are written into a third kept buffer and go as bytes (TelemetryTransport.send takes
the bytes and their length; Http.body_bytes, Fs.write_bytes). The facts are pooled.
tests/ring_test: ten thousand events past the cap in lines and in bytes, 0 bytes of heap; the line
exact JSON, escaped, 2000-02-29 right; the batch puts the id in; the file round-trips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:15:12 +03:00
e227b75472 ludic.save, ludic.telemetry: a parsed tree they refuse is freed (23.2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 22:51:06 +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
71735b10a2 feat(base): 0.R4 - a queue keeps its own count, so every package verb takes only its own state; ludic migrate state --prune
ludic.base's Queue<T> carries a QueueTag (its name and pending count): queue_new(name), q_push(q, v),
q_drain(q), q_clear(q) take no BaseState, and core_undrained(tags) names the given queues still holding
facts. A reducer on a package's state can now call that package's verbs (wallet_earn(wallet_st, n)).

ludic migrate state --prune (ludicc --migrate-prune) takes out each state parameter a function no
longer uses, nor anything it calls, and the argument that fills it - including an argument for a
parameter the callee has dropped, which is taken out before the call is checked, so a generic's T is
told by the argument that says it. A reducer keeps its state. --dry-run now counts the edits it would
make. Every package was moved with it: 608 base_st parameters and their arguments, 1889 edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 04:19:56 +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
07505e7ef2 wip(0.S3): the packages migrated by ludic migrate state packages - every package test green
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:02:21 +03:00
e8c1d54a96 feat(ludic.telemetry): an event queue batched to a PostHog-shaped endpoint
Events are encoded once into lines held in memory; a batch is the first
lines joined, with the player id put in where a mark stood, POSTed on
Http's own thread every flush_ms or at flush_at events; a failure keeps
its lines and doubles the wait up to backoff_max; the queue is on disk
every save_ms and read back at the next start; off (the enabled port)
drops the request in flight, empties the queue and deletes the file; and
a run that may not send (can_send) keeps nothing. The player id is the
machine's own id (MachineGuid, IOPlatformUUID, /etc/machine-id) hashed
with the game's salt, else random; it lives in the game's id file beside
whatever else the game keeps there.

Ports: TelemetryWorld (can_send, enabled, now_ms, stamp) and
TelemetryTransport (send, poll, drop; unbound: Http). Config is a record
(host, key, path, lib, queue_file, id_file, id_salt, and the timings).
Facts: TELEMETRY_SENT, _FAILED, _ID. Not a System: it runs from a
launcher's first frame, before any world exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 05:33:16 +03:00