KAZIK/docs/FORTUNE_AI.md
Artvasil09 ce06659ab2 feat: implement offline neural fortune teller and native tarot divination
- Offline neural worker based on llama.cpp (fortune-engine.exe) with local Qwen3-4B model support

- Native assembly Tarot 3-card spread divination and teacher grade divination mode

- Text input dialog in MODE_FORTUNE communicating over anonymous pipes

- Clean process lifecycle management, WM_CHAR dispatch and fallback handling

- Test suites and packaging tools for offline release
2026-10-21 13:53:06 +03:00

4.5 KiB

Offline Fortune Teller

The approved C++ exception is limited to the neural worker. MASM still owns the room, interaction, question input, card selection, dialogue rendering, process lifetime and all gameplay. No OpenAI API, Ollama, Python runtime, listening port, runtime downloader or external AI application is used by the game.

Model And Resources

  • Qwen3-4B-Instruct-2507, Apache-2.0, Q4_K_M GGUF by Unsloth.
  • Exact file: 2,497,281,120 bytes. Revision and SHA-256 are in ai/model.json.
  • llama.cpp source is pinned in the same manifest; its MIT license is shipped.
  • CPU-only x64 worker, AVX baseline, static MSVC runtime, no GPU driver required.
  • Initial measurement: about 3 GB working set; allow additional RAM for Windows and the game. 8 GB system RAM is a practical starting point, not a tested minimum.
  • On the development i7-14700K, baseline CPU generation took 41-53 seconds per answer in the first three-question test. Do not advertise instant replies.
  • Model loads only for the conversation and is terminated on exit or shutdown. The game continues rendering while the model loads or answers.

The model produces entertainment, not reliable predictions or factual judgements about people. It must not determine real student grades from names, birth years or cards. No academic grading form or grade recommendation is implemented.

Native Integration

MODE_FORTUNE replaces the previous unavailable dialog only at the fortune teller. Users can type up to 240 CP1251 characters, ask a question, read a paged answer, ask a follow-up, or leave. Three distinct major arcana are chosen in assembly, including orientation; the worker interprets those exact cards. The initial catalogue contains 22 major arcana, not a full 78-card deck. History retains one previous question/answer in worker RAM, not a save or log.

Communication is through inherited anonymous pipes, not HTTP. The only child process is ai/fortune-engine.exe, created directly without a shell or console. Requests are five little-endian DWORDs (FCQ1 magic, byte length, three card IDs), then CP1251 question bytes. IDs 0-21 are upright, 22-43 reversed. Maximum worker question length is 768 bytes; the game UI imposes the tighter 240-byte bound. Responses contain three DWORDs (FCR1 magic, status, length), then CP1251 text. Status 0 means ready, 1 answer, 2 failure, 3 token-limited answer. Output is capped at 8192 bytes. Incomplete frames, pipe failures and a 180-second wait are handled without blocking the game. Request text cannot inject ChatML role delimiters.

Developer Build And Release

Install CMake and a Visual Studio C++ toolchain on the development machine only. tools/fortune_ai/build.ps1 builds the pinned worker and checks the model hash; -DownloadModel is an explicit development/release preparation option, never a game startup or installer action. The weights are deliberately ignored by Git. Copying only the Git checkout is not a complete offline distribution.

tools/fortune_ai/package.py makes dist/Assembler Casino Offline.zip with the game, assets, worker, prompts, licenses and actual GGUF, using ZIP64 for the model. Extract it and run Assembler Casino.exe; nothing else needs installing or downloading. --check-only validates the release inputs without creating it. The existing legacy C# self-extracting installer reads its entire embedded payload into a byte array. Do not embed the 2.5 GB model in that installer: it requires a separate streaming-installer update before it can ship this release.

Verification

tools/tests/check_fortune_ai.py runs the actual model, tests Russian output, follow-ups and oversized frame rejection, with no external service. Fictional test prompts and responses are written only to ignored build/fortune-ai. check_hall_expansion.py --with-fortune-ai tests the real native input, purchase- free request, pipe polling, displayed response, bounds and cleanup. The ordinary hall test also checks entering/leaving the dialog, stairs and previous fixes. These tests are not a full interactive desktop playthrough.

Published Build

Root/bin/build game copies and launcher metadata have SHA-256 C1714FEA01C6AA594A1895F56CCC287E5D1F35CDC829F5C2658FF05A4CBB6ECF. Fresh assembly, native dialogue/room/bar tests, function parity (including the WM_CHAR dispatch), billiards, card ranks, terminals and asset-loading checks pass. The worker also reuses only exact cached token prefixes between questions; failed inference clears that cache and history. It has only Windows system DLL imports.