KAZIK/docs/GRAPHICAL_SCENES.md
Artvasil09 4f8ae0893b Implement native slots, coin toss, European roulette and hall furniture
Add native assembly scenes and assets for Slots (777), Coin flip, and European Roulette; add 3D hall furniture packs and prompts; improve Russian UI strings in CP1251; update launcher hash and rebuild shipping binaries.
2026-10-10 14:43:30 +03:00

169 lines
11 KiB
Markdown

# Native Graphical Scenes
The runtime, frame loader, alpha compositor, input, profile selection and games
are MASM32 assembly. This is our own raycaster, not the Doom source code.
Python only normalizes and packs assets offline.
## Implemented In This Stage
- The Eblan Games intro automatically fades out after seven seconds. Every launch
starts a black transition, eyes opening under clouds/rain, gaze lowering into an
alley, smoking, tossing the cigarette into a trash bin, an alley exit, a turn,
a street walk and a turn/approach to the pub-like casino entrance. This uses a
separate 32x32 exterior map and the native raycaster, not a zoomed facade image.
The scripted approach lasts about 26 seconds; Enter can skip to the guards.
The alley is two tiles wide and closed at its back. The camera first faces the
dead end, then turns around and exits onto the sidewalk. Cars have eight viewing
directions per model; three are parked by the curb and two travel along the road.
- The approach leads to a guard stop, local profile
selection, an invitation gesture and entry into the walkable casino.
- Existing signed local accounts are discovered read-only. Choosing one imports
it into `runtime/profiles`. Original AppData/root account files are not changed.
- New profiles are created graphically, without console input. Preview remains
available with its original bank. Zero-bank profiles do not receive free money.
- Sidorovich runs the native card-back shop: thirteen previews, purchase/equip,
paging, keyboard/mouse controls, and persistence in the chosen local account.
- Guards have a 32-frame source sheet with idle, stop, admission and guest-list
actions. The cropped final admission frame is deliberately not played.
- Sidorovich has 24 source frames: idle, showing merchandise and negotiation.
- Native poker/blackjack card flights now last 360 ms, with dealer hand poses
synchronized to the card's grab, movement and release. Chip placement has a
first-person hand prototype. Neither animation controls the result of a hand.
A companion table background removes the static folded hands so the animated
dealer does not acquire an extra hand. The original reference remains intact.
- Durak opens at its hall table as a native two-player game, with podkidnoy
and perevodnoy modes, animated dealing/plays, public-information AI,
eight-card hand pages and a frozen exit confirmation. It shares the existing
first-person table/hand assets; see [Native Durak](native-durak.md).
- Separate blackjack/poker/roulette/dice/shop/bar/backroom props replace selected
repeated table sprites. Walkable geometry and existing interaction IDs remain.
## Visual Direction
The current direction is detailed late-1990s pixel art matching the software
2.5D interior, not realistic illustrations. New guards, Sidorovich, furniture,
hand sprites and the card table have pixel-art variants. Asset packing and
runtime sampling avoid smoothing. The exterior is an old brick working-class
quarter, wet asphalt, weathered wood and a modest pub-like casino entrance.
Buildings have five-storey wall projection with separate upper windows and
human-scale ground-floor doors. A second district of fourteen taller world-space
buildings is drawn behind the near quarter, with perspective, repeated window
materials and blue atmospheric shading; foreground walls occlude it normally.
The street opens into a cross street and continues through the exterior map edge.
Exterior rays that leave the map do not turn the boundary into a fake building.
Sidewalk and road use different materials.
Dumpster bodies, rims, interior floors, hinged lids and casters are world-space
geometry with per-pixel depth, not camera-facing cutouts. They run along the alley
walls and remain inside its open footprint. The open lid is hinged at the rear
short edge, facing the camera, with a thick rim and handle. The closed lid also has
an overhanging edge, thickness and handle rather than just a flat dark plane.
The held cigarette is a connected 64-pixel object with a filter, shaded paper,
ash and ember, not spaced dot samples. Smoke is attached to its burning tip.
Per-frame emitter anchors are generated from the opaque end of each smoke plume;
transparent bottom gutters cannot leave a gap between the ember and smoke.
Grip anchors follow the gap between the index/middle fingers. The fingers render
in front of the filter; holding poses finish before the release poses begin.
The flight starts at the same position, angle and scale as the last held frame.
The hand, cigarette flight, thin smoke
and larger exhaled clouds are independent layers. Solid cutouts use binary alpha;
only smoke uses fractional alpha and scoped opacity.
The rejected palace facade is not rendered by the new opening.
The user's original interior floor/ceiling/wall materials remain unchanged.
This is not yet a complete art conversion. Legacy slot machines, dancers,
terminal/ASCII games, the roulette prototype and some original room assets still
need the same treatment. More frames alone do not guarantee smooth movement:
identity, scale, foot/wrist anchors, connected poses and timing must be checked.
No duplicate-frame padding or crossfade ghosting is used to inflate frame counts.
## Assets And Playback
Source images: `assets/sprites/arrival`; the latest exterior prompt/reference
records are `alley-prompts-v4.json`, `cars-prompt-v4.json` and
`clouds-prompt-v4.json`. The character/interior set is `pixel-prompts-v3.json`.
Earlier, superseded records are in
`prompts.json`, `prompts-v2.json`, and `materials-prompt.json`; the table edit record
is in `assets/sprites/tables/active-background-prompt.json`. Generated with the
built-in image_gen tool; project references never depend on its external cache.
Run `tools/generators/pack_arrival_assets.py` to produce the native frame packs in
`assets/animations/arrival`. `ANM1` uses a 20-byte little-endian header (magic,
width, height, frame count, payload bytes) followed by tightly packed BGRA frames.
The native loader checks dimensions, frame count, exact file length, allocation
and reads before publishing the pixels. Packs are loaded once and reused.
## Remaining Gameplay Work
First-person roulette actions need approved, consistent hand/gun animation
sequences. The requested replacement sheet failed generation and is not shipped.
Multiway poker requires actual 3/4-player betting, side pots and AI seat state,
not decorative extra opponents. Native talisman effects, achievements, daily
tasks and online tables still require integration with the selected profile.
The old installer has not been repackaged with this work.
The classic 777 cabinet is now playable natively: generated cabinet/symbol art,
three easing reel strips, sequential stops, selectable stakes, a paytable and
queued safe exit. See `native-slots.md`. CloverPit remains a separate unported
game rather than a renamed copy of this machine.
Hall furniture now uses isolated, tightly bounded table and cabinet packs rather
than contaminated atlas cells. A full-height skill cabinet and twelve collidable
lounge/rope props are described in `hall-furniture.md`; game entry IDs and saves
remain unchanged.
European roulette now has matching first-person table/close-up scenes and a
separately animated exact 37-pocket rotor, plus persistent result and queued exit.
See `native-european-roulette.md` for supported bets and current visual limits.
The six exterior walkers now exclusively use outdoor art and validated routes;
street people/guards and hall tables use smaller world dimensions.
Coin toss now has its own first-person table, two embossed face sprites and
sixteen hand poses with an integrated coin on the thumb before release.
Its time-based toss, rotation, shadow and landing
bounces end on the paid result, which stays visible until the next-round command.
Escape queues a safe departure during the toss. See `native-coin-scene.md`.
The target is more than twenty actual games, not twenty menu placeholders. Native
expansion candidates, to be specified and tested individually: Texas Hold'em,
blackjack, Durak, European roulette, craps, coin toss, cups, Russian roulette,
Buckshot, CloverPit, classic slots, hook skill checks, baccarat, casino war,
five-card draw, Omaha, seven-card stud, sic bo, keno, bingo, video poker, red dog,
Andar Bahar and dominoes. Tournament/shop/bestiary are features, not extra games.
## Verification
`tools/tests/test_casino_actions.ps1` builds and runs the actual MASM core in a
hidden test window. It checks the existing card/dice/roulette logic plus entry
transitions, profile signatures/import, zero bank, safe name input, creation,
purchase/equip/insufficient money, invalid sprite packs and render invariants.
Test-created profiles live only in `build/arrival/fixtures`.
Durak regressions include 500 complete games, all 5184 trump/attack/defense
combinations, exact 36-card conservation, transfer/refill/take restrictions,
all-card paging and exit from every active phase. A shared 52-card fill check
guards against face-up cards incorrectly reading the back-color palette.
777 checks cover all 8000 stop combinations, 500 complete spins at four update
rates, monotonic reel paths, one-time debits/payouts and safe exit. Eight real
native framebuffer snapshots check reel clipping and sequential stops.
Hall furniture checks cover floor anchors, valid map cells, collision and the
main passage, with three additional close-up native snapshots.
Coin regressions cover 500 paid flips at four update rates, every exit phase,
1701 continuous coin positions, wager controls, missing-art rejection and ten
native framebuffer captures. `check_coin_scene.py --parity` also compares the
tested coin procedures with the shipping object.
The camera route is sampled against the exterior map, the full timed opening
must reach profile selection, restarting must return to the black transition,
and renderer calls must restore the hall camera, eye height, map, horizon, floor,
opacity and RNG. Camera movement and turns are sampled every sixteen milliseconds
to catch discontinuities across phase boundaries. Traffic and the throw have
separate native-frame sequences. A native cigarette check asserts an unbroken
body, different filter/paper/ember colors and bounded thickness. A later street
snapshot covers the distant district instead of checking only the narrow alley.
`tools/tests/check_arrival_frames.py` checks native framebuffer snapshots and
writes a contact sheet. `check_alpha_math.py` exhaustively checks the exact
division-free alpha substitutions; native tests cover transparent, fractional,
opaque and globally faded pixels. `build/actions/city-performance.json` reports
renderer-only frame times on the test machine, excluding presentation/input and
rounded down to integer milliseconds using the coarse GetTickCount timer;
a zero means below its measurable/rounded range, not zero rendering work. It is
not a promise of FPS on other hardware. Visual inspection is still needed before
release.