ludic/packages/ludic.hints
2026-09-30 00:29:03 +03:00
..
tests packages: the registry text a game fills is keys (Maroon Lake's phase 26.4) - ThingKind.name, GearKind blurb/howto/names, HintCard's words, JobDef title/text/how, NpcLine and NpcChoice text, WeatherKind.name are @Text Key fields (a compiled row that leaves one out takes its derived key, the English is the game's en.po); what a package hands back as text is the key's marked text, "" for none; NpcName.name, NpcChoice.line and SettingDef.text are not text and lose @Text; ludic.i18n's tr/trf/trn/key_text say @alloc_ok (tr is a cast); the packages' tests with key literals (built, not run); changes/text-keys-data.md 2026-09-30 00:29:03 +03:00
card.ludic packages: the registry text a game fills is keys (Maroon Lake's phase 26.4) - ThingKind.name, GearKind blurb/howto/names, HintCard's words, JobDef title/text/how, NpcLine and NpcChoice text, WeatherKind.name are @Text Key fields (a compiled row that leaves one out takes its derived key, the English is the game's en.po); what a package hands back as text is the key's marked text, "" for none; NpcName.name, NpcChoice.line and SettingDef.text are not text and lose @Text; ludic.i18n's tr/trf/trn/key_text say @alloc_ok (tr is a cast); the packages' tests with key literals (built, not run); changes/text-keys-data.md 2026-09-30 00:29:03 +03:00
defs.ludic packages: the registry text a game fills is keys (Maroon Lake's phase 26.4) - ThingKind.name, GearKind blurb/howto/names, HintCard's words, JobDef title/text/how, NpcLine and NpcChoice text, WeatherKind.name are @Text Key fields (a compiled row that leaves one out takes its derived key, the English is the game's en.po); what a package hands back as text is the key's marked text, "" for none; NpcName.name, NpcChoice.line and SettingDef.text are not text and lose @Text; ludic.i18n's tr/trf/trn/key_text say @alloc_ok (tr is a cast); the packages' tests with key literals (built, not run); changes/text-keys-data.md 2026-09-30 00:29:03 +03:00
index.ludic play 2's frame keeps and a dropped file: a var() join made at once, the hint rail emptied in place, save_read gives its text back 2026-09-29 13:33:54 +03:00
mute.ludic ludic.settings: the store filled into a kept object in place; texts read from a file kept apart from it 2026-09-29 12:22:07 +03:00
package.ludic 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 2026-09-25 09:36:10 +03:00
port.ludic 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 2026-09-25 09:36:10 +03:00
rail.ludic play 2's frame keeps and a dropped file: a var() join made at once, the hint rail emptied in place, save_read gives its text back 2026-09-29 13:33:54 +03:00
rail_into.ludic frame allocs: a local shadowing a function is no edge, the drain's calls are no edges, HEAP keeps only a growth off the arena, and the arena starts at its first use 2026-09-28 20:23:28 +03:00
rail_slots.ludic play 2's frame keeps and a dropped file: a var() join made at once, the hint rail emptied in place, save_read gives its text back 2026-09-29 13:33:54 +03:00
README.md 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 2026-09-25 09:36:10 +03:00
system.ludic wip(0.S3): packages and examples migrated again from their pre-0.S sources in one run 2026-09-25 15:31:34 +03:00

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 and nothing else.

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

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

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

ludic test packages/ludic.hints