Turn Your Desk into a 3D Racetrack: A Step-by-Step Guide from Photos and Modeling to Screen Recording

A complete breakdown of Desk Racer's production workflow—building a playable tabletop racer with Gemini, Blender MCP, and Three.js, then recording a demo video. Includes the original video with Chinese/English subtitles and complete English follow-along prompt templates.

By Geneviève Huskens · Google AI Studio10-14 · 20 min

Google Developer Relations Engineer Geneviève Huskens shared an impressive project that transforms her desk into a miniature racetrack using Gemini 4 Argon: she took a set of photos of her desk with her phone, loaded them into Google Antigravity to run Gemini 4 Argon, and orchestrated agents connecting Blender MCP with Three.js to turn her keyboard, monitor, and desk accessories into Desk Racer, a playable 3D browser racing game.

The author's 80-second finished showcase: a playable desktop kart racer where the track weaves around the keyboard, mouse, and desk lamp.

Building a game like this by hand would normally require planning prop coordinates and dimensions, modeling meshes, applying materials, and programming vehicle physics, collisions, and camera controls from scratch. In this new workflow, AI analyzes the spatial layout of the desk directly from multi-angle photos, injects Python scripts into 3D modeling software via the Model Context Protocol (MCP) to generate geometries, automatically writes frontend rendering and car control code, and visually inspects runtime screenshots in the browser to iteratively refine materials and lighting.

This was her first serious 3D project. As you follow along, your photos provide the spatial reference, you choose the track layout and visual aesthetic, and the AI translates those directions into models, code, and an interactive, playable scene.


Choose Your Path: Remix Online or Build Your Own Desk Track Locally

Understand the role of each tool first:

Tool Role in This Project
Gemini 4 Argon Inspects photos, clarifies requirements, formulates plans, and writes/refactors code
Nano Banana Generates concept art and surface textures such as wood grain and road surfaces
Blender MCP Enables agents to model via Python scripts and export GLB prop files
Three.js Loads the scene in the browser, renders visuals, and handles driving physics and controls

If you only want a minimal low-poly scene, you can start with native Three.js primitives and skip Blender; introduce the modeling pipeline later when you need more detailed prop structures.

[Path A: Quick Online Experience & Remix (AI Studio)]
No local setup needed ──> Open Desk Racer in browser ──> Click "Remix" ──> Tweak car speed / track colors directly
Best for: Readers who want to test the driving feel immediately, inspect working code, and skip local environment setup.

[Path B: Build Your Own Desk Racetrack (Full Local Pipeline)]
Snap photos of your desk ──> Antigravity / Agent Orchestration ──> Blender MCP (Modeling) ──> Three.js (Playable Game)
Best for: Readers who want to convert their own workspace or bedroom desk into a custom 3D scene and record high-quality demo clips.

1. Path A: Online Experience & Remix (Zero Setup)

The team published a hosted version of Desk Racer in the Google AI Studio app gallery. On that page you will find:

  • Preview & Controls: Click into the game and press W to accelerate, A / D to steer, and S to brake. Press number keys 1 (Chase Cam), 2 (Cockpit Cam), 3 (Desk Overview), or 4 (Drone Cam) to switch perspectives; press Enter to start a 3-lap timed challenge.
  • Source Code & Assets: The top navigation bar provides Preview (live viewport), Code (Three.js and physics script source), Artifacts (models and texture assets), and Remix (fork into your own cloud project).
  • Remixing: Click Remix to copy the existing project to your workspace, then prompt the assistant with modifications. Adjusting speed or colors is the easiest way to see immediate changes; replacing it with your own desk requires redesigning prop layouts and assets.

2. Path B: Build Your Custom Desk Racetrack from Scratch

The custom build requires the model to understand your actual physical geometry. In the original demo, the author used a Blender MCP workflow powered by Gemini 4 Argon. Because the specific configuration of the headless Blender MCP used in the demo was not published, this guide uses mcp-for-blender—a documented desktop-based alternative that keeps Blender open in the background—paired with a locally hosted Three.js project to close the loop from photos to game.

The author's 156-second walkthrough with bilingual subtitles and original audio preserved. Subtitles are placed in a dedicated blank area below the frame for clear visibility of the interface.

Account and Environment Requirements:

In the official demo environment, Gemini 4 Argon was available in Antigravity to Google AI Ultra subscribers, and in AI Studio Build to Ultra subscribers or pay-as-you-go Gemini API accounts with active billing. Because model availability and quota policies evolve across platforms, refer to the models currently accessible in your workspace. If you follow along in Cursor, VS Code, Claude Desktop, or another MCP-compatible coding tool, natural language prompts calling the MCP protocol can also handle modeling and engineering tasks. Just confirm that your tool supports file editing, MCP execution, screenshot capture, and autonomous task continuation.


Phase 1: Configure Blender MCP and Three.js Local Development Environment

To let AI manipulate 3D software and drive a web game on your behalf, you need a communication pipeline connecting your coding assistant, 3D modeling tool, and web rendering environment.

Reference photos of the real desk environment and workflow starting point
Workflow starting point: Reference photos of a real desk taken from multiple angles.
At 15 seconds into the walkthrough video, showing the white wood-grain desktop, monitor base, keyboard, and desk lamp awaiting transformation.

The prompts in this guide are adapted templates for hands-on practice; dimensions, lighting values, and frame rate targets are initial baseline values to adjust against your own desk measurements and hardware performance. The screen-recording and video-editing tools used in the original video were not disclosed; the recording steps covered later in this guide are supplementary additions.

1. Install Base Dependencies and Core Software

Before starting, download and install the following four foundational tools from their official websites:

  1. Google Antigravity (or an MCP-compatible editor such as Cursor, VS Code, or Claude Desktop).
  2. Blender 3.0 or higher: The open-source 3D creation suite. Once installed, confirm it launches into the 3D viewport without issues.
  3. Node.js LTS: The JavaScript runtime bundled with npm, used to run the local frontend dev server.
  4. uv package manager: Used to run Python CLI tools quickly without polluting your system Python environment.
    • macOS Terminal: If Homebrew is installed, run brew install uv. Otherwise, execute the official install script directly in your terminal:
      curl -LsSf https://astral.sh/uv/install.sh | sh
      
    • Linux Terminal:
      curl -LsSf https://astral.sh/uv/install.sh | sh
      
    • Windows PowerShell:
      powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
      

2. Install and Activate the Blender MCP Add-on

We will use the open-source community project mcp-for-blender, which uses a local TCP socket to let external agents inject Python scripts into Blender and retrieve geometric data.

Run the following command in your terminal to automatically install the add-on into Blender:

uvx mcp-for-blender install-addon

Once installed, complete the following steps:

  1. Open Blender and navigate to the top menu: Edit → Preferences → Add-ons.
  2. Type MCP for Blender into the search bar in the top-right corner, then check the box to enable the add-on.
  3. Return to the 3D viewport and press N on your keyboard to reveal the right-hand sidebar.
  4. Locate the MCP for Blender tab, confirm its status displays as started, or click Start MCP Server (default local port is 9876).
  5. Keep the Blender window open throughout all subsequent generation steps.

3. Configure the Antigravity MCP Connection

In Antigravity, you can connect to this service via either a project-level or global configuration file:

  • Global configuration path: ~/.gemini/config/mcp_config.json
  • Project-specific path: .agents/mcp_config.json in your project root

Append the following configuration inside the existing mcpServers object (ensuring any existing service configurations are preserved):

{
  "mcpServers": {
    "blender": {
      "command": "uvx",
      "args": ["mcp-for-blender"],
      "env": {
        "BLENDER_HOST": "localhost",
        "BLENDER_PORT": "9876"
      }
    }
  }
}

Troubleshooting note: If you encounter a spawn uvx ENOENT error on launch, the GUI editor did not inherit your system terminal's environment variables. Run which uvx in your macOS/Linux terminal (or where.exe uvx in Windows PowerShell), and replace "command": "uvx" with the returned absolute path (such as /opt/homebrew/bin/uvx or C:\Users\username\.local\bin\uvx.exe).

Connectivity Checkpoint: Fully restart your AI editor, then send a test instruction to the agent: "Please call the blender tool to inspect current scene info, then create a new red cube named TestCube". If a red cube appears immediately in the Blender viewport and the AI reports the object name correctly, the 3D control bridge is fully operational.

4. Create the Project Directory and Install Three.js

Set up the project directory and dependencies first. Once the concept and plan are confirmed, generate the HTML and game code in Phase 4.

Create the project directory and install dependencies according to your operating system:

  • macOS / Linux Terminal:
    mkdir desk-racer
    cd desk-racer
    npm init -y
    npm install three
    npm install --save-dev vite
    mkdir -p public/models
    mkdir -p public/textures
    mkdir src
    
  • Windows Command Prompt / PowerShell:
    mkdir desk-racer
    cd desk-racer
    npm init -y
    npm install three
    npm install --save-dev vite
    mkdir public\models
    mkdir public\textures
    mkdir src
    

Preserve the dependency versions generated by npm install, and merge the following fields into package.json; do not overwrite the installed dependencies and devDependencies blocks:

{
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}

Once tools are installed and Blender connectivity is confirmed, move on to taking photos and determining the visual direction. Writing the game code happens in Phase 4.


Phase 2: Take Photos and Determine Track Aesthetics and Dimensions

Start by generating concept art with Nano Banana to evaluate which objects the track will loop around, whether lighting should lean warm or cool, and how small the kart should feel. Selecting a reference version establishes a shared visual baseline for subsequent modeling and lighting tweaks.

1. Capture Reference Photos and Multimodal Assets

Reference assets can include photos, sketches, or a ~15-second walkthrough video panning around the desk. Capturing clear photos of the desk overview and key props is more than enough to get started.

Keep these 4 guidelines in mind when shooting reference photos:

  • Even, ample lighting: Shoot under bright, diffuse indoor lighting to avoid heavy dark shadows that obscure object boundaries and contours.
  • Wide overview photos: Stand in front of the desk and take 1–2 wide shots showing the full desk surface, establishing the relative distances and orientations between the monitor stand, keyboard, mouse, and mugs.
  • Key prop close-ups: Take close-up shots of the keyboard keycaps and desk lamp arm to capture prop thickness, bevels, and material reflectivity.
  • Clear unnecessary clutter: Remove tangled cable clusters and loose tissues, keeping only stationery or decorative objects with distinct geometric shapes.

Once concept art is generated, review the 2D concepts with the AI and pick a preferred visual direction before proceeding to 3D code.

Official conceptualization reference process (click to expand)
Another fantasy tabletop game from Google's guide: comparing concept art before solidifying visual style. 18 seconds, no narration.

2. Concept Art Generation Prompt

Upload your desk photos to the multimodal generation interface and submit the following prompt to generate concept art:

Template 1: Generate miniature racing concept art from desktop photos

Copyable prompt (teaching adaptation):

Analyze the desktop layout in the uploaded photos (monitor, mechanical keyboard, mouse, desk lamp). Using these real objects as miniature terrain obstacles, generate a 3D racing concept art with strong tilt-shift macro toy aesthetic.
Key requirements:
1. A vibrant red miniature go-kart racing in front of the keyboard, scaled proportionally to single keycaps.
2. An elevated curved track with red-and-white rumble strips and glowing barriers, looping under the monitor stand and around the mouse.
3. Dramatic lighting contrast: dim room ambience, deep purple backlight behind monitor, cyan glow between keycaps, and warm white key light from desk lamp.
4. Premium stylized game aesthetics reminiscent of a micro miniature toy universe.

3. 2D Spatial Planning Branch for Complex or Cluttered Desks (Optional for Simple Desks)

For simple desk setups, you can proceed directly to the next phase after generating concept art. However, if your desk layout is complex (featuring multi-tier shelves, dual monitor arms, or dense peripheral arrangements), or if you want the track to conform strictly to real-world object clearances, measured physical dimensions serve as an essential scale reference.

Measure the width and depth of the desk along with the length, width, and height of key props. Then have Argon generate a metric top-down floorplan as PLAN/layout.svg, overlaying a numbered grid on the photos. Verifying prop positions and track clearances beforehand prevents discovering that the road clips through the keyboard after assets are built.

Official complex spatial 2D floorplan and metric coordinate annotation example
Horyu-ji architecture example from Google's guide: locking in metric floorplans and cross-sections before generating 3D. Complex desks can leverage this approach.
Template 2: 2D top-down floorplan and metric coordinate generation for complex desks (adapted for this guide)

Additional guide instruction: If the model does not draw the metric grid directly into the SVG, you can instruct it to write a lightweight script to generate the numbered grid overlay.

Copyable prompt (teaching adaptation):

Review my desk photos and measured dimensions. The example tabletop is 1.2m wide and 0.6m deep; ask me to replace these and supply the measured prop sizes before fixing coordinates.
Since this build requires spatial accuracy, do NOT generate any 3D meshes yet:
1. **Generate 2D Vector Plan**: Create a top-down 2D floorplan in metric units and save it to `PLAN/layout.svg`. Map out the exact bounding boxes and center coordinates for the monitor base, keyboard, mouse, and margins (origin at desk center).
2. **Numbered Reference Grid**: Overlay a numbered X/Y metric grid (0.05m spacing) across the layout, plotting the planned closed track loop and key spline control points.
3. **Clearance Verification**: Verify that the gap between the keyboard and monitor base exceeds the road width (0.08m) without collisions before outputting coordinate tables.
Once we verify these 2D spatial dimensions, we will use these locked coordinates to build the 3D scene.

Phase 3: Clarify Requirements First, Then Delegate Tasks

Send /grill-me in Antigravity to let the model interview you on driving controls, camera perspectives, and prop modeling strategies. Once the Phase 2 concept art is approved, have the model draft PLAN.md along with a corresponding /goal command before execution begins.

Actual task orchestration for Desk Racer: three subagents working concurrently on atmosphere and HUD, prop modeling, and textures & branding.

1. Confirm Gameplay, Camera Modes, and Modeling Strategy

Answer these critical implementation questions early on:

  • "Should vehicle physics favor snappy, responsive arcade handling, or weightier simulation handling with inertia and drifting?"
  • "Should desk props be constructed directly from native Three.js primitives, or built via Blender MCP as beveled GLB models with independent world coordinates?"
  • "How should ground clearance be maintained between elevated track spans and the keyboard/monitor base to prevent support pillars from clipping?"

Standard Execution Sequence:

  1. Provide context and trigger the interview: Enter /grill-me in Antigravity, upload your reference photos, and instruct the model not to write any 3D code yet.
  2. Lock in concept art: Direct the model to reference your approved Phase 2 concept art; if not yet finalized, generate candidate options and present them in chat or Markdown.
  3. Solidify the plan and long-running goal: Once the concept art is confirmed and interview questions are answered, have the model document the phased execution plan in PLAN.md and propose a ready-to-run /goal command.
  4. Launch the autonomous execution loop: Execute the /goal command. The model will work autonomously toward concrete verification criteria, ensuring smooth driving loops, functioning camera rigs, and clean asset loading without errors.

2. Task Delegation and Conflict Prevention Across Three Specialized Roles

The image shows the three subagents used in the original build. When following along, you can split responsibilities across files as follows:

  • 3D Desk & Props Architect: Uses Blender MCP to write Python scripts, automating low-poly mesh generation for the monitor base, keyboard, and mouse, then exporting them to public/models/desk-props.glb.
  • Nano Banana Texture & Logo Artist: Prompts Nano Banana to generate seamless wood grain, asphalt, and curb rumble strip textures, supplying material maps for Three.js.
  • Atmosphere & HUD Engineer: Configures Three.js spotlights, ambient point lights, multi-camera follow controllers, and basic HUD overlays.

Core Rules for Preventing Conflicts: Running in parallel does not automatically eliminate conflicts. Enforce these three conventions in the plan, leaving integration verification to the orchestrator:

  1. Shared units and coordinate system: All roles must standardize on meters and adhere to Three.js Y-up conventions (mapping Blender Z=0 to the tabletop plane), using the tabletop geometric center as the shared world origin.
  2. Strict file boundaries: Subagents maintain dedicated files independently (props.js, textures.js, lights.js). Cross-module modifications must be coordinated through the lead orchestrator.
  3. Orchestrator integration: The primary agent imports module assets into main.js and track.js, handling raycasting collisions and pillar alignment to ensure all components fit together seamlessly.
Template 3: Project planning and architecture kickoff

Additional guide instruction: Explicitly instruct the model that its final 3D production objective is to replicate the approved concept art's visual style and spatial layout as faithfully as possible before starting to code.

Copyable prompt (teaching adaptation):

/grill-me Help me plan a miniature browser kart racer based on my desk photos in the `desk-racer` workspace. Hold off on generating 3D code until we agree on the design.
1. Ask about driving feel, camera modes, lighting, and which objects need custom models.
2. Use the Nano Banana concept I have already selected. If none is selected, produce track and prop concepts and show them in chat. Wait for my choice before coding.
3. After I answer the questions and confirm a concept, save a milestone-based plan as `PLAN.md` and propose an executable `/goal` instruction for completing it.
Delegate props, textures, and lighting where subagents are supported; otherwise work through these milestones in sequence.
Deliver a Vite + Three.js project organized into `main.js`, `track.js`, `car.js`, `lights.js`, and `props.js`. Include WASD driving, four smooth camera modes, Blender props exported to `public/models/desk-props.glb`, and an elevated ribbon track with grounded supports and collision boundaries.

Phase 4: Get the Car Driving First, Then Add Desk Props and Elevated Track

Following the confirmed plan, build a drivable whitebox prototype first, load the desk props next, and finally implement and verify the elevated track and collisions.

1. Create the First Playable Prototype

Open the newly created desk-racer folder in Antigravity, confirming that the workspace root matches your terminal directory. In the model selector of a new chat, pick the Gemini 4 Argon variant available to your account. This initial prototype relies strictly on primitive geometries; replacing them with realistic desk props occurs in later steps.

Before running npx vite for the first time, use the following prompt to have the agent scaffold the complete initial playable prototype. The roadway must be designed as a flat ribbon mesh with actual width, rather than an unnavigable tubular spline.

Template 4: Scaffold the first playable prototype codebase (run before starting server)

Additional guide instruction: Use only the dependencies already installed for this project; verify syntax and module exports before starting the server.

Copyable prompt (teaching adaptation):

Please scaffold the first playable prototype in the current `desk-racer` project by creating the following files:
1. `index.html`: Standard HTML5 boilerplate, reset CSS for fullscreen canvas, `#app` mount container, importing `/src/main.js` as an ES module.
2. `src/main.js`: Main Three.js entry point. Set up scene, perspective camera (FOV 60, near 0.02, far 50), WebGLRenderer with shadows and antialiasing enabled, and a responsive resize handler.
3. `src/car.js`: Whitebox vehicle class. Construct a modular box car (red body, white roof, ~0.05m × 0.025m × 0.02m). Implement basic arcade physics with acceleration, steering yaw, braking, and damping. Bind key inputs: W (throttle), S (brake/reverse), A/D (steer), R (reset position and rotation).
4. `src/track.js`: Basic closed ribbon track. Build a flat drivable ribbon road mesh (width 0.08m, thickness 0.005m) forming a continuous loop around the desk center, complete with a checkered start line and red/white curb striping.
5. `src/camera.js`: Multi-camera rig. Implement smooth lerped switching across 4 modes: Key 1 (Chase Cam), Key 2 (Hood/Cockpit Cam), Key 3 (Top-down Overview), Key 4 (Orbiting Drone).
6. `src/lights.js`: Initial lighting. Add a shadow-casting spotlight and dim ambient light.

Verify clean module exports and syntax correctness so the project runs immediately upon server start.

Once the files are created, start the local development server in your terminal:

npx vite --host 127.0.0.1

The terminal will display a local address such as http://127.0.0.1:5173/ (incrementing automatically if port 5173 is in use). Open this URL in your browser to verify that the red-and-white kart rests on the ribbon track, drives smoothly with W/A/S/D, and transitions smoothly across camera angles using number keys 1–4. Keep this terminal running in the background.

Template 5: Troubleshooting follow-up for blank screen or startup errors (fallback)

Copyable prompt (teaching adaptation):

Upon running `npx vite`, the browser console reports an error (blank screen, missing `#app` container, module resolution failure, or WebGL context error).
Please inspect and patch the codebase according to these checkpoints:
1. Verify `index.html` contains `<div id="app"></div>` and `<script type="module" src="/src/main.js"></script>`.
2. Ensure all module imports in `src/main.js` use proper relative specifiers (e.g., `./car.js`, `./track.js`).
3. Ensure the `requestAnimationFrame` render loop actively updates car kinematics and camera lerp transformations each frame.
4. State the root cause and provide patched code files directly.

2. Dispatch Blender MCP to Build Independent Desk Props

Once the whitebox kart drives reliably on screen, instruct the agent to drive Blender via execute_blender_code to generate the prop meshes automatically.

When scripting the modeling routine, avoid aligning all objects to the world origin, which would cause the monitor base, keyboard, and mouse to collapse into an overlapping mess. Assign independent world coordinates to each object based on your reference photos and actual desk measurements.

Template 6: Automate building desk props with independent coordinates via Blender MCP

Copyable prompt (teaching adaptation):

Please invoke `execute_blender_code` via local Blender MCP to generate low-poly desktop props with independent world coordinates using Python:
1. **Layout & Dimensions (meters, adjustable defaults)**:
   - **Keyboard**: Center `(0, 0.01, 0.12)`, base ~0.36m × 0.14m × 0.02m with simplified keycap array, matte dark plastic material.
   - **Monitor**: Center `(0, 0, -0.22)`, thin rectangular base, upright riser, widescreen bezel (0.55m × 0.32m) with glossy dark glass material.
   - **Mouse**: Center `(0.24, 0.015, 0.12)`, ergonomic low-poly contour (~0.11m × 0.06m).
2. **Scene Hierarchy**: Keep distinct object names (`Keyboard`, `Monitor`, `Mouse`) without collapsing all meshes onto origin. The listed coordinates use Three.js Y-up; map (x,y,z) to Blender (x,-z,y), with Blender Z=0 as the tabletop.
3. **Export Specification**: Use the project's absolute filesystem path to export the props collection as binary GLB directly to `public/models/desk-props.glb`.
4. **Verification**: Confirm file existence on disk, verify file size is greater than 0 bytes, and output the final object transform coordinates.

3. Load Assets in Three.js via GLTFLoader

Under Vite, static assets placed in the public directory are mapped to the server root at runtime. Therefore, asset paths in JavaScript must be written as /models/desk-props.glb, without the /public prefix.

Coordinate system conventions must also be observed: when Blender exports glTF/GLB files, it typically converts its Z-up scene into glTF's Y-up convention, which Three.js's GLTFLoader consumes directly. Do not manually apply extra rotations such as props.rotation.x = -Math.PI / 2 to the loaded root scene, as doing so introduces double-rotation errors.

Write the loading function in src/props.js and call it from src/main.js:

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

export function loadDeskProps(scene, onLoaded) {
  const loader = new GLTFLoader();
  loader.load(
    '/models/desk-props.glb',
    (gltf) => {
      const props = gltf.scene;
      props.traverse((child) => {
        if (child.isMesh) {
          child.castShadow = true;
          child.receiveShadow = true;
          // 若有材质,适当微调粗糙度
          const materials = Array.isArray(child.material) ? child.material : [child.material];
          materials.forEach((material) => {
            if (material && typeof material.roughness === 'number') {
              material.roughness = Math.max(material.roughness, 0.4);
            }
          });
        }
      });
      scene.add(props);
      console.log('桌面道具加载成功,包含物体数量:', props.children.length);
      if (onLoaded) onLoaded(props);
    },
    undefined,
    (error) => {
      console.error('加载桌面模型失败,请检查 public/models/desk-props.glb 是否存在:', error);
    }
  );
}

Invoke this loader in src/main.js after initializing the scene. Place any track updates that depend on prop boundaries inside the callback to prevent support pillar raycasts from firing before meshes have loaded:

import { loadDeskProps } from './props.js';

loadDeskProps(scene, (props) => {
  console.log('道具就绪,现在可以按其实际边界检查赛道与支柱', props);
  // 在这里调用项目中已实现的赛道布局/支柱更新函数
});

4. Closed Ribbon Track Construction and Collision Detection

If the track rests directly on the tabletop surface, it will cause coplanar Z-fighting artifacts against the desk texture (where two surfaces compete in the depth buffer) and will be unable to clear obstacles like keyboards and cables.

Key considerations for constructing a high-quality elevated track:

  • Flat Ribbon Road: Construct a 3D spline centerline using CatmullRomCurve3, then extrude cross-sections laterally along curve normals to form a planar mesh with real width, complete with red-and-white curbs and raised barrier edges.
  • Vertical Undulations and Overpasses: Adjust control point elevations dynamically based on prop heights—dipping near desk level when crossing over the thin monitor base, and elevating smoothly when flying over the mechanical keyboard.
  • Grounded Pillar Detection (Raycasting / Geometry Query): In her experiments, original author Geneviève generated 68 vertical pillars to support elevated track spans. When following along, determine pillar counts dynamically from curve length, casting rays downward from the track underside to lock each pillar base securely onto the tabletop or monitor stand without floating or clipping through surfaces.
  • Segmented Collisions and Overpass Layering: At multi-tier road crossings, 2D planar distances alone cannot determine whether the kart is on track. Nearest-point calculations must incorporate segment IDs and local vertical tolerances. Apply rebound impulses when breaching barrier boundaries, and bind the R key to reset the kart onto the nearest valid track centerline immediately.
Template 7: Closed ribbon track generation and multi-layered physics collisions

Copyable prompt (teaching adaptation):

Please develop an elevated closed ribbon track in `src/track.js` that navigates around desktop obstacles:
1. **Geometry**: Build a closed ribbon road mesh (width 0.08m, thickness 0.004m) driven by a 3D CatmullRom spline. Route control points to elevate over keyboard edges and dip gently near the monitor base.
2. **Coplanar Anti-Z-Fighting**: Offset track elevation at least 0.003m above tabletop surfaces to prevent depth-buffer fighting artifacts.
3. **Support Pillars**: Distribute vertical cylindrical pillars under elevated spans. Use downward raycasting against desk meshes to clamp each pillar base securely onto supporting surfaces.
4. **Lap Rules**: Add a checkered start/finish threshold, a 3-lap countdown timer, current/best lap tracking, wrong-way detection, and an instant reset trigger (`R` key).
5. **Layered Collision Handling**: Implement height-gated collision matching at overpass intersections so the vehicle does not snap onto underlying road segments.
Drive a complete test lap in the browser to ensure smooth cornering across elevated bridges.

Phase 5: Scaling Down the Car—and Why the Camera Must Move Closer

Many desktop scenes built by beginners often feel like "a toy car skating on a giant flat cardboard box," failing to deliver the grand sense of micro-scale immersion seen in the video. The core reason lies in realistic scale derivation and close-range camera perspective.

Low-angle micro close-up of the race car speeding past a mechanical keyboard
Micro visual contrast: at a low-angle close-up, the car and mechanical keyboard keycaps exhibit a striking scale contrast.
At 45 seconds in the finished video, the car speeds across the surface while the background keys loom like towering monoliths.

1. Realistic Scale Reduction Calculations (from 1:87 to 1:150)

In early test renders, the author felt the car crowded the track too much, so she adjusted the car from 1:87 scale down to 1:150 while bringing the chase camera closer. What truly matters here is reusing the relative scaling ratio: 87/150 is approximately 0.58, rather than prescribing an identical car length across all projects.

Understanding the geometric and optical principles behind this scale adjustment:

  • Fixed physical environmental dimensions: Absolute dimensions of the desk, monitor, keyboard, and track remain constant in the 3D world (e.g., keyboard length 0.36 m, track width 0.08 m).
  • Proportional scaling of the car and its colliders: When scaling the vehicle body and its collision bounding box from 1:87 down to 1:150, reduce them to 87/150 ≈ 58% of their original size.
  • Synchronously scaled chase camera offsets: The relative offset vector from the camera to the car (such as trailing distance and height above) is likewise multiplied by the 58% factor. Because the camera's field of view (FOV) remains fixed, the car's screen occupancy in pixels stays largely constant.
  • Wider relative drivable surface: Relative to the scaled-down car, the track's effective relative width becomes 150/87 ≈ 1.72 times wider. The road geometry has not changed, but the car now enjoys significantly more relative maneuvering room.
  • Near clipping plane (camera.near) coordination: When the camera draws extremely close to a micro car, if camera.near remains at 0.1 m, the car's rear or hood is prone to being clipped away by the near plane, causing visual pass-through artifacts. Start testing from 0.01 to 0.02 m, tuning it according to actual camera distances while monitoring background depth precision.

In optical principles, the angular size of an object in frame satisfies: θ = 2 arctan(S ÷ 2D) where S represents the object's physical size, and D represents the distance from the object to the lens. When the camera hugs the micro car, it sits only centimeters away; and because the camera's spatial height drops accordingly, keyboard keys originally resting flat across the desk rush into view at low pitch angles, making the keycaps appear towering. Finally, inspect framing and occlusion from actual camera positions.

You can adjust parameters in the interactive simulator below to observe the dynamic coupling between camera distance, object scale, and rendering field of view:

Shrink the Car, Bring the Camera Closer

Keep 1:87 on the left as a baseline and adjust the scale on the right. Try shrinking only the car first, then enable camera compensation to observe the car's screen presence. Road and vehicle shown in idealized perspective.

Before: 1:87
Car & Camera: 100%
After: 1:150 · Camera Compensation
Screen Car Width: 100.0%
Physical Car Size
58.0%
Chase Camera Distance
58.0%
Screen Car Width
100.0%
Road Width Relative to Car
1.72×

Both car size and camera offset scale to 58.0% of baseline, keeping car screen size constant; road width relative to car increases to 1.72×.

Educational assumption: Fixed FOV with coaxial car and camera; projected car width is proportional to physical width ÷ camera distance. Percentages are relative to baseline. Road diagram shows coplanar depth; actual gameplay also requires checking chase angles, occlusion, and collisions.

Template 8: Vehicle Scale, Collider, and Near Clipping Plane Tuning

Copyable prompt (teaching adaptation):

Please refine scale parameters across `src/car.js` and `src/camera.js`, adapting the vehicle from 1:87 down to 1:150 micro scale:
1. **Vehicle & Colliders**: Read the current bounds and multiply vehicle dimensions, collision bounds, and ground-check distances by 87/150 exactly once. Record before/after dimensions.
2. **Camera Offsets**: Multiply the chase-camera offset vector and cockpit local coordinates by 87/150. Keep FOV fixed and compare vehicle screen occupancy before/after.
3. **Near Clipping**: In `src/main.js`, configure `camera.near = 0.01` to prevent clipping artifacts during tight macro shots.
4. **Kinematic Tuning**: Recalibrate top speed (~0.8 m/s) and turn rates to ensure realistic acceleration without visual teleportation at micro scales.
Verify visual framing against keycaps and validate handling responsiveness via test screenshots.

Phase 6: Tuning Materials and Lighting, Using Screenshots to Inspect the Scene

Elevating a 3D web scene beyond raw plastic clay models hinges on three coordinated tasks: assigning physically accurate PBR material textures to meshes, establishing a hierarchy between primary key lights and ambient fill lights, and using screenshot feedback to let an independent Adversarial Visual Critic subagent pinpoint defects and guide code revisions.

Agent evaluating rendering screenshots and critiquing defects during visual review
Actual screenshot inspection: pinpointing issues directly to code.
At 105 seconds in the making-of video, the Critic flags blown-out specular highlights, over-saturated yellow-orange wood grain, and an excessively dark chase-cam background, offering actionable remediation advice.

1. Realistic PBR Texture Mapping

Relying solely on flat base colors makes a scene look cheap. First generate or prepare seamless color maps for the wood grain and road surface, then supplement with roughness and normal maps as needed. PBR materials use these distinct images to separately define color, surface roughness, and microscopic bumps; standard color images cannot directly substitute for normal maps.

Call Nano Banana in Antigravity's image generation tools (or upload photos to the AI Studio image generation interface), requesting two texture maps: "seamless tiling wood grain" and "seamless tiling asphalt gravel," with a fixed top-down view, even lighting, and no track perspective or text. Save them as desk_wood.png and track_asphalt.png respectively. If your agent lacks image generation tools, download the files from the web UI first, then place them into the project directory to proceed.

Note: Texture files should reside in the public/textures/ directory (e.g., desk_wood.png, track_asphalt.png). In Three.js, load them via TextureLoader. Textures are a means to impart microscopic bump and reflective qualities to 3D meshes; do not mistake 2D flat images for three-dimensional geometry.

Template 9: PBR Texture Loading and Material Assignment

Copyable prompt (teaching adaptation):

Please implement a texture loading module in `src/textures.js` to assign PBR materials across scene meshes:
1. **Asset Paths**: Load the saved color textures `/textures/desk_wood.png` and `/textures/track_asphalt.png` with sRGB color space. Load roughness, normal, or metal maps only when their files exist; otherwise use material values and avoid missing URLs.
2. **Wrapping & Repeat**: Configure `wrapS = wrapT = THREE.RepeatWrapping`. Adjust UV repetition along the elongated track mesh (e.g., repeat 40 times longitudinally) to eliminate pixel stretching.
3. **Material Tuning**:
   - Tabletop: `MeshStandardMaterial`, warm walnut tint, roughness: 0.65, subtle specular sheen.
   - Track: Charcoal asphalt, roughness: 0.8; add normal detail only when a valid map is available.
   - Go-kart: Glossy racing red coat, roughness: 0.25, metalness: 0.4.
Export `applyMaterials(scene)` and hook it into `src/main.js`.

2. Three-Tier Composite Ambient Lighting, Interactive Control Panel, and Milestone Gallery

Referencing the warm desk lamp, violet ambient glow, and cyan keyboard accents from the original demo, you can begin tuning your project with three light groups:

  1. Key Light: A warm yellow spotlight (SpotLight, ~3200K color temperature) simulating a desk lamp, shining diagonally downward onto the primary desktop area with shadow casting enabled.
  2. Monitor Rim / Ambient Light: A deep violet or cool cyan point light (PointLight) placed behind the monitor panel to rim the screen outline and illuminate dark background walls, creating a stronger sense of depth.
  3. Gaming Accent Glow: Subtle emissive materials or surface lights between mechanical keyboard keycaps (Emissive Glow) to establish a high-tech micro racing track atmosphere.

To help developers track visual evolution, the official guide recommends two lightweight companion tools:

  • Screenshot gallery: Save a versioned set of screenshots after each milestone. Have the agent place progress.html in the project root and screenshots in public/progress/; while the dev server runs, open /progress.html at the same host and port to review changes over time.
  • Real-time parameter debug panel and true JSON export: Embed a lightweight slider-driven control panel on-screen to tune light intensity, shadow bias, and roughness in real time. Once satisfied, click "Copy Settings as JSON" to copy active values directly to the system clipboard, allowing the agent to bake them back into src/lights.js as permanent defaults before hiding or removing the panel for recording.
Official Desk Racer runtime lighting and camera interactive debug panel
The runtime debug control panel from official Desk Racer: the right panel includes camera presets 1–9, P-key auto cruise, lighting intensity, under-track LEDs, Depth of Field (DoF), Bloom, and vehicle speed sliders. Implementing four basic cameras and core lights is plenty for an initial build, while the original project offered richer advanced controls.
Template 10: Lighting Configuration, Interactive Debug Control Panel, and Progress Gallery

Additional guide instruction: Place the panel at the top right. Include spotlight angle and color temperature controls alongside intensity, shadow bias, and exposure.

Copyable prompt (teaching adaptation):

Please build a composite three-tier lighting setup, an interactive debug GUI, and a progress gallery in `src/lights.js`:
1. **Hierarchy**:
   - Desk Spotlight: `THREE.SpotLight` (warm tone `#fff4e0`, intensity: 2.5, castShadow: true, properly bounded shadow camera frustum).
   - Monitor Rim Light: `THREE.PointLight` (deep violet `#6b21a8`, intensity: 1.2, placed behind monitor panel).
   - Keyboard Glow: Cyan accent point light (`#06b6d4`) or material emissive highlights.
2. **Progress Gallery (`progress.html`)**: After each milestone, capture 4 viewport screenshots (overview, detail close-up, low-angle ground check, wireframe view) into `public/progress/` and index them in `progress.html` with version numbers and timestamps.
3. **Interactive GUI & Real Clipboard Copy**: Embed lightweight on-screen sliders for spot intensity, penumbra, shadow bias, exposure, and color. Add a "Copy Settings as JSON" button that invokes `navigator.clipboard.writeText(JSON.stringify(config, null, 2))` to truly copy active settings to the system clipboard (not just console.log).
4. **Bake Defaults**: Establish a clear workflow: once I paste back the exported JSON, bake those values into `src/lights.js` as permanent defaults, and provide a toggle to hide or remove the debug GUI before final recording.

3. Independent Adversarial Visual Critic Self-Review Loop

Have a separate Critic subagent inspect actual runtime screenshots, then return diagnosed issues to the coding agent for fixes. Together with human review, it examines four views:

  1. Overview: Composition, track layout, and occlusions.
  2. Close-up: Wood grain, road surface, specular highlights, and texture stretching.
  3. Low angle: Ensuring wheels and track pillars make solid contact with the ground without floating.
  4. Wireframe: Mesh topology and geometry interpenetrations; collisions must still be validated through active driving and geometry checks.

The original guide used "itemizing at least 3 defects to reach 9/10" to propel early iterations. When building along, have the Critic report actual problems alongside target files, and re-capture screenshots after fixes. Conclude the round only once visuals match your approved stylistic direction, multi-lap driving works, camera transitions are smooth, and assets load without errors. In AI Studio Build, you can also paste these screenshots directly into the chat and prompt Gemini to critique and modify the code.

Official Adversarial Critic Review Workflow Example (Click to Expand)
Another fantasy tabletop game from Google's guide: the Critic inspects an overly dark overview, potential fog or clipping artifacts, and path clipping. 26 seconds, no narration.
Template 11: Independent Critic Subagent Multi-View Review and Code Remediation

Additional guide instruction: Also inspect for broken or jagged shadow edges; report only defects visible in the actual screenshots.

Copyable prompt (teaching adaptation):

Please invoke an independent Adversarial Visual Critic subagent review pass for the current scene:
1. **Render 4 Verification Screenshots**:
   - 3/4 Overview: Demonstrating overall layout and track composition.
   - Close-up: Inspecting keycap textures and asphalt grain.
   - Low Angle: Inspecting vehicle contact and pillar bases to eradicate floating objects.
   - Wireframe View: Verifying clean 3D topology and potential collision intersections.
2. **Defect List**: Have the Critic subagent inspect all 4 screenshots, itemizing the visual flaws actually present (e.g., specular blowouts, shadow acne/detachment, floating meshes, or flat materials) with targeted remediation advice.
3. **Targeted Patching & Exit Criteria**:
   - Apply fixes directly across `src/lights.js`, `src/textures.js`, or `src/track.js`.
   - Re-capture screenshots for verification. Do not invent defects once they are fixed. End the round when the image matches our approved direction and multi-lap driving, camera modes, and asset loading pass.

4. When Lighting Tuning Stalls, Generate a Target Render from the Same View First

If repeated parameter tweaks leave you unsure where to head next, feed current scene screenshots to Nano Banana to generate 2K target renders maintaining identical camera angles and object layouts. Hide UI buttons, sliders, and the HUD (speed, lap counts, and on-screen text) beforehand to prevent the model from hallucinating interface text into physical scene signage.

Then pass both current screenshots and target renders to Argon to analyze discrepancies in shadows, wood grain, reflections, and shadow regions, updating real 3D geometry, materials, and lighting accordingly. The target render serves as an anchor for direction; improvements must still hold up when orbiting the camera and driving the car in real time.

Architectural city example from Google's guide: the left displays before-and-after live WebGL rendering, while the right shows the 2K target render generated by Nano Banana.
Template 12: Generating Target Renders from Matching Views (Step 1)

Copyable prompt (teaching adaptation):

Switch off the interface buttons, debug GUI, and HUD. Save clear screenshots from 3–5 useful camera positions, labeling the camera and revision.
For each view, ask Nano Banana for a 2K reference image with improved lighting, desk grain, road texture, reflections, and depth. Preserve the camera framing and object arrangement.
Save each source/reference pair and show me previews with their actual paths. Regenerate references that alter the layout before changing the game code.
Template 13: Updating 3D Code Against Target Renders (Execute After Approving Targets)

Copyable prompt (teaching adaptation):

Use matching camera views to compare our live Three.js captures with the approved Nano Banana 2K references. Identify differences in shadows, wood grain, kart reflections, and the darker background.
Update the existing geometry, materials, and lights in src/lights.js, src/textures.js, src/main.js, or the model files actually used by this project.
Keep the reference image out of the scene background. Capture the original views again, rotate the camera, and drive a lap to confirm the improvement survives in real-time 3D. Show the edits and before/after captures.

Phase 7: Benchmark Frame Rates Before Deciding on Room Detail

Once the race car glides smoothly across the desk, many developers are tempted to ask: "Can I also model the whole study room—windows, bookshelves, and sofas—into the 3D scene?"

In real-time 3D rendering, avoid piling high-poly geometry into non-essential areas outside the player's primary field of view. Before optimizing, identify current performance bottlenecks (frame delta ms, DrawCalls, shadow passes, and texture VRAM), then apply targeted fixes based on the bottleneck type. On standard computers, treat 30fps as a playable, steady baseline, measuring bottlenecks first before tuning further toward higher frame rates.

Core Optimization Strategies:

  • Preserve detail in core zones: Keep PBR materials and dynamic key-light shadows focused strictly on the primary desk area (within ~1.2 m diameter) where the vehicle and closed-loop track reside.
  • Suppress background environments into darkness: Outline peripheral walls and bookshelves with minimalist, low-poly geometry, disabling shadow casting and receiving entirely. Allow the key light's natural falloff to envelop them in darkness, avoiding extra shadow pass computations.
  • Merge static meshes (DrawCall optimization): If hundreds of keyboard keycaps are individual meshes, they generate hundreds of draw calls per frame. During Blender modeling or Three.js initialization, batch them using InstancedMesh or merge them (BufferGeometryUtils.mergeGeometries) into a single mesh.
  • Polygon budgets for individual props: Keep individual desktop props between 500 and 2,000 polygons, with the total polycount across the entire desk recommended below 50,000 polygons. Polygon budgets must be evaluated alongside shadow passes and texture resolutions.
Template 14: Performance Profiling and Targeted Bottleneck Optimization

Copyable prompt (teaching adaptation):

Please profile rendering performance for `desk-racer` and apply targeted optimizations:
1. **Telemetry**: Add a lightweight stats overlay tracking FPS, frame delta (ms), and `renderer.info.render.calls` (DrawCalls).
2. **Bottleneck Audit & Shadow Pruning**: Determine whether performance is bounded by CPU DrawCalls or GPU fill-rate/shadow passes. Ensure strictly ONE primary spotlight casts dynamic shadows; disable shadow casting on auxiliary monitor fill lights.
3. **Mesh Merging**: Inspect keyboard keycaps. If composed of dozens of individual meshes, batch them via `BufferGeometryUtils.mergeGeometries` or `InstancedMesh`, comparing DrawCall measurements before and after.
4. **Acceptance Test**: Run a continuous multi-lap driving benchmark to verify smooth performance above the 30fps baseline (targeting 60fps on capable GPUs) without stutter during high-speed cornering.

Phase 8: Switching Camera Angles and Recording a Demo Video

A compelling showcase video does not require elaborate post-production effects; the key lies in camera pacing and alternating perspective choreography.

Opening overhead view of the elevated track and full desk setup in the game demo
Opening shot: Macro panoramic overview revealing the elevated curved track and full lighting across the desk.
At 0 seconds in the finished demo video, the monitor, desk lamp, and glowing keyboard together form a miniature racing arena.

1. Four Essential Camera Views to Implement

Listen for numeric key inputs in code to smoothly interpolate the camera between different attachment nodes:

  • Camera 1 (Chase Cam): The camera smoothly interpolates (Lerp) behind and above the car, conveying high-speed cornering and curb vibrations.
  • Camera 2 (Close-up Cockpit Cam): Fastened just above the vehicle's front hood, letting massive keyboard keycaps and the lamp stem rush toward the viewer for maximum micro-scale impact.
  • Camera 3 (Tabletop Panoramic Overview): Stationed high above overlooking the desk, showcasing the full elevated track layout and desk spatial arrangement.
  • Camera 4 (Orbiting Drone Cam): Slowly rotates along a wide circular path to highlight 3D lighting depth and multi-tiered elevated structures.

Advanced Tip (The Original Full Control Scheme): The original project panel featured camera presets 1–9 alongside shortcuts: Enter to start timing, WASD to drive, Space for handbrake drifting, Shift for boost, R to reset the vehicle, ESC for settings, M to toggle engine audio, and P to trigger auto-cruise along the track. When building along for the first time, implementing basic cameras 1–4 and core driving logic in the template is plenty—there is no need to force advanced features like auto-cruise into your first build.

Template 15: Smooth Multi-Camera Controller

Copyable prompt (teaching adaptation):

Implement a smooth camera controller in `src/camera.js` supporting keys 1, 2, 3, 4 with lerped transitions (Vector3.lerp and Quaternion.slerp):
1. **Key 1 - Chase Cam**: Offset 0.08m behind, 0.035m above the vehicle, looking 0.05m ahead.
2. **Key 2 - Cockpit View**: Mounted directly 0.008m above vehicle hood, looking straight forward.
3. **Key 3 - Overview**: Stationary vantage point 0.8m above and 0.5m offset from desk center, overlooking the track.
4. **Key 4 - Orbit Drone**: Slow orbit around desk center at 0.15 rad/s.
Smooth transitions across states within ~0.6–0.8s without sudden position snaps.

2. Local Production Build Verification (Record Directly Without Public Deployment)

Before recording, test the production bundle build to ensure asset paths are intact and the game runs reliably outside the dev server:

# 1. 编译生产代码至 dist/ 目录
npx vite build

# 2. 预览生产版本
npx vite preview --host 127.0.0.1

Open the preview URL in your browser (typically http://127.0.0.1:4173/) for a comprehensive test drive. Check models, textures, and driving mechanics one by one to verify paths and runtime behavior in the production build. You can record cleanly on your local machine without configuring a public domain or remote server.

3. Step-by-Step OBS Recording Setup Guide

Use open-source OBS Studio:

  1. Hide debug controls: Before recording, hide on-screen slider panels and HUD text based on demo needs (you can set toggle shortcuts like H or ESC) to keep visuals clean.
  2. Add video capture sources:
    • Open OBS and click + in the bottom "Sources" dock.
    • Select Window Capture, picking your running game browser window from the dropdown; if it renders black, switch to Display Capture and capture the corresponding screen.
  3. Canvas and frame rate configuration:
    • Open OBS Settings → Video tab.
    • Set both "Base (Canvas) Resolution" and "Output (Scaled) Resolution" to 1920×1080.
    • Set "Common FPS Values" to 30 initially; if your GPU has headroom and recording causes no dropped frames, bump it to 60.
  4. Audio sources and volume level check:
    • The original demo also incorporated racing engine audio generated by Gemini Omni Flash. Google announcement blog
    • Confirm sound input in the "Audio Mixer". To capture web background music and engine SFX, add "Application Audio Capture" or "Desktop Audio".
    • Monitor green level meters bouncing to prevent red peaking or clipping distortion.
    • Important Note: The native macOS Shift + Command + 5 utility provides microphone options under "Options", but this cannot serve as internal system audio input. To record in-game audio on macOS, add system or application audio capture in OBS suited to your OS version and verify the level meters.
  5. 10-second test run:
    • Click "Start Recording", drive the car in your browser, and switch cameras for 10 seconds before clicking "Stop Recording".
    • Open the output folder and review the clip: check for black screens, stutter/dropped frames, and audio-video sync.
  6. Recording format and remuxing:
    • In OBS Settings → Output, set the recording format to MKV (preventing entire video corruption in case of unexpected crashes).
    • After recording, navigate to the top menu bar File → Remux Recordings, select your recorded MKV file, and remux it into a standard MP4 format recognized across major video editors.

4. Recommended 60–80s Shot List and Pacing

Here is the recommended shot pacing based on the game's mechanics:

  • 0–10s (Panoramic Opening): Camera 3 (Tabletop Overview). Static shot showing the micro car resting next to the illuminated keyboard amid deep shadows across the desk, introducing the game title.
  • 10–35s (High-Speed Acceleration): Camera 1 (Chase Cam). Launch and accelerate, drifting around the mousepad and climbing the elevated track over the keyboard in a continuous dynamic run.
  • 35–55s (Macro Close-Up): Camera 2 (Cockpit Cam). The camera brushes past mechanical keycaps and the monitor stand, amplifying the high-speed impact of micro scale.
  • 55–75s (Finish Line Freeze-Frame): The car crosses the finish line, triggering the 3-lap timer completion notification (or concluding on the crossing maneuver if no victory UI is built), then transitions smoothly into Camera 4 (Drone Cam) orbiting the desk before freezing.
  • Export specs: In editing software (CapCut, DaVinci Resolve, or Premiere), export an MP4 video using H.264 video encoding, AAC audio, and 1080p resolution.

Troubleshooting Guide: Common Errors and Solutions

In following this practical guide, you might encounter these typical issues:

Symptom & Error Root Cause Analysis Troubleshooting & Fix
MCP Connection Failure
Connection refused / port 9876
The addon server in Blender is not running, or the Blender window was closed. Open Blender, press N to toggle the sidebar, inspect the MCP for Blender tab, ensure it shows running or click Start MCP Server, and keep the application open.
Terminal Error
spawn uvx ENOENT
The editor or IDE cannot read the system terminal's PATH variable from the GUI environment. Run which uvx in your terminal (or where.exe uvx on Windows) to get the absolute path, and replace uvx in mcp_config.json with this absolute path.
Model Loading 404
404 Not Found /models/...
The Three.js load path mistakenly included the /public prefix, or static assets were not placed under public/models/. In Vite projects, standardize asset paths as /models/desk-props.glb, confirming the file exists in the project's public/models/ directory with a file size greater than 0.
Flickering Visuals (Z-fighting)
Mottled banding stripes across track or desk
The bottom surface of the track is completely coplanar with the desktop (depth buffer precision limits cause rendering contention). In src/track.js, raise the track base by at least 0.003m, or enable polygonOffset: true on the material.
Shadow Acne or Detachment (Peter Panning) Incorrect shadow bias (shadow.bias): too small causes self-shadow acne, too large causes shadows to detach. In the debug panel, fine-tune light.shadow.bias on the shadow-casting light, checking shadow resolution and frustum coverage; adjust spot light angle and near/far, or directional light orthographic bounds.
Black or White Screen on Startup
Console warns that #app cannot be found
index.html is missing a mount container node, or src/main.js was not created before running npx vite. Use the Phase 4 template ("Generate First Playable Prototype Code") to generate the HTML and JavaScript files, ensuring module paths are correct before starting the dev server.
Recording Lacks In-Game Audio
Recorded video captures only room noise
Used native macOS screen recording without configuring a system audio capture driver. Switch to OBS Studio, add "Application Audio Capture" or "Desktop Audio", and verify green mixer level meters before recording.

Start with the First Drivable Lap Version

Photograph your own desk first, confirm the concept image and plan, and build a rough prototype that can complete a full lap. Once this version stabilizes, add props, textures, and lighting one step at a time, saving screenshots and code versions at each milestone before doing a 10-second test run ahead of final recording.

Practical takeaway

Scroll through the Markdown, then copy and adapt it to your team.

Markdown · Member
Loading Markdown…
↑ End of article
✓ This article is free to read in full

Members can copy or download the full Markdown, and let their AI subscribe and ask.

Read the original ↗
📮 New explainers, straight to your inbox

Found this useful? Leave your email — every new explainer, the moment it's out. Unsubscribe anytime.