diff --git a/packages/ludic.anim/clip.ludic b/packages/ludic.anim/clip.ludic index 73150678..09efbaab 100644 --- a/packages/ludic.anim/clip.ludic +++ b/packages/ludic.anim/clip.ludic @@ -17,7 +17,7 @@ export property Clip { } export state AnimState { - clips: []Clip = null + clips: []Clip = new []Clip positions: bool = false q_a: floats = null q_b: floats = null @@ -31,19 +31,18 @@ export state AnimState { # Keyed translations are off unless asked for: baking keys location on every bone, and a skeleton # does not translate its joints, so applying them turns rounding into a pose. -function clips_init(anim_st: mut AnimState) -> void { - if anim_st.clips == null { anim_st.clips = new []Clip } +function clips_init() -> void { } # the clip of that name, or null; names are per file (per body, per species), never shared -export function anim_find(anim_st: mut AnimState, name: string) -> Clip { - clips_init(anim_st) +export function anim_find(anim_st: AnimState, name: string) -> Clip { + clips_init() for i in 0 .. len(anim_st.clips) { if anim_st.clips[i].name == name { return anim_st.clips[i] } } return null } -export function anim_count(anim_st: mut AnimState) -> int { - clips_init(anim_st) +export function anim_count(anim_st: AnimState) -> int { + clips_init() return len(anim_st.clips) } diff --git a/packages/ludic.anim/read.ludic b/packages/ludic.anim/read.ludic index 63527775..07d0bffe 100644 --- a/packages/ludic.anim/read.ludic +++ b/packages/ludic.anim/read.ludic @@ -4,7 +4,7 @@ # Call it straight after a load and before the next one: `gltf_doc` and `gltf_bin` point at # whichever file was read last, so a clip that is not taken now cannot be taken later. export function anim_read_doc(anim_st: mut AnimState, render3d_st: mut Render3dState, dir: string) -> int { - clips_init(anim_st) + clips_init() if render3d_st.gltf_doc == null { return 0 } if value_has(render3d_st.gltf_doc, "animations") == 0 { return 0 } # REOPEN THE .bin. `gltf_load` closes it before it returns, and an accessor read through a closed @@ -39,7 +39,7 @@ function kept_path(ch: Val) -> string { return path } -function read_one(anim_st: mut AnimState, render3d_st: mut Render3dState, a: Val) -> Clip { +function read_one(anim_st: AnimState, render3d_st: mut Render3dState, a: Val) -> Clip { var nm = "" if value_has(a, "name") != 0 { nm = value_as_str(value_get(a, "name")) } if anim_find(anim_st, nm) != null { return null } # a second rig's file, same clip diff --git a/packages/ludic.clock/state.ludic b/packages/ludic.clock/state.ludic index 47de20b8..654f1897 100644 --- a/packages/ludic.clock/state.ludic +++ b/packages/ludic.clock/state.ludic @@ -35,12 +35,11 @@ export state ClockState { ck_moon_lo: float = 0.0 ck_moon_hi: float = 1.0 ck_dice: Rng = null - ck_days: Queue = null + ck_days: Queue = ck_days__new() } # the facts: each day that turned, in order; the game drains it and runs its morning -export function clock_days(clock_st: mut ClockState) -> Queue { - if clock_st.ck_days == null { clock_st.ck_days = queue_new("clock.days") } +export function clock_days(clock_st: ClockState) -> Queue { return clock_st.ck_days } @@ -61,3 +60,4 @@ export function clock_config_moon(clock_st: mut ClockState, days: float, lo: flo clock_st.ck_moon_lo = lo clock_st.ck_moon_hi = hi } +function ck_days__new() -> Queue { return queue_new("clock.days") } diff --git a/packages/ludic.clock/tests/clock_test.ludic b/packages/ludic.clock/tests/clock_test.ludic index 2109abe6..c8bdcaff 100644 --- a/packages/ludic.clock/tests/clock_test.ludic +++ b/packages/ludic.clock/tests/clock_test.ludic @@ -27,8 +27,8 @@ program ClockTest { clock_reset(clock_st) } - function turned(clock_st: mut ClockState) -> []DayTurned { return q_drain(clock_days(clock_st)) } - function waiting(clock_st: mut ClockState) -> int { return q_len(clock_days(clock_st)) } + function turned(clock_st: ClockState) -> []DayTurned { return q_drain(clock_days(clock_st)) } + function waiting(clock_st: ClockState) -> int { return q_len(clock_days(clock_st)) } function run_hours(h: float) -> void { let s = clock_system() s.tick(tick_new(0.016, 0, h)) diff --git a/packages/ludic.crafting/tests/crafting_test.ludic b/packages/ludic.crafting/tests/crafting_test.ludic index 27dfafa3..8e7fee20 100644 --- a/packages/ludic.crafting/tests/crafting_test.ludic +++ b/packages/ludic.crafting/tests/crafting_test.ludic @@ -65,7 +65,7 @@ program CraftingTest { craft_reset(crafting_st) } - function facts(crafting_st: mut CraftingState) -> []Crafted { return q_drain(craft_facts(crafting_st)) } + function facts(crafting_st: 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) diff --git a/packages/ludic.crafting/verbs.ludic b/packages/ludic.crafting/verbs.ludic index 1431fece..cde2bb4a 100644 --- a/packages/ludic.crafting/verbs.ludic +++ b/packages/ludic.crafting/verbs.ludic @@ -2,11 +2,10 @@ export state CraftingState { craft_hold_i: int = -1 craft_hold_t: float = 0.0 - craft_fact_q: Queue = null + craft_fact_q: Queue = craft_fact_q__new() } -export function craft_facts(crafting_st: mut CraftingState) -> Queue { - if crafting_st.craft_fact_q == null { crafting_st.craft_fact_q = queue_new("crafting.crafted") } +export function craft_facts(crafting_st: CraftingState) -> Queue { return crafting_st.craft_fact_q } @@ -50,7 +49,7 @@ export function craft_refund(i: int) -> void { } } -function craft_fact_push(crafting_st: mut CraftingState, i: int, queued: bool) -> void { +function craft_fact_push(crafting_st: CraftingState, i: int, queued: bool) -> void { let r = CraftRecipes[i] let c = new Crafted c.recipe = i @@ -63,7 +62,7 @@ function craft_fact_push(crafting_st: mut CraftingState, i: int, queued: bool) - # 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(crafting_st: mut CraftingState, i: int) -> bool { +export function craft_make(crafting_st: CraftingState, i: int) -> bool { if not craft_can(i) { return false } let r = CraftRecipes[i] craft_take(i) @@ -79,3 +78,4 @@ export function craft_make(crafting_st: mut CraftingState, i: int) -> bool { craft_fact_push(crafting_st, i, false) return true } +function craft_fact_q__new() -> Queue { return queue_new("crafting.crafted") } diff --git a/packages/ludic.effects/queries.ludic b/packages/ludic.effects/queries.ludic index 8c0ea0fe..5ce998c2 100644 --- a/packages/ludic.effects/queries.ludic +++ b/packages/ludic.effects/queries.ludic @@ -2,20 +2,20 @@ function ef_live(e: Effect) -> bool { return e.delay < 0.01 } # what the rules should add for a kind right now (a delayed one counts only once it begins) -export function effects_sum(effects_st: mut EffectsState, kind: int) -> float { +export function effects_sum(effects_st: EffectsState, kind: int) -> float { let all = ef_all(effects_st) var t = 0.0 for i in 0 .. len(all) { if all[i].kind == kind and ef_live(all[i]) { t = t + all[i].mag } } return t } -export function effects_has(effects_st: mut EffectsState, kind: int) -> bool { +export function effects_has(effects_st: EffectsState, kind: int) -> bool { let all = ef_all(effects_st) for i in 0 .. len(all) { if all[i].kind == kind and ef_live(all[i]) { return true } } return false } -export function effects_bonus_count(effects_st: mut EffectsState) -> int { +export function effects_bonus_count(effects_st: EffectsState) -> int { let all = ef_all(effects_st) var n = 0 for i in 0 .. len(all) { if all[i].bonus { n += 1 } } @@ -23,10 +23,10 @@ export function effects_bonus_count(effects_st: mut EffectsState) -> int { } # everything held, delayed or not, in the order added -export function effects_count(effects_st: mut EffectsState) -> int { return len(ef_all(effects_st)) } +export function effects_count(effects_st: EffectsState) -> int { return len(ef_all(effects_st)) } # a copy, so a reader cannot change the ring -export function effects_at(effects_st: mut EffectsState, i: int) -> Effect { +export function effects_at(effects_st: EffectsState, i: int) -> Effect { let src = ef_all(effects_st)[i] let e = new Effect e.kind = src.kind @@ -39,7 +39,7 @@ export function effects_at(effects_st: mut EffectsState, i: int) -> Effect { } # the indices of the ones that have begun, for a read-out -export function effects_live(effects_st: mut EffectsState) -> []int { +export function effects_live(effects_st: EffectsState) -> []int { let out = new []int let all = ef_all(effects_st) for i in 0 .. len(all) { if ef_live(all[i]) { push(out, i) } } diff --git a/packages/ludic.effects/state.ludic b/packages/ludic.effects/state.ludic index 282c034d..6f478412 100644 --- a/packages/ludic.effects/state.ludic +++ b/packages/ludic.effects/state.ludic @@ -21,20 +21,18 @@ export property EffectEnded { } export state EffectsState { - ef_list: []Effect = null + ef_list: []Effect = new []Effect ef_max: int = 8 ef_bonus_max: int = 3 - ef_ended: Queue = null + ef_ended: Queue = ef_ended__new() } -function ef_all(effects_st: mut EffectsState) -> []Effect { - if effects_st.ef_list == null { effects_st.ef_list = new []Effect } +function ef_all(effects_st: EffectsState) -> []Effect { return effects_st.ef_list } # the facts: what ended and why, oldest first; the game drains it -export function effects_ended(effects_st: mut EffectsState) -> Queue { - if effects_st.ef_ended == null { effects_st.ef_ended = queue_new("effects.ended") } +export function effects_ended(effects_st: EffectsState) -> Queue { return effects_st.ef_ended } @@ -46,3 +44,4 @@ export function effects_config(effects_st: mut EffectsState, max: int, bonus_max export function effects_capacity(effects_st: EffectsState) -> int { return effects_st.ef_max } export function effects_bonus_capacity(effects_st: EffectsState) -> int { return effects_st.ef_bonus_max } +function ef_ended__new() -> Queue { return queue_new("effects.ended") } diff --git a/packages/ludic.effects/system.ludic b/packages/ludic.effects/system.ludic index f134dc51..89a7d456 100644 --- a/packages/ludic.effects/system.ludic +++ b/packages/ludic.effects/system.ludic @@ -6,7 +6,7 @@ export function effects_reset(effects_st: mut EffectsState) -> void { function effects_tick(effects_st: mut EffectsState, t: Tick) -> void { effects_run(effects_st, t.hours * 60.0) } -export function effects_save(effects_st: mut EffectsState) -> Val { +export function effects_save(effects_st: EffectsState) -> Val { let l = Value.list() let all = ef_all(effects_st) for i in 0 .. len(all) { diff --git a/packages/ludic.effects/tests/effects_test.ludic b/packages/ludic.effects/tests/effects_test.ludic index fcb1bc12..d370e92d 100644 --- a/packages/ludic.effects/tests/effects_test.ludic +++ b/packages/ludic.effects/tests/effects_test.ludic @@ -13,8 +13,8 @@ program EffectsTest { effects_reset(effects_st) } - function ended(effects_st: mut EffectsState) -> []EffectEnded { return q_drain(effects_ended(effects_st)) } - function waiting(effects_st: mut EffectsState) -> int { return q_len(effects_ended(effects_st)) } + function ended(effects_st: EffectsState) -> []EffectEnded { return q_drain(effects_ended(effects_st)) } + function waiting(effects_st: EffectsState) -> int { return q_len(effects_ended(effects_st)) } function tick_minutes(m: float) -> void { let s = effects_system() diff --git a/packages/ludic.effects/verbs.ludic b/packages/ludic.effects/verbs.ludic index 856c66e5..8a7e6c45 100644 --- a/packages/ludic.effects/verbs.ludic +++ b/packages/ludic.effects/verbs.ludic @@ -19,7 +19,7 @@ function ef_drop(effects_st: mut EffectsState, i: int) -> void { } # the one with the least time left (of the bonuses only, when asked); -1 when there is none -function ef_nearest_end(effects_st: mut EffectsState, bonus_only: bool) -> int { +function ef_nearest_end(effects_st: EffectsState, bonus_only: bool) -> int { let all = ef_all(effects_st) var at = -1 for i in 0 .. len(all) { diff --git a/packages/ludic.fire/state.ludic b/packages/ludic.fire/state.ludic index 0f632b81..b383f157 100644 --- a/packages/ludic.fire/state.ludic +++ b/packages/ludic.fire/state.ludic @@ -20,7 +20,7 @@ export state FireState { fr_lit: bool = false fr_fuel: float = 0.0 # game minutes left fr_rain_h: float = 0.0 # game hours today it burned in the rain under cover - fr_facts: Queue = null + fr_facts: Queue = fr_facts__new() } # what lighting or feeding would come to, as the world stands @@ -43,12 +43,11 @@ export property FireFact { # the facts, oldest first; the game drains them into its notices -export function fire_facts(fire_st: mut FireState) -> Queue { - if fire_st.fr_facts == null { fire_st.fr_facts = queue_new("fire.facts") } +export function fire_facts(fire_st: FireState) -> Queue { return fire_st.fr_facts } -function fr_fact(fire_st: mut FireState, what: int) -> void { +function fr_fact(fire_st: FireState, what: int) -> void { let f = new FireFact f.what = what f.fuel = fire_st.fr_fuel @@ -68,3 +67,4 @@ export function fire_config_reach(fire_st: mut FireState, warm: float, cook: flo fire_st.fr_warm_radius = warm fire_st.fr_cook_radius = cook } +function fr_facts__new() -> Queue { return queue_new("fire.facts") } diff --git a/packages/ludic.fire/tests/fire_test.ludic b/packages/ludic.fire/tests/fire_test.ludic index 5151a00d..08bda313 100644 --- a/packages/ludic.fire/tests/fire_test.ludic +++ b/packages/ludic.fire/tests/fire_test.ludic @@ -29,7 +29,7 @@ program FireTest { fire_reset(fire_st) } - function facts(fire_st: mut FireState) -> []FireFact { return q_drain(fire_facts(fire_st)) } + function facts(fire_st: FireState) -> []FireFact { return q_drain(fire_facts(fire_st)) } function count(fs: []FireFact, what: int) -> int { var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.fishing/state.ludic b/packages/ludic.fishing/state.ludic index 8e48a17b..b572d9c8 100644 --- a/packages/ludic.fishing/state.ludic +++ b/packages/ludic.fishing/state.ludic @@ -24,7 +24,7 @@ export state FishingState { fishing_run_left: int = 0 fishing_run_next: float = 0.0 fishing_dice: Rng = null - fishing_fact_q: Queue = null + fishing_fact_q: Queue = fishing_fact_q__new() fishing_n: int = 0 # the record: caught, the biggest (cm), a legend landed fishing_big: int = 0 fishing_leg: bool = false @@ -42,8 +42,7 @@ export function fishing_config(fishing_st: mut FishingState, min_depth: float, d fishing_st.fishing_dice = rng_new(seed) } -export function fishing_facts(fishing_st: mut FishingState) -> Queue { - if fishing_st.fishing_fact_q == null { fishing_st.fishing_fact_q = queue_new("fishing.facts") } +export function fishing_facts(fishing_st: FishingState) -> Queue { return fishing_st.fishing_fact_q } @@ -52,7 +51,7 @@ function fishing_rand(fishing_st: mut FishingState) -> float { return rng_float(fishing_st.fishing_dice) } -function fishing_say(fishing_st: mut FishingState, what: int) -> void { +function fishing_say(fishing_st: FishingState, what: int) -> void { let f = new FishingFact f.what = what f.species = fishing_st.fishing_sp @@ -89,3 +88,4 @@ export function fishing_legend_caught(fishing_st: FishingState) -> bool { return export function fishing_water_at(fishing_st: FishingState, x: float, z: float) -> bool { return FishingWorld.afloat() or FishingWorld.depth(x, z) >= fishing_st.fishing_min_depth } +function fishing_fact_q__new() -> Queue { return queue_new("fishing.facts") } diff --git a/packages/ludic.fishing/tests/fishing_test.ludic b/packages/ludic.fishing/tests/fishing_test.ludic index 85156efb..80aad898 100644 --- a/packages/ludic.fishing/tests/fishing_test.ludic +++ b/packages/ludic.fishing/tests/fishing_test.ludic @@ -38,7 +38,7 @@ program FishingTest { fishing_test_st.skill = 0.0 } - function facts(fishing_st: mut FishingState) -> []FishingFact { return q_drain(fishing_facts(fishing_st)) } + function facts(fishing_st: FishingState) -> []FishingFact { return q_drain(fishing_facts(fishing_st)) } function saw(fs: []FishingFact, what: int) -> bool { for i in 0 .. len(fs) { if fs[i].what == what { return true } } return false diff --git a/packages/ludic.gameplay/combat.ludic b/packages/ludic.gameplay/combat.ludic index f2e1c283..042f8abb 100644 --- a/packages/ludic.gameplay/combat.ludic +++ b/packages/ludic.gameplay/combat.ludic @@ -26,7 +26,7 @@ event Crit { target: int = 0, src: int = 0 } # the attacker's crit_pct fired state GameplayState { combat_reflecting: bool = false # thorns never reflect thorns combat_pending: int = 0 - fac_tbl: words = null + fac_tbl: words = words(FAC_MAX * FAC_MAX) } # the mutable channel for lever 6: listeners rewrite the pending damage here. diff --git a/packages/ludic.gameplay/faction.ludic b/packages/ludic.gameplay/faction.ludic index 95d0301f..0bada609 100644 --- a/packages/ludic.gameplay/faction.ludic +++ b/packages/ludic.gameplay/faction.ludic @@ -18,7 +18,6 @@ const REL_HOSTILE: int = 2 # A global var initialiser must be a literal, so it is allocated lazily. function fac_ensure(gameplay_st: mut GameplayState) -> void { - if gameplay_st.fac_tbl == null { gameplay_st.fac_tbl = words(FAC_MAX * FAC_MAX) } } # Faction.set(a, b, rel) — record a symmetric relationship between two factions. diff --git a/packages/ludic.gear/buy.ludic b/packages/ludic.gear/buy.ludic index 10f7b90f..47088fa7 100644 --- a/packages/ludic.gear/buy.ludic +++ b/packages/ludic.gear/buy.ludic @@ -1,5 +1,5 @@ # buy.ludic - a tier bought with money once the standing is there; the kind's item follows -export function gear_can_buy(gear_st: mut GearState, k: int) -> bool { +export function gear_can_buy(gear_st: GearState, k: int) -> bool { if not gear_ok(k) or gear_best(gear_st, k) or GearWorld.hidden(k) { return false } return GearPurse.rep() >= gear_next_rep(gear_st, k) and GearPurse.money() >= gear_next_cost(gear_st, k) } @@ -17,7 +17,6 @@ export function gear_buy(gear_st: mut GearState, k: int) -> bool { # a kind whose item is already carried counts as its first tier export function gear_sync(gear_st: mut GearState) -> void { - gear__ensure(gear_st) for k in 0 .. GEAR_COUNT { let it = GearKinds[k].item if it >= 0 and gear_st.gear__lv[k] == 0 and GearPack.count(it) > 0 { gear_st.gear__lv[k] = 1 } diff --git a/packages/ludic.gear/hand.ludic b/packages/ludic.gear/hand.ludic index 3515cdb0..9676835d 100644 --- a/packages/ludic.gear/hand.ludic +++ b/packages/ludic.gear/hand.ludic @@ -4,7 +4,6 @@ export function gear_hand(gear_st: GearState) -> int { return gear_st.gear__hand # a new thing in the hand (-1 empty): whatever the old one was running goes out export function gear_set_hand(gear_st: mut GearState, it: int) -> void { - gear__ensure(gear_st) gear_st.gear__hand = it for c in 0 .. CHARGE_COUNT { if GearCharges[c].hand { gear_st.gear__on[c] = false } } } @@ -15,26 +14,22 @@ export function gear_charge_of(it: int) -> int { return -1 } -export function gear_charge(gear_st: mut GearState, c: int) -> float { - gear__ensure(gear_st) +export function gear_charge(gear_st: GearState, c: int) -> float { return gear_st.gear__left[c] } export function gear_charge_set(gear_st: mut GearState, c: int, v: float) -> void { - gear__ensure(gear_st) gear_st.gear__left[c] = Math.clamp(v, 0.0, GearCharges[c].full) } export function gear_charge_fill(gear_st: mut GearState, c: int) -> void { gear_charge_set(gear_st, c, GearCharges[c].full) } -export function gear_running(gear_st: mut GearState, c: int) -> bool { - gear__ensure(gear_st) +export function gear_running(gear_st: GearState, c: int) -> bool { return gear_st.gear__on[c] } # on or off; false when it has nothing left, or is held and not in the hand export function gear_run(gear_st: mut GearState, c: int, on: bool) -> bool { - gear__ensure(gear_st) if not on { gear_st.gear__on[c] = false return true @@ -46,13 +41,13 @@ export function gear_run(gear_st: mut GearState, c: int, on: bool) -> bool { } # the hand's own charge is running (a torch lit, a flashlight on) -export function gear_lit(gear_st: mut GearState) -> bool { +export function gear_lit(gear_st: GearState) -> bool { if gear_st.gear__hand < 0 { return false } let c = gear_charge_of(gear_st.gear__hand) return c >= 0 and GearCharges[c].hand and gear_running(gear_st, c) } -function gear__rate(gear_st: mut GearState, c: int) -> float { +function gear__rate(gear_st: GearState, c: int) -> float { let d = GearCharges[c] if d.rate >= 0 { return gear_value(gear_st, d.rate) } return d.per_hour @@ -60,7 +55,6 @@ function gear__rate(gear_st: mut GearState, c: int) -> float { # the game hours of a tick burn every running charge; one that runs out stops and says so function gear__burn(gear_st: mut GearState, hours: float) -> void { - gear__ensure(gear_st) for c in 0 .. CHARGE_COUNT { if not gear_st.gear__on[c] { continue } gear_st.gear__left[c] = gear_st.gear__left[c] - hours * gear__rate(gear_st, c) diff --git a/packages/ludic.gear/state.ludic b/packages/ludic.gear/state.ludic index 20ee7e63..e8046c68 100644 --- a/packages/ludic.gear/state.ludic +++ b/packages/ludic.gear/state.ludic @@ -1,30 +1,32 @@ # state.ludic - the level of each kind, the hand, each charge's units and whether it runs, the facts export state GearState { - gear__lv: []int = null + gear__lv: []int = gear__starts() gear__hand: int = -1 - gear__left: []float = null - gear__on: []bool = null - gear__q: Queue = null + gear__left: []float = gear__fulls() + gear__on: []bool = gear__offs() + gear__q: Queue = gear__queue() +} +# what a new state starts with: every kind at its start, every charge full and off +function gear__starts() -> []int { + let xs = new []int + for k in 0 .. GEAR_COUNT { push(xs, GearKinds[k].start) } + return xs +} +function gear__fulls() -> []float { + let xs = new []float + for c in 0 .. CHARGE_COUNT { push(xs, GearCharges[c].full) } + return xs +} +function gear__queue() -> Queue { return queue_new("gear.facts") } +function gear__offs() -> []bool { + let xs = new []bool + for c in 0 .. CHARGE_COUNT { push(xs, false) } + return xs } -function gear__ensure(gear_st: mut GearState) -> void { - if gear_st.gear__lv != null { return } - gear_st.gear__lv = new []int - for k in 0 .. GEAR_COUNT { push(gear_st.gear__lv, GearKinds[k].start) } - gear_st.gear__left = new []float - gear_st.gear__on = new []bool - for c in 0 .. CHARGE_COUNT { - push(gear_st.gear__left, GearCharges[c].full) - push(gear_st.gear__on, false) - } -} +export function gear_facts(gear_st: GearState) -> Queue { return gear_st.gear__q } -export function gear_facts(gear_st: mut GearState) -> Queue { - if gear_st.gear__q == null { gear_st.gear__q = queue_new("gear.facts") } - return gear_st.gear__q -} - -function gear__fact(gear_st: mut GearState, what: int, k: int, c: int, cost: int) -> void { +function gear__fact(gear_st: GearState, what: int, k: int, c: int, cost: int) -> void { let f = new GearFact f.what = what f.cost = cost diff --git a/packages/ludic.gear/system.ludic b/packages/ludic.gear/system.ludic index 6edc495b..0969777b 100644 --- a/packages/ludic.gear/system.ludic +++ b/packages/ludic.gear/system.ludic @@ -1,7 +1,6 @@ # system.ludic - gear as a system: the burn each tick, and the levels and charges saved by key (the # hand is not saved: a trip opens with empty hands) export function gear_reset(gear_st: mut GearState) -> void { - gear__ensure(gear_st) for k in 0 .. GEAR_COUNT { gear_st.gear__lv[k] = GearKinds[k].start } for c in 0 .. CHARGE_COUNT { gear_st.gear__left[c] = GearCharges[c].full @@ -11,8 +10,7 @@ export function gear_reset(gear_st: mut GearState) -> void { q_clear(gear_facts(gear_st)) } -export function gear_save(gear_st: mut GearState) -> Val { - gear__ensure(gear_st) +export function gear_save(gear_st: GearState) -> Val { let v = Value.object() let lv = Value.object() for k in 0 .. GEAR_COUNT { sv_put_int(lv, GearKinds[k].key, gear_st.gear__lv[k]) } diff --git a/packages/ludic.gear/tests/gear_test.ludic b/packages/ludic.gear/tests/gear_test.ludic index a9aeb9cf..ac3e9d1b 100644 --- a/packages/ludic.gear/tests/gear_test.ludic +++ b/packages/ludic.gear/tests/gear_test.ludic @@ -51,7 +51,7 @@ program GearTest { gear_reset(gear_st) } - function ran_out(gear_st: mut GearState) -> int { + function ran_out(gear_st: GearState) -> int { let fs = q_drain(gear_facts(gear_st)) var n = -1 for i in 0 .. len(fs) { if fs[i].what == GEAR_RAN_OUT { n = fs[i].charge } } diff --git a/packages/ludic.gear/tiers.ludic b/packages/ludic.gear/tiers.ludic index 65d54861..abbfcd52 100644 --- a/packages/ludic.gear/tiers.ludic +++ b/packages/ludic.gear/tiers.ludic @@ -1,20 +1,18 @@ # tiers.ludic - what is owned and what a tier is worth export function gear_ok(k: int) -> bool { return k >= 0 and k < GEAR_COUNT } -export function gear_level(gear_st: mut GearState, k: int) -> int { - gear__ensure(gear_st) +export function gear_level(gear_st: GearState, k: int) -> int { return gear_st.gear__lv[k] } # outright: staging, a test, a camera handed over with the trip export function gear_set_level(gear_st: mut GearState, k: int, lv: int) -> void { - gear__ensure(gear_st) gear_st.gear__lv[k] = lv } -export function gear_owned(gear_st: mut GearState, k: int) -> bool { return gear_level(gear_st, k) > 0 } +export function gear_owned(gear_st: GearState, k: int) -> bool { return gear_level(gear_st, k) > 0 } -export function gear_best(gear_st: mut GearState, k: int) -> bool { return gear_level(gear_st, k) >= GearKinds[k].tiers } +export function gear_best(gear_st: GearState, k: int) -> bool { return gear_level(gear_st, k) >= GearKinds[k].tiers } # a tier's name, "" for none export function gear_level_name(k: int, lv: int) -> string { @@ -23,14 +21,14 @@ export function gear_level_name(k: int, lv: int) -> string { } # the tier on offer next: its name, cost and the standing it wants -export function gear_next_name(gear_st: mut GearState, k: int) -> string { return gear_level_name(k, gear_level(gear_st, k) + 1) } +export function gear_next_name(gear_st: GearState, k: int) -> string { return gear_level_name(k, gear_level(gear_st, k) + 1) } -export function gear_next_cost(gear_st: mut GearState, k: int) -> int { +export function gear_next_cost(gear_st: GearState, k: int) -> int { if gear_best(gear_st, k) { return 0 } return GearKinds[k].cost[gear_level(gear_st, k)] } -export function gear_next_rep(gear_st: mut GearState, k: int) -> int { +export function gear_next_rep(gear_st: GearState, k: int) -> int { if gear_best(gear_st, k) { return 0 } return GearKinds[k].rep[gear_level(gear_st, k)] } @@ -43,10 +41,10 @@ function gear__pick(xs: []float, lv: int, fallback: float) -> float { } # the kind's own number at its level (1.0 when it has none) -export function gear_mult(gear_st: mut GearState, k: int) -> float { return gear__pick(GearKinds[k].mult, gear_level(gear_st, k), 1.0) } +export function gear_mult(gear_st: GearState, k: int) -> float { return gear__pick(GearKinds[k].mult, gear_level(gear_st, k), 1.0) } # a value its kind's tier decides -export function gear_value(gear_st: mut GearState, v: int) -> float { +export function gear_value(gear_st: GearState, v: int) -> float { let d = GearValues[v] return gear__pick(d.at, gear_level(gear_st, d.gear), 0.0) } diff --git a/packages/ludic.hints/rail.ludic b/packages/ludic.hints/rail.ludic index ff17fe62..20943b0b 100644 --- a/packages/ludic.hints/rail.ludic +++ b/packages/ludic.hints/rail.ludic @@ -10,15 +10,14 @@ export state HintsState { hn_t: float = 0.0 # seconds to the next pass hn_pick: int = 0 # which chip the key would open hn_card: int = -1 # the card being read, or -1 - hn_facts: Queue = null + hn_facts: Queue = hn_facts__new() } -export function hints_facts(hints_st: mut HintsState) -> Queue { - if hints_st.hn_facts == null { hints_st.hn_facts = queue_new("hints.facts") } +export function hints_facts(hints_st: HintsState) -> Queue { return hints_st.hn_facts } -function hn_fact(hints_st: mut HintsState, what: int, card: int) -> void { +function hn_fact(hints_st: HintsState, what: int, card: int) -> void { let f = new HintsFact f.what = what f.card = card @@ -104,3 +103,4 @@ export function hints_reset(hints_st: mut HintsState) -> void { hints_st.hn_card = -1 q_clear(hints_facts(hints_st)) } +function hn_facts__new() -> Queue { return queue_new("hints.facts") } diff --git a/packages/ludic.hints/tests/hints_test.ludic b/packages/ludic.hints/tests/hints_test.ludic index 7d220396..941a203f 100644 --- a/packages/ludic.hints/tests/hints_test.ludic +++ b/packages/ludic.hints/tests/hints_test.ludic @@ -29,7 +29,7 @@ program HintsTest { hints_mutes_load(hints_st, Value.list()) } - function count(hints_st: mut HintsState, what: int) -> int { + function count(hints_st: HintsState, what: int) -> int { let fs = q_drain(hints_facts(hints_st)) var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.inventory/state.ludic b/packages/ludic.inventory/state.ludic index 32f55c88..b8f2aad3 100644 --- a/packages/ludic.inventory/state.ludic +++ b/packages/ludic.inventory/state.ludic @@ -15,7 +15,7 @@ export property ItemChanged { export state InventoryState { iv_keys: []string = null iv_counts: []int = null - iv_changes: Queue = null + iv_changes: Queue = iv_changes__new() } # the kinds, by the name each is saved under; the pack starts empty @@ -24,8 +24,7 @@ export function inv_config(inventory_st: mut InventoryState, keys: []string) -> inv_clear(inventory_st) } -export function inv_changes(inventory_st: mut InventoryState) -> Queue { - if inventory_st.iv_changes == null { inventory_st.iv_changes = queue_new("inventory.changes") } +export function inv_changes(inventory_st: InventoryState) -> Queue { return inventory_st.iv_changes } @@ -59,3 +58,4 @@ export function inv_total(inventory_st: InventoryState) -> int { for i in 0 .. len(inventory_st.iv_counts) { t += inventory_st.iv_counts[i] } return t } +function iv_changes__new() -> Queue { return queue_new("inventory.changes") } diff --git a/packages/ludic.inventory/tests/inventory_test.ludic b/packages/ludic.inventory/tests/inventory_test.ludic index 0c15fe59..ddd92e1b 100644 --- a/packages/ludic.inventory/tests/inventory_test.ludic +++ b/packages/ludic.inventory/tests/inventory_test.ludic @@ -28,8 +28,8 @@ program InventoryTest { inv_reset(inventory_st) } - function changes(inventory_st: mut InventoryState) -> []ItemChanged { return q_drain(inv_changes(inventory_st)) } - function waiting(inventory_st: mut InventoryState) -> int { return q_len(inv_changes(inventory_st)) } + function changes(inventory_st: InventoryState) -> []ItemChanged { return q_drain(inv_changes(inventory_st)) } + function waiting(inventory_st: InventoryState) -> int { return q_len(inv_changes(inventory_st)) } test "add puts in what fits and says how many" (inventory_st: mut InventoryState) { fresh(inventory_st) diff --git a/packages/ludic.jobs/state.ludic b/packages/ludic.jobs/state.ludic index dd5ae017..da541b3d 100644 --- a/packages/ludic.jobs/state.ludic +++ b/packages/ludic.jobs/state.ludic @@ -20,7 +20,7 @@ export state JobsState { jobs__serial: []int = null # posts made, per board: each roll its own seed jobs__seed: int = 1000 jobs__dice: Rng = null - jobs__q: Queue = null + jobs__q: Queue = jobs__q__new() } # the posts, every board's slots end to end from jobs__off[b] @@ -59,12 +59,11 @@ function jobs__ensure(jobs_st: mut JobsState) -> void { jobs_st.jobs__dice = rng_new(jobs_st.jobs__seed) } -export function jobs_facts(jobs_st: mut JobsState) -> Queue { - if jobs_st.jobs__q == null { jobs_st.jobs__q = queue_new("jobs.facts") } +export function jobs_facts(jobs_st: JobsState) -> Queue { return jobs_st.jobs__q } -function jobs__fact(jobs_st: mut JobsState, what: int, job: int, b: int, s: int, have: int, need: int) -> void { +function jobs__fact(jobs_st: JobsState, what: int, job: int, b: int, s: int, have: int, need: int) -> void { let f = new JobsFact f.what = what f.job = job @@ -93,3 +92,4 @@ export function jobs_config_seed(jobs_st: mut JobsState, seed: int) -> void { jobs_st.jobs__seed = seed jobs_st.jobs__dice = rng_new(seed) } +function jobs__q__new() -> Queue { return queue_new("jobs.facts") } diff --git a/packages/ludic.jobs/tests/jobs_test.ludic b/packages/ludic.jobs/tests/jobs_test.ludic index 30029925..5e5b72b7 100644 --- a/packages/ludic.jobs/tests/jobs_test.ludic +++ b/packages/ludic.jobs/tests/jobs_test.ludic @@ -59,7 +59,7 @@ program JobsTest { jobs_party_reset(jobs_st) } - function count_of(jobs_st: mut JobsState, what: int) -> int { + function count_of(jobs_st: JobsState, what: int) -> int { let fs = q_drain(jobs_facts(jobs_st)) var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.needs/state.ludic b/packages/ludic.needs/state.ludic index 8e19b2b5..77179e3c 100644 --- a/packages/ludic.needs/state.ludic +++ b/packages/ludic.needs/state.ludic @@ -56,7 +56,7 @@ export state NeedsState { nd_legs: float = 0.0 # seconds left before a collapse, 0 = none nd_last: int = 0 # the need the countdown is for nd_collapses: int = 0 - nd_facts: Queue = null + nd_facts: Queue = nd_facts__new() } function nd_lv(needs_st: mut NeedsState) -> []float { @@ -75,12 +75,11 @@ function nd_fill(needs_st: mut NeedsState) -> void { } # the facts, oldest first; the game drains them into its notices and its collapse -export function needs_facts(needs_st: mut NeedsState) -> Queue { - if needs_st.nd_facts == null { needs_st.nd_facts = queue_new("needs.facts") } +export function needs_facts(needs_st: NeedsState) -> Queue { return needs_st.nd_facts } -function nd_fact(needs_st: mut NeedsState, what: int, need: int) -> void { +function nd_fact(needs_st: NeedsState, what: int, need: int) -> void { let f = new NeedFact f.what = what f.need = need @@ -88,3 +87,4 @@ function nd_fact(needs_st: mut NeedsState, what: int, need: int) -> void { } function nd_ok(k: int) -> bool { return k >= 0 and k < NEED_COUNT } +function nd_facts__new() -> Queue { return queue_new("needs.facts") } diff --git a/packages/ludic.needs/tests/needs_test.ludic b/packages/ludic.needs/tests/needs_test.ludic index 34eb59fa..149738fc 100644 --- a/packages/ludic.needs/tests/needs_test.ludic +++ b/packages/ludic.needs/tests/needs_test.ludic @@ -46,7 +46,7 @@ program NeedsTest { function fresh(needs_st: mut NeedsState) -> void { needs_reset(needs_st) } function hours(needs_st: mut NeedsState, h: float) -> void { for i in 0 .. int(h * 10.0) { needs_run(needs_st, 0.1) } } - function facts(needs_st: mut NeedsState) -> []NeedFact { return q_drain(needs_facts(needs_st)) } + function facts(needs_st: NeedsState) -> []NeedFact { return q_drain(needs_facts(needs_st)) } test "a new body is warm, rested, fed and watered" (needs_st: mut NeedsState) { fresh(needs_st) diff --git a/packages/ludic.net/codec.ludic b/packages/ludic.net/codec.ludic index 67aae75d..be7dd5a1 100644 --- a/packages/ludic.net/codec.ludic +++ b/packages/ludic.net/codec.ludic @@ -73,7 +73,6 @@ export function nr_text(net_st: mut NetState, cap: int) -> string { net_st.net__rbad = true return "" } - if net_st.net__tb == null { net_st.net__tb = buffer(NET_MTU) } nb_copy(net_st.net__tb, 0, net_st.net__rb, net_st.net__rp, n) net_st.net__rp += n return text_of(net_st.net__tb, n) diff --git a/packages/ludic.net/ports.ludic b/packages/ludic.net/ports.ludic index c363b5dd..d0b316ae 100644 --- a/packages/ludic.net/ports.ludic +++ b/packages/ludic.net/ports.ludic @@ -61,17 +61,15 @@ export port NetSocket { export function net_config(net_st: mut NetState, c: NetConfig) -> void { net_st.net__cfg = c } -function net__conf(net_st: mut NetState) -> NetConfig { - if net_st.net__cfg == null { net_st.net__cfg = new NetConfig } +function net__conf(net_st: NetState) -> NetConfig { return net_st.net__cfg } -export function net_facts(net_st: mut NetState) -> Queue { - if net_st.net__facts == null { net_st.net__facts = queue_new("net.facts") } +export function net_facts(net_st: NetState) -> Queue { return net_st.net__facts } -function net__fact(net_st: mut NetState, what: int, slot: int, pid: int, why: int, text: string) -> void { +function net__fact(net_st: NetState, what: int, slot: int, pid: int, why: int, text: string) -> void { let f = new NetFact f.what = what f.slot = slot diff --git a/packages/ludic.net/punch.ludic b/packages/ludic.net/punch.ludic index 4e95e742..c0c71e7c 100644 --- a/packages/ludic.net/punch.ludic +++ b/packages/ludic.net/punch.ludic @@ -4,7 +4,6 @@ function net__new_guest(net_st: mut NetState, pub: string, local: string) -> void { let key = `{pub}|{local}` - if net_st.net__seen == null { net_st.net__seen = new []string } for i in 0 .. len(net_st.net__seen) { if net_st.net__seen[i] == key { return } } push(net_st.net__seen, key) net__log(`room {net_st.net__room}: a guest at {pub} / {local}`) diff --git a/packages/ludic.net/receive.ludic b/packages/ludic.net/receive.ludic index b5689031..ce140469 100644 --- a/packages/ludic.net/receive.ludic +++ b/packages/ludic.net/receive.ludic @@ -77,7 +77,7 @@ function net__messages(net_st: mut NetState, slot: int, n: int) -> void { } # onto the inbox - except a heartbeat, and on a host anything but a hello before its welcome -function net__deliver(net_st: mut NetState, slot: int, from: int, kind: int, o: int, ml: int) -> void { +function net__deliver(net_st: NetState, slot: int, from: int, kind: int, o: int, ml: int) -> void { if kind == NET_BEAT { return } if net_st.net__state == NET_HOSTING and net_st.net__peers[slot].pid < 2 and kind != NET_HELLO { return } let m = new NetMessage diff --git a/packages/ludic.net/relay.ludic b/packages/ludic.net/relay.ludic index cccef615..f05f7401 100644 --- a/packages/ludic.net/relay.ludic +++ b/packages/ludic.net/relay.ludic @@ -38,7 +38,7 @@ function net__use_relay(net_st: mut NetState) -> void { export function net_via_relay(net_st: NetState) -> bool { return net_st.net__via_relay } -function net__relayed(net_st: mut NetState, p: NetPeer) -> bool { +function net__relayed(net_st: NetState, p: NetPeer) -> bool { return net_st.net__relay_ip != 0 and p.ip == net_st.net__relay_ip and (p.port >= net__conf(net_st).relay_port0 or net_st.net__via_relay) } diff --git a/packages/ludic.net/room.ludic b/packages/ludic.net/room.ludic index 89602371..62427a34 100644 --- a/packages/ludic.net/room.ludic +++ b/packages/ludic.net/room.ludic @@ -10,7 +10,7 @@ const NET_R_DONE: int = 5 # a guest: the hello is on its way # room codes are on when the game named a matchmaker -export function net_room_on(net_st: mut NetState) -> bool { return len(net__conf(net_st).signal_url) > 0 } +export function net_room_on(net_st: NetState) -> bool { return len(net__conf(net_st).signal_url) > 0 } export function net_room(net_st: NetState) -> string { return net_st.net__room } export function net_room_asking(net_st: NetState) -> bool { return net_st.net__r_state == NET_R_STUN or net_st.net__r_state == NET_R_ASK } diff --git a/packages/ludic.net/state.ludic b/packages/ludic.net/state.ludic index eed4e268..312fb3dc 100644 --- a/packages/ludic.net/state.ludic +++ b/packages/ludic.net/state.ludic @@ -48,9 +48,9 @@ export property NetMessage { } export state NetState { - net__cfg: NetConfig = null - net__facts: Queue = null - net__seen: []string = null # guests already punched for + net__cfg: NetConfig = new NetConfig + net__facts: Queue = net__facts__new() + net__seen: []string = new []string # guests already punched for net__punch_ip: words = null net__punch_port: words = null net__punch_left: words = null @@ -88,7 +88,7 @@ export state NetState { net__rl: int = 0 net__rp: int = 0 net__rbad: bool = false - net__tb: []byte = null # text read out of a message, through one scratch buffer + net__tb: []byte = buffer(NET_MTU) # text read out of a message, through one scratch buffer net__hello_b: []byte = null # the game's hello, sent again on every dial net__hello_l: int = 0 net__hello_t: float = 0.0 # seconds since it went; -1 not yet @@ -100,15 +100,14 @@ export state NetState { net__code_port: int = 0 net__bytes_out: int = 0 net__kind_out: words = null - net__inbox: Queue = null + net__inbox: Queue = net__inbox__new() net__stun_ip: int = 0 net__stun_port: int = 0 - net__txn: words = null + net__txn: words = words(3) net__dice: Rng = null } -export function net_inbox(net_st: mut NetState) -> Queue { - if net_st.net__inbox == null { net_st.net__inbox = queue_new("net.inbox") } +export function net_inbox(net_st: NetState) -> Queue { return net_st.net__inbox } @@ -126,3 +125,5 @@ function net__init(net_st: mut NetState) -> void { net_st.net__rb = buffer(NET_MTU) net_st.net__hello_b = buffer(NET_MTU) } +function net__facts__new() -> Queue { return queue_new("net.facts") } +function net__inbox__new() -> Queue { return queue_new("net.inbox") } diff --git a/packages/ludic.net/stun.ludic b/packages/ludic.net/stun.ludic index 5ad750b0..df61c7fd 100644 --- a/packages/ludic.net/stun.ludic +++ b/packages/ludic.net/stun.ludic @@ -2,7 +2,6 @@ # from outside: the router's address and the port it mapped function net__stun_send(net_st: mut NetState) -> void { - if net_st.net__txn == null { net_st.net__txn = words(3) } if net_st.net__dice == null { net_st.net__dice = rng_new(net__conf(net_st).seed) } if net_st.net__stun_ip == 0 { let c = net__conf(net_st) diff --git a/packages/ludic.net/tests/net_test.ludic b/packages/ludic.net/tests/net_test.ludic index 6ee59fa7..592d7b38 100644 --- a/packages/ludic.net/tests/net_test.ludic +++ b/packages/ludic.net/tests/net_test.ludic @@ -97,7 +97,7 @@ program NetTest { return net_accept(net_st, got[0].slot) } - function facts_of(net_st: mut NetState, what: int) -> []NetFact { + function facts_of(net_st: NetState, what: int) -> []NetFact { let all = q_drain(net_facts(net_st)) let out = new []NetFact for i in 0 .. len(all) { if all[i].what == what { push(out, all[i]) } } diff --git a/packages/ludic.npc/act.ludic b/packages/ludic.npc/act.ludic index 9d880389..1d04ea36 100644 --- a/packages/ludic.npc/act.ludic +++ b/packages/ludic.npc/act.ludic @@ -30,7 +30,7 @@ function np_turns(act: int) -> bool { } # a player who came within notice since the last look is greeted - once, until they walk off -export function npc_notice(npc_st: mut NpcState, p: NpcPerson) -> void { +export function npc_notice(npc_st: NpcState, p: NpcPerson) -> void { let reach = NpcKinds[p.kind].notice for i in 0 .. NpcWorld.players() { if i >= 30 { break } diff --git a/packages/ludic.npc/census.ludic b/packages/ludic.npc/census.ludic index bff76be3..375c4a91 100644 --- a/packages/ludic.npc/census.ludic +++ b/packages/ludic.npc/census.ludic @@ -1,7 +1,7 @@ # census.ludic - making one (a slot reused before a new one, a look, a name, a start on its own # ground out of the players' sight where that can be had), a post's fixed person, and leaving export function npc_spawn(npc_st: mut NpcState, kind: int) -> NpcPerson { - np_ensure(npc_st) + np_ensure() if npc_st.np_n >= npc_st.np_max or kind < 0 or kind >= NPCK_COUNT { return null } var p: NpcPerson = null for i in 0 .. len(npc_st.np_walkers) { @@ -94,7 +94,7 @@ export function npc_set_at(p: NpcPerson, x: float, z: float) -> void { # somebody fixed at a post (a vendor behind the counter): never walks, never counted, never leaves, # turns to a player within its kind's notice and back to `yaw` when they go export function npc_place(npc_st: mut NpcState, kind: int, x: float, z: float, yaw: float, name: string, look: int) -> NpcPerson { - np_ensure(npc_st) + np_ensure() let p = new NpcPerson p.slot = len(npc_st.np_posts) np_fresh(p, kind, look) diff --git a/packages/ludic.npc/mirror.ludic b/packages/ludic.npc/mirror.ludic index d69530d7..ac22a921 100644 --- a/packages/ludic.npc/mirror.ludic +++ b/packages/ludic.npc/mirror.ludic @@ -3,7 +3,7 @@ # on: this machine's own walkers leave, and only the host's are drawn until it is turned off export function npc_mirror(npc_st: mut NpcState, on: bool) -> void { - np_ensure(npc_st) + np_ensure() if npc_st.np_mirror == on { return } npc_st.np_mirror = on for i in 0 .. len(npc_st.np_walkers) { npc_retire(npc_st, npc_st.np_walkers[i]) } @@ -14,7 +14,7 @@ export function npc_mirroring(npc_st: NpcState) -> bool { return npc_st.np_mirro # the host's slot: somebody new in it (born), or nobody (gone) export function npc_put(npc_st: mut NpcState, slot: int, id: int, kind: int, look: int, seed: float, name: string, hx: float, hz: float) -> NpcPerson { - np_ensure(npc_st) + np_ensure() if slot < 0 or slot >= npc_st.np_max or kind < 0 or kind >= NPCK_COUNT { return null } while len(npc_st.np_walkers) <= slot { let q = new NpcPerson @@ -36,7 +36,7 @@ export function npc_put(npc_st: mut NpcState, slot: int, id: int, kind: int, loo } # where the host says it is now, and what it is doing -export function npc_heard(npc_st: mut NpcState, slot: int, x: float, y: float, z: float, yaw: float, speed: float, act: int, stalk: bool) -> void { +export function npc_heard(npc_st: NpcState, slot: int, x: float, y: float, z: float, yaw: float, speed: float, act: int, stalk: bool) -> void { let p = npc_at(npc_st, slot) if p == null or not p.active { return } if not p.heard { @@ -60,7 +60,7 @@ export function npc_heard(npc_st: mut NpcState, slot: int, x: float, y: float, z export function npc_heard_lately(npc_st: NpcState, p: NpcPerson) -> bool { return p.heard and npc_st.np_clock - p.heard_t <= 6.0 } export function npc_mirror_tick(npc_st: mut NpcState, dt: float) -> void { - np_ensure(npc_st) + np_ensure() npc_st.np_clock = npc_st.np_clock + dt let k = Math.min(1.0, dt * 8.0) for i in 0 .. len(npc_st.np_walkers) { diff --git a/packages/ludic.npc/names.ludic b/packages/ludic.npc/names.ludic index 777c02f3..48582954 100644 --- a/packages/ludic.npc/names.ludic +++ b/packages/ludic.npc/names.ludic @@ -1,7 +1,7 @@ # names.ludic - a name nobody else in the place is using: not another person, not one the place # keeps for itself (NpcWorld.taken: a vendor), and not somebody who left a little while ago -export function npc_name_used(npc_st: mut NpcState, n: string) -> bool { +export function npc_name_used(npc_st: NpcState, n: string) -> bool { if NpcWorld.taken(n) { return true } let all = npc_walkers(npc_st) for i in 0 .. len(all) { if all[i].active and all[i].name == n { return true } } @@ -12,7 +12,7 @@ export function npc_name_used(npc_st: mut NpcState, n: string) -> bool { } # a free name from the body's pool, from a place in it the dice choose ("" when the pool is empty) -export function npc_pick_name(npc_st: mut NpcState, body: int) -> string { +export function npc_pick_name(npc_st: NpcState, body: int) -> string { let pool = new []string for i in 0 .. NPCN_COUNT { if NpcNames[i].body == body { push(pool, NpcNames[i].name) } } let n = len(pool) @@ -26,7 +26,6 @@ export function npc_pick_name(npc_st: mut NpcState, body: int) -> string { } function np_left(npc_st: mut NpcState, name: string) -> void { - if npc_st.np_recent == null { npc_st.np_recent = new []string } push(npc_st.np_recent, name) if len(npc_st.np_recent) <= 8 { return } let keep = new []string @@ -35,7 +34,7 @@ function np_left(npc_st: mut NpcState, name: string) -> void { } # how many pairs share a name, the place's own names included -export function npc_name_clashes(npc_st: mut NpcState) -> int { +export function npc_name_clashes(npc_st: NpcState) -> int { var dup = 0 let all = npc_walkers(npc_st) for i in 0 .. len(all) { diff --git a/packages/ludic.npc/person.ludic b/packages/ludic.npc/person.ludic index 538a2c56..093135d9 100644 --- a/packages/ludic.npc/person.ludic +++ b/packages/ludic.npc/person.ludic @@ -6,13 +6,13 @@ export state NpcState { np_wx: float = 0.0 np_wz: float = 0.0 np_clock: float = 0.0 - np_recent: []string = null # the last few names that left - np_walkers: []NpcPerson = null - np_posts: []NpcPerson = null + np_recent: []string = new []string # the last few names that left + np_walkers: []NpcPerson = new []NpcPerson + np_posts: []NpcPerson = new []NpcPerson np_max: int = 10 # walkers at most np_n: int = 0 # walkers about - np_dice: Rng = null - np_facts: Queue = null + np_dice: Rng = rng_new(20260925) + np_facts: Queue = np_facts__new() np_next_h: float = 0.0 # the hour the census is next looked at np_hold: bool = false # held where they stand (a shot of their poses) np_mirror: bool = false # a guest drawing a host's: no routine runs here @@ -23,12 +23,11 @@ export state NpcState { const NP_PI: float = 3.1415927 const NP_TAU: float = 6.2831853 -export function npc_facts(npc_st: mut NpcState) -> Queue { - if npc_st.np_facts == null { npc_st.np_facts = queue_new("npc.facts") } +export function npc_facts(npc_st: NpcState) -> Queue { return npc_st.np_facts } -function np_fact(npc_st: mut NpcState, what: int, p: NpcPerson, player: int) -> NpcFact { +function np_fact(npc_st: NpcState, what: int, p: NpcPerson, player: int) -> NpcFact { let f = new NpcFact f.what = what f.person = p.id @@ -40,40 +39,37 @@ function np_fact(npc_st: mut NpcState, what: int, p: NpcPerson, player: int) -> return f } -function np_ensure(npc_st: mut NpcState) -> void { - if npc_st.np_walkers == null { npc_st.np_walkers = new []NpcPerson } - if npc_st.np_posts == null { npc_st.np_posts = new []NpcPerson } - if npc_st.np_dice == null { npc_st.np_dice = rng_new(20260925) } +function np_ensure() -> void { } # how many walkers the place can hold at once export function npc_config(npc_st: mut NpcState, max: int) -> void { npc_st.np_max = max } -export function npc_seed(npc_st: mut NpcState, n: int) -> void { - np_ensure(npc_st) +export function npc_seed(npc_st: NpcState, n: int) -> void { + np_ensure() rng_seed(npc_st.np_dice, n) } # 0 .. 1, and whole seconds lo .. hi, off the package's dice -export function npc_rnd(npc_st: mut NpcState) -> float { - np_ensure(npc_st) +export function npc_rnd(npc_st: NpcState) -> float { + np_ensure() return rng_float(npc_st.np_dice) } -export function npc_between(npc_st: mut NpcState, lo: int, hi: int) -> int { - np_ensure(npc_st) +export function npc_between(npc_st: NpcState, lo: int, hi: int) -> int { + np_ensure() return rng_between(npc_st.np_dice, lo, hi) } -export function npc_secs(npc_st: mut NpcState, lo: int, hi: int) -> float { return float(npc_between(npc_st, lo, np_hi(lo, hi))) } +export function npc_secs(npc_st: NpcState, lo: int, hi: int) -> float { return float(npc_between(npc_st, lo, np_hi(lo, hi))) } -export function npc_walkers(npc_st: mut NpcState) -> []NpcPerson { - np_ensure(npc_st) +export function npc_walkers(npc_st: NpcState) -> []NpcPerson { + np_ensure() return npc_st.np_walkers } -export function npc_posts(npc_st: mut NpcState) -> []NpcPerson { - np_ensure(npc_st) +export function npc_posts(npc_st: NpcState) -> []NpcPerson { + np_ensure() return npc_st.np_posts } @@ -82,20 +78,20 @@ export function npc_count(npc_st: NpcState) -> int { return npc_st.np_n } export function npc_max(npc_st: NpcState) -> int { return npc_st.np_max } # a walker's slot or a post, and anyone by id -export function npc_at(npc_st: mut NpcState, slot: int) -> NpcPerson { - np_ensure(npc_st) +export function npc_at(npc_st: NpcState, slot: int) -> NpcPerson { + np_ensure() if slot < 0 or slot >= len(npc_st.np_walkers) { return null } return npc_st.np_walkers[slot] } -export function npc_post(npc_st: mut NpcState, i: int) -> NpcPerson { - np_ensure(npc_st) +export function npc_post(npc_st: NpcState, i: int) -> NpcPerson { + np_ensure() if i < 0 or i >= len(npc_st.np_posts) { return null } return npc_st.np_posts[i] } -export function npc_by_id(npc_st: mut NpcState, id: int) -> NpcPerson { - np_ensure(npc_st) +export function npc_by_id(npc_st: NpcState, id: int) -> NpcPerson { + np_ensure() for i in 0 .. len(npc_st.np_walkers) { if npc_st.np_walkers[i].active and npc_st.np_walkers[i].id == id { return npc_st.np_walkers[i] } } for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active and npc_st.np_posts[i].id == id { return npc_st.np_posts[i] } } return null @@ -118,3 +114,4 @@ function np_hi(lo: int, hi: int) -> int { if hi < lo { return lo } return hi } +function np_facts__new() -> Queue { return queue_new("npc.facts") } diff --git a/packages/ludic.npc/routine.ludic b/packages/ludic.npc/routine.ludic index 9192880b..12d51f0e 100644 --- a/packages/ludic.npc/routine.ludic +++ b/packages/ludic.npc/routine.ludic @@ -1,7 +1,7 @@ # routine.ludic - going somewhere to do something, doing it here, and deciding what is next: the # kind's own plan first, then a weighted draw among its steps for this hour, falling through to the # next step whose spot can be found, and standing a while when none can -export function npc_go(npc_st: mut NpcState, p: NpcPerson, x: float, z: float, act: int, dur: float) -> void { +export function npc_go(npc_st: NpcState, p: NpcPerson, x: float, z: float, act: int, dur: float) -> void { p.tx = x p.tz = z p.next_act = act @@ -76,7 +76,7 @@ export function npc_plan(npc_st: mut NpcState, p: NpcPerson) -> void { # a weighted draw among the steps whose hours hold now; a step whose spot cannot be found # gives way to the next one in the table, round to the start -export function npc_steps(npc_st: mut NpcState, p: NpcPerson, steps: []NpcStep) -> bool { +export function npc_steps(npc_st: NpcState, p: NpcPerson, steps: []NpcStep) -> bool { let h = NpcWorld.hour() var total = 0 for i in 0 .. len(steps) { if np_in_hours(steps[i], h) { total += np_pos(steps[i].weight) } } diff --git a/packages/ludic.npc/spots.ludic b/packages/ludic.npc/spots.ludic index c6951ed2..6e9c3946 100644 --- a/packages/ludic.npc/spots.ludic +++ b/packages/ludic.npc/spots.ludic @@ -10,7 +10,7 @@ def NpcSpots shore_here { find: fn np_spot_shore_here } def NpcSpots wander { find: fn np_spot_wander } # the step's act for the step's time, at (x, z) -export function npc_step_go(npc_st: mut NpcState, p: NpcPerson, s: NpcStep, x: float, z: float) -> void { +export function npc_step_go(npc_st: NpcState, p: NpcPerson, s: NpcStep, x: float, z: float) -> void { npc_go(npc_st, p, x, z, s.act, npc_secs(npc_st, s.lo, s.hi)) } diff --git a/packages/ludic.npc/tests/fake/index.ludic b/packages/ludic.npc/tests/fake/index.ludic index 75532b4c..0c268a70 100644 --- a/packages/ludic.npc/tests/fake/index.ludic +++ b/packages/ludic.npc/tests/fake/index.ludic @@ -55,7 +55,7 @@ function fk_player_at(npc_tests_fake_st: mut NpcTestsFakeState, x: float, z: flo # seconds of the place, in twentieths function fk_run(npc_st: mut NpcState, secs: float) -> void { for k in 0 .. int(secs * 20.0) { npc_tick(npc_st, 0.05) } } -function fk_count(npc_st: mut NpcState, what: int) -> int { +function fk_count(npc_st: NpcState, what: int) -> int { let fs = q_drain(npc_facts(npc_st)) var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.npc/tick.ludic b/packages/ludic.npc/tick.ludic index 4c48caab..4c0a09cd 100644 --- a/packages/ludic.npc/tick.ludic +++ b/packages/ludic.npc/tick.ludic @@ -1,7 +1,7 @@ # tick.ludic - a step of everyone, on the machine that runs the place: the census on the half hour, # the day's end (only ever out of every player's sight), the walk or the act, and who noticed whom export function npc_tick(npc_st: mut NpcState, dt: float) -> void { - np_ensure(npc_st) + np_ensure() for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active { np_step_post(npc_st, npc_st.np_posts[i], dt) } } if npc_st.np_hold or npc_st.np_mirror { return } np_census(npc_st) @@ -15,7 +15,7 @@ export function npc_tick(npc_st: mut NpcState, dt: float) -> void { # the posts alone: a machine that does not run the place still turns its vendors to whoever comes export function npc_posts_tick(npc_st: mut NpcState, dt: float) -> void { - np_ensure(npc_st) + np_ensure() for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active { np_step_post(npc_st, npc_st.np_posts[i], dt) } } } @@ -43,7 +43,7 @@ function np_census(npc_st: mut NpcState) -> void { function np_is_night(h: float) -> bool { return h >= 21.0 or h < 5.0 } -function np_draw_kind(npc_st: mut NpcState, night: bool) -> int { +function np_draw_kind(npc_st: NpcState, night: bool) -> int { var total = 0 for k in 0 .. NPCK_COUNT { if np_drawn(k, night) { total += NpcKinds[k].weight } } if total <= 0 { return -1 } @@ -82,7 +82,7 @@ export function npc_hold(npc_st: mut NpcState, on: bool) -> void { npc_st.np_hol # everyone gone, as a new trip starts; the posts are the place's and stay export function npc_reset(npc_st: mut NpcState) -> void { - np_ensure(npc_st) + np_ensure() for i in 0 .. len(npc_st.np_walkers) { npc_retire(npc_st, npc_st.np_walkers[i]) } npc_st.np_n = 0 npc_st.np_next_h = 0.0 diff --git a/packages/ludic.photo/roll.ludic b/packages/ludic.photo/roll.ludic index 4e9897b1..517a459c 100644 --- a/packages/ludic.photo/roll.ludic +++ b/packages/ludic.photo/roll.ludic @@ -54,17 +54,16 @@ export state PhotoState { pht_pending_stars: bool = false pht_comp: []float = null # size, framing, light, moment of the last subject scored pht_comp_have: bool = false - pht_fact_q: Queue = null + pht_fact_q: Queue = pht_fact_q__new() } -export function photo_facts(photo_st: mut PhotoState) -> Queue { - if photo_st.pht_fact_q == null { photo_st.pht_fact_q = queue_new("photo.facts") } +export function photo_facts(photo_st: PhotoState) -> Queue { return photo_st.pht_fact_q } -function pht_fact(photo_st: mut PhotoState, what: int, i: int) -> PhotoFact { +function pht_fact(photo_st: PhotoState, what: int, i: int) -> PhotoFact { let f = new PhotoFact f.what = what f.index = i @@ -100,3 +99,4 @@ function pht_blank(photo_st: mut PhotoState) -> void { photo_st.pht_comp = pht_floats(4) photo_st.pht_comp_have = false } +function pht_fact_q__new() -> Queue { return queue_new("photo.facts") } diff --git a/packages/ludic.photo/tests/photo_test.ludic b/packages/ludic.photo/tests/photo_test.ludic index 0787558b..047e541e 100644 --- a/packages/ludic.photo/tests/photo_test.ludic +++ b/packages/ludic.photo/tests/photo_test.ludic @@ -56,7 +56,7 @@ program PhotoTest { photo_test_st.sun_z = 0.0 photo_test_st.behaviour = false } - function facts(photo_st: mut PhotoState) -> []PhotoFact { return q_drain(photo_facts(photo_st)) } + function facts(photo_st: PhotoState) -> []PhotoFact { return q_drain(photo_facts(photo_st)) } function count(fs: []PhotoFact, what: int) -> int { var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.session/state.ludic b/packages/ludic.session/state.ludic index beb9ad9a..bb059151 100644 --- a/packages/ludic.session/state.ludic +++ b/packages/ludic.session/state.ludic @@ -66,7 +66,7 @@ export state SessionState { session__max: int = 4 session__open: bool = true session__near_i: int = 0 - session__facts: Queue = null + session__facts: Queue = session__facts__new() session__vote_id: int = 0 session__vote_kind: int = 0 session__vote_param: int = 0 @@ -78,12 +78,11 @@ export state SessionState { session__vote_passed: int = -1 # the last vote: -1 none, 0 failed, 1 passed } -export function ses_facts(session_st: mut SessionState) -> Queue { - if session_st.session__facts == null { session_st.session__facts = queue_new("session.facts") } +export function ses_facts(session_st: SessionState) -> Queue { return session_st.session__facts } -function session__fact(session_st: mut SessionState, what: int, slot: int, pid: int) -> SessionFact { +function session__fact(session_st: SessionState, what: int, slot: int, pid: int) -> SessionFact { let f = new SessionFact f.what = what f.slot = slot @@ -99,3 +98,4 @@ function session__init(session_st: mut SessionState) -> void { for i in 0 .. PLY_MAX { push(session_st.session__slot, new PartyMember) } session_st.session__slot[0].on = true } +function session__facts__new() -> Queue { return queue_new("session.facts") } diff --git a/packages/ludic.session/tests/session_test.ludic b/packages/ludic.session/tests/session_test.ludic index b7a58863..dd7ce8da 100644 --- a/packages/ludic.session/tests/session_test.ludic +++ b/packages/ludic.session/tests/session_test.ludic @@ -14,14 +14,14 @@ program SessionTest { function fname() -> string { return "me" } bind SessionLocal { x: fn fx, y: fn fy, z: fn fz, name: fn fname } - function whats(session_st: mut SessionState) -> []int { + function whats(session_st: SessionState) -> []int { let fs = q_drain(ses_facts(session_st)) let out = new []int for i in 0 .. len(fs) { push(out, fs[i].what) } return out } - function last_of(session_st: mut SessionState, what: int) -> SessionFact { + function last_of(session_st: SessionState, what: int) -> SessionFact { let fs = q_drain(ses_facts(session_st)) var f: SessionFact = null for i in 0 .. len(fs) { if fs[i].what == what { f = fs[i] } } diff --git a/packages/ludic.session/votes.ludic b/packages/ludic.session/votes.ludic index 8883fd5d..14de6bd2 100644 --- a/packages/ludic.session/votes.ludic +++ b/packages/ludic.session/votes.ludic @@ -92,7 +92,7 @@ function session__vote_finish(session_st: mut SessionState) -> void { f.yes = passed } -function session__vote_fact(session_st: mut SessionState, what: int) -> SessionFact { +function session__vote_fact(session_st: SessionState, what: int) -> SessionFact { let f = session__fact(session_st, what, -1, 0) f.id = session_st.session__vote_id f.kind = session_st.session__vote_kind diff --git a/packages/ludic.settings/store.ludic b/packages/ludic.settings/store.ludic index 7f30624f..fd8f0d81 100644 --- a/packages/ludic.settings/store.ludic +++ b/packages/ludic.settings/store.ludic @@ -4,7 +4,7 @@ export state SettingsState { sg_defs: []SettingDef = null sg_num: []float = null sg_text: []string = null - sg_changes: Queue = null + sg_changes: Queue = sg_changes__new() } function sg_init(settings_st: mut SettingsState) -> void { @@ -14,8 +14,7 @@ function sg_init(settings_st: mut SettingsState) -> void { settings_st.sg_text = new []string } -export function settings_changes(settings_st: mut SettingsState) -> Queue { - if settings_st.sg_changes == null { settings_st.sg_changes = queue_new("settings.changes") } +export function settings_changes(settings_st: SettingsState) -> Queue { return settings_st.sg_changes } @@ -55,7 +54,7 @@ export function settings_get_int(settings_st: SettingsState, id: int) -> int { r export function settings_get_bool(settings_st: SettingsState, id: int) -> bool { return settings_st.sg_num[id] != 0.0 } export function settings_get_text(settings_st: SettingsState, id: int) -> string { return settings_st.sg_text[id] } -function sg_changed(settings_st: mut SettingsState, id: int) -> void { +function sg_changed(settings_st: SettingsState, id: int) -> void { let c = new SettingChanged c.id = id c.key = settings_st.sg_defs[id].key @@ -93,3 +92,4 @@ export function settings_held(settings_st: SettingsState, id: int, v: float) -> if d.hi >= d.lo and (x < d.lo or x > d.hi) { return d.num } return x } +function sg_changes__new() -> Queue { return queue_new("settings.changes") } diff --git a/packages/ludic.settings/tests/settings_test.ludic b/packages/ludic.settings/tests/settings_test.ludic index 0374a8d6..07ef279b 100644 --- a/packages/ludic.settings/tests/settings_test.ludic +++ b/packages/ludic.settings/tests/settings_test.ludic @@ -11,7 +11,7 @@ program SettingsTest { for i in 0 .. TOY_COUNT { settings_add(settings_st, Toy[i]) } } - function facts(settings_st: mut SettingsState) -> []SettingChanged { return q_drain(settings_changes(settings_st)) } + function facts(settings_st: SettingsState) -> []SettingChanged { return q_drain(settings_changes(settings_st)) } test "a registry declares the store, each at its default" (settings_st: mut SettingsState) { declare(settings_st) diff --git a/packages/ludic.shop/state.ludic b/packages/ludic.shop/state.ludic index e60fe585..01f423d7 100644 --- a/packages/ludic.shop/state.ludic +++ b/packages/ludic.shop/state.ludic @@ -49,7 +49,7 @@ export state ShopState { shop_buy_best: float = 0.92 shop_sell_new: float = 0.62 shop_sell_best: float = 0.85 - shop_trade_q: Queue = null + shop_trade_q: Queue = shop_trade_q__new() } # the curve: buying from `buy_new` of base at rep 0 down to `buy_best` at 100; selling the same way @@ -106,7 +106,7 @@ export property ShopTrade { } -export function shop_trades(shop_st: mut ShopState) -> Queue { - if shop_st.shop_trade_q == null { shop_st.shop_trade_q = queue_new("shop.trades") } +export function shop_trades(shop_st: ShopState) -> Queue { return shop_st.shop_trade_q } +function shop_trade_q__new() -> Queue { return queue_new("shop.trades") } diff --git a/packages/ludic.shop/tests/shop_test.ludic b/packages/ludic.shop/tests/shop_test.ludic index 1c109068..b0c8dd2d 100644 --- a/packages/ludic.shop/tests/shop_test.ludic +++ b/packages/ludic.shop/tests/shop_test.ludic @@ -98,7 +98,7 @@ program ShopTest { shop_reset(shop_st) } - function trades(shop_st: mut ShopState) -> []ShopTrade { return q_drain(shop_trades(shop_st)) } + function trades(shop_st: ShopState) -> []ShopTrade { return q_drain(shop_trades(shop_st)) } test "buying takes the price and puts one in the pack, and says so" (shop_st: mut ShopState, shop_test_st: mut ShopTestState) { fresh(shop_st, shop_test_st) diff --git a/packages/ludic.shop/trade.ludic b/packages/ludic.shop/trade.ludic index 0fd6ba0b..95227115 100644 --- a/packages/ludic.shop/trade.ludic +++ b/packages/ludic.shop/trade.ludic @@ -26,7 +26,7 @@ export function shop_sellable(shop_st: ShopState, v: int) -> []int { return out } -function shop_trade_fact(shop_st: mut ShopState, what: int, it: int, n: int, price: int) -> void { +function shop_trade_fact(shop_st: ShopState, what: int, it: int, n: int, price: int) -> void { let t = new ShopTrade t.what = what t.vendor = shop_st.shop_at @@ -41,7 +41,7 @@ export function shop_can_buy(shop_st: ShopState, it: int) -> bool { } # one, paid for and in the pack; false and nothing spent when it cannot be -export function shop_buy(shop_st: mut ShopState, it: int) -> bool { +export function shop_buy(shop_st: ShopState, it: int) -> bool { if not shop_can_buy(shop_st, it) { return false } let pr = shop_price_buy(shop_st, it) if not ShopPurse.spend(pr) { return false } diff --git a/packages/ludic.steps/state.ludic b/packages/ludic.steps/state.ludic index 12088490..2de19892 100644 --- a/packages/ludic.steps/state.ludic +++ b/packages/ludic.steps/state.ludic @@ -56,15 +56,14 @@ export state StepsState { steps__need: []int = null steps__cur: int = 0 steps__done: int = 0 - steps__facts: Queue = null + steps__facts: Queue = steps__facts__new() } -export function steps_facts(steps_st: mut StepsState) -> Queue { - if steps_st.steps__facts == null { steps_st.steps__facts = queue_new("steps.facts") } +export function steps_facts(steps_st: StepsState) -> Queue { return steps_st.steps__facts } -function steps__fact(steps_st: mut StepsState, what: int, ch: int, i: int) -> void { +function steps__fact(steps_st: StepsState, what: int, ch: int, i: int) -> void { let f = new StepsFact f.what = what f.chapter = ch @@ -81,3 +80,4 @@ export function steps_popcount(m: int) -> int { } return n } +function steps__facts__new() -> Queue { return queue_new("steps.facts") } diff --git a/packages/ludic.steps/tests/steps_test.ludic b/packages/ludic.steps/tests/steps_test.ludic index b1c4a3a5..e88b3353 100644 --- a/packages/ludic.steps/tests/steps_test.ludic +++ b/packages/ludic.steps/tests/steps_test.ludic @@ -63,7 +63,7 @@ program StepsTest { steps_add(steps_st, K_COMPASS, 0, 1) } - function facts_of(steps_st: mut StepsState, what: int) -> int { + function facts_of(steps_st: StepsState, what: int) -> int { let fs = q_drain(steps_facts(steps_st)) var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.telemetry/ports.ludic b/packages/ludic.telemetry/ports.ludic index 7e74c73c..e8d2cb6c 100644 --- a/packages/ludic.telemetry/ports.ludic +++ b/packages/ludic.telemetry/ports.ludic @@ -1,8 +1,7 @@ # ports.ludic - the config, and what the ports answer when the game leaves them unbound export function telemetry_config(telemetry_st: mut TelemetryState, c: TelemetryConfig) -> void { telemetry_st.telemetry__cfg = c } -function telemetry__conf(telemetry_st: mut TelemetryState) -> TelemetryConfig { - if telemetry_st.telemetry__cfg == null { telemetry_st.telemetry__cfg = new TelemetryConfig } +function telemetry__conf(telemetry_st: TelemetryState) -> TelemetryConfig { return telemetry_st.telemetry__cfg } @@ -10,7 +9,7 @@ function telemetry__yes() -> bool { return true } function telemetry__wall_ms(telemetry_st: TelemetryState) -> int { return (Time.now() - telemetry_st.telemetry__t0) * 1000 } function telemetry__wall_stamp() -> string { return DateTime.format(Time.now(), "YYYY-MM-DDTHH:mm:ssZ") } -function telemetry__can_send(telemetry_st: mut TelemetryState) -> bool { +function telemetry__can_send(telemetry_st: TelemetryState) -> bool { let c = telemetry__conf(telemetry_st) if len(c.host) == 0 or len(c.key) == 0 { return false } return TelemetryWorld.can_send() @@ -40,7 +39,7 @@ function telemetry__http_poll(h: int) -> int { function telemetry__http_drop(h: int) -> void { Http.free(h) } -function telemetry__send(telemetry_st: mut TelemetryState, body: string) -> int { return TelemetryTransport.send(telemetry__conf(telemetry_st).host + telemetry__conf(telemetry_st).path, body) } +function telemetry__send(telemetry_st: TelemetryState, body: string) -> int { return TelemetryTransport.send(telemetry__conf(telemetry_st).host + telemetry__conf(telemetry_st).path, body) } function telemetry__poll(h: int) -> int { return TelemetryTransport.poll(h) } # a request abandoned (the player said no) diff --git a/packages/ludic.telemetry/queries.ludic b/packages/ludic.telemetry/queries.ludic index df83b987..641ba8f9 100644 --- a/packages/ludic.telemetry/queries.ludic +++ b/packages/ludic.telemetry/queries.ludic @@ -2,7 +2,7 @@ export function telemetry_id(telemetry_st: TelemetryState) -> string { return telemetry_st.telemetry__id } export function telemetry_session(telemetry_st: TelemetryState) -> string { return telemetry_st.telemetry__session } export function telemetry_ready(telemetry_st: TelemetryState) -> bool { return telemetry_st.telemetry__ready } -export function telemetry_get_config(telemetry_st: mut TelemetryState) -> TelemetryConfig { return telemetry__conf(telemetry_st) } +export function telemetry_get_config(telemetry_st: TelemetryState) -> TelemetryConfig { return telemetry__conf(telemetry_st) } export function telemetry_fails(telemetry_st: TelemetryState) -> int { return telemetry_st.telemetry__fails } export function telemetry_next_ms(telemetry_st: TelemetryState) -> int { return telemetry_st.telemetry__next_ms } export function telemetry_in_flight(telemetry_st: TelemetryState) -> bool { return telemetry_st.telemetry__h >= 0 } diff --git a/packages/ludic.telemetry/queue.ludic b/packages/ludic.telemetry/queue.ludic index b507ac70..db920021 100644 --- a/packages/ludic.telemetry/queue.ludic +++ b/packages/ludic.telemetry/queue.ludic @@ -13,7 +13,7 @@ export function telemetry_start(telemetry_st: mut TelemetryState) -> void { } # may an event be kept right now? -export function telemetry_on(telemetry_st: mut TelemetryState) -> bool { return telemetry_st.telemetry__ready and telemetry__enabled() and telemetry__can_send(telemetry_st) } +export function telemetry_on(telemetry_st: TelemetryState) -> bool { return telemetry_st.telemetry__ready and telemetry__enabled() and telemetry__can_send(telemetry_st) } # an event: the properties (null for none) with the session and the library added, and the player # as a mark put in when the batch goes, so an event queued before the id is known is not misfiled @@ -77,7 +77,7 @@ function telemetry__queue_drop(telemetry_st: mut TelemetryState, n: int) -> void } # the batch: the first n lines joined, with the player id put in - no parsing -export function telemetry_batch_body(telemetry_st: mut TelemetryState, n: int) -> string { +export function telemetry_batch_body(telemetry_st: TelemetryState, n: int) -> string { let part = new []string for i in 0 .. n { push(part, telemetry_st.telemetry__q[i]) } let head = Value.object() diff --git a/packages/ludic.telemetry/state.ludic b/packages/ludic.telemetry/state.ludic index aa584cb6..d8280f28 100644 --- a/packages/ludic.telemetry/state.ludic +++ b/packages/ludic.telemetry/state.ludic @@ -52,7 +52,7 @@ export state TelemetryState { telemetry__proc_t0: int = 0 telemetry__rand_n: int = 0 telemetry__clock_on: bool = false - telemetry__cfg: TelemetryConfig = null + telemetry__cfg: TelemetryConfig = new TelemetryConfig telemetry__ready: bool = false telemetry__id: string = "" telemetry__session: string = "" @@ -64,15 +64,14 @@ export state TelemetryState { telemetry__saved_ms: int = 0 # when the queue was last put on disk telemetry__fails: int = 0 # sends failed in a row telemetry__t0: int = 0 # the default clock's zero, wall seconds - telemetry__facts: Queue = null + telemetry__facts: Queue = telemetry__facts__new() } -export function telemetry_facts(telemetry_st: mut TelemetryState) -> Queue { - if telemetry_st.telemetry__facts == null { telemetry_st.telemetry__facts = queue_new("telemetry.facts") } +export function telemetry_facts(telemetry_st: TelemetryState) -> Queue { return telemetry_st.telemetry__facts } -function telemetry__fact(telemetry_st: mut TelemetryState, what: int, count: int, status: int, retry: int) -> void { +function telemetry__fact(telemetry_st: TelemetryState, what: int, count: int, status: int, retry: int) -> void { let f = new TelemetryFact f.what = what f.count = count @@ -80,3 +79,4 @@ function telemetry__fact(telemetry_st: mut TelemetryState, what: int, count: int f.retry_ms = retry q_push(telemetry_facts(telemetry_st), f) } +function telemetry__facts__new() -> Queue { return queue_new("telemetry.facts") } diff --git a/packages/ludic.telemetry/tests/telemetry_test.ludic b/packages/ludic.telemetry/tests/telemetry_test.ludic index e2e4c54d..3c6edaa0 100644 --- a/packages/ludic.telemetry/tests/telemetry_test.ludic +++ b/packages/ludic.telemetry/tests/telemetry_test.ludic @@ -73,7 +73,7 @@ program TelemetryTest { telemetry_tick(telemetry_st) } - function facts_of(telemetry_st: mut TelemetryState, what: int) -> int { + function facts_of(telemetry_st: TelemetryState, what: int) -> int { let fs = q_drain(telemetry_facts(telemetry_st)) var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.things/dispatch.ludic b/packages/ludic.things/dispatch.ludic index 492508d6..c00fcc20 100644 --- a/packages/ludic.things/dispatch.ludic +++ b/packages/ludic.things/dispatch.ludic @@ -21,7 +21,7 @@ export function thing_prompt(t: Thing) -> string { } # the kind does what using it does; the use is a fact whatever the kind made of it -export function thing_use(things_st: mut ThingsState, t: Thing) -> void { +export function thing_use(things_st: ThingsState, t: Thing) -> void { if t == null or not thing_kind_ok(t.kind) { return } let k = ThingKinds[t.kind] th_fact(things_st, THING_USED, t) @@ -46,7 +46,7 @@ export function thing_is_personal(t: Thing) -> bool { return thing_kind_ok(t.kin export function thing_is_put_down(t: Thing) -> bool { return ThingsWorld.put_down(t) } # every active Thing whose kind ticks, `hours` of the world's clock on -export function things_tick(things_st: mut ThingsState, hours: float) -> void { +export function things_tick(things_st: ThingsState, hours: float) -> void { let all = things_all(things_st) for i in 0 .. len(all) { let t = all[i] @@ -58,7 +58,7 @@ export function things_tick(things_st: mut ThingsState, hours: float) -> void { # a restock: every Thing the world grew is back, and loses its `used` unless its kind keeps it; # what was put down is left as it is -export function things_restock(things_st: mut ThingsState) -> void { +export function things_restock(things_st: ThingsState) -> void { let all = things_all(things_st) for i in 0 .. len(all) { let t = all[i] diff --git a/packages/ludic.things/queries.ludic b/packages/ludic.things/queries.ludic index a38a6d86..82f9961d 100644 --- a/packages/ludic.things/queries.ludic +++ b/packages/ludic.things/queries.ludic @@ -3,7 +3,7 @@ function th_of(t: Thing, kind: int) -> bool { return kind < 0 or t.kind == kind } # the first active one of a kind (and of that id, unless id < 0), in the order placed -export function thing_find(things_st: mut ThingsState, kind: int, id: int) -> Thing { +export function thing_find(things_st: ThingsState, kind: int, id: int) -> Thing { let all = things_all(things_st) for i in 0 .. len(all) { let t = all[i] @@ -12,14 +12,14 @@ export function thing_find(things_st: mut ThingsState, kind: int, id: int) -> Th return null } -export function thing_by_uid(things_st: mut ThingsState, uid: int) -> Thing { +export function thing_by_uid(things_st: ThingsState, uid: int) -> Thing { let all = things_all(things_st) for i in 0 .. len(all) { if all[i].uid == uid { return all[i] } } return null } # the nearest active one of a kind to (x, z), or null -export function thing_nearest(things_st: mut ThingsState, kind: int, x: float, z: float) -> Thing { +export function thing_nearest(things_st: ThingsState, kind: int, x: float, z: float) -> Thing { var best: Thing = null var bd = 0.0 let all = things_all(things_st) @@ -43,7 +43,7 @@ export function thing_dist2(t: Thing, x: float, z: float) -> float { } # every active one within r of (x, z), nearest first -export function things_within(things_st: mut ThingsState, x: float, z: float, r: float) -> []Thing { +export function things_within(things_st: ThingsState, x: float, z: float, r: float) -> []Thing { let out = new []Thing let all = things_all(things_st) for i in 0 .. len(all) { @@ -64,7 +64,7 @@ function th_insert(out: []Thing, t: Thing, x: float, z: float) -> void { } # every active one of a kind, in the order placed -export function things_each(things_st: mut ThingsState, kind: int) -> []Thing { +export function things_each(things_st: ThingsState, kind: int) -> []Thing { let out = new []Thing let all = things_all(things_st) for i in 0 .. len(all) { if all[i].active and th_of(all[i], kind) { push(out, all[i]) } } @@ -72,7 +72,7 @@ export function things_each(things_st: mut ThingsState, kind: int) -> []Thing { } # every one of a kind, active or not -export function things_each_all(things_st: mut ThingsState, kind: int) -> []Thing { +export function things_each_all(things_st: ThingsState, kind: int) -> []Thing { let out = new []Thing let all = things_all(things_st) for i in 0 .. len(all) { if th_of(all[i], kind) { push(out, all[i]) } } diff --git a/packages/ludic.things/store.ludic b/packages/ludic.things/store.ludic index ed42bb2b..673463a9 100644 --- a/packages/ludic.things/store.ludic +++ b/packages/ludic.things/store.ludic @@ -1,18 +1,17 @@ # store.ludic - the Things, and the only verbs that make, remove, move, show and hide one; each # placing and removing is a fact, and the port is told at once so the game can draw it export state ThingsState { - th_list: []Thing = null + th_list: []Thing = new []Thing th_uid: int = 0 - th_facts: Queue = null + th_facts: Queue = th_facts__new() th_marked: int = -1 } -export function things_facts(things_st: mut ThingsState) -> Queue { - if things_st.th_facts == null { things_st.th_facts = queue_new("things.facts") } +export function things_facts(things_st: ThingsState) -> Queue { return things_st.th_facts } -function th_fact(things_st: mut ThingsState, what: int, t: Thing) -> void { +function th_fact(things_st: ThingsState, what: int, t: Thing) -> void { let f = new ThingFact f.what = what f.uid = t.uid @@ -28,12 +27,11 @@ function th_fact(things_st: mut ThingsState, what: int, t: Thing) -> void { export function things_ready(things_st: ThingsState) -> bool { return things_st.th_list != null } # every Thing, in the order placed; the list is the package's, never to be pushed to -export function things_all(things_st: mut ThingsState) -> []Thing { - if things_st.th_list == null { things_st.th_list = new []Thing } +export function things_all(things_st: ThingsState) -> []Thing { return things_st.th_list } -export function things_count(things_st: mut ThingsState) -> int { return len(things_all(things_st)) } +export function things_count(things_st: ThingsState) -> int { return len(things_all(things_st)) } # a new world: every Thing forgotten, quietly (the game has already dropped its drawings) export function things_clear(things_st: mut ThingsState) -> void { things_st.th_list = new []Thing } @@ -110,3 +108,4 @@ export function thing_set_active(t: Thing, on: bool) -> void { } export function thing_hide(t: Thing) -> void { thing_set_active(t, false) } export function thing_show(t: Thing) -> void { thing_set_active(t, true) } +function th_facts__new() -> Queue { return queue_new("things.facts") } diff --git a/packages/ludic.things/system.ludic b/packages/ludic.things/system.ludic index ecf81f8b..1aeb22f9 100644 --- a/packages/ludic.things/system.ludic +++ b/packages/ludic.things/system.ludic @@ -1,6 +1,6 @@ # system.ludic - the things as a system: its save section carries every active Thing the port # keeps, by its kind's KEY (so the game may reorder its kinds), and a load puts each back -export function things_save(things_st: mut ThingsState) -> Val { +export function things_save(things_st: ThingsState) -> Val { let l = Value.list() let all = things_all(things_st) for i in 0 .. len(all) { diff --git a/packages/ludic.things/tests/things_test.ludic b/packages/ludic.things/tests/things_test.ludic index 412f3fdd..ee29c413 100644 --- a/packages/ludic.things/tests/things_test.ludic +++ b/packages/ludic.things/tests/things_test.ludic @@ -45,7 +45,7 @@ program ThingsTest { bind ThingsWorld { ground: fn hill, placed: fn on_placed, removed: fn on_removed, shown: fn on_shown, restored: fn on_restored } function put(things_st: mut ThingsState, kind: int, x: float, z: float) -> Thing { return thing_spawn(things_st, kind, "m", x, 0.0, z, 0.0, 0) } - function facts(things_st: mut ThingsState) -> []ThingFact { return q_drain(things_facts(things_st)) } + function facts(things_st: ThingsState) -> []ThingFact { return q_drain(things_facts(things_st)) } test "a spawn is drawn, numbered and said" (things_st: mut ThingsState, things_test_st: ThingsTestState) { things_clear(things_st) diff --git a/packages/ludic.tracks/state.ludic b/packages/ludic.tracks/state.ludic index 61099770..303b244a 100644 --- a/packages/ludic.tracks/state.ludic +++ b/packages/ludic.tracks/state.ludic @@ -59,12 +59,12 @@ export state TracksState { tk_read_n: int = 0 # signs read for the first time, of every source tk_yaw: float = 0.0 # the heading of the last sign read tk_has_yaw: bool = false - tk_reads: Queue = null + tk_reads: Queue = tk_reads__new() } # the facts: every sign read, oldest first -export function tracks_reads(tracks_st: mut TracksState) -> Queue { - if tracks_st.tk_reads == null { tracks_st.tk_reads = queue_new("tracks.reads") } +export function tracks_reads(tracks_st: TracksState) -> Queue { return tracks_st.tk_reads } +function tk_reads__new() -> Queue { return queue_new("tracks.reads") } diff --git a/packages/ludic.tracks/tests/tracks_test.ludic b/packages/ludic.tracks/tests/tracks_test.ludic index 9fc1cde1..ae193349 100644 --- a/packages/ludic.tracks/tests/tracks_test.ludic +++ b/packages/ludic.tracks/tests/tracks_test.ludic @@ -35,7 +35,7 @@ program TracksTest { tracks_reset(tracks_st) } - function reads(tracks_st: mut TracksState) -> []TrackRead { return q_drain(tracks_reads(tracks_st)) } + function reads(tracks_st: TracksState) -> []TrackRead { return q_drain(tracks_reads(tracks_st)) } test "a print goes into its kind's ring and is drawn" (tracks_st: mut TracksState, tracks_test_st: mut TracksTestState) { fresh(tracks_st, tracks_test_st) diff --git a/packages/ludic.ui/backend.ludic b/packages/ludic.ui/backend.ludic index 9aa51e19..3b6d3558 100644 --- a/packages/ludic.ui/backend.ludic +++ b/packages/ludic.ui/backend.ludic @@ -51,7 +51,7 @@ export state UiState { ca_bare: bool = false cs_pass: int = 0 ua_sh: UiSheet = null - uc_list: []UiClass = null # filled by the compiler's registrations, before the program's globals + uc_list: []UiClass = new []UiClass # filled by the compiler's registrations, before the program's globals cl_alpha: float = 1.0 ct_capture: string = "" ct_capture_at: int = -1 # the frame listening began, whose own key started it diff --git a/packages/ludic.ui/class.ludic b/packages/ludic.ui/class.ludic index c95080ba..a79248c8 100644 --- a/packages/ludic.ui/class.ludic +++ b/packages/ludic.ui/class.ludic @@ -17,7 +17,6 @@ export property UiClass { seen_lss: string = "" } export function ui_register(ui_st: mut UiState, k: UiClass) -> int { - if ui_st.uc_list == null { ui_st.uc_list = new []UiClass } push(ui_st.uc_list, k) return len(ui_st.uc_list) } diff --git a/packages/ludic.update/chain.ludic b/packages/ludic.update/chain.ludic index 34454b27..03a51d8c 100644 --- a/packages/ludic.update/chain.ludic +++ b/packages/ludic.update/chain.ludic @@ -46,4 +46,4 @@ export function update_plan_version(update_st: UpdateState, i: int) -> string { export function update_target(update_st: UpdateState) -> string { return update_st.update__target } export function update_total_bytes(update_st: UpdateState) -> int { return update_st.update__total_bytes } -function update__path(update_st: mut UpdateState, i: int) -> string { return update_packages(update_st) + update__sep() + update_st.update__files[i] } +function update__path(update_st: UpdateState, i: int) -> string { return update_packages(update_st) + update__sep() + update_st.update__files[i] } diff --git a/packages/ludic.update/install.ludic b/packages/ludic.update/install.ludic index c295a02e..49e85852 100644 --- a/packages/ludic.update/install.ludic +++ b/packages/ludic.update/install.ludic @@ -44,7 +44,7 @@ function update__up(p: string) -> string { # the executable's directory export function update_dir() -> string { return update__up(UpdateWorld.exe()) } -export function update_root(update_st: mut UpdateState) -> string { +export function update_root(update_st: UpdateState) -> string { let c = update__conf(update_st) if len(c.root) > 0 { return c.root } if update__mac() { return update__up(update__up(update_dir())) } @@ -52,7 +52,7 @@ export function update_root(update_st: mut UpdateState) -> string { } # where the packages live: never inside a macOS bundle, which is read-only and which apply replaces -export function update_packages(update_st: mut UpdateState) -> string { +export function update_packages(update_st: UpdateState) -> string { let c = update__conf(update_st) if len(c.packages) > 0 { return c.packages } if update__mac() and len(c.mac_packages) > 0 { return c.mac_packages } @@ -64,7 +64,7 @@ function update__feed_file() -> string { return "releases.win.json" } -function update__updater(update_st: mut UpdateState) -> string { +function update__updater(update_st: UpdateState) -> string { if update__mac() { return update_root(update_st) + "/Contents/MacOS/UpdateMac" } return update_root(update_st) + update__sep() + "Update.exe" } @@ -76,7 +76,7 @@ export function update_translocated() -> bool { } # can this copy update itself? A copy Velopack did not install downloads the game again instead. -export function update_installed(update_st: mut UpdateState) -> bool { +export function update_installed(update_st: UpdateState) -> bool { if len(update__conf(update_st).root) > 0 { return true } if update_translocated() { return false } if update__mac() { return Fs.exists(update_dir() + "/UpdateMac") } diff --git a/packages/ludic.update/plan.ludic b/packages/ludic.update/plan.ludic index f2384b9a..b255f655 100644 --- a/packages/ludic.update/plan.ludic +++ b/packages/ludic.update/plan.ludic @@ -10,7 +10,7 @@ property UpdateAsset { } # this app's packages in the feed ({"Assets": [{PackageId, Version, Type, FileName, SHA256, Size}]}) -function update__assets(update_st: mut UpdateState, feed: Val) -> []UpdateAsset { +function update__assets(update_st: UpdateState, feed: Val) -> []UpdateAsset { let out = new []UpdateAsset if feed == null or Value.kind(feed) != 6 or Value.has(feed, "Assets") == 0 { return out } let all = Value.get(feed, "Assets") @@ -31,7 +31,7 @@ function update__assets(update_st: mut UpdateState, feed: Val) -> []UpdateAsset # What the feed calls the FULL package of version v. Never built here: Velopack puts the channel in # a macOS name (App-0.3.4-osx-full.nupkg) and not a Windows one, and it is both the name a patch # writes and the name the next update looks for as its base. -function update__full_name(update_st: mut UpdateState, as: []UpdateAsset, v: string) -> string { +function update__full_name(update_st: UpdateState, as: []UpdateAsset, v: string) -> string { for i in 0 .. len(as) { if not as[i].delta and as[i].ver == v { return as[i].file } } return update__conf(update_st).app_id + "-" + v + "-full.nupkg" } @@ -46,7 +46,7 @@ function update__newest_full(as: []UpdateAsset) -> int { } # the deltas above this version up to the newest, oldest first -function update__chain(update_st: mut UpdateState, as: []UpdateAsset, newest: string) -> []UpdateAsset { +function update__chain(update_st: UpdateState, as: []UpdateAsset, newest: string) -> []UpdateAsset { let out = new []UpdateAsset let mine = update__conf(update_st).version for i in 0 .. len(as) { @@ -65,7 +65,7 @@ function update__chain(update_st: mut UpdateState, as: []UpdateAsset, newest: st return out } -function update__fulls_after(update_st: mut UpdateState, as: []UpdateAsset) -> int { +function update__fulls_after(update_st: UpdateState, as: []UpdateAsset) -> int { var n = 0 for i in 0 .. len(as) { if not as[i].delta and update_newer(as[i].ver, update__conf(update_st).version) { n += 1 } } return n diff --git a/packages/ludic.update/state.ludic b/packages/ludic.update/state.ludic index ea08ecd7..e5394d84 100644 --- a/packages/ludic.update/state.ludic +++ b/packages/ludic.update/state.ludic @@ -56,7 +56,7 @@ export state UpdateState { update__ask_h: int = -1 update__latest: string = "" update__notes: Val = null - update__cfg: UpdateConfig = null + update__cfg: UpdateConfig = new UpdateConfig update__state: int = 0 update__err: int = 0 update__h: int = -1 # the request @@ -77,22 +77,20 @@ export state UpdateState { update__rate: int = 0 # bytes a second, eased update__rate_t: int = -1 update__rate_bytes: int = 0 - update__facts: Queue = null + update__facts: Queue = update__facts__new() } export function update_config(update_st: mut UpdateState, c: UpdateConfig) -> void { update_st.update__cfg = c } -function update__conf(update_st: mut UpdateState) -> UpdateConfig { - if update_st.update__cfg == null { update_st.update__cfg = new UpdateConfig } +function update__conf(update_st: UpdateState) -> UpdateConfig { return update_st.update__cfg } -export function update_facts(update_st: mut UpdateState) -> Queue { - if update_st.update__facts == null { update_st.update__facts = queue_new("update.facts") } +export function update_facts(update_st: UpdateState) -> Queue { return update_st.update__facts } -function update__fact(update_st: mut UpdateState, what: int) -> void { +function update__fact(update_st: UpdateState, what: int) -> void { let f = new UpdateFact f.what = what f.error = update_st.update__err @@ -101,3 +99,4 @@ function update__fact(update_st: mut UpdateState, what: int) -> void { f.bytes = update_st.update__total_bytes q_push(update_facts(update_st), f) } +function update__facts__new() -> Queue { return queue_new("update.facts") } diff --git a/packages/ludic.update/steps.ludic b/packages/ludic.update/steps.ludic index 05030153..c5a64546 100644 --- a/packages/ludic.update/steps.ludic +++ b/packages/ludic.update/steps.ludic @@ -50,7 +50,7 @@ function update__fetch(update_st: mut UpdateState, i: int) -> void { update_st.update__state = UPDATE_FETCH } -function update__hash_file(update_st: mut UpdateState) -> string { +function update__hash_file(update_st: UpdateState) -> string { if len(update__conf(update_st).scratch) > 0 { return update__conf(update_st).scratch } return Os.temp_dir() + "/ludic-update-hash.txt" } @@ -80,7 +80,7 @@ function update__check(update_st: mut UpdateState, i: int) -> void { } # the hash the child wrote: the first line with anything on it -function update__hash_read(update_st: mut UpdateState) -> string { +function update__hash_read(update_st: UpdateState) -> string { let s = Fs.read_text(update__hash_file(update_st)) if s == null { return "" } let lines = Text.split(s, "\n") diff --git a/packages/ludic.update/tests/update_test.ludic b/packages/ludic.update/tests/update_test.ludic index 94f52891..2dfa30b4 100644 --- a/packages/ludic.update/tests/update_test.ludic +++ b/packages/ludic.update/tests/update_test.ludic @@ -89,7 +89,7 @@ program UpdateTest { function seed_base() -> void { Fs.write_text(pkgs() + "/Game-1.0.0-osx-full.nupkg", "base") } function plan_of(update_st: mut UpdateState, text: string) -> bool { return update_plan(update_st, Json.parse(text)) } - function facts_of(update_st: mut UpdateState, what: int) -> int { + function facts_of(update_st: UpdateState, what: int) -> int { let fs = q_drain(update_facts(update_st)) var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.wallet/tests/wallet_test.ludic b/packages/ludic.wallet/tests/wallet_test.ludic index 8ae062bb..9af82e53 100644 --- a/packages/ludic.wallet/tests/wallet_test.ludic +++ b/packages/ludic.wallet/tests/wallet_test.ludic @@ -5,8 +5,8 @@ import "ludic.base" program WalletTest { numbers float - function changes(wallet_st: mut WalletState) -> []MoneyChanged { return q_drain(wallet_changes(wallet_st)) } - function waiting(wallet_st: mut WalletState) -> int { return q_len(wallet_changes(wallet_st)) } + function changes(wallet_st: WalletState) -> []MoneyChanged { return q_drain(wallet_changes(wallet_st)) } + function waiting(wallet_st: WalletState) -> int { return q_len(wallet_changes(wallet_st)) } test "earning and spending move the purse, and each says so" (wallet_st: mut WalletState) { wallet_reset(wallet_st) diff --git a/packages/ludic.wallet/wallet.ludic b/packages/ludic.wallet/wallet.ludic index fd1da04d..fbf1c711 100644 --- a/packages/ludic.wallet/wallet.ludic +++ b/packages/ludic.wallet/wallet.ludic @@ -6,11 +6,10 @@ export property MoneyChanged { export state WalletState { wl_money: int = 0 - wl_changes: Queue = null + wl_changes: Queue = wl_changes__new() } -export function wallet_changes(wallet_st: mut WalletState) -> Queue { - if wallet_st.wl_changes == null { wallet_st.wl_changes = queue_new("wallet.changes") } +export function wallet_changes(wallet_st: WalletState) -> Queue { return wallet_st.wl_changes } @@ -62,3 +61,4 @@ export function wallet_system() -> System { s.load = fn wallet_load return s } +function wl_changes__new() -> Queue { return queue_new("wallet.changes") } diff --git a/packages/ludic.weather/state.ludic b/packages/ludic.weather/state.ludic index ca95366c..9e99b11e 100644 --- a/packages/ludic.weather/state.ludic +++ b/packages/ludic.weather/state.ludic @@ -74,19 +74,19 @@ export state WeatherState { wx_wet_today: bool = false wx_wet_yesterday: bool = false wx_dice: Rng = null - wx_facts: Queue = null + wx_facts: Queue = wx_facts__new() } # the facts, oldest first; the game drains them into its notices and sounds -export function weather_facts(weather_st: mut WeatherState) -> Queue { - if weather_st.wx_facts == null { weather_st.wx_facts = queue_new("weather.facts") } +export function weather_facts(weather_st: WeatherState) -> Queue { return weather_st.wx_facts } -function wx_fact(weather_st: mut WeatherState, what: int, kind: int, from: int) -> void { +function wx_fact(weather_st: WeatherState, what: int, kind: int, from: int) -> void { let f = new WeatherFact f.what = what f.kind = kind f.from = from q_push(weather_facts(weather_st), f) } +function wx_facts__new() -> Queue { return queue_new("weather.facts") } diff --git a/packages/ludic.weather/tests/weather_test.ludic b/packages/ludic.weather/tests/weather_test.ludic index a911f123..876b065a 100644 --- a/packages/ludic.weather/tests/weather_test.ludic +++ b/packages/ludic.weather/tests/weather_test.ludic @@ -73,7 +73,7 @@ program WeatherTest { weather_reset(weather_st) } - function facts(weather_st: mut WeatherState) -> []WeatherFact { return q_drain(weather_facts(weather_st)) } + function facts(weather_st: WeatherState) -> []WeatherFact { return q_drain(weather_facts(weather_st)) } function step(weather_st: mut WeatherState, dt: float, gh: float, n: int) -> void { for i in 0 .. n { weather_run(weather_st, dt, gh) } } function count(fs: []WeatherFact, what: int) -> int { var n = 0 diff --git a/packages/ludic.wildlife/birds.ludic b/packages/ludic.wildlife/birds.ludic index 9ce3248c..f205cbf4 100644 --- a/packages/ludic.wildlife/birds.ludic +++ b/packages/ludic.wildlife/birds.ludic @@ -42,7 +42,7 @@ function wl_come_down(a: WildAnimal, x: float, z: float) -> void { } # a circle about home, climbing to its height: the eagle wide and high, the jay low -function wl_circle(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> void { +function wl_circle(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> void { let s = wl_sp(wildlife_st, a.sp) a.fly_h = a.fly_h + (8.0 + s.home * 0.12 - a.fly_h) * Math.min(1.0, 0.4 * dt) let r = s.home * 0.5 @@ -57,13 +57,13 @@ function wl_circle(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> a.bank = 0.35 } -function wl_take_off(wildlife_st: mut WildlifeState, a: WildAnimal, h: float) -> void { +function wl_take_off(wildlife_st: WildlifeState, a: WildAnimal, h: float) -> void { a.state = WILD_FLY a.timer = 20.0 + wl_rnd(wildlife_st) * 40.0 a.fly_h = Math.max(a.fly_h, h) } -function wl_land(wildlife_st: mut WildlifeState, a: WildAnimal, dh: float, dt: float) -> void { +function wl_land(wildlife_st: WildlifeState, a: WildAnimal, dh: float, dt: float) -> void { let s = wl_sp(wildlife_st, a.sp) a.fly_h = Math.max(0.0, a.fly_h - dt * 3.2) a.speed = s.walk * 0.8 @@ -84,7 +84,7 @@ function wl_land(wildlife_st: mut WildlifeState, a: WildAnimal, dh: float, dt: f } # on the ground it pecks at seed or takes a drink at the water's edge; it leaves no droppings -function wl_perch(wildlife_st: mut WildlifeState, a: WildAnimal, dh: float, dt: float) -> void { +function wl_perch(wildlife_st: WildlifeState, a: WildAnimal, dh: float, dt: float) -> void { a.speed = 0.0 a.y = WildlifeWorld.ground(a.x, a.z) a.bank = 0.0 diff --git a/packages/ludic.wildlife/facts.ludic b/packages/ludic.wildlife/facts.ludic index 09f71364..7ac31445 100644 --- a/packages/ludic.wildlife/facts.ludic +++ b/packages/ludic.wildlife/facts.ludic @@ -28,12 +28,11 @@ export property WildFact { } -export function wildlife_facts(wildlife_st: mut WildlifeState) -> Queue { - if wildlife_st.wl_facts == null { wildlife_st.wl_facts = queue_new("wildlife.facts") } +export function wildlife_facts(wildlife_st: WildlifeState) -> Queue { return wildlife_st.wl_facts } -function wl_fact(wildlife_st: mut WildlifeState, what: int, a: WildAnimal) -> WildFact { +function wl_fact(wildlife_st: WildlifeState, what: int, a: WildAnimal) -> WildFact { let f = new WildFact f.what = what f.key = a.key diff --git a/packages/ludic.wildlife/ground.ludic b/packages/ludic.wildlife/ground.ludic index e8c3bb9e..4ed6ba8b 100644 --- a/packages/ludic.wildlife/ground.ludic +++ b/packages/ludic.wildlife/ground.ludic @@ -41,7 +41,7 @@ export function wildlife_tick_ground(wildlife_st: mut WildlifeState, a: WildAnim } # a charger close enough comes at the nearest player; true while it is charging -function wl_charge(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> bool { +function wl_charge(wildlife_st: WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> bool { let s = wl_sp(wildlife_st, a.sp) if s.charges and a.state != WILD_CHARGE and dh < WildlifeWorld.charge_reach() and not (a.calm > 0.0) { a.state = WILD_CHARGE @@ -63,7 +63,7 @@ function wl_charge(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dh: f # Four postures read off the alert. Staring is a REACTION, not a condition: each times out and # hands the animal back to its business, and only a fresh rise above `seen` looks up again. -function wl_posture(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dt: float) -> void { +function wl_posture(wildlife_st: WildlifeState, a: WildAnimal, np: int, dt: float) -> void { if wl_sp(wildlife_st, a.sp).tame or a.state == WILD_EAT { return } if a.alert > 95.0 { if a.state != WILD_FLEE { diff --git a/packages/ludic.wildlife/lures.ludic b/packages/ludic.wildlife/lures.ludic index 2cadd758..34160075 100644 --- a/packages/ludic.wildlife/lures.ludic +++ b/packages/ludic.wildlife/lures.ludic @@ -1,9 +1,7 @@ # lures.ludic - what an animal would walk to: food of its diet, a lure of its diet, a snare it is # small enough for (half the time: a curiosity), within 70 m - 175 m for food while feeding is taught -function wl_lure_scratch(wildlife_st: mut WildlifeState) -> void { - if wildlife_st.wl_ask == null { wildlife_st.wl_ask = new WildLure } - if wildlife_st.wl_best == null { wildlife_st.wl_best = new WildLure } +function wl_lure_scratch() -> void { } function wl_copy_lure(from: WildLure, to: WildLure) -> void { @@ -16,15 +14,15 @@ function wl_copy_lure(from: WildLure, to: WildLure) -> void { to.owner = from.owner } -function wl_draws(wildlife_st: mut WildlifeState, a: WildAnimal, l: WildLure) -> bool { +function wl_draws(wildlife_st: WildlifeState, a: WildAnimal, l: WildLure) -> bool { let s = wl_sp(wildlife_st, a.sp) if l.kind == WILD_SNARE { return s.size <= l.size and wl_rnd(wildlife_st) > 0.5 } return l.diet == s.diet and l.diet != WILD_SEED } # the nearest thing set out that draws it, into `wl_best`; false when none does -function wl_attraction(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool { - wl_lure_scratch(wildlife_st) +function wl_attraction(wildlife_st: WildlifeState, a: WildAnimal) -> bool { + wl_lure_scratch() var bd = 70.0 var got = false let taught = WildlifeWorld.taught() @@ -58,7 +56,7 @@ function wl_seed_scan(wildlife_st: mut WildlifeState, dt: float) -> void { if wildlife_st.wl_seed_t > 0.0 { return } wildlife_st.wl_seed_t = 1.0 wildlife_st.wl_seed_any = false - wl_lure_scratch(wildlife_st) + wl_lure_scratch() for i in 0 .. WildlifeWorld.lures() { if WildlifeWorld.lure(i, wildlife_st.wl_ask) and wildlife_st.wl_ask.kind == WILD_FEED and wildlife_st.wl_ask.diet == WILD_SEED { wildlife_st.wl_seed_any = true @@ -68,9 +66,9 @@ function wl_seed_scan(wildlife_st: mut WildlifeState, dt: float) -> void { } # the nearest seed within 120 m, into `wl_best`: the one thing that brings an animal TO you -function wl_bird_seed(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool { +function wl_bird_seed(wildlife_st: WildlifeState, a: WildAnimal) -> bool { if not wildlife_st.wl_seed_any { return false } - wl_lure_scratch(wildlife_st) + wl_lure_scratch() var bd = 120.0 var got = false for i in 0 .. WildlifeWorld.lures() { @@ -88,7 +86,7 @@ function wl_bird_seed(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool { } # it ate what was set out: calm for three game hours, and the game credits whoever left it -function wl_ate(wildlife_st: mut WildlifeState, a: WildAnimal, uid: int, owner: int, diet: int) -> void { +function wl_ate(wildlife_st: WildlifeState, a: WildAnimal, uid: int, owner: int, diet: int) -> void { a.calm = 180.0 a.fed += 1 let f = wl_fact(wildlife_st, WILD_FED, a) diff --git a/packages/ludic.wildlife/migrate.ludic b/packages/ludic.wildlife/migrate.ludic index 7715c00a..0735a05f 100644 --- a/packages/ludic.wildlife/migrate.ludic +++ b/packages/ludic.wildlife/migrate.ludic @@ -1,6 +1,6 @@ # migrate.ludic - each morning the ranges slide toward where the season wants them, and the animals # that live in them are dragged along rather than teleported; an animal keeps inside its own -export function wildlife_ranges_migrate(wildlife_st: mut WildlifeState) -> void { +export function wildlife_ranges_migrate(wildlife_st: WildlifeState) -> void { let rs = wildlife_ranges(wildlife_st) let w = WildlifeWorld.winterness() for i in 0 .. len(rs) { @@ -24,7 +24,7 @@ export function wildlife_ranges_migrate(wildlife_st: mut WildlifeState) -> void } # its home kept inside its range -function wl_clamp(wildlife_st: mut WildlifeState, a: WildAnimal) -> void { +function wl_clamp(wildlife_st: WildlifeState, a: WildAnimal) -> void { let r = wildlife_range(wildlife_st, a.rg) if r == null { return } let d = wildlife_range_dist(r, a.home_x, a.home_z) @@ -34,7 +34,7 @@ function wl_clamp(wildlife_st: mut WildlifeState, a: WildAnimal) -> void { } # how many live in range `i`, legends apart -export function wildlife_range_alive(wildlife_st: mut WildlifeState, i: int) -> int { +export function wildlife_range_alive(wildlife_st: WildlifeState, i: int) -> int { var n = 0 let all = wildlife_all(wildlife_st) for k in 0 .. len(all) { if all[k].alive and not all[k].legend and all[k].rg == i { n += 1 } } @@ -42,7 +42,7 @@ export function wildlife_range_alive(wildlife_st: mut WildlifeState, i: int) -> } # how many are alive in the whole valley, legends apart -export function wildlife_total(wildlife_st: mut WildlifeState) -> int { +export function wildlife_total(wildlife_st: WildlifeState) -> int { var n = 0 let all = wildlife_all(wildlife_st) for k in 0 .. len(all) { if all[k].alive and not all[k].legend { n += 1 } } @@ -50,7 +50,7 @@ export function wildlife_total(wildlife_st: mut WildlifeState) -> int { } # the nearest range of `sp` a player has found, to (x, z), or -1 -export function wildlife_range_found_near(wildlife_st: mut WildlifeState, sp: int, x: float, z: float) -> int { +export function wildlife_range_found_near(wildlife_st: WildlifeState, sp: int, x: float, z: float) -> int { var best = -1 var bd = 99999.0 let rs = wildlife_ranges(wildlife_st) diff --git a/packages/ludic.wildlife/ranges.ludic b/packages/ludic.wildlife/ranges.ludic index fb792c3d..587ebf99 100644 --- a/packages/ludic.wildlife/ranges.ludic +++ b/packages/ludic.wildlife/ranges.ludic @@ -1,12 +1,11 @@ # ranges.ludic - a species keeps to discs placed once, against the ground, 120-700 m out from where # the valley starts; each winters lower, toward the timber, as far down as it summered high -export function wildlife_ranges(wildlife_st: mut WildlifeState) -> []WildRange { - if wildlife_st.wl_ranges == null { wildlife_st.wl_ranges = new []WildRange } +export function wildlife_ranges(wildlife_st: WildlifeState) -> []WildRange { return wildlife_st.wl_ranges } -export function wildlife_range(wildlife_st: mut WildlifeState, i: int) -> WildRange { +export function wildlife_range(wildlife_st: WildlifeState, i: int) -> WildRange { if i < 0 or i >= len(wildlife_ranges(wildlife_st)) { return null } return wildlife_ranges(wildlife_st)[i] } @@ -17,7 +16,7 @@ export function wildlife_range_dist(r: WildRange, x: float, z: float) -> float { return Math.sqrt(dx * dx + dz * dz) } -function wl_range_clashes(wildlife_st: mut WildlifeState, sp: int, x: float, z: float) -> bool { +function wl_range_clashes(wildlife_st: WildlifeState, sp: int, x: float, z: float) -> bool { let rs = wildlife_ranges(wildlife_st) for j in 0 .. len(rs) { if rs[j].sp == sp and wildlife_range_dist(rs[j], x, z) < wl_sp(wildlife_st, sp).range * 1.6 { return true } } return false @@ -83,12 +82,12 @@ function wl_pick_winter(r: WildRange) -> void { } # a player stood at (x, z): any range they are inside is found -export function wildlife_ranges_visit(wildlife_st: mut WildlifeState, x: float, z: float) -> void { +export function wildlife_ranges_visit(wildlife_st: WildlifeState, x: float, z: float) -> void { let rs = wildlife_ranges(wildlife_st) for i in 0 .. len(rs) { if not rs[i].found and wildlife_range_dist(rs[i], x, z) < rs[i].r { rs[i].found = true } } } -function wl_found_apply(wildlife_st: mut WildlifeState) -> void { +function wl_found_apply(wildlife_st: WildlifeState) -> void { if wildlife_st.wl_found == null { return } let rs = wildlife_ranges(wildlife_st) for i in 0 .. len(rs) { if i < len(wildlife_st.wl_found) { rs[i].found = wildlife_st.wl_found[i] != 0 } } diff --git a/packages/ludic.wildlife/react.ludic b/packages/ludic.wildlife/react.ludic index 51e361b6..c953050f 100644 --- a/packages/ludic.wildlife/react.ludic +++ b/packages/ludic.wildlife/react.ludic @@ -1,6 +1,6 @@ # react.ludic - alert (it stops and looks: the window the camera wants), wary (it puts ground between # you without running) and fleeing; true when it is doing one of them, which is all it does this tick -function wl_react(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dt: float) -> bool { +function wl_react(wildlife_st: WildlifeState, a: WildAnimal, np: int, dt: float) -> bool { let s = wl_sp(wildlife_st, a.sp) if a.state == WILD_ALERT { a.speed = 0.0 @@ -29,7 +29,7 @@ function wl_react(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dt: fl } # walking to (or reached) something set out; true while it is -function wl_approach(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bool { +function wl_approach(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> bool { if (a.state == WILD_IDLE or a.state == WILD_WANDER) and wl_attraction(wildlife_st, a) { wl_take_lure(wildlife_st, a) } if a.state != WILD_APPROACH { return false } if a.lure == 0 or not WildlifeWorld.present(a.lure) { @@ -52,7 +52,7 @@ function wl_approach(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) - } # at a snare it is held; at food it eats for 14 s; at a lure it stands curious for 9 -function wl_arrive(wildlife_st: mut WildlifeState, a: WildAnimal) -> void { +function wl_arrive(wildlife_st: WildlifeState, a: WildAnimal) -> void { a.state = WILD_EAT a.timer = 9.0 if a.lure_kind == WILD_FEED { a.timer = 14.0 } @@ -67,7 +67,7 @@ function wl_arrive(wildlife_st: mut WildlifeState, a: WildAnimal) -> void { } # eating what it came to; when it is done, food is credited and it wanders off -function wl_eat(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool { +function wl_eat(wildlife_st: WildlifeState, a: WildAnimal) -> bool { if a.state != WILD_EAT { return false } a.speed = 0.0 if a.timer < 0.0 { diff --git a/packages/ludic.wildlife/run.ludic b/packages/ludic.wildlife/run.ludic index 719cfc40..0229aee1 100644 --- a/packages/ludic.wildlife/run.ludic +++ b/packages/ludic.wildlife/run.ludic @@ -32,7 +32,7 @@ function wl_tick_one(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float, g } # the gait advanced by a copy the game moves itself (a guest's copy of the host's animal) -export function wildlife_stride(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> void { +export function wildlife_stride(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> void { var stride = 1.2 * a.scale if wl_sp(wildlife_st, a.sp).flies { stride = 0.6 } a.phase = (a.phase + a.speed * dt / stride * WL_TAU) % WL_TAU @@ -48,7 +48,7 @@ export function wildlife_release(a: WildAnimal) -> void { } # the animal a snare holds, by the snare's uid -export function wildlife_in_snare(wildlife_st: mut WildlifeState, uid: int) -> WildAnimal { +export function wildlife_in_snare(wildlife_st: WildlifeState, uid: int) -> WildAnimal { let all = wildlife_all(wildlife_st) for i in 0 .. len(all) { let a = all[i] diff --git a/packages/ludic.wildlife/senses.ludic b/packages/ludic.wildlife/senses.ludic index 067c0850..5a723d72 100644 --- a/packages/ludic.wildlife/senses.ludic +++ b/packages/ludic.wildlife/senses.ludic @@ -46,7 +46,7 @@ function wl_near_sq(d: float, reach: float) -> float { } # alert points a second from player p at `dh` metres; 0 when nothing of them reaches it -export function wildlife_alert_rate(wildlife_st: mut WildlifeState, a: WildAnimal, p: int, dh: float) -> float { +export function wildlife_alert_rate(wildlife_st: WildlifeState, a: WildAnimal, p: int, dh: float) -> float { let s = wl_sp(wildlife_st, a.sp) if s.tame or a.calm > 0.0 { return 0.0 } if (a.state == WILD_APPROACH or a.state == WILD_EAT) and a.lure != 0 and a.lure_kind == WILD_FEED and dh > 5.0 and WildlifeWorld.taught() { return 0.0 } @@ -65,7 +65,7 @@ export function wildlife_alert_rate(wildlife_st: mut WildlifeState, a: WildAnima } # how fast it forgets player p: standing still buys it, sitting down buys more -export function wildlife_alert_decay(wildlife_st: mut WildlifeState, a: WildAnimal, p: int) -> float { +export function wildlife_alert_decay(wildlife_st: WildlifeState, a: WildAnimal, p: int) -> float { var d = wl_sp(wildlife_st, a.sp).forget let still = WildlifeWorld.stillness(p) if still == WILD_SITTING { d = d * 2.5 } else if still == WILD_STILL { d = d * 1.6 } @@ -74,7 +74,7 @@ export function wildlife_alert_decay(wildlife_st: mut WildlifeState, a: WildAnim } # the alert rises and falls with the player who nets it the most, and it watches them -function wl_alert(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> void { +function wl_alert(wildlife_st: WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> void { var rise = wildlife_alert_rate(wildlife_st, a, np, dh) var fall = wildlife_alert_decay(wildlife_st, a, np) var who = np diff --git a/packages/ludic.wildlife/species.ludic b/packages/ludic.wildlife/species.ludic index 767d2bc0..533c9d50 100644 --- a/packages/ludic.wildlife/species.ludic +++ b/packages/ludic.wildlife/species.ludic @@ -33,47 +33,47 @@ export property WildSpecies { } export state WildlifeState { - wl_facts: Queue = null + wl_facts: Queue = wl_facts__new() wl_own: []WildAnimal = null wl_px: float = 0.0 wl_pz: float = 0.0 - wl_ask: WildLure = null - wl_best: WildLure = null + wl_ask: WildLure = new WildLure + wl_best: WildLure = new WildLure wl_seed_any: bool = false wl_seed_t: float = 0.0 wl_ids: int = 0 - wl_ranges: []WildRange = null + wl_ranges: []WildRange = new []WildRange wl_found: []int = null # found flags a load brought before the ranges were set out wl_seen: int = 0 wl_fed: int = 0 wl_fed_any: bool = false wl_near_i: int = 0 - wl_species: []WildSpecies = null - wl_list: []WildAnimal = null + wl_species: []WildSpecies = new []WildSpecies + wl_list: []WildAnimal = new []WildAnimal wl_keys: int = 0 - wl_dice: Rng = null + wl_dice: Rng = rng_new(97) wl_hold: bool = false # staged: nobody thinks, everybody keeps their speed - wl_spot_ask: WildSpot = null + wl_spot_ask: WildSpot = new WildSpot } -function wl_sp_all(wildlife_st: mut WildlifeState) -> []WildSpecies { - if wildlife_st.wl_species == null { wildlife_st.wl_species = new []WildSpecies } +function wl_sp_all(wildlife_st: WildlifeState) -> []WildSpecies { return wildlife_st.wl_species } export function wildlife_species_clear(wildlife_st: mut WildlifeState) -> void { wildlife_st.wl_species = new []WildSpecies } # the next species; returns its number -export function wildlife_species_add(wildlife_st: mut WildlifeState, s: WildSpecies) -> int { +export function wildlife_species_add(wildlife_st: WildlifeState, s: WildSpecies) -> int { push(wl_sp_all(wildlife_st), s) return len(wl_sp_all(wildlife_st)) - 1 } -export function wildlife_species_count(wildlife_st: mut WildlifeState) -> int { return len(wl_sp_all(wildlife_st)) } +export function wildlife_species_count(wildlife_st: WildlifeState) -> int { return len(wl_sp_all(wildlife_st)) } -export function wildlife_species(wildlife_st: mut WildlifeState, sp: int) -> WildSpecies { +export function wildlife_species(wildlife_st: WildlifeState, sp: int) -> WildSpecies { if sp < 0 or sp >= len(wl_sp_all(wildlife_st)) { return null } return wl_sp_all(wildlife_st)[sp] } -function wl_sp(wildlife_st: mut WildlifeState, sp: int) -> WildSpecies { return wl_sp_all(wildlife_st)[sp] } +function wl_sp(wildlife_st: WildlifeState, sp: int) -> WildSpecies { return wl_sp_all(wildlife_st)[sp] } +function wl_facts__new() -> Queue { return queue_new("wildlife.facts") } diff --git a/packages/ludic.wildlife/steer.ludic b/packages/ludic.wildlife/steer.ludic index baf39b13..32c57e52 100644 --- a/packages/ludic.wildlife/steer.ludic +++ b/packages/ludic.wildlife/steer.ludic @@ -14,7 +14,7 @@ function wl_face(a: WildAnimal, tx: float, tz: float, rate: float, dt: float) -> } # true when it moved -function wl_step(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bool { +function wl_step(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> bool { let d = a.speed * dt if d < 0.0001 { return false } let nx = a.x - Math.sin(a.yaw) * d @@ -36,7 +36,7 @@ function wl_step(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bo return true } -function wl_pick_target(wildlife_st: mut WildlifeState, a: WildAnimal, radius: float) -> void { +function wl_pick_target(wildlife_st: WildlifeState, a: WildAnimal, radius: float) -> void { let ang = wl_rnd(wildlife_st) * WL_TAU let d = wl_rnd(wildlife_st) * radius a.tx = a.home_x + Math.cos(ang) * d @@ -50,14 +50,14 @@ function wl_at_target(a: WildAnimal, r: float) -> bool { } # back to wandering about home after `t` seconds of whatever it was doing -function wl_wander(wildlife_st: mut WildlifeState, a: WildAnimal, t: float) -> void { +function wl_wander(wildlife_st: WildlifeState, a: WildAnimal, t: float) -> void { a.state = WILD_WANDER a.timer = t wl_pick_target(wildlife_st, a, wl_sp(wildlife_st, a.sp).home) } # home where it stands now, kept inside its range -function wl_rehome(wildlife_st: mut WildlifeState, a: WildAnimal) -> void { +function wl_rehome(wildlife_st: WildlifeState, a: WildAnimal) -> void { a.home_x = a.x a.home_z = a.z wl_clamp(wildlife_st, a) diff --git a/packages/ludic.wildlife/store.ludic b/packages/ludic.wildlife/store.ludic index d40979c7..04a9640e 100644 --- a/packages/ludic.wildlife/store.ludic +++ b/packages/ludic.wildlife/store.ludic @@ -1,25 +1,23 @@ # store.ludic - the animals, their own dice, and the verbs that make and take one away const WL_TAU: float = 6.2831853 -export function wildlife_all(wildlife_st: mut WildlifeState) -> []WildAnimal { - if wildlife_st.wl_list == null { wildlife_st.wl_list = new []WildAnimal } +export function wildlife_all(wildlife_st: WildlifeState) -> []WildAnimal { return wildlife_st.wl_list } -export function wildlife_count_all(wildlife_st: mut WildlifeState) -> int { return len(wildlife_all(wildlife_st)) } +export function wildlife_count_all(wildlife_st: WildlifeState) -> int { return len(wildlife_all(wildlife_st)) } # a new valley: every animal forgotten, quietly (the game has already let its drawings go) export function wildlife_clear(wildlife_st: mut WildlifeState) -> void { wildlife_st.wl_list = new []WildAnimal } -function wl_rng(wildlife_st: mut WildlifeState) -> Rng { - if wildlife_st.wl_dice == null { wildlife_st.wl_dice = rng_new(97) } +function wl_rng(wildlife_st: WildlifeState) -> Rng { return wildlife_st.wl_dice } -function wl_rnd(wildlife_st: mut WildlifeState) -> float { return rng_float(wl_rng(wildlife_st)) } +function wl_rnd(wildlife_st: WildlifeState) -> float { return rng_float(wl_rng(wildlife_st)) } # the package's dice from a known place (a spawn, a test) -export function wildlife_seed(wildlife_st: mut WildlifeState, seed: int) -> void { rng_seed(wl_rng(wildlife_st), seed) } +export function wildlife_seed(wildlife_st: WildlifeState, seed: int) -> void { rng_seed(wl_rng(wildlife_st), seed) } # an individual exactly as given: the host's own, or the host's on a guest export function wildlife_make(wildlife_st: mut WildlifeState, sp: int, x: float, z: float, legend: bool, yaw: float, variant: int, scale: float, nid: int) -> WildAnimal { @@ -76,14 +74,14 @@ export function wildlife_remove(a: WildAnimal) -> void { # staged for a picture: nobody thinks, and everybody keeps the speed they were given export function wildlife_hold(wildlife_st: mut WildlifeState, on: bool) -> void { wildlife_st.wl_hold = on } -export function wildlife_by_nid(wildlife_st: mut WildlifeState, nid: int) -> WildAnimal { +export function wildlife_by_nid(wildlife_st: WildlifeState, nid: int) -> WildAnimal { let all = wildlife_all(wildlife_st) for i in 0 .. len(all) { if all[i].nid == nid { return all[i] } } return null } # how many of a species are alive, legends apart -export function wildlife_count(wildlife_st: mut WildlifeState, sp: int) -> int { +export function wildlife_count(wildlife_st: WildlifeState, sp: int) -> int { var n = 0 let all = wildlife_all(wildlife_st) for i in 0 .. len(all) { if all[i].alive and all[i].sp == sp and not all[i].legend { n += 1 } } diff --git a/packages/ludic.wildlife/system.ludic b/packages/ludic.wildlife/system.ludic index 79606183..425ebf75 100644 --- a/packages/ludic.wildlife/system.ludic +++ b/packages/ludic.wildlife/system.ludic @@ -9,7 +9,7 @@ export function wildlife_reset(wildlife_st: mut WildlifeState) -> void { q_clear(wildlife_facts(wildlife_st)) } -export function wildlife_save(wildlife_st: mut WildlifeState) -> Val { +export function wildlife_save(wildlife_st: WildlifeState) -> Val { let v = Value.object() sv_put_int(v, "seen", wildlife_st.wl_seen) sv_put_int(v, "fed", wildlife_st.wl_fed) diff --git a/packages/ludic.wildlife/tests/fake/index.ludic b/packages/ludic.wildlife/tests/fake/index.ludic index 05e036e6..faae5510 100644 --- a/packages/ludic.wildlife/tests/fake/index.ludic +++ b/packages/ludic.wildlife/tests/fake/index.ludic @@ -33,7 +33,7 @@ function fk_setup(wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut Wi } # 0 deer (meadow, tracks, medium), 1 bear (forest, charges), 2 hare (small), 3 jay (flies) -function fk_species(wildlife_st: mut WildlifeState) -> void { +function fk_species(wildlife_st: WildlifeState) -> void { let d = new WildSpecies d.key = "deer" d.walk = 1.1 diff --git a/packages/ludic.wildlife/tests/lures_test.ludic b/packages/ludic.wildlife/tests/lures_test.ludic index 0e9d9b1e..ff7d0051 100644 --- a/packages/ludic.wildlife/tests/lures_test.ludic +++ b/packages/ludic.wildlife/tests/lures_test.ludic @@ -19,7 +19,7 @@ program LuresTest { spot: fn fk_spot } - function facts(wildlife_st: mut WildlifeState) -> []WildFact { return q_drain(wildlife_facts(wildlife_st)) } + function facts(wildlife_st: WildlifeState) -> []WildFact { return q_drain(wildlife_facts(wildlife_st)) } function set_out(wildlife_tests_fake_st: mut WildlifeTestsFakeState, uid: int, kind: int, diet: int, x: float, z: float, owner: int) -> WildLure { let l = new WildLure l.uid = uid diff --git a/packages/ludic.wildlife/tests/wildlife_test.ludic b/packages/ludic.wildlife/tests/wildlife_test.ludic index 259c95b5..14c1ea7c 100644 --- a/packages/ludic.wildlife/tests/wildlife_test.ludic +++ b/packages/ludic.wildlife/tests/wildlife_test.ludic @@ -31,7 +31,7 @@ program WildlifeTest { spot: fn fk_spot } - function facts(wildlife_st: mut WildlifeState) -> []WildFact { return q_drain(wildlife_facts(wildlife_st)) } + function facts(wildlife_st: WildlifeState) -> []WildFact { return q_drain(wildlife_facts(wildlife_st)) } function count(fs: []WildFact, what: int) -> int { var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } diff --git a/packages/ludic.wildlife/want.ludic b/packages/ludic.wildlife/want.ludic index 999a7945..891fd143 100644 --- a/packages/ludic.wildlife/want.ludic +++ b/packages/ludic.wildlife/want.ludic @@ -1,7 +1,7 @@ # want.ludic - thirst and hunger over sixty send it to the water or the forage the game offers for # it (a hungry one on its way turns to food put down nearer); it drinks or grazes there -function wl_seek(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bool { +function wl_seek(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> bool { if a.state == WILD_GO_FEED and wl_attraction(wildlife_st, a) and wildlife_st.wl_best.kind == WILD_FEED { wl_take_lure(wildlife_st, a) } if a.state != WILD_GO_DRINK and a.state != WILD_GO_FEED { return false } if a.spot == 0 or not WildlifeWorld.present(a.spot) { @@ -28,7 +28,7 @@ function wl_seek(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bo } # true while it drinks or grazes, or when it has just set off -function wl_drink(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float, gh: float) -> bool { +function wl_drink(wildlife_st: WildlifeState, a: WildAnimal, dt: float, gh: float) -> bool { if a.state == WILD_DRINK { a.speed = 0.0 a.timer = a.timer - dt @@ -41,7 +41,6 @@ function wl_drink(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float, gh: } if a.state != WILD_IDLE and a.state != WILD_WANDER { return false } if not (a.thirst > 60.0 or a.hunger > 60.0) { return false } - if wildlife_st.wl_spot_ask == null { wildlife_st.wl_spot_ask = new WildSpot } let water = a.thirst > a.hunger if not WildlifeWorld.spot(a, water, wildlife_st.wl_spot_ask) { return false } a.spot = wildlife_st.wl_spot_ask.uid