Pre-1.0 Notice: This library is under active development. The API may change between minor versions until 1.0.
Declarative Swift extensions for Godot 4.4 game development. Built with Swift 6 and async/await.
- Property Wrappers -
@GodotState,@GodotNode,@GodotSignalfor SwiftUI-like declarative patterns - Async/Await - Modern concurrency for signals, frame sync, and game loops
- Protocol Abstractions - Type-safe scene and node lifecycle management
- Swift 6 - Full strict concurrency support with
Sendableconformance - Re-exports SwiftGodot - Drop-in enhancement, no additional imports needed
Add SwiftGodotKit to your Package.swift:
dependencies: [
.package(url: "https://github.com/CorvidLabs/swift-godot.git", from: "0.1.0")
]Then add the dependency to your target:
.target(
name: "YourGame",
dependencies: [
.product(name: "SwiftGodotKit", package: "swift-godot")
]
)- Getting Started - Step-by-step guide for your first game
- Quick Start - Get running in 5 minutes
- Testing Guide - Running tests and demo games
- Security - Thread safety and memory management
- Contributing - How to contribute to the project
import SwiftGodotKit // Includes all of SwiftGodot
@Godot
class Player: CharacterBody3D {
// Reactive state with change tracking
@GodotState var health: Int = 100
@GodotState var isAlive: Bool = true
// Declarative node references
@GodotNode("HealthBar") var healthBar: ProgressBar?
@GodotNode(.unique("AnimPlayer")) var animator: AnimationPlayer?
override func _ready() {
$healthBar.configure(owner: self)
$animator.configure(owner: self)
}
override func _process(delta: Double) {
// React to state changes
if $health.changed {
healthBar?.value = Double(health)
if health <= 0 { isAlive = false }
}
$health.reset()
}
func takeDamage(_ amount: Int) {
health = max(0, health - amount)
}
}@GodotState var score: Int = 0
// Check if changed this frame
if $score.changed {
updateScoreDisplay()
}
// Get previous value for animations
if let previous = $score.previous {
animateScoreChange(from: previous, to: score)
}
// Create bindings for UI
let binding = $score.binding// By path
@GodotNode("UI/HealthBar") var healthBar: ProgressBar?
// By unique name (% prefix in scene)
@GodotNode(.unique("Player")) var player: CharacterBody3D?
// By group
@GodotNode(.group("enemies")) var firstEnemy: Node?@GodotSignal("pressed")
var onPressed: () -> Void = { print("Pressed!") }// Wait for a signal
await SignalAwaiter.wait(for: button, signal: "pressed")
// Wait with timeout
let succeeded = try await SignalAwaiter.wait(
for: enemy,
signal: "died",
timeout: .seconds(5)
)// Stream signals as AsyncSequence
for await _ in AsyncSignal(source: timer, signal: "timeout") {
updateGame()
}// Wait for next frame
await GodotTask.nextFrame()
// Wait for physics frame
await GodotTask.nextPhysicsFrame()
// Wait specific duration
await GodotTask.wait(seconds: 1.5)class GameScene: SceneController {
typealias RootNode = Node3D
var rootNode: Node3D?
func sceneDidBecomeReady() {
setupGame()
}
func sceneDidProcess(delta: Double) {
updateGameLogic(delta: delta)
}
}class PlayerController: NodeController {
typealias NodeType = CharacterBody3D
let node = CharacterBody3D()
var children: [any NodeController] {
[HealthBarController(), WeaponController()]
}
func configure() {
node.name = "Player"
}
}// Iterate children
for child in node.children {
print(child.name)
}
// Type-safe queries
let buttons: [Button] = panel.children(ofType: Button.self)
let allEnemies: [Enemy] = level.descendants(ofType: Enemy.self)
// Fluent configuration
let label = Label().configure {
$0.text = "Hello"
$0.horizontalAlignment = .center
}The library is organized into key components:
- Property Wrappers:
@GodotState,@GodotNode,@GodotSignal - Async Utilities:
SignalAwaiter,AsyncSignal,GodotTask - Protocols:
SceneController,NodeController,SignalEmitting,SignalReceiving - Extensions:
Node+Extensions,Object+Extensions - Internal:
GodotContext,Box
All components are designed for Swift 6 strict concurrency with proper Sendable conformance.
| Platform | Minimum Version |
|---|---|
| macOS | 14.0+ |
| iOS | 17.0+ |
| Swift | 6.0+ |
| Godot | 4.4+ |
The repository includes a comprehensive demo suite with 6 playable games:
# Build the demo library
./scripts/build-demo.sh
# Open in Godot
open -a Godot GodotProject/project.godotDemo Games: Breakout, Platformer, Snake, Asteroids, Rhythm, Dungeon
Feature Demos: Audio, Tween, Camera, Particles, Async, Color Lab, Music Theory, QR Code
MIT License - See LICENSE for details.
Contributions are welcome! See CONTRIBUTING.md for guidelines.
- SwiftGodot - Swift bindings for Godot
- Godot Engine - Game engine
- Swift.org - Swift programming language
Built with love for the Swift and Godot communities.