feat(packages): ludic.hints - a rail of things that are true now and can be acted on now: cards as an open registry (urgency, a glyph or an item's picture, the chip's line, three steps and how not to be here again) asked through a port whether each is true, the most urgent few once a pass in registry order within an urgency, a card opened off the rail, walked along it and put down when its subject stops being true, and "I know this" muting kept by the card's key (a key this build lacks is carried through); opened, closed, muted and unmuted as facts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1005a677f2
commit
fe9d28bf4e
12 changed files with 540 additions and 0 deletions
75
packages/ludic.hints/README.md
Normal file
75
packages/ludic.hints/README.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# ludic.hints
|
||||
|
||||
A rail of things that are true now and can be acted on now - thirsty, the fire burning low, a
|
||||
bear near, a job ready to hand in - sorted by how much they matter, each one a card that teaches
|
||||
it in three steps and can be muted for good. Uses [`ludic.base`](../ludic.base/README.md) and
|
||||
nothing else.
|
||||
|
||||
```ludic
|
||||
import "ludic.hints"
|
||||
```
|
||||
|
||||
The package never reads a key and never draws: the game's input calls the verbs (the key opens
|
||||
and puts down, the arrows walk, a third key mutes), its interface reads the rail and the card,
|
||||
and its words are the cards' own text keys, translated where they are drawn.
|
||||
|
||||
## Cards are data
|
||||
|
||||
```ludic
|
||||
def Hints from "assets/data/hints.lres" # the game's cards, in an open registry
|
||||
```
|
||||
|
||||
```
|
||||
thirsty {
|
||||
urgency: HINTS_NOTE, icon: "bottle", item: IT_BOTTLE
|
||||
line: "Thirsty - drink", title: "Water"
|
||||
s1: "Drink at any shore, for nothing", pic1: "waterfull"
|
||||
s2: "Fill a bottle there as well", item2: IT_BOTTLE
|
||||
s3: "Boil it in the pot to be safe", item3: IT_BOILED
|
||||
later: "Buy or make a bottle, fill it at the shore and boil it."
|
||||
}
|
||||
```
|
||||
|
||||
`urgency` is `HINTS_TIP`, `HINTS_NOTE`, `HINTS_WARN` or `HINTS_URGENT`. A picture is a glyph by
|
||||
name (`icon`, `picN`) or a thing's picture by number (`item`, `itemN`, -1 for none) - both the
|
||||
game's to interpret.
|
||||
|
||||
## The rules it keeps
|
||||
|
||||
1. **The most urgent few.** Once a pass (a second by default) the rail is the true, unmuted cards,
|
||||
most urgent first and in registry order within an urgency, up to `hints_config`'s count.
|
||||
2. **A card follows its subject.** As the rail re-sorts under an open card, the pick follows it;
|
||||
when what it was about stops being true (or the rail stops showing) it is put down, with no fact.
|
||||
3. **A lesson lands once.** `hints_mute_card()` takes the open card off the rail until
|
||||
`hints_unmute_all()`. Mutes are kept **by key**, so a card added or removed moves nobody else's,
|
||||
and a key this build does not know is carried through a load and a save.
|
||||
|
||||
## The port
|
||||
|
||||
```ludic
|
||||
export port HintsWorld {
|
||||
true_now: fn(int) -> bool # is card i true now? pure and cheap (unbound: never)
|
||||
showing: fn() -> bool # the rail is wanted: in play, the player's switch on (unbound: yes)
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| `HintCard { key, urgency, icon, item, line, title, s1..s3, pic1..pic3, item1..item3, later }`, `open registry Hints ... as HINT` | a card |
|
||||
| `hints_config(shown, every)` | how many the rail holds (3) and seconds between passes (1) |
|
||||
| `hints_tick(dt)`, `hints_sort()`, `hints_refresh()` | a pass when due, a pass now, the next tick's pass now |
|
||||
| `hints_rail() -> []int`, `hints_count()`, `hints_at(k)`, `hints_pick()`, `hints_hot(k)` | the rail |
|
||||
| `hints_card()`, `hints_key()`, `hints_open(k)`, `hints_close()`, `hints_move(d)` | the card being read (-1) and its verbs |
|
||||
| `hints_step_text(id, n)`, `hints_step_icon(id, n)`, `hints_step_item(id, n)` | a step, n 1..3 |
|
||||
| `hints_mute_card()`, `hints_mute(id, on)`, `hints_muted(id)`, `hints_mute_count()`, `hints_unmute_all()` | "I know this" |
|
||||
| `hints_mutes_save() -> Val`, `hints_mutes_load(v)` | the mutes as a list of keys, for the game's settings file |
|
||||
| `hints_facts() -> Queue<HintsFact>` | `{ what, card }`: `HINTS_F_OPENED`, `_CLOSED`, `_MUTED`, `_UNMUTED` |
|
||||
| `hints_system() -> System` | `"hints"`, `PH_PRESENT`: reset and the tick; nothing in a trip's save |
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
ludic test packages/ludic.hints
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue