End-to-end game model workflow
Read as Markdown · Exact contract · Per-game guides
1. Download the current world and contract
Connect an AI client to Betworld MCP with the credential for the intended world. world_download({}) returns the current draft revision, document, owned assets and native model source URLs. The credential is world-scoped and cannot publish, bet or access balances. Keep it out of Blender custom properties, saved Text blocks and exported files.
Call game_skin_contract({"game":"baccarat"}) for each game being designed. Store the returned fingerprint and the exact socket list. Read the corresponding game guide, /model-proportions.json, /betting-interfaces.json and /game-model-reference.json. Do not take measurements from an image or use another game's controls.
The two MCP services have different roles: local Blender MCP can run your AI's modeling operations on your own workstation; Betworld MCP accepts converted assets and strict world JSON. Python used locally to construct a model is never uploaded as world behavior.
2. Create a locked reference assembly
Download the world through the current Betworld Blender bridge. It creates a new scene without deleting existing scenes. Existing skin definitions and entity references round-trip with the scene. The bridge imports the native source library with the proper source scale; do not apply that scale again.
Keep the game at unit entity scale. Set its anchor Y to the supporting floor elevation (0–64 world units). Use the player's canonical body and eye-height reference. The Baccarat playing plane must remain at 0.48273607884945505 of canonical bare body height, approximately 1.376896 world units above the floor. Blackjack and shared Blackjack have their own precisely documented playing planes. Game entity scale remains [1,1,1].
Make wireframe guides for body bounds, every physical button and the live screen/grid area. The catalog's bounds are world-space measurements; the native control's local geometry and matrixSource define its local fitting orientation. Keep native meshes locked as reference, not included in your export.
3. Model the replacement body
Create a cabinet or table shell matching the contract's body-box aspect ratio. The runtime fits the uploaded model's whole bounds to that fixed box. If the width:height:depth ratio is wrong, the artwork will stretch. An accidentally exported object far from the machine changes those bounds and can shrink the intended model.
Leave openings for the platform interface. The client retains its interactive top, labels, buttons, live screen, grids, cards, coins and other dynamic pieces. Do not sculpt a solid panel across a live display, or cover the control bank with a new rail. Preserve all seat approaches and the original collider envelope. Custom holes in visual geometry do not remove native collisions.
For reusable button shapes, model one compact static mesh per distinct design. It will be fitted to a named native control's mesh-local box. Do not bake a second button label into the mesh. The platform retains the native label and hit proxy. Bind the same asset hash to multiple sockets when appropriate. If a game exposes part.playing_surface, its static surface can be replaced while card mounts and game-state rendering remain unchanged.
Body textures may include thematic art. They must not impersonate a balance, result, payout, success indicator or live betting control. V1 preserves protected game visuals; static artwork can still be misleading and needs visual review.
4. Export and upload assets
Select only the meshes for one asset and choose Upload selected skin mesh. The bridge exports embedded GLB, disables animation, skinning, extras, cameras and lights, and calls asset_upload. The returned owner-scoped canonical hash is stored as scene["betworld_last_skin_asset"]. No ordinary prop entity is added.
Alternatively, export a self-contained GLB and call asset_upload from your AI client with its base64 bytes. Export each body, button design and optional surface separately. Do not upload .blend, a Python script, a ZIP archive, linked textures or a JavaScript package. Each input and converted result must fit 4,000,000 bytes. Embedded texture dimensions and aggregate decoded pixels have independent limits; a small compressed file can still be rejected.
Record the returned hash, byte size, triangles, texture pixels and mesh count. Never guess the canonical hash from the source file. Conversion rewrites bytes and removes metadata. Changing the local artwork requires a new upload and replacing the relevant hash in the manifest.
5. Build the strict skin manifest
Use the starter from game_skin_contract. Set a unique skin id, replace the body placeholder with your uploaded hash, and add any desired bindings. Each binding contains only a listed slot and an owned asset hash. Omitted sockets retain native meshes.
For example, a Baccarat choice control is selected by control.choice_0, control.choice_1 or control.choice_2. Those sockets already mean Player, Tie and Banker respectively. Do not add an index, action, label or callback field. For Poker, control.hold_0 through control.hold_4 are the five stable card indices. For shared Blackjack, seat identity is part of the socket name and cannot be changed through uploaded parameters.
Put the manifest into a Blender Text datablock called betworld-skin.json, select the existing game anchors, and use Save skin JSON to selected stations. Or call game_skin_save directly with revision, skin and entityIds. This updates the draft and returns its next revision and budget. A stale revision fails; download and merge deliberately before retrying.
For layout changes, add placements using the returned presentation.targets. Use clips for idle/result transforms and motions for the game's listed result-motion channels. Export GLB geometry without animation tracks; put bounded numeric keyframes in the skin JSON. The v2 contract specifies units, pivots, timing and endpoints.
A skin can be reused by matching game entities. It cannot turn a prop into a game or make an additional station ID available. The same complete skin cannot be assigned to a different game, even if two models look similar.
6. Review the actual result
Download again into a new Blender scene to inspect the fitted body and socket meshes. The bridge preserves the strict manifest when the world is uploaded later. Blender previews static geometry; platform screens, animated cards, odds and control states are verified in a browser preview of the world.
Check the player-height front view, oblique side views, portrait mobile and neighboring stations. Inspect gaps, z-fighting, native labels, the complete hit area and collision paths. Check state-specific geometry: Blackjack split fans and dealer reveal, all three multiplayer seats, Baccarat third cards, all five Poker Holds, Mines 3×3 through 8×8, all Drago difficulties, Keno's eight columns, Dice extremes, Limbo long results, Plinko's entire drop and the full coin-flip envelope. Doubler/Crash need clear reconnecting and live-result displays.
Use local preview fixtures for active game states. Check controls, moving parts and approach paths from the player camera, including on your target mobile devices.
7. Save the world and publish
World uploads preserve the skins array and each entity's optional skin ID. To revert a station to its native appearance, remove that entity's skin field. Remove an unused definition only after no entity refers to it.
The owner publishes the saved revision through the website when the world has no active players. Publication revalidates the document, ownership and budgets. MCP credentials cannot publish. Joining players download only the used canonical model hashes along with the world assets, using the existing progress screen.
Report the world ID, draft revision, assigned station IDs, skin IDs, asset hashes, byte/triangle/pixel costs, budget response, local .blend location and visual states reviewed. Do not claim publication when only the draft was saved, and use v2 placements/clips/motions when the design changes presentation layout or animation.