T.TAO
Back to Works
2026/engineering / engineering

MetalCaster

An Apple platform dedicated game engine, where GenAI is the first class citizen.

GameEngineRenderingMetal
MetalCaster

Metal Caster is my attempt to rethink game engine design for the Apple ecosystem from first principles.

Instead of building a general-purpose engine for every platform and every workflow, Metal Caster is intentionally opinionated: Swift + SwiftUI + Metal + ECS, Apple platforms only, and AI as a first-class interface to the engine.

The engine is open source and can be accessed through GitHub.

Why I Started This

Most engines optimize for flexibility and cross-platform scale.
Metal Caster optimizes for something else:

  • Better defaults over endless configuration
  • Deep Apple Silicon optimization over portability
  • AI-native creation workflows over manual boilerplate
  • Visual clarity and tool elegance over feature bloat

The core idea is simple:

Describe what you want -> AI builds it through engine tools -> refine visually in the editor.

I want the engine to feel like a precision instrument: focused, minimal, and fast.

Engine Architecture

Metal Caster is organized as a Swift Package with ten library modules and two executables β€” roughly 63k lines of Swift across the engine, editor, and tooling:

ModuleResponsibility
MetalCasterMathVectors, matrices, quaternions, AABB/OBB/frustum, ray-primitive intersection (MΓΆller-Trumbore, slab tests, SAT), splines
MetalCasterCoreECS world, engine loop, event bus, profiler
MetalCasterRendererMetal abstraction, render graph, shader compilation & caching, PBR materials, post-processing
MetalCasterSceneScene graph, USD import, camera/light/mesh systems, light & reflection probes
MetalCasterAssetAsset pipeline, MSL β†’ .metallib precompilation, texture compression, .mcbundle
MetalCasterAIMulti-provider LLM layer, 9 specialist agents, orchestrator, engine snapshots
MetalCasterPhysicsRigid bodies, sort-and-sweep broadphase, CPU raycasting against colliders
MetalCasterAudio / InputSpatial audio, cross-platform input abstraction

The Rendering Stack

This is where most of my recent work has gone. The renderer is built around a render graph that sequences mixed render and compute passes, with two selectable render paths:

  • Forward path β€” Shadow β†’ Skybox β†’ Mesh + Lighting β†’ Post-Process β†’ Blit
  • Deferred path β€” Shadow β†’ G-Buffer (MRT) β†’ screen-space deferred PBR lighting β†’ Skybox β†’ Post-Process

The G-Buffer packs albedo+metallic (RGBA8 sRGB), normal+roughness (RGBA16F), and world position (RGBA32F) alongside a Depth32F target.

Physically based shading

The core material model is Cook-Torrance: GGX normal distribution, Smith geometry term, and Fresnel-Schlick, driven by metallic/roughness material properties and textures. The same BRDF runs in both the forward multi-light shader and the deferred lighting pass.

MSLfloat3 F0 = mix(float3(0.04), albedo, metallic);
float  D  = distributionGGX(NdotH, roughness);   // GGX NDF
float  G  = geometrySmith(NdotV, NdotL, roughness);
float3 kD = (1.0 - F) * (1.0 - metallic);

Lighting & global illumination groundwork

  • Shadow mapping with a dedicated depth-only pass (front-face culling + depth bias)
  • Light probes storing L2 spherical harmonics, evaluated in-shader for diffuse GI
  • Reflection probes with box/sphere shapes and parallax-corrected cubemap projection
  • Procedural atmosphere with Rayleigh + Mie scattering, and an animated water surface with vertex displacement

Post-processing stack

A volume-based post-process chain over ping-pong HDR targets:

SSAO β†’ Height Fog β†’ Bloom (mip-chain downsample/upsample) β†’ Depth of Field β†’ Motion Blur β†’ Panini Projection β†’ Color Grading β†’ Vignette / Chromatic Aberration / Film Grain β†’ FXAA

Editor-grade GPU features

  • GPU object picking: every entity is rendered with its ID into an r32Uint target, giving pixel-perfect selection; the same buffer drives an edge-detected outline post effect.
  • GPU profiling: per-pass timestamps via MTLCounterSampleBuffer, surfaced in the editor and consumed by the Optimize agent.
  • Runtime MSL compilation with a pipeline cache, so user- and agent-authored shaders hot-reload without restarting the engine.
  • Compute passes power the Scene Composer's terrain tools: heightmap generation, hydraulic erosion, normal derivation, and sculpting brushes all run as Metal compute kernels.

AI as an Engine Interface

The AI system is not a chat sidebar β€” it is a control layer that operates the engine through the same APIs the editor uses.

  • 9 specialist agents: Scene, Render, Shader, Asset, Optimize, Analyze, Art, Audio, and Composer β€” each with a scoped toolset (30+ tools total, e.g. createEntity, addPostProcess, modifyShader, profileFrame, generateColorPalette).
  • Multi-agent orchestrator: a planner LLM decomposes a request into prioritized delegations ("create 12 building entities" β†’ Scene; "neon-glow materials" β†’ Shader; "colored point lights" β†’ Render) and executes them in order.
  • Snapshot-driven context: before every call, the engine serializes an EngineSnapshot β€” entity hierarchy, components, render state, draw calls, frame timing β€” so agents reason about the actual world state instead of hallucinating it.
  • Tools, not code dumps: agents mutate the world through typed, fail-safe tool calls that return structured results, keeping every AI action inspectable and reversible.
  • PromptScript: a compiler that turns natural-language behavior descriptions into Swift ECS components and systems, with a preview runner.
  • Multi-provider: OpenAI, Anthropic, and Gemini backends behind one interface.

Tooling: Shader Canvas & SDF Canvas

Two companion tools grew out of the engine and became projects in their own right:

  • Metal Shader Canvas β€” a standalone real-time MSL workbench with layered shader authoring and an agentic editing loop (see its dedicated page).
  • SDF Canvas β€” a node-based signed distance field editor that generates sphere-tracing MSL: the generated fragment shader ray-marches the SDF scene, with soft shadows (64-step shadow marching) and ray-marched ambient occlusion. A "Pro" version is embedded directly in the editor.

Current Status & Honest Gaps

Metal Caster is in an active pre-alpha / architecture-hardening stage with a working vertical slice across all core systems: ECS runtime, dual-path renderer, macOS editor (multi-panel workspace, build & play workflows), asset/build pipeline, and the agent system.

Still on the roadmap, stated plainly:

  • Hardware ray tracing (MTLAccelerationStructure) and a proper GI solution beyond probes
  • A dedicated particle/VFX system
  • Wiring the Composer agent's terrain tools and viewport spatial queries into the agent pipeline
  • Broader test coverage and large-scene production hardening

Ambition

Metal Caster is not trying to be the next "everything engine."
Its ambition is more specific:

  1. Become the best native engine experience on Apple platforms
    iOS, macOS, tvOS, and visionOS β€” with Metal-first performance and Swift-native ergonomics.

  2. Make AI the primary creation interface
    Not a chat sidebar, but a real engine control layer that can inspect state, call tools, and build scenes/materials/systems safely.

  3. Build a USD-native collaborative workflow
    Scene data as composable, version-friendly assets for real team workflows.

  4. Stay open, inspectable, and performance-transparent
    Clean package boundaries, measurable runtime behavior, and APIs that both humans and agents can reason about.

If successful, Metal Caster should feel like the Leica of game engines: focused, deliberate, and uncompromising in its domain.