refactor(packages): the mechanic packages use ludic_base only, and ask through ports
ludic.clock, .effects, .inventory, .wallet, .weather and .tracks say 'uses ludic_base' (ludic.base uses nothing). ClockWorld, PackRules, WeatherWorld and TracksWorld are export ports whose defaults are the old fallbacks; clock_bind, inv_bind, weather_bind and tracks_bind are gone, and the tests bind their fakes. The base README's toy does the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f4062010e9
commit
63e29f024c
31 changed files with 130 additions and 149 deletions
|
|
@ -16,18 +16,24 @@ the hour; another machine is told it (`clock_set_hours`, `clock_set_day`, `clock
|
|||
## The port
|
||||
|
||||
```ludic
|
||||
property ClockWorld {
|
||||
owns_world: fn() -> bool # does this machine run the world? (unbound: yes)
|
||||
rest_scale: fn() -> float # how much everyone's rest speeds the clock; 1 when nobody rests
|
||||
seed: fn() -> int # a seed for a new trip's moon
|
||||
export port ClockWorld {
|
||||
owns_world: fn() -> bool = ... # does this machine run the world? (unbound: yes)
|
||||
rest_scale: fn() -> float = ... # how much everyone's rest speeds the clock (unbound: 1)
|
||||
seed: fn() -> int = ... # a seed for a new trip's moon (unbound: 1)
|
||||
}
|
||||
```
|
||||
|
||||
The game fills it once, where it is put together, and may leave any member out:
|
||||
|
||||
```ludic
|
||||
bind ClockWorld { owns_world: fn ses_owns_world, rest_scale: fn rt_rest_scale, seed: fn rt_clock_seed }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| `clock_bind(w)` | the port |
|
||||
| `bind ClockWorld { ... }` | the port (a declaration, not a call) |
|
||||
| `clock_config(start_hours, night_from, night_to)` | when a trip starts, and which hours are night |
|
||||
| `clock_config_moon(days, lo, hi)` | the moon's month in days, and the part of it a new trip starts in |
|
||||
| `clock_calendar(month_days, season_of_month)` | a month's length, and each month's season (the list's length is the year) |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# ludic.clock - one clock for a whole world: the hour, the day, the moon's place in its month and
|
||||
# where the day falls in a calendar the game describes; a day turning is a fact on a queue
|
||||
module ludic_clock
|
||||
module ludic_clock uses ludic_base
|
||||
numbers float
|
||||
import "ludic.base"
|
||||
import "state.ludic"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
# state.ludic - the clock's port, its facts, and what it holds
|
||||
# what the clock asks the world: whether this machine runs it, how much the rest speeds it (1 when
|
||||
# nobody rests), and a seed for a new trip's moon
|
||||
export property ClockWorld {
|
||||
owns_world: fn() -> bool = null
|
||||
rest_scale: fn() -> float = null
|
||||
seed: fn() -> int = null
|
||||
# (unbound: this machine runs it, nobody rests, and a seed of 1)
|
||||
export port ClockWorld {
|
||||
owns_world: fn() -> bool = fn ck_owns_alone
|
||||
rest_scale: fn() -> float = fn ck_no_rest
|
||||
seed: fn() -> int = fn ck_seed_one
|
||||
}
|
||||
function ck_owns_alone() -> bool { return true }
|
||||
function ck_no_rest() -> float { return 1.0 }
|
||||
function ck_seed_one() -> int { return 1 }
|
||||
|
||||
# how a day turned: the hour ran past midnight, or a verb turned it (a night slept, a collapse)
|
||||
export const DAY_STAYED_UP: int = 0
|
||||
|
|
@ -16,7 +20,6 @@ export property DayTurned {
|
|||
how: int = 0
|
||||
}
|
||||
|
||||
var ck_world: ClockWorld = null
|
||||
var ck_day: int = 1
|
||||
var ck_hours: float = 0.0
|
||||
var ck_moon: float = 0.0
|
||||
|
|
@ -30,23 +33,15 @@ var ck_moon_hi: float = 1.0
|
|||
var ck_dice: Rng = null
|
||||
var ck_days: Queue<DayTurned> = null
|
||||
|
||||
export function clock_bind(w: ClockWorld) -> void { ck_world = w }
|
||||
|
||||
# the facts: each day that turned, in order; the game drains it and runs its morning
|
||||
export function clock_days() -> Queue<DayTurned> {
|
||||
if ck_days == null { ck_days = queue_new("clock.days") }
|
||||
return ck_days
|
||||
}
|
||||
|
||||
function ck_owns() -> bool {
|
||||
if ck_world == null or ck_world.owns_world == null { return true }
|
||||
return ck_world.owns_world()
|
||||
}
|
||||
function ck_owns() -> bool { return ClockWorld.owns_world() }
|
||||
|
||||
function ck_rest() -> float {
|
||||
if ck_world == null or ck_world.rest_scale == null { return 1.0 }
|
||||
return ck_world.rest_scale()
|
||||
}
|
||||
function ck_rest() -> float { return ClockWorld.rest_scale() }
|
||||
|
||||
# when a trip starts, when the night is, and how long the moon's month is
|
||||
export function clock_config(start_hours: float, night_from: float, night_to: float) -> void {
|
||||
|
|
|
|||
|
|
@ -11,14 +11,11 @@ program ClockTest {
|
|||
function fake_rest() -> float { return rest }
|
||||
function fake_seed() -> int { return 42 }
|
||||
|
||||
bind ClockWorld { owns_world: fn fake_owns, rest_scale: fn fake_rest, seed: fn fake_seed }
|
||||
|
||||
function fresh() -> void {
|
||||
owns = true
|
||||
rest = 1.0
|
||||
let w = new ClockWorld
|
||||
w.owns_world = fn fake_owns
|
||||
w.rest_scale = fn fake_rest
|
||||
w.seed = fn fake_seed
|
||||
clock_bind(w)
|
||||
clock_config(8.0, 20.0, 6.0)
|
||||
clock_config_moon(29.5, 0.2, 0.8)
|
||||
clock_set_scale(60.0)
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ export function clock_advance(gh: float) -> void {
|
|||
|
||||
# a new trip: day one at the start hour, the moon somewhere in its month
|
||||
export function clock_reset() -> void {
|
||||
var seed = 1
|
||||
if ck_world != null and ck_world.seed != null { seed = ck_world.seed() }
|
||||
ck_dice = rng_new(seed)
|
||||
ck_dice = rng_new(ClockWorld.seed())
|
||||
ck_day = 1
|
||||
ck_hours = ck_start_hours
|
||||
ck_moon = rng_span(ck_dice, ck_moon_lo, ck_moon_hi) % 1.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue