TakeFlight — A Bird's Life

A SpriteKit survival game for iPad and macOS with full keyboard support, where players build a nest, protect their flock, and escape Belle Isle through connected mini-games.

Demo Video

Demo video: TakeFlight gameplay walkthrough.

Problem

Many game prototypes have fun mechanics but weak continuity between interactions. This project focused on creating a connected survival loop where each mini-game affects player state and long-term progression.

Project Snapshot

  • Platform: iPadOS + macOS (SpriteKit)
  • Type: Narrative survival game
  • Focus: Multi-mode gameplay loop, persistence, controller/input support
  • Input: Full keyboard compatibility, plus touch and motion where applicable
  • Team: Small collaboration
  • Timeline: Jan 12, 2026 - Feb 20, 2026

Role

Gameplay engineer and designer responsible for SwiftUI + SpriteKit architecture, scene systems, mini-game mechanics, and persistence/Game Center integration.

My Contributions

  • Implemented the root app flow between main menu and game using a state-driven SwiftUI coordinator
  • Built major SpriteKit mini-game logic, including predator timing, feed loops, and escape-state handling
  • Integrated persistence for game/session state and resume behavior with SwiftData models
  • Connected Game Center authentication and achievement reporting into gameplay milestones
  • Designed onboarding/instruction gating so tutorial prompts appear contextually without interrupting flow

Constraints

Ship five distinct mini-games in a short development window while maintaining input consistency, understandable controls, and smooth transitions across iPad and macOS.

Key Decisions

  • Built a root SwiftUI coordinator (`menu` / `game`) for clean state transitions and replayability
  • Used SwiftData models (`GameState`, `GameSettings`) to persist progress, inventory, and player state
  • Implemented a central view model to coordinate HUD, tutorials, mini-game flow, and world scene updates
  • Created instruction gating so tutorials appear contextually once, then get out of the player’s way

Core Features

  • Five mini-games with unique mechanics: predator escape timing, nest-building memory drag/drop, self-feeding catch system, rope-cut baby feeding, and Flappy-style island escape
  • Multi-input support including keyboard, touch, and tilt modes where relevant
  • Persistent inventory and score systems tied to in-world objectives
  • Haptics/audio feedback layers for success, danger, and state transitions
  • Game Center achievements integration for milestone progression

Technical Highlights

  • SpriteKit scene composition split into focused files (player, camera, map, predators, nest, updates) for maintainability
  • Physics-based mini-game interactions (rope links, falling items, contact categories) tuned for responsiveness
  • State-safe mini-game pausing and resuming during instructional overlays
  • Dynamic menu behavior with resume/new game paths based on persisted save state

Code Highlights

SWIFTDATA PERSISTENCE MODEL Defines a SwiftData model that stores all player progress, inventory, and game state for seamless saving and loading.
@Model
	final class GameState {
		var id: UUID
		var birdXPos: Double
		var birdYPos: Double
		var birdZPos: Double

		var hasNest: Bool
		var hasFedBabyBird: Bool
		var hasEscapedIsland: Bool
		var hungerLevel: Double

		var inventoryFood: Int

		var babyBirdHungerLevel: Double
		var hasBabyBird: Bool
		var hasHatchedBabyBird: Bool

		init(
			id: UUID = UUID(),
			birdXPos: Double = 0,
			birdYPos: Double = 0,
			birdZPos: Double = 0,
			hasNest: Bool = false,
			hasFedBabyBird: Bool = false,
			hasEscapedIsland: Bool = false,
			hungerLevel: Double = 100,
			inventoryFood: Int = 0,
			babyBirdHungerLevel: Double = 100,
			hasBabyBird: Bool = false,
			hasHatchedBabyBird: Bool = false
		) {
			self.id = id
			self.birdXPos = birdXPos
			self.birdYPos = birdYPos
			self.birdZPos = birdZPos
			self.hasNest = hasNest
			self.hasFedBabyBird = hasFedBabyBird
			self.hasEscapedIsland = hasEscapedIsland
			self.hungerLevel = hungerLevel
			self.inventoryFood = inventoryFood
			self.babyBirdHungerLevel = babyBirdHungerLevel
			self.hasBabyBird = hasBabyBird
			self.hasHatchedBabyBird = hasHatchedBabyBird
		}
	}
MAIN UPDATE LOOP ORCHESTRATION Runs the main game loop, updating health, saving progress, and triggering mini-games based on player actions and proximity.
func update(currentTime: TimeInterval) {
		if isPausedForMiniGame { return }

		let deltaTime = (lastUpdateTime == 0) ? 0 : currentTime - lastUpdateTime
		lastUpdateTime = currentTime

		timeSinceLastSave += deltaTime
		if timeSinceLastSave >= saveInterval {
			saveCurrentState()
			timeSinceLastSave = 0
		}

		decreaseHealthOverTime(deltaTime: deltaTime)

		if !isInInteractionRange,
		   let player = cameraNode.childNode(withName: "//player") {
			checkProximityToNestAndPredator(playerNode: player)
		}

		if isNearNest { handleNestInteraction() }

		if isNearPredator {
			isNearPredator = false
			startFlyAwayMiniGame()
		}

		checkForFoodCollection()
	}

Key Screens

Key screens: Nest-building, predator, feed, and island-escape mini-game moments from the shipped build.

TakeFlight build-nest mini-game screen

Build Nest mini-game where players assemble materials under pressure to unlock core progression.

TakeFlight predator mini-game screen

Predator mini-game where players react quickly to evade threats and preserve survival state.

TakeFlight feed mini-game screen

Feed mini-game focused on timing and resource collection to maintain hunger and progression.

TakeFlight leave-island mini-game screen

Leave Island mini-game sequence where players complete the final escape challenge.

Outcome

The final build delivers a cohesive survival experience rather than disconnected mini-games. It demonstrates system-level thinking, robust scene orchestration, and practical game architecture choices in SwiftUI + SpriteKit. At project completion, the game was presented to an Apple Arcade employee for feedback and industry insight.

Next Iteration

Next improvements would include adaptive difficulty scaling, expanded narrative beats between milestones, and richer telemetry for balancing challenge pacing across input modes.