Designing no-code games with Reality Composer Pro 3
At a glance
| Item | Summary |
|---|---|
| Purpose | Build a video game in Reality Composer Pro without code using Script Graphs. |
| App architecture | SquirrelApp is a thin SwiftUI shell around authored Reality Composer Pro content; ContentView supplies attachments and sends events while Script Graph owns most game behavior. |
| Main patterns | SwiftUI scene composition, SwiftUI–RealityKit bridge, Script Graph event bridge |
| Project style | Code-rich sample with 6 scanned Swift file(s) and 723 Swift line(s); resources and generated assets are excluded from those counts. |
Project structure
Source bundle/
├── Squirrel/SquirrelApp.swift # SquirrelApp
├── Squirrel/ContentView.swift # ContentView
├── Squirrel/DinnerBubbleView.swift # TreeTalkAttachmentView, SpeechBubbleShape
├── Squirrel/SquirrelTalkAttachmentView.swift # SquirrelTalkAttachmentView
├── Squirrel/ContentViewAttachments.swift # StartButtonAttachment, EndScreenAttachment, OrnamentBar
├── Squirrel/UIPreview.swift
└── Data/RealityFiles/Scenes.reality # authored RealityKit content
Structure observations
- The runtime boundary is WindowGroup + volumetric window; the pruned tree lists only files that explain lifecycle, state, or framework integration.
- App code is split into role-named views, models, managers, providers, components, or systems.
- Authored
.realityor Reality Composer Pro content is a real implementation boundary; Swift loads or drives it rather than reproducing its entity graph.
Overall architecture
flowchart LR
SquirrelApp_1["SquirrelApp"]
WindowGroup___volumetric_window_2["WindowGroup + volumetric window"]
ContentView_3["ContentView"]
RealityView_entity_graph_4["RealityView entity graph"]
RealityKit_Scripting_runtime_5["RealityKit Scripting runtime"]
SquirrelApp_1 --> WindowGroup___volumetric_window_2
WindowGroup___volumetric_window_2 --> ContentView_3
ContentView_3 --> RealityView_entity_graph_4
RealityView_entity_graph_4 --> RealityKit_Scripting_runtime_5
Reference code
Squirrel/SquirrelApp.swift:19 — the app or executable entry declares the outer scene lifecycle.
struct SquirrelApp: App {
// ...
}The diagram is a responsibility flow, not a claim that every adjacent node directly calls the next. It keeps scene ownership, shared state, RealityKit content, and framework-provider work at separate levels.
Ownership and state
classDiagram
ContentView *-- Entity : scene
ContentView *-- Array : cancellables
SquirrelTalkAttachmentView *-- Bool : isVisible
Ownership evidence
Squirrel/ContentView.swift:16 — representative stored state or the nearest verified lifecycle anchor.
@State var scene: Entity?
@State var cancellables: [AnyCancellable] = []
@State var squirrelTalkText: String = "zzz"
@State var squirrelTalkTimer: Float = 0
@State var showStartButton: Bool = false
@State var forceHideSquirrelTalk: Bool = false
@State var showOrnament: Bool = false| Owner | Object or state | Relationship | Mutation authority |
|---|---|---|---|
ContentView |
Entity as scene |
owns a SwiftUI-managed reference slot | The owning type coordinates writes |
ContentView |
Array as cancellables |
owns SwiftUI value state | The owning type coordinates writes |
SquirrelTalkAttachmentView |
Bool as isVisible |
owns SwiftUI value state | Only the declaring scope writes |
Ownership here is deliberately narrow: @Environment and weak references are shared links, initialized @State or stored services are lifecycle ownership, and a RealityView content closure owns additions to its entity graph without making the SwiftUI view a reference-type owner.
Class and protocol design
| Type | Responsibility | Depends on or conforms to |
|---|---|---|
SquirrelApp (Squirrel/SquirrelApp.swift:19) |
Declares app scenes and top-level dependency lifetime. | App |
ContentView (Squirrel/ContentView.swift:14) |
Presents UI and forwards gestures or lifecycle events. | View |
SquirrelTalkAttachmentView (Squirrel/SquirrelTalkAttachmentView.swift:10) |
Presents UI and forwards gestures or lifecycle events. | View |
TreeTalkAttachmentView (Squirrel/DinnerBubbleView.swift:10) |
Presents UI and forwards gestures or lifecycle events. | View |
The source defines no local substitution protocol in the reviewed boundary. Its protocol use is framework-facing (App, View, RealityKit/ARKit protocols, or platform adapters), so this document does not label the whole app protocol-oriented.
Access control
| Symbol | Access | Verified effect | Likely rationale |
|---|---|---|---|
@State private var displayedText: String = "zzz" (Squirrel/SquirrelTalkAttachmentView.swift:18) |
private |
Use is restricted to the declaration and same-file extensions permitted by Swift. | Inference: Hide implementation details and lifecycle-sensitive state. |
No reviewed declaration uses fileprivate, private(set), public, open; unmodified Swift declarations are internal.
Reference code
Squirrel/SquirrelTalkAttachmentView.swift:18 — representative visibility boundary.
struct SquirrelTalkAttachmentView: View {
// ...
@State private var displayedText: String = "zzz"
@State private var scale: CGFloat = 0
// ...
}Logic ownership and placement
| Logic | Owning type or file | Placement rationale |
|---|---|---|
| Scene declaration and dependency lifetime | SquirrelApp |
The App/entry boundary determines window, volume, and immersive-space lifetime. |
| Presentation, attachments, and gestures | ContentView |
SwiftUI view code forwards user intent and RealityView lifecycle events. |
| Authored game behavior | Squirrel/SquirrelApp.swift:24 plus Reality Composer Pro content |
Script Graph owns authored rules; Swift bridges UI and runtime events. |
Design patterns
| Pattern | Source evidence | Purpose or tradeoff |
|---|---|---|
| SwiftUI scene composition | Squirrel/SquirrelApp.swift:19 |
Keeps windows, volumes, and immersive-space lifecycle visible at the app boundary. |
| SwiftUI–RealityKit bridge | Squirrel/ContentView.swift:36 |
Builds and updates a RealityKit entity graph from SwiftUI lifecycle closures. |
| Script Graph event bridge | Squirrel/SquirrelApp.swift:24 |
Leaves authored behavior in Reality Composer Pro while Swift forwards UI events and attachments. |
Naming conventions
- Role suffixes are evidence, not decoration: App:
SquirrelApp; View:ContentView,SquirrelTalkAttachmentView,TreeTalkAttachmentView. - Protocols: no app-defined protocol in the reviewed source.
- Commands use verb-led methods:
sendSceneEvent,jumpToScene,formatPlayTime,scriptingEntity,inset,path,addCorner. - Files generally match their primary type;
Views,Models,Managers,Providers,Components,Systems, andPackagesfolders describe architectural roles where present.
Architecture takeaways
- Treat
SquirrelAppas the owner of scene declarations, not as the owner of every RealityKit entity created later. - Keep view-local interaction in SwiftUI, but move provider sessions, playback resources, shared game state, or transport state into a stable owner when their lifetime exceeds one render pass.
- Count Reality Composer Pro and Script Graph assets as implementation; the Swift shell alone is not the full architecture.
Source map
| Source file | Relevant symbols |
|---|---|
Squirrel/SquirrelApp.swift:19 |
SquirrelApp |
Squirrel/ContentView.swift:14 |
ContentView |
Squirrel/DinnerBubbleView.swift:10 |
TreeTalkAttachmentView, SpeechBubbleShape |
Squirrel/SquirrelTalkAttachmentView.swift:10 |
SquirrelTalkAttachmentView |
Squirrel/ContentViewAttachments.swift:10 |
StartButtonAttachment, EndScreenAttachment, OrnamentBar |
Squirrel/UIPreview.swift:1 |
Feature implementation |