From bfec11926fb0f66f92a92af68a2e762f6464a793 Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Sun, 13 Sep 2026 12:46:46 +0300 Subject: [PATCH] fix(render3d): a rim from outline_model goes out when the caller stops asking The queue was only emptied by the next outline_model call, so the last highlighted tree kept its rim after the player looked away. r3d_frame now calls outline_frame, which drops a batch the previous frame closed and nobody reopened. Co-Authored-By: Claude Opus 5 --- changes/outline-queue-stale.md | 6 ++++++ packages/ludic.render3d/actor.ludic | 5 +++++ packages/ludic.render3d/render.ludic | 1 + 3 files changed, 12 insertions(+) create mode 100644 changes/outline-queue-stale.md diff --git a/changes/outline-queue-stale.md b/changes/outline-queue-stale.md new file mode 100644 index 00000000..6775a6f8 --- /dev/null +++ b/changes/outline-queue-stale.md @@ -0,0 +1,6 @@ +bump: patch +type: fix +**A rim from `outline_model` no longer stays on after the caller stops asking** — the queue +was only emptied by the next `outline_model` call, so a game that highlights what the +crosshair is on left the last highlighted tree outlined for good once the player looked +away. `r3d_frame` now drops a batch nobody reopened this frame (`outline_frame`). diff --git a/packages/ludic.render3d/actor.ludic b/packages/ludic.render3d/actor.ludic index fe966945..bf414238 100644 --- a/packages/ludic.render3d/actor.ludic +++ b/packages/ludic.render3d/actor.ludic @@ -230,6 +230,11 @@ function outline_model(m: Model, mat: words, width: int, r: int, g: int, b: int) ac_oq_n += 1 } function outline_clear() -> void { ac_oq_n = 0; ac_oq_closed = true } +# Called at the top of every frame. A batch the last frame closed and nobody has reopened +# since is stale: the caller stopped asking. Without this it was drawn for ever - flush +# closes a batch but only the NEXT outline_model call empties it, so looking away from a +# highlighted tree left its rim on until something else was highlighted. +function outline_frame() -> void { if ac_oq_closed { ac_oq_n = 0 } } function actor_draw() -> void { if ac_actors == null { return } diff --git a/packages/ludic.render3d/render.ludic b/packages/ludic.render3d/render.ludic index 72428e2b..c472f376 100644 --- a/packages/ludic.render3d/render.ludic +++ b/packages/ludic.render3d/render.ludic @@ -124,6 +124,7 @@ function r3d_resize() -> void { print(`r3d: resized to {gl_w}x{gl_h}`) } function r3d_frame(time: int) -> void { + outline_frame() if not r3d_ready { return } if gl_resize_check() { r3d_resize() } # R3D_RESIZE_AT=: rebuild every screen-sized buffer mid-run, as a window resize