refactor(packages): 0.R5 - jobs, session, settings, hints and net make their tables when the state is made, not on the first question (jobs__ensure, session__init and ply_init, sg_init, hn_mute_ensure, net__init gone); their questions read

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-27 01:29:32 +03:00
parent 63c30b9ebe
commit 9e4f4edb92
21 changed files with 98 additions and 163 deletions

View file

@ -2,14 +2,12 @@
# the jobs' own dice seeded by the day, so a board never moves anyone else's rolls
export function jobs_board_ok(b: int) -> bool { return b >= 0 and b < BOARD_COUNT }
function jobs__at(jobs_st: mut JobsState, b: int, s: int) -> int {
jobs__ensure(jobs_st)
function jobs__at(jobs_st: JobsState, b: int, s: int) -> int {
return jobs_st.jobs__off[b] + s
}
# a whole number in [lo, hi] from the jobs' dice: what JobsWorld.roll draws with
export function jobs_roll(jobs_st: mut JobsState, lo: int, hi: int) -> int {
jobs__ensure(jobs_st)
export function jobs_roll(jobs_st: JobsState, lo: int, hi: int) -> int {
return rng_between(jobs_st.jobs__dice, lo, hi)
}
@ -51,7 +49,6 @@ function jobs__repost(jobs_st: mut JobsState, b: int, s: int) -> void {
# a new day, on the boards this machine keeps: an empty or stale post is replaced, and one
# finished on an earlier day
export function jobs_morning(jobs_st: mut JobsState) -> void {
jobs__ensure(jobs_st)
let day = JobsWorld.day()
for b in 0 .. BOARD_COUNT {
let bd = JobBoards[b]

View file

@ -17,7 +17,6 @@ function jobs__takes(only: int, scope: int) -> bool {
}
function jobs__count(jobs_st: mut JobsState, only: int, kind: int, param: int, n: int) -> void {
jobs__ensure(jobs_st)
for i in 0 .. JOB_COUNT {
let d = Jobs[i]
if jobs_st.jobs__st[i] != JOBS_ACTIVE or not jobs__takes(only, d.scope) { continue }
@ -49,7 +48,6 @@ function jobs__recheck_one(jobs_st: mut JobsState, i: int) -> void {
# every job under way against what the state already proves: work done before it was taken counts
# for a written job; a post counts only what came after it went up
export function jobs_recheck(jobs_st: mut JobsState) -> void {
jobs__ensure(jobs_st)
for i in 0 .. JOB_COUNT { jobs__recheck_one(jobs_st, i) }
for b in 0 .. BOARD_COUNT {
if not JobsWorld.owns(JobBoards[b].scope) { continue }
@ -64,7 +62,6 @@ export function jobs_recheck(jobs_st: mut JobsState) -> void {
# offers newly open are said once; the first look after a reset says none of them
function jobs__offers(jobs_st: mut JobsState) -> void {
jobs__ensure(jobs_st)
for i in 0 .. JOB_COUNT {
let now = jobs_offered(jobs_st, i)
if now and not jobs_st.jobs__seen[i] and jobs_st.jobs__primed { jobs__fact(jobs_st, JOBS_F_OFFERED, i, -1, -1, 0, Jobs[i].need) }

View file

@ -1,26 +1,24 @@
# jobs.ludic - the written jobs: offered by standing and story, taken, readied, handed in and paid
export function jobs_ok(i: int) -> bool { return i >= 0 and i < JOB_COUNT }
export function jobs_state(jobs_st: mut JobsState, i: int) -> int {
jobs__ensure(jobs_st)
export function jobs_state(jobs_st: JobsState, i: int) -> int {
return jobs_st.jobs__st[i]
}
export function jobs_have(jobs_st: mut JobsState, i: int) -> int {
jobs__ensure(jobs_st)
export function jobs_have(jobs_st: JobsState, i: int) -> int {
return jobs_st.jobs__hv[i]
}
export function jobs_ready_now(jobs_st: mut JobsState, i: int) -> bool { return jobs_state(jobs_st, i) == JOBS_READY }
export function jobs_ready_now(jobs_st: JobsState, i: int) -> bool { return jobs_state(jobs_st, i) == JOBS_READY }
# taken and not yet paid
export function jobs_under_way(jobs_st: mut JobsState, i: int) -> bool {
export function jobs_under_way(jobs_st: JobsState, i: int) -> bool {
let s = jobs_state(jobs_st, i)
return s == JOBS_ACTIVE or s == JOBS_READY
}
# on offer: not taken, the scope's standing and the story far enough, and the game allowing it
export function jobs_offered(jobs_st: mut JobsState, i: int) -> bool {
export function jobs_offered(jobs_st: JobsState, i: int) -> bool {
let d = Jobs[i]
if jobs_state(jobs_st, i) != JOBS_OFFERED { return false }
return JobsWorld.rep(d.scope) >= d.minrep and JobsWorld.stage() >= d.minstage and JobsWorld.open(i)
@ -79,18 +77,15 @@ export function jobs_complete(jobs_st: mut JobsState, i: int) -> bool {
# the state outright: the host's word for a party job, a test
export function jobs_set(jobs_st: mut JobsState, i: int, state: int, have: int) -> void {
jobs__ensure(jobs_st)
jobs_st.jobs__st[i] = state
jobs_st.jobs__hv[i] = have
}
export function jobs_done(jobs_st: mut JobsState, group: int) -> int {
jobs__ensure(jobs_st)
export function jobs_done(jobs_st: JobsState, group: int) -> int {
if group < 0 or group >= JOBS_GROUPS { return 0 }
return jobs_st.jobs__done_n[group]
}
export function jobs_set_done(jobs_st: mut JobsState, group: int, n: int) -> void {
jobs__ensure(jobs_st)
if group >= 0 and group < JOBS_GROUPS { jobs_st.jobs__done_n[group] = n }
}

View file

@ -1,6 +1,6 @@
# lists.ludic - the written jobs as a screen lists them: a vendor's, the taken, the ones to show
# a vendor's offers and the ones it can take back, in a group (-1 every vendor)
export function jobs_at(jobs_st: mut JobsState, group: int, vendor: int) -> []int {
export function jobs_at(jobs_st: JobsState, group: int, vendor: int) -> []int {
let out = new []int
for i in 0 .. JOB_COUNT {
let d = Jobs[i]
@ -13,14 +13,14 @@ export function jobs_at(jobs_st: mut JobsState, group: int, vendor: int) -> []in
}
# every job of a group taken at some point, done ones too
export function jobs_taken(jobs_st: mut JobsState, group: int) -> []int {
export function jobs_taken(jobs_st: JobsState, group: int) -> []int {
let out = new []int
for i in 0 .. JOB_COUNT { if Jobs[i].group == group and jobs_state(jobs_st, i) != JOBS_OFFERED { push(out, i) } }
return out
}
# the first `most` of a group under way
export function jobs_shown(jobs_st: mut JobsState, group: int, most: int) -> []int {
export function jobs_shown(jobs_st: JobsState, group: int, most: int) -> []int {
let out = new []int
for i in 0 .. JOB_COUNT {
if len(out) >= most { break }
@ -30,7 +30,7 @@ export function jobs_shown(jobs_st: mut JobsState, group: int, most: int) -> []i
}
# the first under way and not yet met, or -1
export function jobs_first_open(jobs_st: mut JobsState, group: int) -> int {
export function jobs_first_open(jobs_st: JobsState, group: int) -> int {
for i in 0 .. JOB_COUNT { if Jobs[i].group == group and jobs_state(jobs_st, i) == JOBS_ACTIVE { return i } }
return -1
}

View file

@ -1,12 +1,12 @@
# posts.ludic - what is on a board, slot by slot, and a board as the host says it
export function jobs_post_kind(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__pk[jobs__at(jobs_st, b, s)] }
export function jobs_post_param(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__pp[jobs__at(jobs_st, b, s)] }
export function jobs_post_need(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__pn[jobs__at(jobs_st, b, s)] }
export function jobs_post_have(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__ph[jobs__at(jobs_st, b, s)] }
export function jobs_post_money(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__pm[jobs__at(jobs_st, b, s)] }
export function jobs_post_rep(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__pr[jobs__at(jobs_st, b, s)] }
export function jobs_post_state(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__ps[jobs__at(jobs_st, b, s)] }
export function jobs_post_day(jobs_st: mut JobsState, b: int, s: int) -> int { return jobs_st.jobs__pd[jobs__at(jobs_st, b, s)] }
export function jobs_post_kind(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__pk[jobs__at(jobs_st, b, s)] }
export function jobs_post_param(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__pp[jobs__at(jobs_st, b, s)] }
export function jobs_post_need(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__pn[jobs__at(jobs_st, b, s)] }
export function jobs_post_have(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__ph[jobs__at(jobs_st, b, s)] }
export function jobs_post_money(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__pm[jobs__at(jobs_st, b, s)] }
export function jobs_post_rep(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__pr[jobs__at(jobs_st, b, s)] }
export function jobs_post_state(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__ps[jobs__at(jobs_st, b, s)] }
export function jobs_post_day(jobs_st: JobsState, b: int, s: int) -> int { return jobs_st.jobs__pd[jobs__at(jobs_st, b, s)] }
export function jobs_slots(b: int) -> int {
if not jobs_board_ok(b) { return 0 }
@ -14,21 +14,20 @@ export function jobs_slots(b: int) -> int {
}
# the slots with something posted, in order
export function jobs_posted(jobs_st: mut JobsState, b: int) -> []int {
export function jobs_posted(jobs_st: JobsState, b: int) -> []int {
let out = new []int
for s in 0 .. jobs_slots(b) { if jobs_post_kind(jobs_st, b, s) >= 0 { push(out, s) } }
return out
}
# how many of a board's posts are paid
export function jobs_posts_done(jobs_st: mut JobsState, b: int) -> int {
export function jobs_posts_done(jobs_st: JobsState, b: int) -> int {
var n = 0
for s in 0 .. jobs_slots(b) { if jobs_post_kind(jobs_st, b, s) >= 0 and jobs_post_state(jobs_st, b, s) == JOBS_DONE { n += 1 } }
return n
}
export function jobs_total(jobs_st: mut JobsState, b: int) -> int {
jobs__ensure(jobs_st)
export function jobs_total(jobs_st: JobsState, b: int) -> int {
return jobs_st.jobs__total[b]
}
@ -46,6 +45,5 @@ export function jobs_post_set(jobs_st: mut JobsState, b: int, s: int, kind: int,
}
export function jobs_set_total(jobs_st: mut JobsState, b: int, n: int) -> void {
jobs__ensure(jobs_st)
jobs_st.jobs__total[b] = n
}

View file

@ -1,7 +1,6 @@
# save.ludic - a scope's jobs and boards in a section of their own, by key: a job the game has since
# removed is dropped, a new one starts offered
function jobs__reset_scope(jobs_st: mut JobsState, sc: int) -> void {
jobs__ensure(jobs_st)
for i in 0 .. JOB_COUNT {
if Jobs[i].scope != sc { continue }
jobs_st.jobs__st[i] = JOBS_OFFERED

View file

@ -1,25 +1,25 @@
# state.ludic - each job's state and count, the posts on the boards, the done counts, the dice and
# the facts. Made on first use, so the registries are complete by then.
# the facts, each sized from the registries when the state is made.
export state JobsState {
jobs__st: []int = null
jobs__hv: []int = null
jobs__seen: []bool = null # an offer already said
jobs__st: []int = jobs__ints(JOB_COUNT, JOBS_OFFERED)
jobs__hv: []int = jobs__ints(JOB_COUNT, 0)
jobs__seen: []bool = jobs__bools(JOB_COUNT) # an offer already said
jobs__primed: bool = false # the first tick after a reset learns the offers quietly
jobs__done_n: []int = null # handed in, per group
jobs__off: []int = null
jobs__pk: []int = null # kind, -1 empty
jobs__pp: []int = null
jobs__pn: []int = null
jobs__ph: []int = null
jobs__pb: []int = null # the evidence when it went up
jobs__pm: []int = null
jobs__pr: []int = null
jobs__ps: []int = null
jobs__pd: []int = null # the day it went up
jobs__total: []int = null # handed in, per board
jobs__serial: []int = null # posts made, per board: each roll its own seed
jobs__done_n: []int = jobs__ints(JOBS_GROUPS, 0) # handed in, per group
jobs__off: []int = jobs__offsets()
jobs__pk: []int = jobs__ints(jobs__slots(), -1) # kind, -1 empty
jobs__pp: []int = jobs__ints(jobs__slots(), -1)
jobs__pn: []int = jobs__ints(jobs__slots(), 0)
jobs__ph: []int = jobs__ints(jobs__slots(), 0)
jobs__pb: []int = jobs__ints(jobs__slots(), 0) # the evidence when it went up
jobs__pm: []int = jobs__ints(jobs__slots(), 0)
jobs__pr: []int = jobs__ints(jobs__slots(), 0)
jobs__ps: []int = jobs__ints(jobs__slots(), JOBS_OFFERED)
jobs__pd: []int = jobs__ints(jobs__slots(), 0) # the day it went up
jobs__total: []int = jobs__ints(BOARD_COUNT, 0) # handed in, per board
jobs__serial: []int = jobs__ints(BOARD_COUNT, 0) # posts made, per board: each roll its own seed
jobs__seed: int = 1000
jobs__dice: Rng = null
jobs__dice: Rng = rng_new(1000)
jobs__q: Queue<JobsFact> = jobs__q__new()
}
@ -32,31 +32,25 @@ function jobs__ints(n: int, v: int) -> []int {
return out
}
function jobs__ensure(jobs_st: mut JobsState) -> void {
if jobs_st.jobs__st != null { return }
jobs_st.jobs__st = jobs__ints(JOB_COUNT, JOBS_OFFERED)
jobs_st.jobs__hv = jobs__ints(JOB_COUNT, 0)
jobs_st.jobs__seen = new []bool
for i in 0 .. JOB_COUNT { push(jobs_st.jobs__seen, false) }
jobs_st.jobs__done_n = jobs__ints(JOBS_GROUPS, 0)
jobs_st.jobs__off = new []int
function jobs__bools(n: int) -> []bool {
let out = new []bool
for i in 0 .. n { push(out, false) }
return out
}
# every board's slots end to end: where each board's start, and how many in all
function jobs__offsets() -> []int {
let out = new []int
var n = 0
for b in 0 .. BOARD_COUNT {
push(jobs_st.jobs__off, n)
push(out, n)
n += JobBoards[b].slots
}
jobs_st.jobs__pk = jobs__ints(n, -1)
jobs_st.jobs__pp = jobs__ints(n, -1)
jobs_st.jobs__pn = jobs__ints(n, 0)
jobs_st.jobs__ph = jobs__ints(n, 0)
jobs_st.jobs__pb = jobs__ints(n, 0)
jobs_st.jobs__pm = jobs__ints(n, 0)
jobs_st.jobs__pr = jobs__ints(n, 0)
jobs_st.jobs__ps = jobs__ints(n, JOBS_OFFERED)
jobs_st.jobs__pd = jobs__ints(n, 0)
jobs_st.jobs__total = jobs__ints(BOARD_COUNT, 0)
jobs_st.jobs__serial = jobs__ints(BOARD_COUNT, 0)
jobs_st.jobs__dice = rng_new(jobs_st.jobs__seed)
return out
}
function jobs__slots() -> int {
var n = 0
for b in 0 .. BOARD_COUNT { n += JobBoards[b].slots }
return n
}
export function jobs_facts(jobs_st: JobsState) -> Queue<JobsFact> {

View file

@ -8,8 +8,7 @@ export function jobs_reset(jobs_st: mut JobsState) -> void {
export function jobs_party_reset(jobs_st: mut JobsState) -> void { jobs__reset_scope(jobs_st, JOBS_PARTY) }
export function jobs_save(jobs_st: mut JobsState) -> Val {
jobs__ensure(jobs_st)
export function jobs_save(jobs_st: JobsState) -> Val {
let v = jobs__save_scope(jobs_st, JOBS_SELF)
sv_put_ints(v, "done", jobs_st.jobs__done_n)
return v
@ -24,8 +23,7 @@ export function jobs_load(jobs_st: mut JobsState, v: Val, version: int) -> void
}
}
export function jobs_party_save(jobs_st: mut JobsState) -> Val {
jobs__ensure(jobs_st)
export function jobs_party_save(jobs_st: JobsState) -> Val {
return jobs__save_scope(jobs_st, JOBS_PARTY)
}