|
Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
|
Replace retail HMD/DAT presentation assets incrementally with modern Blender-authored GLB assets without changing Monopoly rules, square placement, sequence timing, camera behavior or the existing DAT fallback.
The authoring file remains:
pack monopoly blender/Monopoly_Paris_procedural_RECUPERE.blend
It is never modified by the export pipeline. Blender is opened headless and the exporter changes only the in-memory scene before writing generated GLB files.
The recovered scene opens successfully in Blender 5.2.2 LTS.
Six of the eleven retail tokens currently exist as grouped assets:
| Blender collection | Export slug | Retail token index |
|---|---|---|
| Pion automobile | race_car | 1 |
| Pion terrier | dog | 2 |
| Pion haut-de-forme | top_hat | 3 |
| Pion bottine | boot | 7 |
| Pion cuirasse | ship | 6 |
| Pion de a coudre | thimble | 8 |
Absent from the recovered authoring file (now separately authored sculptures):
Each existing token is already parented below one EMPTY root. Those roots are the canonical asset pivots.
A diagnostic full-scene export is valid glTF 2.0, but it is not a production asset:
Most Blender materials use procedural Noise/ColorRamp/Bump node graphs. glTF cannot reproduce those arbitrary Blender graphs. The diagnostic export proves this: several materials lose their procedural base color and the procedural bump does not become a glTF normal texture.
Therefore the production pipeline uses small purpose-specific GLBs and materials that are glTF-compatible or baked to textures.
Generated files are build artifacts and must not be committed until an asset is explicitly approved for production.
Runtime and separate diagnostic asset layout:
The checked-in headless exporter is:
modern/tools/blender/export_monopoly_assets.py
It currently exports the six existing tokens independently. Their generated sizes are approximately 27 KiB to 653 KiB rather than the 148 MiB monolith.
GLB 2.0 is the first supported modern asset container.
Each token GLB has exactly one scene root. The root transform is identity and carries glTF extras:
Placement on the board must never be baked into a token GLB. The existing PiecePlacement, PieceMovePlayback and sequence transforms remain the owners of world position and yaw.
Blender exports with export_yup=true. The GLB is therefore standard glTF right-handed Y-up data. Conversion to Monopoly engine coordinates is owned by one loader boundary only; renderer and gameplay code must not each apply their own axis correction.
Token height, yaw and pivot use per-token calibration against decoded HMDs. The aligned runtime board is a separate export: its loader uses 200 units/metre and local offset (2430, 0, 2430), followed by the existing CNK board scale of 0.10. Its 40 case positions are mapped to actual retail cell geometry. The uncalibrated diagnostic board export is not interchangeable with that asset.
First implementation supports:
Animated scenes, skins, morph targets, sparse accessors, alpha BLEND, external images, nonzero texture-coordinate sets and texture transforms are explicitly unsupported by this static bridge. They are never reinterpreted as HMD data.
The existing MeshRenderData is the renderer-facing geometry contract:
MeshVertexThe GLB path should produce an equivalent modern render asset without converting the GLB back into HMD or DAT.
The static bridge is now implemented with pinned fastgltf v0.9.0, linked statically into MonopolyDataCore.
ModernGltfMesh decodes bounded GLB triangle geometry, node transforms, POSITION/NORMAL/UV0, optional tangents, indices, bounds and material factors. PNG/JPEG images must be embedded buffer views. Immutable modern RGBA owners remain distinct from HMD image metadata. Allocation budgets cover geometry, encoded/decoded images and decoder working storage.
ModernTokenCatalog maps the complete retail HMD families back to their logical token index. MeshRuntimeCache asks the modern resolver first and falls back to HMD when an asset is absent or rejected.
The exporter/probe decode the six recovered and five newly authored token assets. Nine single-HMD resting idles load in a bounded startup. Dog root 0x801D3 has a complete four-state adapter and horse root 0x802FC a six-state adapter; unqualified multi-HMD roots retain retail geometry. An explicit table qualifies 46 rigid CNK roots for modern geometry while CNK remains the timing/transform/visibility owner. Other movements retain retail frames. The ship two-state pack for root 0x80360 passes 71 production timeline ticks against retail: clocks, HMD selection, matrices, priorities and lifecycle match. The dog adapter passes 99 production frames with modern geometry, no fallback/errors, and identical paired-retail clocks, matrices, HMD choices and lifecycle. Horse likewise passes 99 paired production frames with all states modern and no errors. Strict root/priority qualification, independent complete-pack failure and GPU rejection tests pass. These timeline comparisons are CPU proof; separately captured GPU frames do not prove continuous in-game animation.
The recovered assets have explicit per-token authoring calibration. Height is matched against a representative retail HMD, and yaw/grounding/local offsets reproduce its measured pivot. The dog variant basis uses +90 degrees around Y and common offset (-0.5, 0, -15.05967734); a universal -90-degree correction is incorrect. Static-idle eligibility remains separate from these measurements.
The CMake targets are:
A normal MonopolyModern build stages already-generated modern assets but does not require Blender. Missing GLBs therefore remain a normal HMD fallback case.
The modern GPU path uses separate GGX metallic/roughness shaders and pipelines. It supports baseColorFactor, metallicFactor, roughnessFactor, emissiveFactor/strength, double-sided materials and all five PBR map roles. Legacy HMD batches keep the Gouraud path, including retail shadows. Missing modern shader files log a diagnostic and temporarily draw through legacy diffuse.
Pinned project-local DXC and SPIRV-Cross compile DXIL, SPIR-V and MSL; see shader tooling. Generated ModernPBR assets are staged by normal builds. MonopolyCompileShaders regenerates both shader families into the build directory without changing checked-in binaries.
Optional studio image-based specular lighting uses a bounded MSTUDIO file: a linear HDR 64x64 RGBA16F cube with deterministic GGX-prefiltered mip levels. MonopolyGenerateStudioEnvironment generates analytic softboxes under build/modern-assets/lighting/studio_environment.mstudio (262,160 bytes). The modern shader binds five material 2D maps plus this cube and retains its 256-byte uniform ABI. Missing or invalid optional lighting binds a black cube and disables the environment contribution, preserving previous pixels. Specular lighting uses an analytic DFG approximation; diffuse lighting remains the ambient approximation. A diffuse irradiance cube and BRDF LUT are not implemented. Optional scene decorations remain geometry. Animated GLB playback is unsupported; procedural Blender graphs still need conversion or baking.
Legacy batches retain diffuse material plus their optional HMD texture. Modern GLB batches carry immutable image/map/sampler ownership through the existing mesh GPU cache and a dedicated shader path.
Implemented material inputs:
Base color and emissive maps are sampled as sRGB; metallic/roughness, normal and occlusion maps are linear. Shared pixels can have distinct GPU interpretations. Sampler wraps, filters and mip levels are retained. BLEND falls back explicitly until transparent pipelines and sorting exist.
The recovered tokens and gameplay-house prototype have factor-only Principled graphs and need no procedural bake. tools/blender/bake_monopoly_materials.py bakes actual linked channels on disposable evaluated subsets. The asphalt proof bakes Noise/ColorRamp base color and actual Bump into tangent normals; roughness/metallic occupy glTF G/B channels. Collapsed evaluated triangles are removed with recorded area tolerance, split normals are preserved, and UVs are checked for degeneracy. Blender's zero tangents on thin bevel corners are omitted so the runtime derives a basis. Two fresh processes produced identical GLB, geometry, PNG and pixel hashes. This subset is not proof that every procedural material has been converted.
The recovered top-hat factor-only materials were also baked as an explicit self-test into an isolated build/material-bake-qualification directory. Two fresh exports and production loader runs agree: three base-color/MR bindings, six 512px PNGs, 6 MiB decoded RGBA, 70,053 encoded PNG bytes and a 188,636-byte GLB. Normal/emissive/occlusion maps remain absent because the source has no such map inputs. GLB, geometry, PNG and pixel hashes repeat; source hash is unchanged. An isolated native Blender comparison at 256px/32 samples has full-frame RGB mean absolute difference 0.00043311. It qualifies factor conversion, not procedural fidelity, engine shading or gameplay.
The legacy Gouraud shader remains available for HMD fallback assets. Modern GLB materials get a separate shader/pipeline path; do not weaken retail fidelity to make both formats share one lowest-common-denominator shader.
Procedural Blender materials must be either:
The recovered Blender scene currently contains no animation data.
A retail-DAT inventory changed the integration plan: every playable-token HMD examined has poseCount() == 1. Token motion is therefore not a MIMe pose interpolation problem. The CNK sequences animate tokens by switching between multiple HMD assets over time.
Examples from the real retail banks:
SequenceMeshChoice3D remains relevant for genuine MIMe meshes elsewhere, but it is not the token-animation authority.
The runtime now carries the top-level/root CNK DataId with every 3D mesh instance. Modern token resolution is context-sensitive: a static GLB may replace a single-HMD resting idle only at root activation priorities 224..229; qualified rigid movement roots use activation priority 100. Authored leaf draw priority (including zero) remains separate and is preserved. The same HMD DataId resolves to retail in an unqualified root. Modern/legacy immutable owners and cache entries remain distinct so one context cannot poison another.
A future complete modern token animation must replace a whole retail sequence, not isolated HMD frames. The sequence clock, board transforms and gameplay timing remain authoritative. The Blender representation may use Actions, armatures, shape keys or a deterministic frame/pose table; the chosen form must map the complete CNK/HMD state sequence without changing timing or rules.
Do not spend a deep Codex pass on discovery.
Discovery, parser integration, bounded static GLB decode, token routing, calibration and HMD fallback are already implemented. A deep Codex pass should therefore be reserved for one bounded problem at a time:
Do not modify gameplay or Source/. Do not spend a deep pass rediscovering the Blender scene or the retail token animation mechanism.
MonopolyModern.exe still builds with no modern assets installed.0x80236, tick zero, root priority 224 was rendered at 1920x1080 with environment enabled and PBR loaded. The inspected capture build/hat-ibl-gpu-20261001.png shows broad white, blue and gold reflections. All 23 requested production-CNK frames (11 token idles and 12 state frames) also pass with environment enabled and PBR loaded; see build/token-ibl-qualification/qualification.json. The inspected eleven_tokens_ibl.png gallery shows all 11 tokens. A fresh generator repeat matches SHA-256 cdd97760353a46538136cb6ea40d045bf1ba58921152e1b57814987c9b4e5726. The application remained alive for more than 25 seconds with nine token loads before its owned process was stopped; logs are build/ibl-app-smoke-20261001.out.log and .err.log. Requested frame captures and this bounded startup do not qualify interactive gameplay or live animation.MonopolyTokenAnimationTimeline and tools/token_animation_inventory.py inventoried all 1,089 token CNKs against local runtime-data over 600 parent ticks. Generated metadata stays in build/token_animation_inventory.json. This is standalone CPU render intent with decoded-default root placement; board dispatch/placement and external media clocks remain separate context.MonopolyReconstructModernTokens reproduces separate deterministic exports and a derived authoring file under build/authoring, preserving the original. Height/pivot calibration comes from production-decoded retail geometry. A fresh 25-second runtime remains alive and logs nine static idle loads. This does not show a live dog animation or qualify gameplay.assets/modern-token-sequences.json records 46 fully traced rigid CNK roots paired with their sole representative HMD. These roots use modern geometry with existing CNK matrices, visibility, sounds and tweekers at priority100. This is CPU timing/context proof, not visual gameplay qualification or an authored glTF animation clip. Other movements remain retail.dat_borde.dat, dat_ln03.dat, dat_lm03.dat, dat_lk03.dat payloads.Reproduce one horse frame through production CNK and the real GPU path from the repository root (the output directory must exist):
The four --token-frame arguments are retail runtime root, complete sequence DataId, parent tick and root activation priority. Optional --benchmark measures fenced renderer throughput; it excludes setup/load/readback and is not a game benchmark. The variants export target includes the production deformation contracts and the reconstruction dependency for newly authored tokens.
MonopolyExportModernSceneAssets exports the board and one gameplay house via --include-board --include-house --skip-tokens. The whitelist includes only the plateau, central identity and Case 00..39 collections, not scenery or placed houses. Temporary evaluated copies convert text/apply modifiers; neither this operation nor token export saves over the recovered authoring file.
Fresh board export: 21,329,928 bytes, 206 nodes/205 meshes; house: 17,912 bytes, 3 nodes/2 meshes. Both have identity scene roots and measured glTF Y-up metre bounds in extras and JSON sidecars. Three repeat exports produced equal hashes. Those diagnostic exports remain separate from board/paris_board_runtime.glb, the aligned runtime board with explicit 40-case mapping and derivative tangents. Its current derivative keeps X/Z alignment, sets the playing floor to Y=0, compresses case relief by a positive factor of 0.1 and lowers pavement below that floor. The smaller 0.01 candidate produced depth fighting in the production renderer; the accepted 0.1 derivative retains solid color strips in the fresh GPU capture. Repeat exports agree; gameplay contact and independent ray-based qualification are checked separately. The current aligned board has 386,402 vertices, 381,690 triangles, 205 batches and one PNG. Independent bounded geometry checks pass: all 40 case reference planes are Y=0, and 720 contact-ray samples hit world heights in [-0.002, 0.064107]. At 440 house centre/corner rays the playing-color swatch top is 0.016 world units above historical feet Y=0, a small geometric overlap, not a numerical-error bound. These checks do not qualify gameplay. MonopolyExportAlignedBoardAssets uses decoded retail cell geometry; MonopolyExportModernEnvironment exports fountain, station and Morris-column chunks independently. These targets run only when requested. Normal builds stage existing generated assets and do not require Blender.
Runtime flags opt into --modern-board=paris, --modern-buildings=house and --modern-environment=paris. Paris board replacement also requires compatible Europe/French/Paris/Euro context, qualified root/priority and no custom board. Decorations require the actual modern board and inherit its CNK transform; failed assets retain retail geometry or omit optional scenery. The adapters have real SDL_GPU probe evidence, but French startup and in-game qualification remain blocked/pending. Optional qualified procedural bakes are described below. Scenery hotels remain distinct from the reconstructed gameplay-hotel prototype below.
The runtime now contains 608 distinct root descriptors: 606 complete roots at Generic100 priority, plus the original dog/horse idle roots at priorities 224..229. There are 63 geometry definitions and nine calibration frames. The catalog adds the reviewed moneybag, iron and horse97 profiles while preserving all previous 401 roots, 55 geometry paths/frame/grounding assignments and seven calibration frames exactly (build/old-variant-root-preservation.json). Immutable meshes load lazily per HMD; each root publishes transactionally. A failed state retains its whole root in retail, and GPU rejection invalidates published and future uses. Raw canonical ship HMDs 0x80018/0x8001B require shared rest grounding; other exported states are already grounded and retain that distinction in the generated catalog.
build/qualified-nine-profile-production-20261001.json qualifies all 606 selected roots with production CPU playback, disk endings and ending action zero. Every tick and event matches paired retail clocks, matrices, HMD choices and lifecycle, with zero errors. Only 37 different HMDs were actually observed in these runs. Those 37 states also have real 1920x1080 GPU captures with environment enabled and PBR loaded; build/nine-profile-gpu-qualification/production_states_gpu.png was inspected. These proofs do not establish continuous gameplay animation, visual fidelity of every frame, or glTF animation clips.
tools/qualify_complete_token_variants.py repeats two fresh exports for nine profiles and stages only the 58 explicitly reviewed states. Review hash rejection, cross-volume publication using adjacent backups, and three injected failure cases are qualified. tools/generate_token_variant_catalog.py reproduces the table in bounded build output, records source hashes and checks source consistency. MonopolyExportCompleteTokenVariants executed successfully with its complete dependencies at the earlier 49-state checkpoint. The completed 58-state clean CLI pipeline has identical reviewed outputs, preserves all previous 49 hashes and 12 default-state hashes, and qualifies representative geometry/normals; see build/next-token-profile-diagnostics/pipeline_completion_proof.json. The nine new bindings have identical rendering fingerprints with provenance-only JSON changes. A mismatched review is rejected without changing staged outputs. Moneybag08/09 and thimble CD remain excluded. The 606-root CPU comparison and 37-state GPU captures remain distinct proof boundaries; they do not qualify continuous gameplay or all-frame visual fidelity.
buildings/hotel.glb is a newly reconstructed red gameplay asset using a recovered material, not a recovered original sculpture. UDPieces starts HMD/root 4 directly with a RySTxz transform and scale 0.10; there is no hotel CNK. Building slot priority is decimal 55 + square*4. At 200 units/metre, decoded bounds are [-65,0,-90]..[65,155,90], with zero measured bounds error. Its real GPU probe renders 40 triangles, three batches and 461,453 colored pixels; the inspected capture is build/gameplay-hotel-gpu-20261001.png. Focused hotel catalog bounds/eligibility and existing BuildingDisplay lifecycle tests pass; no dedicated Engine hotel-cache runtime test was added. Complete-token pack tests pass and the application compiles. --modern-buildings=house now opts into both house and hotel; they use separate caches and independently retain retail fallback on missing assets or invalid bounds. MonopolyExportGameplayHotel was successfully executed as a CMake target, together with the complete-token target; build/expanded-hotel-export-targets-20261001.log records exit zero. Application placement and visual gameplay remain unqualified.
MonopolyExportProceduralScene writes a separate build/procedural-assets bundle. The empty-by-default cache path MONOPOLY_PROCEDURAL_SCENE_ASSET_ROOT selects an existing absolute bundle path for staging only board/environment over normal assets; token exports remain intact. The first complete qualified bundle is build/procedural-integration/bundle-qualified/procedural_bundle.json. Nine actual procedural families (asphalt, cream, pavement, roof, stone, stone_dark, stone_light, water and wood) bake base-color and normal maps at 512px. Constant metallic/roughness/emission remain factors; no AO is invented.
The four GLBs pass the production loader: 113 images decode to 123,731,968 RGBA bytes (118 MiB), and 158,222 normal-mapped triangles have nondegenerate UVs. Two complete bundle runs exit zero with all four GLBs and manifest identical (marker SHA-256 b281dd4aa724e4b7bc32e209bee226e0b66d2a9f60ea6248c4766a7c836293bd). An injected final-publication failure restores all 121 prior files. The recovered source hash remains unchanged. The inspected board GPU capture uses an additional 0.2-world-unit pavement clearance while retaining all 40 playing floors at Y=0. Native procedural-only full-geometry foreground RGB MAEs are board 0.00136724, fountain 0.00411734, Morris 0.0000930136 and station 0.0273178. The station retains different window-region contrast; these optional approximations do not establish exact native or full-scene parity. The final CMake target execution and complete bundle GPU sweep are recorded below.
The actual MonopolyExportProceduralScene target succeeds with factory Blender preferences and a retail board OBJ generated by its probe dependency. All four GLBs match the qualified bundle; their optional application-side staging is checked by SHA-256. build/final-procedural-scene-gpu-20261001.png captures those staged files with Direct3D12, PBR and studio IBL active: four objects, 246 batches and 895,665 triangles at 1920x1080. The probe's 100 serial GPU-fenced frames are not a full-game benchmark.
MonopolyModern rebuilds with this bundle and remains alive for 25.35 seconds using the supplied USA data and --modern-buildings=house. Its log opens all eight required banks and reports requested borderless fullscreen. This startup does not qualify interactions, F11 transitions or audible audio. Missing French banks still block in-game Paris qualification. Both Source/ and the recovered Blender file retain their locked hashes.
Nine visually inspected GPU passes, an opt-in faithful USA board path, real mesh shadows/4xMSAA, readable Paris prints and UI-safe framing are recorded in VISUAL_POLISH.md. Real USA play opens at 1920x1080 with about 60FPS title telemetry; F11 and the repaired toolbar projection were tested. Audio playback reports an unsupported WAVE format; sustained complete-game FPS and turn-animation traversal remain unqualified. Missing French DAT banks still block Paris in-game. Retail fallbacks and immutable Source/ remain preserved.