import InfoBox from '../components/InfoBox.astro';
import PullQuote from '../components/PullQuote.astro';

Several of the game's mechanics only become clear after the player discovers them by accident. Fruit increases the multiplier, longer words tend to score better, combos spawn rewards rather than awarding points immediately, but none of that helps someone who never performs the action that reveals it. The hint engine starts from those absences and chooses one useful thing to explain while the game is still in progress.

## Absence is the signal

The engine is pure TypeScript and receives a summary of the current game: words played, fruit eaten, combos found, and whether a reward has been collected. It prioritizes a small set of hints, fires each at most once per game, and behaves the same in daily and duel. A player using only short words gets a different nudge from one who has spawned a fruit but not collected it. If several hints could apply, the engine chooses one rather than turning guidance into another notification queue.

<InfoBox title="The four gaps it can name">
  No fruit collected yet. Only short words submitted. A combo type still undiscovered. A first
  combo triggered without the player yet knowing that its points land when the spawned fruit is
  collected. End-game guidance uses the same evidence and disappears when every combo was found.
</InfoBox>

## One shell, two jobs

Design review began with the idea of reusing the existing [combo notification](/posts/length-multiplier-and-combo-feedback#explain-the-fruit-after-it-exists), then pushed it far enough to replace that component entirely. One notice shell now has two roles. Reward notices keep the fruit colour, icon, and points; guidance notices use a neutral surface, a short reason, and more reading time. They share the same overlay rail and dismissal machinery, but not the same behaviour: rewards may stack, while a newly relevant hint replaces the previous hint so it stays connected to the action that caused it.

<PullQuote>A hint that arrives after its moment has become documentation.</PullQuote>

## The history was not a reliable witness

The agent's self-review found that the first-combo hint was inferred from the word history. That looked reasonable until multi-word combos retroactively marked earlier entries, making some first combos appear as though they had already happened. A dedicated game-state flag now records the event directly. The same review restored the reward notice's silent live-region setting, avoiding a second screen-reader announcement beside the existing combo announcer, and removed a duplicated mapping between combo types and fruit.

## Guidance at the end as well

The end-game dialog uses the same guidance notice without a timer, alongside a compact layout that fits both score-submission states inside a phone viewport. It chooses a lesson from the completed game, unless the player found all four combos and has nothing left for this system to teach. The dialog becomes a second delivery point for the same decision, not a separate collection of hand-written conditions.

## Closing the native-client surface

The other half of the day removes the [mobile compatibility contract and offline summary path](/posts/the-mobile-api-detour#one-summary-after-the-game). No native client reached production, so there are no installed versions to preserve and no stored mobile summaries with value. The endpoint, its storage, its types, and the decision record come out together. One new system earns a named engine because several interfaces need its decision; one abandoned system disappears because nothing needs its interface at all.