From d8fa2ce6b00e3ca853e7528754c3af3f1abda7bb Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Sun, 27 Sep 2026 23:56:07 +0300 Subject: [PATCH] fix(render3d): a scatter layer allocates its whole capacity up front again e634177 started a layer at 256 instances and grew it in layer_add and the stream gather, but a game writes l.inst directly (Maroon Lake's track prints, trees and rocks), past what had been grown: "index out of range: 2048, len 2048" in play. layer_new takes its cap up front as before; layer_reserve(l, n) is exported for a caller that writes l.inst itself once layers start small again, opt-in. Co-Authored-By: Claude Opus 5.5 --- packages/ludic.render3d/scatter.ludic | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/ludic.render3d/scatter.ludic b/packages/ludic.render3d/scatter.ludic index 773a1b91..1a3aefdc 100644 --- a/packages/ludic.render3d/scatter.ludic +++ b/packages/ludic.render3d/scatter.ludic @@ -387,9 +387,9 @@ function layer_new(render3d_st: mut Render3dState, model: Model, cap: int, folia l.near = near l.cull = cull l.tint = v3_new(1.0, 1.0, 1.0) - # room for what the layer holds, not for what it might: 45 layers at full capacity up front were - # 0.4 GB, most of it never filled (plan 23 of maroon-lake) - l.have = min(cap, 256) + # the whole capacity up front: a game writes l.inst directly (Maroon Lake's prints, trees and + # rocks do), so a layer cannot start smaller than it may be written to + l.have = cap l.inst = floats(l.have * INST_FLOATS) l.scratch = floats(l.have * INST_FLOATS) l.last_cam = v3_new(100000.0, 0.0, 0.0) @@ -402,7 +402,9 @@ function layer_new(render3d_st: mut Render3dState, model: Model, cap: int, folia return l } -# room for n instances (at most the layer's cap), doubling what there is so a fill costs a few copies +# room for n instances (at most the layer's cap), doubling what there is so a fill costs a few copies; +# a caller writing l.inst itself reserves first +function layer_reserve(l: Layer, n: int) -> void { layer_room(l, n) } function layer_room(l: Layer, n: int) -> void { if n <= l.have { return } var want = max(l.have * 2, n)