Skip to main content
When a player shares their profile, your game receives their OG as 2 short recipes. The look describes the head; the character describes the body and outfit. You build a model from them and show it as “Your OG” wherever the player appears. The numbers on this page come from 2 sources. The OG character kit is OpenGame’s character code, with the cameras from OpenGame’s 3D world. OG Clash is a first- and third-person shooter built on Kaigen, with “Your OG” in it. A number from OG Clash worked in that game at that scale, so use it as a starting point and measure yours.

Before you start

  • Your game calls og.init(). Connect the SDK covers that and the player fields.
  • For a 3D OG, the OG character kit. Ask the OpenGame team for it, because it is not in the SDK package. It has the Three.js player, 6 cameras, a GLB exporter and the joint spec. The kit’s notice asks you not to publish the kit or the GLB it exports as an asset pack.
  • For your art, the SDK’s @opengamehq/sdk/avatar entry, which names each part of the recipe.

Read the recipe

Use watchAvatar. It calls you once with the player’s OG, then again only when the look or outfit changes, and with null when they sign out.
main.js
avatar.head.recipe and avatar.outfit.recipe are the strings the kit takes. og.player.avatar.look and og.player.avatar.character are the same strings. Without a bundler, copy dist/avatar.js from the SDK package into your game, import it from a <script type="module">, and pass OpenGame.og in place of og. A native engine reads the raw recipes from the bridge’s player(). Call readAvatar in the page and send the result as JSON to the engine, or parse the strings with the table below.

What the strings mean

The look is shape.eyes.color, then an optional accessory, then female if the player chose that face set. A female head with no accessory writes none in the accessory place. panda.dots.white is a panda head with dot eyes in white. The face set changes the face only, so do not use it for pronouns, a voice or anything about the player. The character starts with a version, then the parts in this order: avatar and match follow the head’s color. OpenGame uses match unchanged and renders avatar darker by garment, with bottoms at roughly half the head’s brightness and shoes close to it. Luxury watches stay their metal color. readAvatar and watchAvatar give you these parts by name, with a hex value for each color in this SDK build:
For a color that follows the head, hex is the head’s color before any shading. finish is true for about 30 head colors that are patterns, metals, glows or glass, such as plaid, gold, neon pink and jelly, and hex is a single color close to them. mono, shown to players as “Auto”, is black on a light page and white on a dark one, and the hex for it is the black. OpenGame adds shapes, garments and colors over time, so a player can arrive with a part your game has not seen. The SDK passes it through, and the rest of the OG is still there. Draw your default for that part and keep the rest. An outfit in a version the SDK cannot lay out comes back as outfit: null, so draw their head on your default body.

When there is no OG

OpenGame checks the setting when the game opens. Settings asks a player who changes it to reopen the game.

Keep the player’s trust

The player agreed to show their OG to games. They did not agree to have it stored or passed on.
  • Read it each session and do not store it. Keep the recipe, and any part of it, out of local storage, save files, your server and analytics events. The same goes for what you build from it: a cached model, a baked GLB (OG Clash writes both recipes into the file’s metadata), a replay or a spectator feed. A player who turns sharing off expects their OG to leave your game. OG Clash holds the models in memory and builds them again on the next visit. You may remember that the player picked “Your OG”, as a choice, without the recipe.
  • Log to the console only. A log line that names an unknown part names part of the recipe, so keep it out of analytics and error reports.
  • Share images only when the player shares. A picture of their OG leaves your game only when the player clicks to share it.
  • Do not ask the player to type or pick their OG. It comes from OpenGame. A guest gets your default character and, if you like, a sign-in button.
  • Do not send it to other players. Rooms do not carry looks yet. A recipe that one client sends to another goes beyond what the player agreed to share, and any client can claim any look. Draw other players from your roster until OpenGame sends their OG.
  • Draw it as it is. You can scale it a little, light it for your world, mark a team with an outline, ring or badge, and give it a prop to hold. Do not change the head, the outfit colors or the accessories and call the result theirs.

Build the model

Pick by what your engine can run.

Three.js

player.js
The kit draws with WebGL shader materials, so use WebGLRenderer, not WebGPURenderer, and the Three.js version the kit pins (0.185 for the 14 Oct 2026 kit). Call createOgPlayer only when there is an OG, and use your default character otherwise. Called with no recipe at all, it builds the kit’s preview character, a lion head that is not your player. The kit falls back for the entire head, not one part. A single shape, eye, color or accessory it does not know turns the head into the kit’s default white circle, which is why the code above swaps unknown ids before the call. A single unknown garment turns the entire outfit into the kit’s plain default. If the kit’s parseCharacter returns null for outfit.recipe, rebuild the outfit with formatCharacter. Its fields are named differently: accessories becomes extras, colors.shirt.id becomes shirtColor, the bottoms and shoes follow that pattern, and colors.accessories.id becomes extraColor. Swap an unknown garment or color for one in the kit’s CHARACTER_SHIRTS, CHARACTER_COLORS and the other lists, and drop an unknown accessory. formatCharacter throws on any id it still does not know, so catch that and use the kit’s default outfit. The kit’s player is the full OG. It has 21 named joints under a root scaled by 0.6, so one rig unit is 0.6 m. The head is shaded, and the eyes follow where the OG looks. It can flip and do 50 dances; show each dance’s display name from spec/dances.json to players. Jumps use a gravity of 23 m/s², and the flips are timed to it. The kit’s INTEGRATION.md is the frame loop. The kit is a copy of OpenGame’s character code from a fixed date. The kit from 14 Oct 2026 included 202 head shapes; OpenGame had 214 by 27 Oct. Ask for a current kit before you launch, and log each fallback to the console so you see it.

Other JavaScript engines

Run the kit’s player in a Three.js scene on a canvas of its own, layered with your engine’s canvas, and call player.step each frame. That suits a character screen or a title scene, where the OG does not need to share depth with your world. In play, draw the OG in your engine’s art, or bake a GLB as described under native engines. To drive a GLB of the same character from the kit’s motion, copy each named joint’s local position, quaternion and scale to the node with that name. Copy quaternions rather than angles, because the kit’s legs rotate in a different order from the other joints. Some parents in the tree are scaled, the root at 0.6 and the head at 0.8, so world matrices would apply those twice.

Native engines

The engine needs a GLB, and only the page has the player’s recipe, so the GLB has to be built in their browser. The kit has an exporter, and it shows where that build starts. npm run export:glb runs runtime/src/export-glb.ts in Node:
It calls createOgPlayer, replaces each shader material with a flat color, and exports the root with Three.js’s GLTFExporter.parseAsync(root, { binary: true }). The command also rewrites spec/rest-pose.json with that character’s joints, so put the file back after you use it with another recipe. That GLB is a stand-in, not the player’s OG. Each limb is a node with separate meshes rather than a skinned mesh, and the kit’s shader, which paints the eyes, markings and patterned colors onto the head, becomes 1 flat color per mesh. The head has no face. Use it to test your import and your joint mapping, and do not show it as “Your OG”. For a face, the build has to paint the head’s shader into a texture, which the kit does not do. OG Clash wrote that bake for itself, and it is not part of the kit. It runs OpenGame’s character code in a Web Worker and merges the OG into 1 skinned mesh with 1 PBR material, a 1024 px color atlas and an eye sheet of 12 expressions. One OG Clash build measured 2.01 m tall, about 100,000 triangles and 4.4 MB. A bake took about 2 s in Node on a desktop Mac, and OG Clash’s notes record 3.7 s for a first bake in the browser. The page waits for the game’s title or menus, builds the GLB with the player’s recipe, and drops the bytes on the game’s canvas as og_custom_<hash>.glb. The engine checks the file, imports it, and adds “Your OG” to the character list. Play as your own OG covers how a Kaigen game receives the recipe. Without a bake like that, draw the OG in your engine’s art from readAvatar’s parts. The joints are the contract. The kit and OG Clash use the same 21 joints under different names, and the kit names its sides as you see the OG from the front, so the kit’s left is the OG’s right:
  • Units are meters, +Y is up, the OG faces +Z, and the feet are at height 0. The OG’s right side is at -X. In the kit, legs rotate in ZYX order and the other joints in XYZ.
  • Arms are children of trunk, and legs are children of the root. The head is a child of trunk in OG Clash and of rig in the kit, which copies the trunk’s rotation onto it each frame. When you retarget the head, convert through its parent.
  • With 1 torso joint, a twist all happens at the hips. OG Clash limited chest twist to about 45° to stop the waist pinching.
  • The hand is a mitten with 3 finger joints. To retarget onto a humanoid, map these names to the upper arm, lower arm, hand, thigh, calf and foot, minding the sides.
  • The kit scales trunk unevenly to breathe, squash and stretch. OG Clash’s bake keeps no scale on any joint and gives that up. If your engine’s bones cannot scale, expect to lose it too.
Check the file before you import it, and keep your default character if a check fails. OG Clash requires these 21 joint names, a metadata block with sizes in range, and the file name it expects. It logs why it rejected a file. The kit’s motion is a pose function, not clips. For an engine that needs clips, sample sampleCharacterMotion at 30 or 60 Hz and save the keys. OG Clash sampled 5 of OpenGame’s dances this way, once for each of the 3 leg lengths. It also bought 40 motion-capture clips, including walk, jog, run and sprint, for about $2.40.

Your art

Use readAvatar’s parts to choose a head mesh or sprite for each shape you support and a hat for each accessory. Apply the shirt color to your torso material. Keep a default for each part, and use it for any id missing from your table. Color is the strongest part of an OG’s identity at a distance, so get head.hex right even if you draw little else, and give finish colors a pattern or sheen.

Each point of view

First person

Choose the approach that fits your game. Exploring. OpenGame’s 3D world hides the head and collar and keeps the body. For actions with the hands, such as swinging an axe, it swaps the body’s arms for a separate set drawn at 0.78 of their size through a 58° lens. The world lens is 74° with a near plane of 0.04 m, and the eye moves forward when the player looks down, so the view clears the collar. The kit has the 74° lens, the near plane and the eye offset. The second set of arms and hiding the head and collar are up to your game. Shooting. Draw separate first-person sleeves and hands, and hide the third-person body. OG Clash first shrank the head and arms of the body to almost nothing. Hood and sleeve triangles then spread from those points as white shards under the camera, and the owner asked, “wtf is this when i look down?” Now OG Clash has:
  • Sleeves in the outfit’s shirt color, so the player sees their clothes.
  • Mitten hands, a thumb and one closed shape. The owner asked for “basically a thumb and then a blob for hands”, because that is easier to rig and animate with a gun than 5 fingers. Open, rigid gloves looked like paddles, and animation could not close them.
  • Mittens attached to the gun’s posed transform, so they stay on it through reloads and inspection.
  • A fill light for the sleeves and mittens, and no shadows from them. Backlit mittens turned black, and glossy cream ones turned pink in muzzle flash.
  • A separate lens. OG Clash renders the sleeves and mittens with a 68° lens and the world with 66° vertical by default.
Give the hands the same color in all views. OpenGame renders an OG’s hands in the head’s color, and so does OG Clash’s third-person “Your OG”. The first-person mittens there are white on all OGs, so the player’s hands change color when they switch views. OG Clash fades any OG that comes within 0.65 m of the camera, down to 30% at 0.3 m, with an ordered dither. On each build, capture a frame looking straight down while standing, walking, jumping and downed. OG Clash missed the downed case, and the player’s head filled the view as a big blue ball.

Third person over the shoulder

Keep the OG to one side of the frame and small enough to aim past. OG Clash puts it on the left, at the owner’s request: “The character should never be on the right side.” These are the targets OG Clash’s review set, and what the shoulder view measured:
  • Scale the camera with the OG’s height. OG Clash multiplies these distances by the height divided by 2, limited to 0.8 to 1.2.
  • Aim at what is under the crosshair, along the camera’s ray, so the crosshair is accurate with any shoulder offset. Then check the line from the gun to that point, so the OG cannot shoot through a wall it is standing behind. OG Clash fires along the camera ray and turns the barrel toward a point 4 m past the OG.
  • An OG’s body and large, round head sit where the gun would show. In OG Clash the body hid the gun in the shoulder view for about 5 hours of work, and later the head hid it again. Carry long guns low and to the right, muzzle dropped. Raise the gun to the collar to aim or fire, with the top of the gun tipped about 0.16 rad outward so it shows past the head.
  • Include hats and tall accessories. OG Clash measures clearance from the head’s radius only, and a top hat or crown can stick out above it.
  • Hide the body when a wall pushes the camera into it. OG Clash hides it within half the body’s width plus 0.3 m.
  • Offer few views. The owner said “there are too many camera views” again and again, and OG Clash went down to 3: first person, shoulder and wide.
The kit’s standard camera is a wider, walking view: 7.6 m behind, 2.1 m up, aimed 1.45 m above the feet, with a 52° lens.

Fair play

OGs differ in height, from the small sprout body to tall, and in head size. In a competitive game, give all players the same hitbox, collision capsule, eye height and speed, and fit the model to them. OG Clash is single-player and sets each OG’s first-person eye height from the OG’s measured eyes, which is fine there and an advantage in a match.

Top-down and isometric

From above, the head is most of what shows. Keep the head’s color and accessory readable at the size you draw them. The kit’s overhead camera is 11 m up and 1.15 times the standard distance back. Outfits show less from that height, so a name label or team ring helps a player find their OG.

Side view and 2D

Draw the head the way OpenGame shows it in 2D. In the kit, mascotPaths(personMascot(look), size, dark) from runtime/src/mascot/render.ts returns the head as SVG paths, one per color. personMascot is exported from the kit’s index; mascotPaths is imported from that file. Pass a look with the unknown ids already swapped, as in the Three.js example, because personMascot returns the default head for any look it does not fully know. The paths are in OpenGame’s pixel style, so scale them by whole numbers. For a 2D body, draw sprites chosen from readAvatar’s parts and colors. Show the OG as a 3D figure on a turntable, with light set for the menu instead of the level. OG Clash lights the stage with a warm key light and a cyan rim, and the player drags to turn the figure.
  • Set lighting per screen. In OG Clash, a gameplay light boost spread to the title and results screens and made the OG look like a white suit.
  • Show the old figure until the new one has loaded, then scale the new one in. OG Clash takes 0.24 s. Do not show a half-built figure.
  • Use still pictures in the list, not live models. Live portraits made OG Clash load more models at once than the cache allowed. The fixed 128 MB geometry buffer broke into small gaps, and the game froze at the 39th quick switch.
  • Check the pose against the head. OG Clash’s launch fixes included a rifle held across the OG’s face on the character screen.
  • Force the eyes open in still poses. In OG Clash, blinks and downward glances gave about 1 frame in 8 with slit eyes.

Title, cinematics and results

Put the player’s OG in the title scene and the victory shot. In OG Clash it sits by the campfire on the title screen. Frame it larger than in play. On OG Clash’s title it fills about 0.27 to 0.30 of the frame’s height, and in the victory shot 0.37 to 0.39, with a lens between 30° and 52°.
  • Check each staged camera for a clear line to the OG and for a position inside a wall. OG Clash’s game-over screen was black for about 7 rounds because the camera was 0.3 m inside a stone ledge.
  • Aim at the OG’s real height. OG Clash’s victory camera aimed for a 1.25 m figure and missed a 1.8 m OG.
  • Continue the cinematic’s last camera into the results screen instead of cutting.

HUD and name tags

Show the handle with a mark that it is the player. OG Clash writes @handle (You). With no handle it writes the character’s name and (You), or You on “Your OG”. Use og.player.handle as it arrives, without extra checks. A small 2D head from mascotPaths works as a portrait. A name a guest types is a local label and not an OpenGame handle.

Make “Your OG” the default

  1. First in the list, with a label. Put “Your OG” above your roster, with a label such as “OpenGame” so the player knows where it came from.
  2. Equipped when ready. Select it once the model has loaded, unless the player already picked a different character this session.
  3. The outfit too. Lock outfit options that would replace it, and say why. OG Clash says “Your OG wears the outfit from your OpenGame profile”.
  4. Changes wait for the menus. A guest who signs in during a run plays the run out with the same body, then finds “Your OG” in the next menu. OG Clash also holds a model that finishes building during a run.
  5. Sign-out removes it. At the next menu, remove “Your OG” and go back to the default. OG Clash reloads the page at that point, because the engine cannot unload an imported model.
  6. A guest gets the roster. Show “Your OG” only when there is a model, and select your default for a guest.
  7. One OG in all places. The title, the character screen, the spawn, the first-person sleeves and the scoreboard show the same OG. OG Clash’s launch film showed 4 different first-person looks until a single OG was set for all shots.

When something is missing

Performance and memory

An OG is a large model, and the player’s OG is built while they wait. Plan the memory for it from the start.
  • Do not make boot wait for it. Start with your default character, call og.ready(), then build the OG in the background.
  • Build off the main thread, in few workers. OG Clash’s desktop build runs a warm worker and a spare, and found 3 background workers to be the limit, since 5 slowed imports. It stops them when the player leaves the character screen.
  • Phones get one worker and small caches. Opening “Your OG” added 861 MB to OG Clash’s page on 21 Oct 2026, from 4 to 8 workers, builds started in advance, and caches. It crashed an iPhone. OG Clash now has a light mode for touch screens, phones, tablets and devices that report 4 GB of memory or less. Light mode uses 1 worker, no builds in advance, a 24 MB model cache in place of 96 MB, and textures up to 1024 px.
  • Count the builder in your download. Building in the page ships Three.js and OpenGame’s character code to a game that may not use either. OG Clash’s worker bundle is 748 KB before compression.
  • Import in menus only. Importing a full OG cost OG Clash 144 to 188 ms over 5 slow frames.
  • Change parameters, not models. Make color and eyes material parameters on a mask in the model. Rebuilding the model for each change took seconds.
  • Limit what stays loaded. OG Clash budgets about 4 MB of GPU memory for each roster OG, cut the largest textures from 4096 px to 2048 px, and keeps at most 2 imported custom OGs.
  • Test in Safari on a real phone. Chrome’s phone emulation does not apply Safari’s memory limit.

Pitfalls

Checklist

  • watchAvatar drives the model, and a guest gets your default character.
  • The recipe, and anything built from it, is not stored, asked for, sent to other players or logged outside the console.
  • An unknown part, an unknown outfit version and a failed build each fall back without losing the rest.
  • Boot does not wait for the OG, and models change only in menus.
  • “Your OG” is first, labeled, equipped when ready, and removed after sign-out.
  • First person, looking down while standing, jumping and downed: no body parts in view, and hands the same color as in third person.
  • Third person: the OG on one side, the gun visible next to the head, the crosshair accurate, hats checked.
  • Competitive play: the same hitbox, eye height and speed for all OGs.
  • Menus, title and results show the OG with a face and open eyes, lighting for the screen and a clear view.
  • The HUD shows @handle (You) from og.player.handle.
  • Memory measured on a real phone, on the character screen and in play.
  • Captured as a guest and with ?og-dev-player=signed-in.

Ask your coding agent

Paste this into your agent from the game’s folder.

Where next

Connect the SDK

Read the player, follow sign-in and sign-out, and check capabilities.

Kaigen

Pass the player’s recipe to a Kaigen game.

Read the SDK reference

Look up readAvatar, watchAvatar and their types.

Memory diagnostics

Measure what the model costs before you call it done.