Swift Game Engine Selection & VFX Architecture

SkillAI & models

Choose the right Swift game/VFX stack across SpriteKit, RealityKit, Metal, GameplayKit, and community engines with practical architecture and performance guidance.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Swift Game Engine Selection & VFX Architecture skill

What this skill tells your AI

The instructions your AI receives, as published by lev-os/agents in skills-db/design-ux/swift-game-engine/SKILL.md and read by ahel’s review.

Decision Tree

What are you building?
|
|-- 2D Game / 2D Effects?
|   |-- Simple sprites + physics? -> SpriteKit (built-in, battle-tested)
|   |-- UI particle overlays in SwiftUI? -> Vortex (zero Metal knowledge)
|   |-- GPU shader effects on SwiftUI views? -> Inferno (Metal fragments)
|   |-- Declarative particles (no Metal)? -> SwiftUI-Particles (Canvas-based)
|   |-- Cross-platform 2D? -> GateEngine (macOS/Win/Linux/iOS/Android/Web)
|   -> See: references/apple-frameworks.md#spritekit
|
|-- 3D Game / 3D Scene?
|   |-- AR / visionOS / spatial? -> RealityKit (Apple's primary 3D)
|   |-- Quick 3D prototype (non-AR)? -> RealityKit (SceneKit is deprecated)
|   |-- Pure Swift 3D engine? -> Untold Engine (custom Metal renderer)
|   |-- Cross-platform 3D? -> GateEngine or SwiftVVD
|   |-- AAA-quality custom pipeline? -> Metal direct (maximum control)
|   -> See: references/apple-frameworks.md#realitykit
|
|-- VFX / Post-Processing Pipeline?
|   |-- SwiftUI shader effects? -> .colorEffect / .layerEffect / .distortionEffect (iOS 17+)
|   |-- Full post-process stack? -> Metal render passes (effect compositor)
|   |-- Console-quality techniques? -> references/ps5-techniques.md
|   |-- Bloom / glow / TAA / SSR? -> Metal compute + render passes
|   -> See: references/architecture-patterns.md#effect-stack
|
|-- Game Logic / AI (renderer-agnostic)?
|   |-- State machines? -> GameplayKit GKStateMachine
|   |-- Pathfinding / nav mesh? -> GameplayKit GKGraphNode
|   |-- AI opponents? -> GameplayKit GKMinMaxStrategist
|   |-- Procedural noise? -> GameplayKit GKNoise
|   |-- ECS architecture? -> RealityKit (native) or Fireblade ECS (standalone)
|   -> See: references/apple-frameworks.md#gameplaykit
|
|-- Custom Render Engine?
|   |-- From scratch, maximum GPU control? -> Metal direct
|   |-- Need ECS but not RealityKit? -> Fireblade ECS + Metal
|   |-- Cross-API (Vulkan + Metal)? -> SwiftVVD
|   |-- Render graph architecture? -> references/architecture-patterns.md
|   -> See: references/apple-frameworks.md#metal
|
\-- Unsure / Need Comparison?
    -> See: Comparison Matrix below

Comparison Matrix

FrameworkVFX CapSwiftUI3DPerf CeilingLearningStatus
SpriteKitMidSpriteViewNoMidLowActive
SceneKitMid-HighSceneViewYesMidMidDeprecated (WWDC25)
RealityKitHighRealityViewYesHighMid-HighActive (primary)
MetalMaximumMTKView/UIViewRepYesMaximumHighActive (Metal 4)
GameplayKitN/A (logic)N/AN/AN/ALowActive
VortexLow-MidNativeNoLowVery LowActive
InfernoMidNativeNoMidLowActive
SwiftUI-ParticlesLowNativeNoLowVery LowCommunity
GateEngineMidNoYesMidMidActive
Untold EngineMid-HighNoYesMid-HighMid-HighActive
SwiftVVDHighNoYesHighHighNiche
Fireblade ECSN/A (arch)N/AN/AN/AMidActive

Rating key: VFX Cap = range of visual effects achievable. Perf Ceiling = maximum rendering throughput. Learning = time to first meaningful output. Status as of 2025.

SceneKit warning: Deprecated at WWDC 2025. Critical-bug-only maintenance. Do NOT start new projects with SceneKit. Migrate existing projects to RealityKit.

Quick-Start Patterns

SpriteKit (2D Game)

import SpriteKit
import SwiftUI

struct GameView: View {
    var body: some View {
        SpriteView(scene: makeScene())
            .ignoresSafeArea()
    }

    func makeScene() -> SKScene {
        let scene = GameScene(size: CGSize(width: 390, height: 844))
        scene.scaleMode = .aspectFill
        return scene
    }
}

class GameScene: SKScene {
    override func didMove(to view: SKView) {
        // Particle emitter
        if let emitter = SKEmitterNode(fileNamed: "Fire") {
            emitter.position = CGPoint(x: size.width / 2, y: size.height / 2)
            addChild(emitter)
        }
    }
}

RealityKit (3D / AR)

import RealityKit
import SwiftUI

struct Scene3DView: View {
    var body: some View {
        RealityView { content in
            let sphere = MeshResource.generateSphere(radius: 0.1)
            var material = PhysicallyBasedMaterial()
            material.baseColor = .init(tint: .blue)
            material.roughness = .init(floatLiteral: 0.2)
            material.metallic = .init(floatLiteral: 0.8)
            let entity = ModelEntity(mesh: sphere, materials: [material])
            content.add(entity)
        }
    }
}

Metal (Custom Pipeline)

import MetalKit
import SwiftUI

struct MetalView: UIViewRepresentable {
    func makeUIView(context: Context) -> MTKView {
        let view = MTKView()
        view.device = MTLCreateSystemDefaultDevice()
        view.delegate = context.coordinator
        view.preferredFramesPerSecond = 60
        view.colorPixelFormat = .bgra8Unorm
        return view
    }

    func updateUIView(_ uiView: MTKView, context: Context) {}

    func makeCoordinator() -> Renderer { Renderer() }

    class Renderer: NSObject, MTKViewDelegate {
        var device: MTLDevice!
        var commandQueue: MTLCommandQueue!
        var pipelineState: MTLRenderPipelineState!

        override init() {
            super.init()
            device = MTLCreateSystemDefaultDevice()!
            commandQueue = device.makeCommandQueue()!
            // Build pipeline from .metal shader file
        }

        func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {}

        func draw(in view: MTKView) {
            guard let drawable = view.currentDrawable,
                  let descriptor = view.currentRenderPassDescriptor,
                  let buffer = commandQueue.makeCommandBuffer(),
                  let encoder = buffer.makeRenderCommandEncoder(descriptor: descriptor) else { return }
            encoder.setRenderPipelineState(pipelineState)
            // Draw calls here
            encoder.endEncoding()
            buffer.present(drawable)
            buffer.commit()
        }
    }
}

Vortex (SwiftUI Particles)

import Vortex
import SwiftUI

struct FireView: View {
    var body: some View {
        VortexView(.fire) {
            Circle()
                .fill(.orange)
                .frame(width: 16, height: 16)
                .blur(radius: 3)
                .tag("circle")
        }
        .frame(width: 200, height: 300)
    }
}

Inferno (Metal Shader on SwiftUI View)

import Inferno
import SwiftUI

struct GlowingCard: View {
    @State private var time: Float = 0
    let timer = Timer.publish(every: 1/60, on: .main, in: .common).autoconnect()

    var body: some View {
        RoundedRectangle(cornerRadius: 16)
            .fill(.blue)
            .frame(width: 200, height: 120)
            .colorEffect(ShaderLibrary.emboss(.float(time)))
            .onReceive(timer) { _ in time += 1/60 }
    }
}

Architecture Patterns (Summary)

PatternUse CaseKey IdeaReference
ECSGames, simulationsEntities = IDs, Components = data, Systems = logicreferences/architecture-patterns.md#ecs
Render GraphCustom Metal pipelinesDAG of render passes, auto resource managementreferences/architecture-patterns.md#render-graph
Effect StackPost-processingOrdered list: bloom -> color grade -> vignette -> FXAAreferences/architecture-patterns.md#effect-stack
VFX ManagerSpawning effectsCentralized pool + spawn APIreferences/architecture-patterns.md#vfx-manager
Audio-Visual SyncReactive effectsFFT/RMS -> parameter bridge -> VFX intensityreferences/architecture-patterns.md#audio-visual-sync
State-DrivenSpell lifecyclesenum state machine drives VFX transitionsreferences/architecture-patterns.md#state-driven-effects
CompositionComplex effectsSpellEffect = [Particle + Shader + Audio + Shake]references/architecture-patterns.md#composition

Console-Quality on Apple Silicon (Summary)

TechniqueM1M2M3/M4PS5 Equivalent
TAAYesYesYesYes
MetalFX UpscalingYesYesYesPSSR/DLSS/FSR
Screen-Space ReflectionsYesYesYesYes
Mesh ShadersNoPartialYesYes
Variable Rate ShadingNoNoYesYes
Ray TracingBasicBetterFullYes

Feasibility: M1 = 60-80% PS5 quality. M2 = 70-85%. M3/M4 = 80-90%. Key bottleneck: memory bandwidth.

See references/ps5-techniques.md for implementation details.

Framework Selection Cheat Sheet

Need SwiftUI integration?
|-- Yes + 2D particles? -> Vortex
|-- Yes + shader effects? -> Inferno or .colorEffect/.layerEffect
|-- Yes + 3D scene? -> RealityView (RealityKit)
|-- Yes + 2D game? -> SpriteView (SpriteKit)
|-- Yes + custom GPU? -> MTKView in UIViewRepresentable
\-- No? -> Metal direct, GateEngine, or Untold Engine

Need cross-platform?
|-- Apple only? -> SpriteKit / RealityKit / Metal
|-- Apple + Windows + Linux? -> GateEngine
|-- Apple + Vulkan platforms? -> SwiftVVD
\-- Apple + Web? -> GateEngine

Need ECS?
|-- Built into renderer? -> RealityKit
|-- Standalone (any renderer)? -> Fireblade ECS
\-- With SpriteKit? -> OctopusKit (archived, use cautiously)

References

FileContent
references/apple-frameworks.mdDeep dive on SpriteKit, SceneKit, RealityKit, Metal, GameplayKit
references/third-party-engines.mdVortex, Inferno, GateEngine, Untold, SwiftVVD, Fireblade ECS, OctopusKit
references/ps5-techniques.mdTAA, MetalFX, SSR, mesh shaders, VRS, ray tracing, feasibility matrix
references/architecture-patterns.mdECS, render graph, effect stack, VFX manager, audio-visual sync, state-driven, composition

Related Skills

  • vfx-spell-effects -- Specific VFX implementations (smoke, lightning, particles, bloom, spell composition)
  • metal-shaders -- Shader authoring for any engine (MSL, vertex/fragment/compute)
  • orb -- Practical multi-layer VFX composition in SwiftUI (OCMiniOrb)
  • swiftui-animation -- Animation integration with engine rendering

External Resources

Technique Map

  • Decision tree by target — 2D game, 3D/AR, VFX pipeline, game logic, custom renderer; because framework choice depends on use case.
  • SceneKit deprecated — Do not start new projects; migrate to RealityKit; because WWDC 25 deprecation.
  • SwiftUI integration check — Vortex (particles), Inferno (shaders), RealityView, SpriteView; because many needs are SwiftUI-embedded.
  • ECS when needed — RealityKit native or Fireblade standalone; because games/simulations benefit from entity-component architecture.
  • Reference routing — apple-frameworks, third-party-engines, ps5-techniques, architecture-patterns; because each has deep content.

Technique Notes

Comparison matrix: SpriteKit, RealityKit, Metal, GameplayKit, Vortex, Inferno, GateEngine, Untold, SwiftVVD, Fireblade. M1-M4 feasibility for console-quality: 60-90% PS5. References: apple-frameworks.md, architecture-patterns.md, ps5-techniques.md.


Prompt Architect Overlay

Role Definition: Swift game engine and VFX stack selector. SpriteKit, RealityKit, Metal, GameplayKit, Vortex, Inferno, GateEngine. Architecture patterns, performance, cross-platform.

Input Contract: Accepts "which engine for X," 2D/3D game, VFX pipeline, particle system, or framework comparison. Target platform, SwiftUI needs, cross-platform needs.

Output Contract: Decision tree result with framework recommendation. Quick-start code pattern. Comparison matrix row. Reference to deep-dive (apple-frameworks, architecture-patterns). Related skills (vfx-spell-effects, metal-shaders, orb).

Edge Cases & Fallbacks: If SceneKit mentioned→warn deprecated; recommend RealityKit. If SwiftUI required→Vortex, Inferno, or MTKView in UIViewRepresentable. If cross-platform→GateEngine or SwiftVVD. If ECS→RealityKit or Fireblade.

Signals

GitHub stars
22
Forks
2
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
swift-game-engine
Source
github.com/lev-os/agents