KAZIK/docs/FORTUNE_AI.md
Игорь Федосеев 5dedaf459f fix: restore fortune AI and add model setup
Restore native inference, card-bound readings and paged dialogue.

Provide manual, checksum-verified model setup instead of Git LFS so
source checkouts work without uploading multi-gigabyte weights. The
game stays offline; complete release archives still bundle the model.
2026-10-31 00:37:36 +03:00

110 lines
6 KiB
Markdown

# Offline Fortune Teller
## Current integration (2026-10-31)
The seated tarot scene now calls the bundled neural worker again. The visual
session had replaced process startup, polling and interpretation with stubs;
keeping `fortune-engine.exe` alone did not make that scene AI-enabled.
MASM owns question input, selection of three distinct major arcana, orientation,
animation, IPC, process lifetime, response validation, pagination and rendering.
Only local neural inference/text generation runs in the approved C++ worker.
The crystal-ball lottery is unchanged and does not invoke the model.
## Answers and interaction
Enter a question of up to 240 CP1251 characters. Submission commits three cards
and starts the worker while the normal shuffle/deal/flip animation continues.
The first explanation waits if inference has not finished. Rendering and exit
remain responsive. Continue advances a fully displayed page; it does not skip
dealing or flip animations. All interpretation pages require Continue, so a long
answer cannot disappear before it is read. Again starts a new independent reading.
The worker returns four Russian sections: situation, obstacle, direction, and
overall advice. A grammar fixes the first three headings to the actual supplied
card names, positions and orientations. Each body is bounded to 80-220 characters
and ends with punctuation. The body itself is model-generated, not a canned card
description. Grammar prevents structural/card-heading errors; it does **not** prove
that every interpretation is sensible. Semantic quality still needs human review.
Each native bubble page wraps words within nine 23-character rows. Missing model, startup
failure, broken pipes, invalid/oversized frames, incomplete output and a 180-second
wait produce visible errors, not fake successful readings. Exit/Selection close
the worker and its pipes; no model is loaded for the crystal ball or walking.
No questions or answers are written to the player profile or runtime logs.
## Model and distribution
- Qwen3-4B-Instruct-2507, Q4_K_M GGUF, Apache-2.0.
- Exactly 2,497,281,120 bytes; pinned revision and SHA-256: `ai/model.json`.
- Pinned llama.cpp source, CPU-only x64 worker, AVX baseline, static MSVC runtime.
- About 3 GB working set in the earlier baseline; 8 GB system RAM is a practical
starting point, not a verified minimum.
- Generation is not instant: the first updated development-machine sample took
about 55 seconds. Hardware and question length affect this substantially.
- No cloud API, Ollama, Python runtime, listening port, runtime downloader or GPU
driver requirement. The game must ship with the actual GGUF in `ai/models/`.
`tools/fortune_ai/build.ps1` builds the worker and verifies the model. Its explicit
`-DownloadModel` option is a developer/release preparation action only.
The GGUF and vendor build files are ignored by Git. After cloning or copying the
repository, double-click **`download_fortune_model.bat`** in the repository root.
No Python, Git LFS or administrator access is required. The setup uses Windows
PowerShell and `curl.exe` (current Windows 10/11), requires Internet and about
3 GB free space. For unattended setup:
```powershell
.\download_fortune_model.bat --no-pause
```
The setup downloads from pinned ModelScope/Hugging Face revisions, resumes partial
downloads where supported and falls back to the next source. It checks size and
SHA-256 from `ai/model.json` before replacing the destination. An existing valid
model is verified without network access. Failed downloads do not replace an
existing destination; rerun setup to retry. URLs, size and hash are versioned in
the manifest. The game never invokes setup or downloads weights at runtime.
The legacy Python download entry point and build script's `-DownloadModel` option
delegate to the same PowerShell implementation. Complete offline release ZIPs
still bundle the real weights and need no setup download.
`python tools/fortune_ai/package.py` builds `dist/Assembler Casino Offline.zip`
with launcher, game, assets, worker, prompts, licenses and the verified weights.
`--check-only` validates inputs without making an archive. Use this full ZIP for
another PC. The old C# self-extracting installer is not suitable for embedding the
2.5 GB weights; the existing launcher is C#, not assembly.
## Protocol
Inherited anonymous pipes, no shell or HTTP. Request: five little-endian DWORDs
(`FCQ1`, question byte length, three card IDs), then CP1251 question bytes. IDs
0-21 are upright; 22-43 reversed. Worker limit: 768 question bytes, distinct cards.
Response: three DWORDs (`FCR1`, status, text byte length), then CP1251 text, capped
at 8192 bytes. Status 0 is ready, 1 complete answer, 2 error. Legacy status 3
(token-limited output) is rejected rather than displayed as a finished reading.
Complete answers have exactly four nonempty newline-separated sections. Native
polling waits only for bytes already available and never blocks on partial frames.
## Verification
```powershell
python -B tools/tests/check_fortune_ai.py
python -B tools/tests/check_fortune_session_ai.py
python -B tools/tests/check_fortune_session_ai.py --with-model
python -B tools/tests/check_hall_expansion.py
```
Python test dependencies: `tools/tests/requirements.txt`. Native tests require
the MASM/MSVC x86 toolchain. Real-model tests also require the bundled weights.
- Worker test checks actual Russian inference, exact card headings/orientations,
four complete bounded sections, independent requests and oversized input.
- Native test exercises actual submission, split headers/bodies, parser, paging,
oversized frames, broken pipes, timeout and cleanup with controlled pipe frames.
- `--with-model` exercises real WM_CHAR input, assembly-selected request data,
child/model response and all four reading stages through native UI controls.
- Hall regression preserves shuffle/deal/flip artwork, crystal-ball validation,
number tracking, navigation, bowling and other existing scenes.
Fictional test questions, answers and captures stay under ignored `build/`.
Automated format checks do not certify tarot predictions or replace desktop QA.