ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic 1804 vars into 126 states, 64 into lets; 23498 edits in 460 files Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| tests | ||
| fight.ludic | ||
| index.ludic | ||
| kinds.ludic | ||
| package.ludic | ||
| ports.ludic | ||
| README.md | ||
| run.ludic | ||
| state.ludic | ||
| system.ludic | ||
| verbs.ludic | ||
ludic.fishing
One angler's line: a cast into water deep enough, the wait for a bite (bait halves it), the strike,
the reel's fight - a marker sweeping a bar and a green band to press in, a Gentle ring of one
press, a legend that runs and takes line back - and the landing, with the species, length and
weight from data. Uses ludic.base and nothing else.
import "ludic.fishing"
The package never draws, never speaks and never touches a pack. It reports what happened as facts
(fishing_facts()), and the game takes the bait, puts the fish in the pack, shows it and says the
line. Its dice are its own Rng.
The species
FishSpecies is an open registry the game fills, FISH_<KEY> in the order written:
def FishSpecies cutthroat { weight: 0.45 }
def FishSpecies brook { weight: 0.25, cm_min: 20, cm_spread: 10 }
def FishSpecies old_maroon { legend: true, cm_min: 70, cm_spread: 25, skill_cm: 0.0, need: 5, runs: 2, fight: 30.0, speed: 1.3, speed_per_hit: 0.22, closes: 0.12 }
| field | |
|---|---|
weight |
how often it takes, among the everyday ones |
cm_min, cm_spread, skill_cm |
length: cm_min + up to cm_spread, + skill_cm per point of skill |
kg_k |
weight is kg_k x cm^3 (a trout by default) |
legend, chance, chance_deep |
takes only a lure, at chance in the shallows and chance_deep past the deep line or afloat (+ skill) |
need, runs, fight |
crossings to land it, runs it makes, seconds before the line goes slack |
speed, speed_per_hit, closes, floor |
the marker's sweep, and a window that narrows with each crossing won (at every rung) |
The port
export port FishingWorld {
depth: fn(float, float) -> float # metres of water at a point
afloat: fn() -> bool # in a boat (unbound: no)
has_bait: fn() -> bool # (unbound: no)
has_lure: fn() -> bool # (unbound: no)
skill: fn() -> float # gear or hands (unbound: 0)
bite_mult: fn() -> float # the wait, x (unbound: 1)
window: fn(int) -> float # the green's half width for a species (unbound: 0.12)
level: fn() -> int # FISHING_RELAXED / _STANDARD / _HARD / _GENTLE (unbound: relaxed)
}
API
fishing_config(min_depth, deep, seed) |
0.15 m to cast, 2.5 m is deep, the line's seed |
fishing_cast(x, z) -> int |
FISHING_CAST_OK, FISHING_NOT_WATER, FISHING_BUSY |
fishing_press() |
the one button: waiting it reels in, on a bite it strikes, on a fish it reels |
fishing_run(dt), fishing_stop(), fishing_set_wait(secs) |
real seconds of line; put away; the bite in exactly secs |
fishing_state() (FISHING_OFF, _WAIT, _BITE_ON, _REEL), fishing_active(), fishing_species(), fishing_cm(), fishing_line_x(), fishing_line_z(), fishing_baited(), fishing_lured() |
the line |
fishing_marker(), fishing_window(), fishing_window_lo(), fishing_window_hi(), fishing_hits(), fishing_need(), fishing_running(), fishing_gentle(), fishing_ring() |
the fight, for a HUD |
fishing_caught(), fishing_biggest(), fishing_legend_caught(), fishing_record_set(n, cm, legend) |
the record |
fishing_weight_of(species, cm), fishing_legend(), fishing_water_at(x, z) |
questions |
fishing_facts() -> Queue<FishingFact> |
{ what, species, cm, kg, hits, need, bait, lure, x, z }: FISHING_CAST, _BAIT_USED, _BITE, _MISSED, _HOOKED, _GOOD, _CHECKED, _TURNED, _RUNS, _TIRED, _REELED_IN, _CAUGHT, _LINE_SNAPPED, _SLACK |
fishing_reset(), fishing_system() -> System |
"fishing", PH_SIMULATE: its tick, and the record in its save section (a line in the water is not saved) |
Tests
ludic test packages/ludic.fishing