feat(base): 0.R4 - a queue keeps its own count, so every package verb takes only its own state; ludic migrate state --prune

ludic.base's Queue<T> carries a QueueTag (its name and pending count): queue_new(name), q_push(q, v),
q_drain(q), q_clear(q) take no BaseState, and core_undrained(tags) names the given queues still holding
facts. A reducer on a package's state can now call that package's verbs (wallet_earn(wallet_st, n)).

ludic migrate state --prune (ludicc --migrate-prune) takes out each state parameter a function no
longer uses, nor anything it calls, and the argument that fills it - including an argument for a
parameter the callee has dropped, which is taken out before the call is checked, so a generic's T is
told by the argument that says it. A reducer keeps its state. --dry-run now counts the edits it would
make. Every package was moved with it: 608 base_st parameters and their arguments, 1889 edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-26 04:19:56 +03:00
parent 8cf4b3fed6
commit 71735b10a2
151 changed files with 58668 additions and 54719 deletions

View file

@ -26,7 +26,7 @@ export function craft_hold_frac(crafting_st: CraftingState, i: int) -> float {
}
# `dt` real seconds of holding; true on the frame it is made
export function craft_hold_run(base_st: mut BaseState, crafting_st: mut CraftingState, dt: float) -> bool {
export function craft_hold_run(crafting_st: mut CraftingState, dt: float) -> bool {
if crafting_st.craft_hold_i < 0 { return false }
if not craft_can(crafting_st.craft_hold_i) {
craft_hold_stop(crafting_st)
@ -36,5 +36,5 @@ export function craft_hold_run(base_st: mut BaseState, crafting_st: mut Crafting
if crafting_st.craft_hold_t <= CraftRecipes[crafting_st.craft_hold_i].hold { return false }
let i = crafting_st.craft_hold_i
craft_hold_stop(crafting_st)
return craft_make(base_st, crafting_st, i)
return craft_make(crafting_st, i)
}

View file

@ -1,8 +1,8 @@
# system.ludic - crafting as a system: a reset, and nothing saved (a hold never outlives its
# screen; what a station holds is the station's)
export function craft_reset(base_st: mut BaseState, crafting_st: mut CraftingState) -> void {
export function craft_reset(crafting_st: mut CraftingState) -> void {
craft_hold_stop(crafting_st)
q_clear(base_st, craft_facts(base_st, crafting_st))
q_clear(craft_facts(crafting_st))
}
export function craft_system() -> System {

View file

@ -59,13 +59,13 @@ program CraftingTest {
bind CraftPack { count: fn count, take: fn take, add: fn add, room: fn room, leaves: fn leaves }
bind CraftStations { ready: fn ready, start: fn start }
function fresh(base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) -> void {
function fresh(crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) -> void {
crafting_test_st.pack = new []int
for i in 0 .. 8 { push(crafting_test_st.pack, 0) }
craft_reset(base_st, crafting_st)
craft_reset(crafting_st)
}
function facts(base_st: mut BaseState, crafting_st: mut CraftingState) -> []Crafted { return q_drain(base_st, craft_facts(base_st, crafting_st)) }
function facts(crafting_st: mut CraftingState) -> []Crafted { return q_drain(craft_facts(crafting_st)) }
test "the registry is the game's, in the order written" {
expect_eq(CRAFT_COUNT, 5)
@ -76,31 +76,31 @@ program CraftingTest {
expect_eq(craft_find(99), -1)
}
test "made at once from the makings, and said" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "made at once from the makings, and said" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
expect(not craft_can(CRAFT_TORCH))
crafting_test_st.pack[WOOD] = 2
crafting_test_st.pack[CLOTH] = 1
expect(craft_make(base_st, crafting_st, CRAFT_TORCH))
expect(craft_make(crafting_st, CRAFT_TORCH))
expect_eq(crafting_test_st.pack[WOOD], 1)
expect_eq(crafting_test_st.pack[CLOTH], 0)
expect_eq(crafting_test_st.pack[TORCH], 1)
let fs = facts(base_st, crafting_st)
let fs = facts(crafting_st)
expect_eq(len(fs), 1)
expect_eq(fs[0].item, TORCH)
expect(not fs[0].queued)
}
test "nothing is taken when it cannot be made" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "nothing is taken when it cannot be made" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pack[WOOD] = 1
expect(not craft_make(base_st, crafting_st, CRAFT_TORCH))
expect(not craft_make(crafting_st, CRAFT_TORCH))
expect_eq(crafting_test_st.pack[WOOD], 1)
expect_eq(len(facts(base_st, crafting_st)), 0)
expect_eq(len(facts(crafting_st)), 0)
}
test "the station decides, and so does the room for what it makes" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "the station decides, and so does the room for what it makes" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pack[WOOD] = 9
crafting_test_st.bench_near = false
expect(craft_has(CRAFT_CHAIR))
@ -111,68 +111,68 @@ program CraftingTest {
expect(not craft_can(CRAFT_CHAIR))
}
test "an unlearned recipe is never made" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "an unlearned recipe is never made" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pack[WOOD] = 5
expect(not craft_can(CRAFT_SECRET))
}
test "a timed recipe goes into its station, and water leaves its bottle" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "a timed recipe goes into its station, and water leaves its bottle" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pack[HERB] = 2
crafting_test_st.pack[WATER] = 1
expect(craft_make(base_st, crafting_st, CRAFT_TEA))
expect(craft_make(crafting_st, CRAFT_TEA))
expect_eq(crafting_test_st.pot_got, CRAFT_TEA)
expect_eq(crafting_test_st.pack[TEA], 0)
expect_eq(crafting_test_st.pack[WATER], 0)
expect_eq(crafting_test_st.pack[BOTTLE], 1)
let fs = facts(base_st, crafting_st)
let fs = facts(crafting_st)
expect(fs[0].queued)
expect_eq(fs[0].station, POT)
}
test "a station that says no gives everything back" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "a station that says no gives everything back" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pot_takes = false
crafting_test_st.pack[HERB] = 2
crafting_test_st.pack[WATER] = 1
expect(not craft_make(base_st, crafting_st, CRAFT_TEA))
expect(not craft_make(crafting_st, CRAFT_TEA))
expect_eq(crafting_test_st.pack[HERB], 2)
expect_eq(crafting_test_st.pack[WATER], 1)
expect_eq(crafting_test_st.pack[BOTTLE], 0)
expect_eq(len(facts(base_st, crafting_st)), 0)
expect_eq(len(facts(crafting_st)), 0)
}
test "a hold makes it after its seconds, and not before" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "a hold makes it after its seconds, and not before" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pack[HERB] = 4
expect(craft_holds(CRAFT_ROPE))
expect(not craft_holds(CRAFT_TORCH))
expect(craft_hold_start(crafting_st, CRAFT_ROPE))
expect(not craft_hold_run(base_st, crafting_st, 1.0))
expect(not craft_hold_run(crafting_st, 1.0))
expect(craft_hold_frac(crafting_st, CRAFT_ROPE) == 0.5)
expect(not craft_hold_run(base_st, crafting_st, 0.9))
expect(craft_hold_run(base_st, crafting_st, 0.2))
expect(not craft_hold_run(crafting_st, 0.9))
expect(craft_hold_run(crafting_st, 0.2))
expect_eq(crafting_test_st.pack[ROPE], 2)
expect_eq(craft_holding(crafting_st), -1)
}
test "letting go wastes nothing, and losing the makings stops the hold" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "letting go wastes nothing, and losing the makings stops the hold" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pack[HERB] = 4
craft_hold_start(crafting_st, CRAFT_ROPE)
craft_hold_run(base_st, crafting_st, 1.5)
craft_hold_run(crafting_st, 1.5)
craft_hold_stop(crafting_st)
expect_eq(crafting_test_st.pack[HERB], 4)
craft_hold_start(crafting_st, CRAFT_ROPE)
crafting_test_st.pack[HERB] = 3
expect(not craft_hold_run(base_st, crafting_st, 5.0))
expect(not craft_hold_run(crafting_st, 5.0))
expect_eq(craft_holding(crafting_st), -1)
expect_eq(crafting_test_st.pack[ROPE], 0)
}
test "a click recipe cannot be held" (base_st: mut BaseState, crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(base_st, crafting_st, crafting_test_st)
test "a click recipe cannot be held" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) {
fresh(crafting_st, crafting_test_st)
crafting_test_st.pack[WOOD] = 1
crafting_test_st.pack[CLOTH] = 1
expect(not craft_hold_start(crafting_st, CRAFT_TORCH))

View file

@ -5,8 +5,8 @@ export state CraftingState {
craft_fact_q: Queue<Crafted> = null
}
export function craft_facts(base_st: mut BaseState, crafting_st: mut CraftingState) -> Queue<Crafted> {
if crafting_st.craft_fact_q == null { crafting_st.craft_fact_q = queue_new(base_st, "crafting.crafted") }
export function craft_facts(crafting_st: mut CraftingState) -> Queue<Crafted> {
if crafting_st.craft_fact_q == null { crafting_st.craft_fact_q = queue_new("crafting.crafted") }
return crafting_st.craft_fact_q
}
@ -50,7 +50,7 @@ export function craft_refund(i: int) -> void {
}
}
function craft_fact_push(base_st: mut BaseState, crafting_st: mut CraftingState, i: int, queued: bool) -> void {
function craft_fact_push(crafting_st: mut CraftingState, i: int, queued: bool) -> void {
let r = CraftRecipes[i]
let c = new Crafted
c.recipe = i
@ -58,12 +58,12 @@ function craft_fact_push(base_st: mut BaseState, crafting_st: mut CraftingState,
c.n = r.n
c.station = r.station
c.queued = queued
q_push(base_st, craft_facts(base_st, crafting_st), c)
q_push(craft_facts(crafting_st), c)
}
# make it: a timed recipe at a station goes into the station (given back if it will not take it),
# anything else is handed over at once. False, and the pack untouched, when it cannot be made.
export function craft_make(base_st: mut BaseState, crafting_st: mut CraftingState, i: int) -> bool {
export function craft_make(crafting_st: mut CraftingState, i: int) -> bool {
if not craft_can(i) { return false }
let r = CraftRecipes[i]
craft_take(i)
@ -72,10 +72,10 @@ export function craft_make(base_st: mut BaseState, crafting_st: mut CraftingStat
craft_refund(i)
return false
}
craft_fact_push(base_st, crafting_st, i, true)
craft_fact_push(crafting_st, i, true)
return true
}
CraftPack.add(r.out, r.n)
craft_fact_push(base_st, crafting_st, i, false)
craft_fact_push(crafting_st, i, false)
return true
}