From c8c230449ee5ad442cfd4aaabd73e86d56b12da5 Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Mon, 28 Sep 2026 15:57:22 +0300 Subject: [PATCH] fix(character, physics, vehicles, wildlife): fact records made at the start (64) with a free list of room for all, as ludic.npc's A frame holding a new peak of facts made a record and grew the free list; now nothing is made until 64 are held at once. The two record-count tests hold the 64. Co-Authored-By: Claude Opus 5.5 --- packages/ludic.character/fact_pool.ludic | 14 ++++++++++++++ packages/ludic.character/index.ludic | 1 + packages/ludic.character/ports.ludic | 4 ++-- packages/ludic.physics/fact_pool.ludic | 14 ++++++++++++++ packages/ludic.physics/index.ludic | 1 + packages/ludic.physics/state.ludic | 4 ++-- packages/ludic.vehicles/fact_pool.ludic | 14 ++++++++++++++ packages/ludic.vehicles/index.ludic | 1 + packages/ludic.vehicles/ports.ludic | 4 ++-- packages/ludic.vehicles/tests/vehicles_test.ludic | 4 ++-- packages/ludic.wildlife/fact_pool.ludic | 14 ++++++++++++++ packages/ludic.wildlife/index.ludic | 1 + packages/ludic.wildlife/species.ludic | 4 ++-- packages/ludic.wildlife/tests/crowd_test.ludic | 4 ++-- 14 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 packages/ludic.character/fact_pool.ludic create mode 100644 packages/ludic.physics/fact_pool.ludic create mode 100644 packages/ludic.vehicles/fact_pool.ludic create mode 100644 packages/ludic.wildlife/fact_pool.ludic diff --git a/packages/ludic.character/fact_pool.ludic b/packages/ludic.character/fact_pool.ludic new file mode 100644 index 00000000..fcb7dfa5 --- /dev/null +++ b/packages/ludic.character/fact_pool.ludic @@ -0,0 +1,14 @@ +# ludic.character/fact_pool.ludic - the facts' records made at the start (CHARACTERFACTS of them) with a free list +# of room for all, so a frame holding a new peak of facts makes nothing until that many are held +const CHR_FACTS: int = 64 + +function chr_fpool_new() -> []CharacterFact { + let l = new []CharacterFact + for i in 0 .. CHR_FACTS { push(l, new CharacterFact) } + return l +} +function chr_ffree_new() -> []CharacterFact { + let l = chr_fpool_new() + List.clear(l) + return l +} diff --git a/packages/ludic.character/index.ludic b/packages/ludic.character/index.ludic index b145db18..e14df30c 100644 --- a/packages/ludic.character/index.ludic +++ b/packages/ludic.character/index.ludic @@ -6,6 +6,7 @@ numbers float import "ludic.base" import "rules.ludic" import "ports.ludic" +import "fact_pool.ludic" import "state.ludic" import "queries.ludic" import "ground.ludic" diff --git a/packages/ludic.character/ports.ludic b/packages/ludic.character/ports.ludic index 306c5dd2..a53a55a0 100644 --- a/packages/ludic.character/ports.ludic +++ b/packages/ludic.character/ports.ludic @@ -104,8 +104,8 @@ export state CharacterState { chr_safe_x: float = 0.0 chr_safe_z: float = 0.0 chr_fact_q: Queue = chr_fact_q__new() - chr_fpool: []CharacterFact = new []CharacterFact # every fact record made, reused once no drain holds it - chr_ffree: []CharacterFact = new []CharacterFact + chr_fpool: []CharacterFact = chr_fpool_new() # every fact record made, reused once no drain holds it + chr_ffree: []CharacterFact = chr_ffree_new() chr_fnext: int = 0 } function chr__top_plain(x: float, z: float, r: float, from_y: float, step: float, base: float) -> float { return base } diff --git a/packages/ludic.physics/fact_pool.ludic b/packages/ludic.physics/fact_pool.ludic new file mode 100644 index 00000000..77bdfc79 --- /dev/null +++ b/packages/ludic.physics/fact_pool.ludic @@ -0,0 +1,14 @@ +# ludic.physics/fact_pool.ludic - the facts' records made at the start (PHYSFACTS of them) with a free list +# of room for all, so a frame holding a new peak of facts makes nothing until that many are held +const PH_FACTS: int = 64 + +function ph_fpool_new() -> []PhysFact { + let l = new []PhysFact + for i in 0 .. PH_FACTS { push(l, new PhysFact) } + return l +} +function ph_ffree_new() -> []PhysFact { + let l = ph_fpool_new() + List.clear(l) + return l +} diff --git a/packages/ludic.physics/index.ludic b/packages/ludic.physics/index.ludic index df3b930b..4de40a96 100644 --- a/packages/ludic.physics/index.ludic +++ b/packages/ludic.physics/index.ludic @@ -5,6 +5,7 @@ numbers float import "ludic.base" import "native.ludic" import "state.ludic" +import "fact_pool.ludic" import "shape_ids.ludic" import "owned.ludic" import "shapes.ludic" diff --git a/packages/ludic.physics/state.ludic b/packages/ludic.physics/state.ludic index 1ef9edb2..ba01b327 100644 --- a/packages/ludic.physics/state.ludic +++ b/packages/ludic.physics/state.ludic @@ -55,8 +55,8 @@ export state PhysicsState { ph_ids: []int = words(PH_CAP * 2) ph_vals: []float = floats(PH_CAP * 4) ph_facts: Queue = ph_facts__new() - ph_fpool: []PhysFact = new []PhysFact # every fact record made, reused once no drain holds it - ph_ffree: []PhysFact = new []PhysFact + ph_fpool: []PhysFact = ph_fpool_new() # every fact record made, reused once no drain holds it + ph_ffree: []PhysFact = ph_ffree_new() ph_fnext: int = 0 } diff --git a/packages/ludic.vehicles/fact_pool.ludic b/packages/ludic.vehicles/fact_pool.ludic new file mode 100644 index 00000000..84e6d0e9 --- /dev/null +++ b/packages/ludic.vehicles/fact_pool.ludic @@ -0,0 +1,14 @@ +# ludic.vehicles/fact_pool.ludic - the facts' records made at the start (VEHICLEFACTS of them) with a free list +# of room for all, so a frame holding a new peak of facts makes nothing until that many are held +const VE_FACTS: int = 64 + +function ve_fpool_new() -> []VehicleFact { + let l = new []VehicleFact + for i in 0 .. VE_FACTS { push(l, new VehicleFact) } + return l +} +function ve_ffree_new() -> []VehicleFact { + let l = ve_fpool_new() + List.clear(l) + return l +} diff --git a/packages/ludic.vehicles/index.ludic b/packages/ludic.vehicles/index.ludic index 4f51ef00..6e641dda 100644 --- a/packages/ludic.vehicles/index.ludic +++ b/packages/ludic.vehicles/index.ludic @@ -7,6 +7,7 @@ import "ludic.base" import "kinds.ludic" import "table.ludic" import "ports.ludic" +import "fact_pool.ludic" import "state.ludic" import "places.ludic" import "call.ludic" diff --git a/packages/ludic.vehicles/ports.ludic b/packages/ludic.vehicles/ports.ludic index 3e1c04a4..4682596c 100644 --- a/packages/ludic.vehicles/ports.ludic +++ b/packages/ludic.vehicles/ports.ludic @@ -63,8 +63,8 @@ export state VehiclesState { ve_ly: float = 0.0 ve_lz: float = 0.0 ve_fact_q: Queue = ve_fact_q__new() - ve_fpool: []VehicleFact = new []VehicleFact # every fact record made, reused once no drain holds it - ve_ffree: []VehicleFact = new []VehicleFact + ve_fpool: []VehicleFact = ve_fpool_new() # every fact record made, reused once no drain holds it + ve_ffree: []VehicleFact = ve_ffree_new() ve_fnext: int = 0 } function ve__dry(x: float, z: float) -> float { return -10000.0 } diff --git a/packages/ludic.vehicles/tests/vehicles_test.ludic b/packages/ludic.vehicles/tests/vehicles_test.ludic index 71e4cba7..7ff6263e 100644 --- a/packages/ludic.vehicles/tests/vehicles_test.ludic +++ b/packages/ludic.vehicles/tests/vehicles_test.ludic @@ -376,7 +376,7 @@ program VehiclesTest { expect(vehicle_by_nid(vehicles_st, b.nid) == null) } - test "a fed fact a turn, drained each turn, makes a few records and then reuses them" (vehicles_st: mut VehiclesState, vehicles_test_st: mut VehiclesTestState) { + test "a fed fact a turn, drained each turn, makes no record past the ones made at the start" (vehicles_st: mut VehiclesState, vehicles_test_st: mut VehiclesTestState) { fresh(vehicles_st, vehicles_test_st) vehicle_call_for(vehicles_st, 0, VEHICLE_HORSE, 0) let h = vehicle_find(vehicles_st, VEHICLE_HORSE) @@ -386,6 +386,6 @@ program VehiclesTest { fed += count(facts(vehicles_st), VEHICLE_FED) } expect_eq(fed, 1000) - expect(vehicle_fact_records(vehicles_st) <= 4) + expect_eq(vehicle_fact_records(vehicles_st), 64) } } diff --git a/packages/ludic.wildlife/fact_pool.ludic b/packages/ludic.wildlife/fact_pool.ludic new file mode 100644 index 00000000..bf300903 --- /dev/null +++ b/packages/ludic.wildlife/fact_pool.ludic @@ -0,0 +1,14 @@ +# ludic.wildlife/fact_pool.ludic - the facts' records made at the start (WILDFACTS of them) with a free list +# of room for all, so a frame holding a new peak of facts makes nothing until that many are held +const WL_FACTS: int = 64 + +function wl_fpool_new() -> []WildFact { + let l = new []WildFact + for i in 0 .. WL_FACTS { push(l, new WildFact) } + return l +} +function wl_ffree_new() -> []WildFact { + let l = wl_fpool_new() + List.clear(l) + return l +} diff --git a/packages/ludic.wildlife/index.ludic b/packages/ludic.wildlife/index.ludic index 6ce99a14..2b5347db 100644 --- a/packages/ludic.wildlife/index.ludic +++ b/packages/ludic.wildlife/index.ludic @@ -4,6 +4,7 @@ module ludic_wildlife uses ludic_base numbers float import "ludic.base" import "species.ludic" +import "fact_pool.ludic" import "animal.ludic" import "places.ludic" import "port.ludic" diff --git a/packages/ludic.wildlife/species.ludic b/packages/ludic.wildlife/species.ludic index c563dfd3..66834e3b 100644 --- a/packages/ludic.wildlife/species.ludic +++ b/packages/ludic.wildlife/species.ludic @@ -35,8 +35,8 @@ export property WildSpecies { export state WildlifeState { wl_facts: Queue = wl_facts__new() - wl_fpool: []WildFact = new []WildFact # every fact record made, reused once no drain holds it - wl_ffree: []WildFact = new []WildFact # of those, the ones free at the last look + wl_fpool: []WildFact = wl_fpool_new() # every fact record made, reused once no drain holds it + wl_ffree: []WildFact = wl_ffree_new() # of those, the ones free at the last look wl_fnext: []int = words(1) # the next of them to hand out wl_own: WildTable = null # a guest's own animals, put away whole while it draws the host's wl_px: float = 0.0 diff --git a/packages/ludic.wildlife/tests/crowd_test.ludic b/packages/ludic.wildlife/tests/crowd_test.ludic index 97805767..3d896957 100644 --- a/packages/ludic.wildlife/tests/crowd_test.ludic +++ b/packages/ludic.wildlife/tests/crowd_test.ludic @@ -84,13 +84,13 @@ program WildCrowdTest { expect(not wildlife_listed(wildlife_st, a)) } - test "a fact a frame, drained each frame, makes a few records and then reuses them" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) { + test "a fact a frame, drained each frame, makes no record past the ones made at the start" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) { let a = walker(wildlife_st, wildlife_tests_fake_st) for k in 1 .. 3001 { wildlife_moved(wildlife_st, a, 0.0, -3.0 * float(k), 0.0, -1.2) let fs = q_drain(wildlife_facts(wildlife_st)) for i in 0 .. len(fs) { expect_eq(fs[i].what, WILD_PRINT) } } - expect(wildlife_fact_records(wildlife_st) <= 4) + expect_eq(wildlife_fact_records(wildlife_st), 64) } }