# 009 - Milionar Game (MyTV AppleTV)

**Status:** COMPLETED
**Updated:** 2026-02-22 23:28
**XML:** `DialogMyTV_appletv.xml` [L4155-4666](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/resources/skins/Default/1080i/ai/DialogMyTV_appletv.xml#L4155-L4666)
**Python:** `DialogMyTV.py` [L3607-3714](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/wcs/ai/DialogMyTV.py#L3607-L3714), adapter + game logic

---

## Ucel

Inline kviz "Filmovy Milionar" v MyTV/MyCinema AppleTV dialogu. AI generuje otazky o filmech/serialech v realnem case pres continuous chat. 9 urovni, 3 napovedy, TTS, autoplay mode. Bezi jako sub-dialog uvnitr MyTV okna (ne samostatny fullscreen dialog).

---

## Architektura

```
DialogMyTV.py
  _show_game_dialog() → vytvori MillionaireMyTVAdapter
  _handle_game_click() → deleguje onClick na adapter
  _handle_game_action() → deleguje onAction (ESC = zavre)
    |
    v
MillionaireMyTVAdapter (361ř, adapter pattern)
  mapuje controller callbacks → dialog.setProperty()
    |
    v
MillionaireGameController (2153ř, game logic)
  continuous chat, otazky, lifelines, autoplay
    |
    v
millionaire_prompts.py (421ř, prompt building)
millionaire_tts.py (330ř, TTS orchestrace)
moderator_styles/ (5 SKILL.md stylů)
```

---

## File Map

| Soubor | Radku | Role |
|--------|-------|------|
| [DialogMyTV.py L3607-3714](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/wcs/ai/DialogMyTV.py#L3607-L3714) | 107 | MyTV integrace: show/close/handle game |
| [MillionaireMyTVAdapter.py](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/wcs/games/MillionaireMyTVAdapter.py) | 361 | Adapter: controller → window properties |
| [MillionaireGame.py](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/wcs/games/MillionaireGame.py) | 2153 | Hlavni game logic (continuous chat) |
| [millionaire_prompts.py](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/wcs/games/millionaire_prompts.py) | 421 | System prompt + user message builders |
| [millionaire_tts.py](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/wcs/games/millionaire_tts.py) | 330 | TTS orchestrace (viz 010-milionar-tts.md) |
| [moderator_styles/](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/wcs/games/moderator_styles) | 5 | comedian, dramatic, friendly, mysterious, professional |
| [DialogMyTV_appletv.xml L4155-4666](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/resources/skins/Default/1080i/ai/DialogMyTV_appletv.xml#L4155-L4666) | 511 | Inline game UI layout |

Deprecated (dedi se z nich, ale nespousti se): `DialogWcsTextGame.py` (757ř), `DialogWcsTextGame.xml`, `GameManager.py`.

---

## XML Layout (inline sub-dialog)

**Visibility:** `WCS.MyTV.Game.Active` (neprazdne)
**Panel:** 1600x850 na pozici 160,115

### Vizualni struktura

```
+----------------------------------------+
| [Poster 280x580]  [Title]     [Ladder] |
|                   [Text/     ] [1M Kč] |
|                    Content   ] [500K  ] |
|    [Logo]         [area     ] [...    ] |
|                   [textbox  ] [1K Kč ] |
|                                        |
|  [50:50] [Tip] [Divaci]    (lifelines) |
|                                        |
|  [Question text ......... scroll]      |
|  [A: answer     ] [B: answer     ]    |
|  [C: answer     ] [D: answer     ]    |
+----------------------------------------+
```

### Control ID mapa

| ID | Typ | Oblast | Ucel |
|----|-----|--------|------|
| 9500 | button | Footer | Odpoved A (top-left, 760x65) |
| 9501 | button | Footer | Odpoved B (top-right) |
| 9502 | button | Footer | Odpoved C (bottom-left) |
| 9503 | button | Footer | Odpoved D (bottom-right) |
| 9510 | button | Lifelines | 50:50 (120x65) |
| 9511 | button | Lifelines | Tip (120x65) |
| 9512 | button | Lifelines | Divaci (120x65) |
| 9513 | button | Menu | Konec hry (cervena `FFFF3B30`) |
| 9514 | button | Menu | Dynamicky btn 1 (modra `CC2997FF`) |
| 9515 | button | Menu | Dynamicky btn 2 (seda) |
| 9520 | label | Footer | Text otazky (scroll) |
| 9521 | textbox | Content | Hlavni text (moderator/feedback, autoscroll) |
| 9530 | button | Hidden | Focus trap (loading states) |
| 9541-9549 | image | Ladder | 9 urovni pill backgrounds |

### 2 stavy footeru

**Stav 1: Answers** (`WCS.Game.ShowAnswers == true`)
- Otazka (9520) + 2x2 grid odpovedi (9500-9503)
- Lifelines hore (9510-9512)

**Stav 2: Menu** (odpovedi skryte)
- 3 dynamicke buttony (9514/9515/9513)
- Labels z properties: `WCS.Game.MenuBtn1`, `WCS.Game.MenuBtn2`

### Focus navigace

```
Lifelines:  9510 → 9511 → 9512
              ↓       ↓       ↓
Answers:    9500 ↔ 9501     (top row)
              ↕       ↕
            9502 ↔ 9503     (bottom row)

Menu:       9514 → 9515 → 9513
```

---

## Window Properties (adapter → XML)

### Staticke (nastavene pri otevreni)

| Property | Popis |
|----------|-------|
| `WCS.MyTV.Game.Active` | `true` = dialog viditeln |
| `WCS.Game.Poster` | Poster serialu/filmu |
| `WCS.Game.Logo` | Clearlogo (skryje nazev) |
| `WCS.Game.SeriesName` | Nazev (fallback kdyz neni logo) |

### Dynamicke (meni se behem hry)

| Property | Popis |
|----------|-------|
| `WCS.Game.Title` | Titulek (uroven, castka) |
| `WCS.Game.Text` | Hlavni text (moderator, feedback, vysvetleni) |
| `WCS.Game.Question` | Text aktualni otazky |
| `WCS.Game.ShowAnswers` | `true` = zobraz otazku + odpovedi |
| `WCS.Game.AnswerA-D` | Texty 4 odpovedi |
| `WCS.Game.AnswerA-D.Color` | Barvy nofocus (default `30FFFFFF`) |
| `WCS.Game.AnswerA-D.FocusColor` | Barvy focus (default `90FFFFFF`) |
| `WCS.Game.MenuBtn1` / `MenuBtn2` | Dynamicke labely menu buttonu |

### Lifeline properties

| Property | Popis |
|----------|-------|
| `WCS.Game.Lifeline5050` | Neprazdne = pouzita (disable button) |
| `WCS.Game.LifelineTip` | Neprazdne = pouzita |
| `WCS.Game.LifelineAudience` | Neprazdne = pouzita |

### Ladder properties

| Property | Popis |
|----------|-------|
| `WCS.Game.Ladder.1-9` | Barva pill pozadi (colordiffuse) |
| `WCS.Game.Ladder.1-9.Color` | Barva textu |

Ladder barvy v adapteru:
- Default: `20FFFFFF` (pruhledna), text `AAFFFFFF`
- Current: `CC2997FF` (modra), text `FFFFFFFF`
- Completed: `FF3CB371` (zelena), text `FFFFFFFF`
- Failed: `FFB04A4A` (cervena)
- Dim: text `60FFFFFF`

Milestones (vetsi font `font25_title`): L3 (5000), L6 (50000), L9 (1000000).

---

## Answer barvy (reveal faze)

| Faze | Vybrana | Spravna | Ostatni |
|------|---------|---------|---------|
| Faze 1 (countdown) | Modra `CC2997FF` | default | default |
| Faze 2 (reveal correct) | - | Zelena `CC4CAF50` | default |
| Faze 2 (reveal wrong) | Cervena `CCFF3B30` | Zelena `CC4CAF50` | default |

---

## Spousteni z MyTV/MyCinema

| Zdroj | Button ID | media_type | Popis |
|-------|-----------|-----------|-------|
| Home ROW 0 | 9043 | `channel` | Z hlavni obrazovky, vse v kanale |
| Series Grid | 9115 | `channel`/`cinema` | Z gridu serialu/filmu |
| Play Selection | - | `episode` | Z vyberoveho menu epizody |
| Series Detail | - | `series` | Z detailu serialu |
| Add Series listing | - | `series` | Z action buttons v Add dialogu |

`_show_game_dialog()` v `DialogMyTV.py` vytvori `MillionaireMyTVAdapter` a spusti hru.

---

## Continuous Chat (game flow)

Cela hra = jeden AI chat session (`_chat_inference()`):

| Inference | Zprava | Odpoved (JSON) |
|-----------|--------|-----------------|
| 1 | `build_welcome_message()` | `welcome_text`, `rules_summary` |
| 2 | `build_question_message(1)` | `moderator_intro`, `question`, `options[]`, `correct`, `explanation` |
| 3 | `build_feedback_message(1, ...)` | `result_text`, `transition_text`, `explanation` |
| 4-17 | otazky a feedback pro urovne 2-9 | |

Prefetch: po feedback se dalsi otazka generuje na pozadi (`_prefetch_next_question()`).

### 9 urovni

| Uroven | Castka | Obtiznost |
|--------|--------|-----------|
| 1-3 | 1K-5K Kc | lehka |
| 4-6 | 10K-50K Kc | stredni |
| 7-9 | 100K-1M Kc | tezka |

### 3 napovedy

| Napoveda | ID | Metoda | Popis |
|----------|----|--------|-------|
| 50:50 | 9510 | `use_5050_lifeline()` | Odebere 2 spatne odpovedi |
| Tip | 9511 | `use_tip_lifeline()` | AI generovana rada od rezisera (separatni inference) |
| Divaci | 9512 | `use_audience_poll_lifeline()` | Simulovane procenta s 10s animaci |

### Autoplay mode

| Setting | Popis |
|---------|-------|
| `millionaire_autoplay_enabled` | Zapnout |
| `millionaire_autoplay_delay` | Zpozdeni pred odpovedi (s) |
| `millionaire_autoplay_fail_chance` | Sance na spatnou odpoved (%) |
| `millionaire_autoplay_lifeline_frequency` | Frekvence pouziti napoved |

Autoplay ceka na TTS (`wait_for_tts_completion()`) pred odpovedi.

---

## Adapter pattern

`MillionaireMyTVAdapter` mapuje controller callbacks na `dialog.setProperty()`:

| Controller callback | Adapter metoda | Co dela |
|---------------------|---------------|---------|
| `update_display` | `_on_display_update()` | Parze title+text → properties |
| `update_buttons` | `_on_buttons_update()` | Mapuje labels na Answer/Menu properties |
| `update_sidebar` | `_on_sidebar_update()` | Update ladder + lifeline state |
| `set_focus` | `_on_set_focus()` | Mapuje stare IDs 305-308 → 9500-9503 |
| `start_countdown` | `_on_countdown()` | Countdown timer |
| `close_dialog` | `_on_close()` | Zavre game dialog |
| `update_millionaire_ladder` | `_on_ladder_update()` | Ladder barvy z controller state |
| `set_answer_button_colors` | `_on_answer_colors()` | Selected/correct/wrong barvy |

---

## Zavislosti

- `MillionaireGameController` -- hlavni game logika (dedeno z fullscreen verze)
- `millionaire_prompts` -- system prompt + user message building
- `millionaire_tts` -- TTS (viz [010-milionar-tts.md](file:///Users/chudy/Library/Application%20Support/Kodi/addons/plugin.video.milionar/docs/features/010-milionar-tts.md))
- `wcs.ai.AIHandler` + `AIProvider` -- AI inference
- `DialogMyTV.py` -- host dialog (MyTV/MyCinema)
