From d3911d4ba83b57ea61cab2a85cfc95efd4b99c13 Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Mon, 28 Sep 2026 16:22:48 +0300 Subject: [PATCH] ludic.compass: the marks' pools made with the state (512), compass_at's empty mark kept; ludic.base imap_clear in place; ludic.things' kept lists through kept_push; ludic.net's once-per-room and STUN log lines declared Co-Authored-By: Claude Opus 5.5 --- packages/ludic.base/ecs_map.ludic | 7 ++++++- packages/ludic.compass/bearing.ludic | 2 +- packages/ludic.compass/capture.ludic | 11 ++++------- packages/ludic.compass/gather.ludic | 14 ++++++++++++-- packages/ludic.compass/marks.ludic | 7 ++++--- packages/ludic.net/room_tick.ludic | 1 + packages/ludic.net/stun.ludic | 1 + packages/ludic.things/chunks.ludic | 2 +- packages/ludic.things/dispatch.ludic | 2 +- packages/ludic.things/facts.ludic | 5 ++++- packages/ludic.things/spare.ludic | 7 +++++-- 11 files changed, 40 insertions(+), 19 deletions(-) diff --git a/packages/ludic.base/ecs_map.ludic b/packages/ludic.base/ecs_map.ludic index c80b7fe5..ca8e9c8c 100644 --- a/packages/ludic.base/ecs_map.ludic +++ b/packages/ludic.base/ecs_map.ludic @@ -67,7 +67,12 @@ export function imap_del(m: IntMap, k: int) -> bool { } export function imap_len(m: IntMap) -> int { return m.n } -export function imap_clear(m: IntMap) -> void { imap_alloc(m, m.mask + 1) } +# every key gone, in place: the arrays are kept at the size they grew to +export function imap_clear(m: IntMap) -> void { + for i in 0 .. len(m.keys) { m.keys[i] = -1 } + m.n = 0 + m.used = 0 +} # room for `n` keys before the map grows, made now export function imap_reserve(m: IntMap, n: int) -> void { diff --git a/packages/ludic.compass/bearing.ludic b/packages/ludic.compass/bearing.ludic index 2b6a8f3f..406dc620 100644 --- a/packages/ludic.compass/bearing.ludic +++ b/packages/ludic.compass/bearing.ludic @@ -8,7 +8,7 @@ export function compass_count(compass_st: CompassState) -> int { # the i-th mark, or an empty one past the end export function compass_at(compass_st: CompassState, i: int) -> CompassMark { - if i < 0 or i >= compass_count(compass_st) { return new CompassMark } + if i < 0 or i >= compass_count(compass_st) { return compass_st.cmp_none } return compass_st.cmp_list[i] } diff --git a/packages/ludic.compass/capture.ludic b/packages/ludic.compass/capture.ludic index e5797dc6..2741e22a 100644 --- a/packages/ludic.compass/capture.ludic +++ b/packages/ludic.compass/capture.ludic @@ -1,10 +1,6 @@ # capture.ludic - someone else wants to know where the providers point (a guide's arrow): until the # end every mark is theirs, whatever the tier, and the frame's list is left alone export function compass_capture_begin(compass_st: mut CompassState) -> void { - if compass_st.cmp_caught == null { - compass_st.cmp_caught = new []CompassMark - compass_st.cmp_cpool = new []CompassMark - } List.clear(compass_st.cmp_caught) compass_st.cmp_cused = 0 compass_st.cmp_capturing = true @@ -13,14 +9,15 @@ export function compass_capture_begin(compass_st: mut CompassState) -> void { # what was caught: the compass's own list and marks, good until the next capture begins export function compass_capture_end(compass_st: mut CompassState) -> []CompassMark { compass_st.cmp_capturing = false - if compass_st.cmp_caught == null { compass_st.cmp_caught = new []CompassMark } return compass_st.cmp_caught } # the capture pool's next mark, filled (one made only when the pool is short) function cmp_catch(compass_st: mut CompassState, x: float, z: float, icon: int, colour: int, tier: int, prio: int, label: string) -> CompassMark { - if compass_st.cmp_cpool == null { compass_st.cmp_cpool = new []CompassMark } - if compass_st.cmp_cused >= len(compass_st.cmp_cpool) { push(compass_st.cmp_cpool, new CompassMark) } + if compass_st.cmp_cused >= len(compass_st.cmp_cpool) { + @alloc_ok("past COMPASS_POOL marks in one capture only, then kept") + push(compass_st.cmp_cpool, new CompassMark) + } compass_st.cmp_cused += 1 return cmp_fill(compass_st.cmp_cpool[compass_st.cmp_cused - 1], x, z, icon, colour, tier, prio, label) } diff --git a/packages/ludic.compass/gather.ludic b/packages/ludic.compass/gather.ludic index 9011d893..fdedfe57 100644 --- a/packages/ludic.compass/gather.ludic +++ b/packages/ludic.compass/gather.ludic @@ -5,7 +5,6 @@ export function compass_begin(compass_st: mut CompassState) -> void { if compass_st.cmp_list == null { compass_st.cmp_list = new []CompassMark compass_st.cmp_back = new []CompassMark - compass_st.cmp_pool = new []CompassMark } List.clear(compass_st.cmp_list) compass_st.cmp_used = 0 @@ -37,7 +36,10 @@ export function compass_end(compass_st: mut CompassState) -> void { # the pool's next mark, filled (one made only when the pool is short) function cmp_take(compass_st: mut CompassState, x: float, z: float, icon: int, colour: int, tier: int, prio: int, label: string) -> CompassMark { - if compass_st.cmp_used >= len(compass_st.cmp_pool) { push(compass_st.cmp_pool, new CompassMark) } + if compass_st.cmp_used >= len(compass_st.cmp_pool) { + @alloc_ok("past COMPASS_POOL marks in one frame only, then kept") + push(compass_st.cmp_pool, new CompassMark) + } compass_st.cmp_used += 1 return cmp_fill(compass_st.cmp_pool[compass_st.cmp_used - 1], x, z, icon, colour, tier, prio, label) } @@ -56,3 +58,11 @@ export function compass_gather(compass_st: mut CompassState) -> void { } export function compass_capturing(compass_st: CompassState) -> bool { return compass_st.cmp_capturing } + +# more marks than any frame has asked for (the tracking view's peak is well under it) +const COMPASS_POOL: int = 512 +function cmp_pool__new() -> []CompassMark { + let xs = new []CompassMark + for i in 0 .. COMPASS_POOL { push(xs, new CompassMark) } + return xs +} diff --git a/packages/ludic.compass/marks.ludic b/packages/ludic.compass/marks.ludic index 75c70294..23bc5046 100644 --- a/packages/ludic.compass/marks.ludic +++ b/packages/ludic.compass/marks.ludic @@ -26,11 +26,12 @@ export state CompassState { cmp_cap: int = 64 cmp_list: []CompassMark = null # this frame's, sorted and culled cmp_back: []CompassMark = null # the list the sort fills, then swapped with cmp_list - cmp_pool: []CompassMark = null # a frame's marks, reused: Ludic frees nothing + cmp_pool: []CompassMark = cmp_pool__new() # a frame's marks, made with the state and reused: Ludic frees nothing cmp_used: int = 0 cmp_capturing: bool = false - cmp_caught: []CompassMark = null # what providers said while someone was listening - cmp_cpool: []CompassMark = null # the capture's marks, reused from one capture to the next + cmp_caught: []CompassMark = new []CompassMark # what providers said while someone was listening + cmp_cpool: []CompassMark = cmp_pool__new() # the capture's marks, reused from one capture to the next + cmp_none: CompassMark = new CompassMark # what compass_at answers past the end cmp_cused: int = 0 cmp_ranges: []float = null cmp_radar_from: int = 2 # marks of at least this tier are blips; the tracked one always is diff --git a/packages/ludic.net/room_tick.ludic b/packages/ludic.net/room_tick.ludic index 9e0a7093..e2412503 100644 --- a/packages/ludic.net/room_tick.ludic +++ b/packages/ludic.net/room_tick.ludic @@ -69,6 +69,7 @@ function net__room_answer(net_st: mut NetState) -> void { net__take_relay(net_st, v) net_st.net__r_state = NET_R_ROOM net_st.net__poll_t = 0.0 + @alloc_ok("once per room") net__log(`room {code}`) net__fact(net_st, NET_ROOM, -1, 0, 0, code) return diff --git a/packages/ludic.net/stun.ludic b/packages/ludic.net/stun.ludic index d0889f3a..4cb94dcb 100644 --- a/packages/ludic.net/stun.ludic +++ b/packages/ludic.net/stun.ludic @@ -51,6 +51,7 @@ function net__stun_packet(net_st: mut NetState, n: int) -> bool { } net_st.net__pub_ip = ip net_st.net__pub_port = port + @alloc_ok("a STUN answer: a few per session") net__log(`outside we are {net__addr_text(ip, port)}`) } o += 4 + ((l + 3) / 4) * 4 diff --git a/packages/ludic.things/chunks.ludic b/packages/ludic.things/chunks.ludic index d337f4ed..67a45fd2 100644 --- a/packages/ludic.things/chunks.ludic +++ b/packages/ludic.things/chunks.ludic @@ -29,6 +29,6 @@ export function things_changed(things_st: ThingsState, since: int, rows: words, List.clear(out) let tb = things_st.th.tab let n = tb_changed_since(tb, since, rows) - for k in 0 .. n { push(out, tb.rec[rows[k]]) } + for k in 0 .. n { kept_push(out, tb.rec[rows[k]]) } return n } diff --git a/packages/ludic.things/dispatch.ludic b/packages/ludic.things/dispatch.ludic index f0a500f3..737bb017 100644 --- a/packages/ludic.things/dispatch.ludic +++ b/packages/ludic.things/dispatch.ludic @@ -54,7 +54,7 @@ export function things_tick(things_st: mut ThingsState, hours: float) -> void { for k in 0 .. TH_COUNT { if ThingKinds[k].tick == null { continue } let rows = ix_rows(things_st.th.kinds, k) - for i in 0 .. len(rows) { push(hs, tb.ent[rows[i]]) } + for i in 0 .. len(rows) { kept_push(hs, tb.ent[rows[i]]) } } for i in 0 .. len(hs) { let r = tb_row(tb, hs[i]) diff --git a/packages/ludic.things/facts.ludic b/packages/ludic.things/facts.ludic index ff3ed08b..76e58800 100644 --- a/packages/ludic.things/facts.ludic +++ b/packages/ludic.things/facts.ludic @@ -9,7 +9,10 @@ function th_fact(things_st: mut ThingsState, what: int, t: Thing) -> void { } var pool = things_st.th_fact_a if things_st.th_fact_on_b { pool = things_st.th_fact_b } - if things_st.th_fact_n >= len(pool) { push(pool, new ThingFact) } + if things_st.th_fact_n >= len(pool) { + @alloc_ok("a pool miss: past the most facts in one drain only, then kept") + push(pool, new ThingFact) + } let f = pool[things_st.th_fact_n] things_st.th_fact_n += 1 f.what = what diff --git a/packages/ludic.things/spare.ludic b/packages/ludic.things/spare.ludic index 9b46fc1a..aa3be26a 100644 --- a/packages/ludic.things/spare.ludic +++ b/packages/ludic.things/spare.ludic @@ -4,7 +4,7 @@ # uid change long after the removal; everything else about it is set back as new const TH_SPARE_LAG: int = 32 -function th_spare_put(things_st: mut ThingsState, t: Thing) -> void { push(things_st.th_spare, t) } +function th_spare_put(things_st: mut ThingsState, t: Thing) -> void { kept_push(things_st.th_spare, t) } # a record for a Thing about to be placed: the oldest spare past the lag, or a new one function th_record(things_st: mut ThingsState) -> Thing { @@ -69,5 +69,8 @@ export function thing_slot(t: Thing) -> int { # spare records made now, up to `n` waiting: a world that will place Things in play takes them # from the first placement instead of making new ones until enough have been removed export function things_spare_warm(things_st: mut ThingsState, n: int) -> void { - while things_spare_count(things_st) < n { push(things_st.th_spare, new Thing) } + while things_spare_count(things_st) < n { + @alloc_ok("at a world's start: the spare records it will place in play") + push(things_st.th_spare, new Thing) + } }