ludic.base's Queue<T> carries a QueueTag (its name and pending count): queue_new(name), q_push(q, v), q_drain(q), q_clear(q) take no BaseState, and core_undrained(tags) names the given queues still holding facts. A reducer on a package's state can now call that package's verbs (wallet_earn(wallet_st, n)). ludic migrate state --prune (ludicc --migrate-prune) takes out each state parameter a function no longer uses, nor anything it calls, and the argument that fills it - including an argument for a parameter the callee has dropped, which is taken out before the call is checked, so a generic's T is told by the argument that says it. A reducer keeps its state. --dry-run now counts the edits it would make. Every package was moved with it: 608 base_st parameters and their arguments, 1889 edits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92 lines
4.1 KiB
Text
92 lines
4.1 KiB
Text
# state.ludic - the port, the kinds, the facts, and what the sky holds
|
|
# what the weather asks the world. Any member may be left out of the bind: the answer is then
|
|
# "yes, it is mine", noon and daylight, the kind's own odds, no bias, the first wet kind, and a
|
|
# seed of 1.
|
|
export port WeatherWorld {
|
|
owns_world: fn() -> bool = fn wx_owns_alone
|
|
hours: fn() -> float = fn wx_noon
|
|
is_night: fn() -> bool = fn wx_daylight
|
|
odds: fn(int) -> []float = fn wx_own_odds # weights for the next spell, per kind, from this kind
|
|
bias: fn() -> int = fn wx_no_bias # what the story wants now: WEATHER_* below
|
|
front: fn() -> int = fn wx_first_wet # the kind a wanted front comes as
|
|
front_hours: fn() -> float = fn wx_no_hours # the least a wanted front lasts once it arrives
|
|
seed: fn() -> int = fn wx_seed_one
|
|
}
|
|
function wx_owns_alone() -> bool { return true }
|
|
function wx_noon() -> float { return 12.0 }
|
|
function wx_daylight() -> bool { return false }
|
|
function wx_own_odds(weather_st: WeatherState, from: int) -> []float { return weather_st.wx_kinds[from].odds }
|
|
function wx_no_bias() -> int { return WEATHER_NO_BIAS }
|
|
function wx_no_hours() -> float { return 0.0 }
|
|
function wx_seed_one() -> int { return 1 }
|
|
|
|
# what the story may ask of the sky
|
|
export const WEATHER_NO_BIAS: int = 0
|
|
export const WEATHER_WANT_WET: int = 1 # send a front, soon
|
|
export const WEATHER_HOLD: int = 2 # keep this spell going a while yet
|
|
export const WEATHER_WANT_CLEAR: int = 3 # clear the sky and keep it clear
|
|
|
|
# one kind of weather; its place in the list the game hands in is its number
|
|
export property WeatherKind {
|
|
name: string = ""
|
|
clear: bool = false # the kind a sky eases out to: nothing falls, amount goes to 0
|
|
wet: bool = false # rain or snow is falling (weather_wet)
|
|
soak: float = 0.0 # how wet the ground gets under it, 0..1
|
|
overcast: float = 0.0
|
|
cold: float = 0.0 # extra cold per game hour, in the game's units
|
|
wind: float = 0.2 # the strength the wind builds toward, 0..1
|
|
wind_dir: float = -1.0 # radians the wind blows toward; below 0, the valley's daily turn
|
|
thunder: bool = false
|
|
spell_lo: float = 2.0 # game hours a spell lasts, drawn in [lo, hi)
|
|
spell_hi: float = 8.0
|
|
odds: []float = null # weights for the next spell, per kind
|
|
}
|
|
|
|
export const WEATHER_BEGAN: int = 0 # a spell began (kind, from)
|
|
export const WEATHER_CLEARED: int = 1 # a wet spell gave way to clear sky in daylight
|
|
export const WEATHER_THUNDER: int = 2 # a lightning strike, and its thunder
|
|
export const WEATHER_FRONT: int = 3 # a front the story asked for is forecast (kind)
|
|
|
|
export property WeatherFact {
|
|
what: int = 0
|
|
kind: int = 0
|
|
from: int = 0
|
|
}
|
|
|
|
export state WeatherState {
|
|
wx_down_dir: float = 0.0 # the wind overnight and into the morning
|
|
wx_up_dir: float = 3.1415927 # the wind while the slopes are warm
|
|
wx_up_from: float = 10.0
|
|
wx_up_to: float = 19.0
|
|
wx_kinds: []WeatherKind = null
|
|
wx_state: int = 0
|
|
wx_next: int = 0
|
|
wx_left: float = 0.0 # game hours left in this spell
|
|
wx_amount: float = 0.0 # 0..1, how far in (eases at the edges)
|
|
wx_forecast: int = 0
|
|
wx_forced: bool = false # the next spell is a front the story asked for
|
|
wx_wind: float = 0.2
|
|
wx_dir: float = 0.0 # radians the wind blows toward
|
|
wx_ground: float = 0.0 # 0 dry .. 1 soaked
|
|
wx_flash: float = 0.0
|
|
wx_thunder_t: float = 0.0 # real seconds to the next strike
|
|
wx_clear_t: float = 0.0 # game hours of after-the-front light left
|
|
wx_wet_today: bool = false
|
|
wx_wet_yesterday: bool = false
|
|
wx_dice: Rng = null
|
|
wx_facts: Queue<WeatherFact> = null
|
|
}
|
|
|
|
# the facts, oldest first; the game drains them into its notices and sounds
|
|
export function weather_facts(weather_st: mut WeatherState) -> Queue<WeatherFact> {
|
|
if weather_st.wx_facts == null { weather_st.wx_facts = queue_new("weather.facts") }
|
|
return weather_st.wx_facts
|
|
}
|
|
|
|
function wx_fact(weather_st: mut 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)
|
|
}
|