ludic/packages/ludic.hints/README.md

75 lines
3.3 KiB
Markdown

# 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
```