ludic/changes
Orkuncakilkaya 18755d9057 ludic.devlink: an editor's live link into a running dev build (protocol v1, stage 1)
A package on ludic.base alone. DevlinkNet is the transport (a game binds Udp, the test a fake);
DevlinkWorld's members are the verbs, each defaulting to "not offered" (err unbound): ping, hello (with
Build.schema_hash as 16 hex digits), cam_get / cam_set / cam_release, goto, map_load, time, weather, shot,
pause / resume / step. One request a frame, parsed in place from a fixed 8 KB buffer and answered into
another; map_load, shot and step answer later by id, one at a time, 5 s at most. Loopback senders only,
opened only when enabled() (dev_tools), co-op refuses everything but ping and hello. tests/devlink_test:
each answer byte for byte, bad arguments, a stranger dropped, co-op, the late answers and their timeout,
a closed build that never opens. Compiles; not run (the Master runs the package tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 19:09:59 +03:00
..
a-hidden-body-still-stands-in-the-sun.md fix(render3d): a body hidden from the camera still stands in the sun 2026-09-19 21:32:11 +03:00
a-leaf-is-not-matte.md fix(render3d): a leaf is not matte 2026-09-19 16:41:33 +03:00
a-lens-and-an-edge.md feat(render3d): anti-aliasing that exists, and a lens for the viewfinder 2026-09-19 17:38:25 +03:00
actions.md feat(lang): 0.R1 - actions and reducers 2026-09-25 19:13:46 +03:00
an-aspen-quakes.md feat(render3d): an aspen quakes, and a tree is no longer bent like a bow 2026-09-19 21:13:42 +03:00
anim-ozz.md feat(ludic.anim): ozz-animation 0.17.0 underneath - a skin's skeleton and each clip built at load, sampled to 1e-4 of anim_mix (phase 19.1) 2026-09-28 12:44:49 +03:00
baked-textures.md render3d: baked textures before the PNG - a png_decode takes assets/baked/png, a cut-out load assets/baked/cutouts 2026-09-29 17:30:57 +03:00
bind-variable.md feat(lang): bind a port member that takes nothing to a variable 2026-09-25 13:02:01 +03:00
build-ir-in-temp.md fix(cli): build's IR goes to the run's temp directory, not the project 2026-09-23 17:29:55 +03:00
check-build.md feat(cli): ludic build --check / ludicc --check - check without building 2026-09-25 13:13:42 +03:00
contact-darkening.md feat(render3d): the lake answers to a body standing in it 2026-09-19 20:23:27 +03:00
declared-namespaces.md feat(lang): L6 namespaces declared in Ludic - alias 2026-09-24 02:40:57 +03:00
def-from-resource.md feat(lang): def REGISTRY from "file.lres" - a game fills an open registry from its own file 2026-09-25 07:22:05 +03:00
defaults-views-templates.md feat(ui): ui_scale and ui_box, on-submit, zoom (and a length over a length in calc), on-hold 2026-09-25 03:31:38 +03:00
deps-alias-writes.md feat(cli): ludic deps --writes warns about writes through a local alias 2026-09-25 13:22:37 +03:00
deps-reach.md feat(cli): 0.R4 - ludic deps sees through fn values (widest_reach) and lists the widest functions (--widest N, --reach N) 2026-09-26 06:24:46 +03:00
deps-write-reach.md feat(cli): 0.R5 - ludic deps says what a function can come to change (widest_write_reach, --wreach N); a port member and a registry field reach only themselves 2026-09-26 23:19:54 +03:00
devlink.md ludic.devlink: an editor's live link into a running dev build (protocol v1, stage 1) 2026-09-29 19:09:59 +03:00
dilate-parallel.md render3d: cut-out padding on every core - tex_dilate's rows per pass through Job.parallel_for, bytes unchanged 2026-09-29 17:11:21 +03:00
dispatch-kept-records.md changes: a dispatched action's record kept by the queue 2026-09-28 02:09:35 +03:00
duplicate-definitions.md feat(lang): a name is defined once, a local once per block, and a result is always returned 2026-09-23 23:55:20 +03:00
ecs-growable-stores.md feat(compiler): the built-in ECS's stores grow - 100 000 entities, where 1024 was the wall 2026-09-27 22:53:24 +03:00
editor-schema.md Build.schema_hash(): FNV-1a 64 of the program's own schema (the bytes ludic schema prints), worked out only when a program names it, 0 under ludicc --release, which ludic bundle now passes (Mac and Windows); reseeded 2026-09-29 19:05:28 +03:00
engine-alias-shadow.md fix(lang): a function named like an engine namespace method's target is refused 2026-09-25 05:14:45 +03:00
expect-eq-strings.md fix(test): expect_eq on strings compares their text and prints both on a failure 2026-09-25 19:23:38 +03:00
expect-floats.md fix(test): expect_eq and expect_near compare floats as floats 2026-09-25 05:06:15 +03:00
friend-of.md feat(lang): friend module lab of fishing, data - a friend of the modules it names 2026-09-25 04:12:47 +03:00
function-values.md feat(lang): functions are values (L2), and render3d takes its scene as callbacks 2026-09-24 00:27:26 +03:00
generics.md feat(lang): L5 generic records and functions 2026-09-24 02:21:15 +03:00
inflate-context.md inflate: its context in a caller-owned record, allocation-free per block; the state-backed calls kept 2026-09-29 17:25:16 +03:00
json-write-file.md runtime: Json.write_file, and Json.encode through a kept buffer 2026-09-28 15:32:36 +03:00
leaves-light-and-the-bole.md fix(runtime): the wheel on macOS did nothing, or everything 2026-09-20 01:24:37 +03:00
lexer-literals.md fix(lang): a template inside another's hole, and integer literals past 2^31 - 1 2026-09-25 08:10:46 +03:00
light-air-and-the-hour.md feat(render3d): the air and the light are the hour's, not one constant apiece 2026-09-19 14:42:30 +03:00
light-you-can-see.md feat(render3d): light you can see - sun shafts and valley mist 2026-09-19 16:06:16 +03:00
lint.md feat(tools): L10 ludic-fmt enforces a project's style 2026-09-24 14:38:35 +03:00
listener-return.md fix(events): a listener's return ends that listener, not the dispatch 2026-09-23 17:42:18 +03:00
ludic-deps.md feat(cli): ludic deps - the module graph as the compiler resolved it 2026-09-25 11:16:34 +03:00
ludic-lab.md feat(ludic.lab): the visual lab as a package - a scene on a plate, never a world 2026-09-25 07:48:43 +03:00
math-result-types.md fix(check): a Math.* call has the type the emitter gives it 2026-09-28 14:12:28 +03:00
model-release.md feat(render3d): 23.4 - model_release, shared textures counted, and scatter layers sized to what they hold 2026-09-27 23:34:14 +03:00
module-layers.md feat(lang): layers - module flow in layer app uses base, items 2026-09-25 12:54:15 +03:00
module-scope.md feat(lang): L3 module scope - module, export, friend module 2026-09-24 00:52:12 +03:00
module-uses.md feat(lang): module NAME uses A, B - a module reaches only the modules it names 2026-09-25 04:06:45 +03:00
moltenvk-no-command-pooling.md Os.platform/arch uname once; render3d primes a new buffer's Metal buffer 2026-09-28 13:34:45 +03:00
native-libraries.md feat(pkg): phase 15 - a package can carry a native library 2026-09-26 23:35:45 +03:00
native-notices.md feat(bundle): a native library's licence ships with it - each linked package's native/LICENSE* beside the .exe, in Contents/Resources on macOS 2026-09-27 14:43:16 +03:00
near-fade-spirv.md feat(render3d): Vulkan in a macOS window through MoltenVK; window built-ins take a slice's elements; the NEAR_FADE SPIR-V 2026-09-27 00:52:45 +03:00
numbers-float-strict.md feat(lang): strict numbers in float files; render3d on float 2026-09-23 17:13:25 +03:00
numbers-float.md feat(lang): numbers float - a module whose decimal literals are float 2026-09-23 16:02:11 +03:00
one-wind.md feat(render3d): one wind, and everything in the valley is moved by it 2026-09-19 18:24:43 +03:00
open-registry.md feat(lang): open registry - other modules' defs, in an order imports cannot change 2026-09-25 04:28:34 +03:00
os-platform-once.md Os.platform/arch uname once; render3d primes a new buffer's Metal buffer 2026-09-28 13:34:45 +03:00
package-export-clash.md fix(lang): 0.R4 - ludic.ui's UiAct is its own, and a name that meets a package's export says whose it is 2026-09-26 06:57:35 +03:00
physics-jolt.md feat(physics): phase 16 - ludic.physics over Jolt Physics v5.6.0 2026-09-26 23:41:37 +03:00
ports.md feat(lang): ports - port Clock { ... } in a module, bind Clock { ... } in the app 2026-09-25 04:20:12 +03:00
private-kinds.md feat(lang): a module's private records and events are its own 2026-09-25 11:02:48 +03:00
private-per-module.md feat(lang): a module's private names are its own 2026-09-25 07:08:05 +03:00
prune-late-states.md fix(migrate): 0.R4 - --prune keeps a state declared after a plain parameter; a parameter named twice is refused 2026-09-26 05:32:08 +03:00
queue-owns-count.md feat(base): 0.R4 - a queue keeps its own count, so every package verb takes only its own state; ludic migrate state --prune 2026-09-26 04:19:56 +03:00
rain-that-leaves-something.md feat(render3d): rain that leaves something behind 2026-09-19 19:43:29 +03:00
README.md refactor(cli)!: split the contributor tool out of the ludic CLI 2026-09-05 23:15:12 +03:00
redeclared-local-missing-return.md feat(lang): a name is defined once, a local once per block, and a result is always returned 2026-09-23 23:55:20 +03:00
reducer-reads.md feat(lang): 0.R5 - a reducer writes one state and may read others, declared between its state and the action 2026-09-26 18:23:48 +03:00
registries.md feat(lang): L8 registries by declaration - registry and def 2026-09-24 13:34:51 +03:00
render3d-bc-not-a-target.md fix(render3d): nothing draws into a BC7 texture - sampler binding binds, and compressed images get no mips 2026-09-28 10:34:23 +03:00
render3d-bc-textures.md feat(render3d): 23.3 - a .dds beside a .png is uploaded BC-compressed with its whole mip chain 2026-09-28 01:23:45 +03:00
render3d-chunk-heights.md feat(render3d): terrain_chunk_heights - the ground's B-spline heights a chunk at a time (23.5) 2026-09-28 11:25:21 +03:00
render3d-gltf-cached.md changes: gltf_cached 2026-09-28 11:39:49 +03:00
render3d-height-format.md perf(render3d): the terrain's height and normal in R32F + RG16F, 128 MB where one RGBA32F was 256 2026-09-28 02:31:18 +03:00
render3d-hooks.md feat(lang): functions are values (L2), and render3d takes its scene as callbacks 2026-09-24 00:27:26 +03:00
render3d-moltenvk.md feat(render3d): 22.10 - ludic.render3d carries MoltenVK, so a Mac program has its Vulkan driver 2026-09-28 01:16:26 +03:00
render3d-plan25-vulkan.md render3d: VkAllocationCallbacks counted (R3D_ALLOC_VK), pipeline create infos freed, actor pool at init 2026-09-28 15:46:19 +03:00
render3d-recycle.md render3d: recycle texture and buffer ids, free a released model whole, actor_release 2026-09-28 12:00:53 +03:00
render3d-small-window.md render3d: r3d_small, a renderer sized for a small UI window 2026-09-29 14:23:00 +03:00
render3d-texture-scratch.md render3d: free a texture's create infos and the .dds path it looked for; steady's model at 0 2026-09-28 12:25:02 +03:00
render3d-vulkan-only.md wip(render3d): plan 22.14 - the OpenGL backend removed (suite 306/306, not yet handed over) 2026-09-28 00:30:11 +03:00
render3d-zero-per-frame.md fix(render3d): nothing allocated in the steady state - the Vulkan allocator reuses its records 2026-09-28 11:14:56 +03:00
resources.md feat(lang): L9 resource files - registry ... from 2026-09-24 14:00:20 +03:00
runtime-on-call.md fix(runtime): Random.* in any program; value_* called directly brings the value tree 2026-09-25 04:59:48 +03:00
runtime-temporaries.md runtime: Log, DateTime.format, Input.text, Path, Mime, Fs, Os and Text keep nothing per call 2026-09-28 13:55:49 +03:00
state.md feat(lang): 0.S - components take states in their header; migrate writes them, never inside a name, never outside the programs given, never into a package's state 2026-09-25 17:11:15 +03:00
still-water.md fix(render3d): the meadow is vegetation, and still water reads as water 2026-09-19 18:07:01 +03:00
stream-arena.md render3d: a stream's cache is made with the stream - records and an arena - and evicts in place 2026-09-28 13:26:59 +03:00
string-temporaries.md Os.heap_bytes: the heap without the renderer; string_temps reads it 2026-09-28 12:31:42 +03:00
test-generics.md fix(test): a generic function called from a test block works 2026-09-25 04:46:08 +03:00
test-parallel.md feat(test): ludic test -j N runs tests side by side 2026-09-25 11:38:09 +03:00
test-per-process.md feat(test): ludic test <dir>, each test block in a process of its own 2026-09-25 04:39:55 +03:00
text-to-float.md feat(text): Text.to_float; a void function's return <value> is an error 2026-09-23 19:19:28 +03:00
the-ground-up-close.md fix(render3d): the ground keeps more of its own colour, and the rock keeps all of it 2026-09-19 16:29:17 +03:00
the-world-knows-you-are-there.md feat(render3d): the lake answers to a body standing in it 2026-09-19 20:23:27 +03:00
toolchain-r3-fixes.md fix(lang): the action drain is the program's; --check runs every check a build makes; a registry key named count is refused; name lookups are tables 2026-09-25 23:34:43 +03:00
type-checker.md feat(lang): L4 type checker between parse and emit 2026-09-24 01:34:49 +03:00
ui-press-drain.md fix(ui): 0.R4 - an action a UI button dispatches is reduced before the frame is presented 2026-09-26 07:08:26 +03:00
unknown-type-names.md fix(check): 0.R4 - a misspelled type in a parameter, a result or a field is refused where it is written 2026-09-26 05:58:35 +03:00
unsafe.md feat(lang): L7 memory is safe unless it says unsafe 2026-09-24 12:53:27 +03:00
uses-packages.md feat(lang): packages count under uses; a port of defaults may go unbound 2026-09-25 05:36:11 +03:00
void-return-error.md feat(text): Text.to_float; a void function's return <value> is an error 2026-09-23 19:19:28 +03:00
vulkan-leaks.md fix(render3d): the Vulkan renderer stops leaking as it loads and draws 2026-09-27 23:03:38 +03:00
vulkan-on-macos.md feat(render3d): Vulkan in a macOS window through MoltenVK; window built-ins take a slice's elements; the NEAR_FADE SPIR-V 2026-09-27 00:52:45 +03:00
window-buffers.md feat(render3d): Vulkan in a macOS window through MoltenVK; window built-ins take a slice's elements; the NEAR_FADE SPIR-V 2026-09-27 00:52:45 +03:00
worker-reads-states.md feat(compiler): a Job.parallel_for worker may read a state but not change one 2026-09-27 22:04:59 +03:00
zones.md ludic.zones: a disc per player from their fog, merged into clusters; the simulating packages ask whether a place is simulated 2026-09-29 15:53:23 +03:00

Changesets

A changeset is one small Markdown file describing a single user-facing change, dropped in this directory. ludic-dev release consumes every changeset here into a new CHANGELOG.md section, bumps VERSION, and deletes the consumed files.

Format

bump: minor
type: feat
One or more lines describing the change, in the past-agnostic imperative used in
the changelog. Markdown is fine.
  • bump: — major, minor, or patch (SemVer). The release version is bumped by the highest level among the pending changesets (unless ludic-dev release <level> overrides it).
  • type: — the Conventional Commit type (feat, fix, perf, docs, …). It decides which group the change lands in: feat → Features, fix → Fixes, perf → Performance, and so on, in that order. A type with no known heading gets one named after itself.

Writing the body

The body is markdown and reaches the changelog as markdown: it becomes one list item, with continuation lines indented to stay inside it. Nested bullets, blank lines between paragraphs and inline code all survive.

bump: minor
type: feat
**Tiled map support** — load and draw Tiled maps.

- **TMX/TSX** — the XML formats, decoded to the same intermediate as JSON.
- **Collision** — the `collision` layer projects onto the engine tilemap.

Lead with the thing that changed, not with the mechanism. A reader scanning the release should be able to stop after your first clause.

Adding one

Create a file with a short, unique name, e.g. changes/regex-namespace.md. Any filename works except this README.md, which the release step always skips.

Preview how the next release will read before cutting it — this writes nothing:

ludic-dev release --dry-run