# 040 — Entry points, sources, and settings

## Common entry policy

Keep `milionar_game`, `millionaire.open_game(subject, content=None)`, `run(params)`, and `start(subject)` as compatible public entry paths. The common modern title card adds the mode selector. No per-caller “which game?” popup, new catalog, or two game buttons throughout the addon.

The subject must arrive unchanged in meaning, with title, year when known, media type, TMDb identity when known, art, and the supplied episode/season scope. Normalize `tv` to `series` consistently. Detect episode scope from its actual fields, not from an invented type requirement.

Do not move the subject module simply because its package name contains `millionaire`. Reuse it with minimal field round-trip fixes; a module relocation would add risk without player value.

## Mode preference

Implemented setting IDs (added by Story; independent of existing Millionaire preferences):

| ID | Stored value | Default / behavior |
|---|---|---|
| `game_last_mode` | `millionaire` or `story` | `millionaire` if absent/invalid; write on an explicit eligible mode choice |
| `story_difficulty` | select index 0/1/2 | 1 (Medium); maps to 10/15/20 independently of `millionaire_difficulty` |

These names were checked against existing settings and are stored through the existing setting helpers. The title card and addon settings read the same values.

If the stored mode is Story but the subject/source is ineligible, show Millionaire for that launch without overwriting the preference. An unavailable option is not selectable; explain it briefly in the existing card if needed. Returning from a person game must not reset the user's Story choice for their next film.

The mode selector is visible only on the title card and changes both descriptive chips and available settings. No switching while an attempt is loading, playing, showing feedback, or terminal; return to title first.

## Eligibility and source matrix

| Subject/source | Millionaire | Story |
|---|---|---|
| AI film / series / identified episode | Existing behavior | Available |
| AI explicitly identified season, if an existing entry provides it | Existing behavior | Preserve exact scope; no new picker |
| Actor/director/writer/creator | Existing behavior | Unavailable |
| Mixed channel / cinema topic | Existing behavior | Unavailable |
| Any of the 29 existing offline demos | Existing authored Millionaire pack | Authored Story pack for selected difficulty; eight series use identified S01E01 scopes |
| Unknown/incomplete offline demo | Existing source behavior | Unavailable; all three local difficulty files are required |

Never silently use AI when a demo source is selected. A missing offline Story pack stays an offline limitation, not a chargeable fallback.

For `milionar_demo&demo=<id>`, retain an explicit lightweight demo identity/context in the common launcher. The Millionaire adapter receives `DemoContent`; the Story adapter reads that ID's Story fixture. Switching back restores the proper source. Do not derive demo identity from a title string or the existence of arbitrary attributes.

`DemoSource.scoped_subject` reads the episode overlay from `resources/demo/story/scopes.json` only when the caller has no season/episode/title scope. The Story adapter owns that scoped copy and shows S01E01 in the existing offline source note. An explicitly supplied different episode/season is preserved and rejected by identity validation rather than silently replaced. The modal/Millionaire metadata stays unchanged. See `140-demo-catalog.md` for the approved narrative scope table.

The existing `content=` injection used by tests remains valid. Keep only the small optional launch context needed to support both sources; avoid a source plugin registry. Existing `demo=random` keeps its current random title selection and now has Story counterparts for the entire pool. Incomplete fixtures still follow the eligibility rule above.

## Settings shown by mode

- Millionaire keeps its current difficulty, presenter style, length, spectator/autoplay, and existing settings behavior.
- Story shows its own difficulty/count. Its narrator length/style is fixed by the approved concise contract; no new narrator-persona or text-length controls.
- Story has no lifelines or autoplay settings. An enabled Millionaire autoplay setting must not cause Story to answer/advance automatically.
- Both use existing voice configuration. No separate voice credentials, provider selector, or voice defaults are added.
- Shared row read/write/description helpers may accept a small explicit rows argument; do not duplicate their functions.
- Append new addon settings in a suitable game section. Preserve relative provider visibility offsets and add required cs/sk/en strings.

## Modern and legacy design boundary

The approved selector and Story layout target the modern card. `designs.py` still supports a classic card today; its removal is part of another plan, not this feature.

The canonical launch described in this plan explicitly uses the modern shell for both modes, including eligible subjects with Millionaire selected. This is the narrow UI adjustment needed to deliver the approved common modern selector. A saved legacy `milionar_game_design` value must not hide the selector or route Story into classic XML.

Leave classic XML/classes/settings intact for any explicit legacy compatibility path still in use; they remain Millionaire-only. Do not silently migrate/delete the user's stored design setting or undertake the old cleanup plan. Record the canonical launch-design adjustment and its regression evidence in the handoff. Existing Millionaire rules, content, voice, and modern gameplay appearance remain unchanged.

## Touchpoint checklist

For each path in `020-current-state.md`, record whether it already converges at the canonical entry or needs a specific field/label fix. Check film identity, whole-series identity, episode title/numbers, demo context, person exclusion, and mixed-topic exclusion.

Use a generic localized “Play game” label where a launch affordance must describe both modes. Preserve the product/skin brand “Milionář”; do not redesign or rename the entire Home section. “Change title” retains the current navigation and work selection rather than opening a new picker.

Playback notification behavior remains: close notification -> plugin launch -> card over still-playing video. Existing library, search, detail and Home metadata caches remain the source of metadata; no new independent fetching/storage path is introduced.
