Projects

Soulless Knight 2026

iOS Gameplay Demo

Soulless Knight is a top-down roguelite dungeon crawler for iOS. Built from scratch over 6-weeks, we integrated a custom Entity-Component-System (ECS) engine in pure Swift and rendered natively using Apple's SpriteKit. We developed the game as part of a 4-person team for NUS CS3217.

Our team put extensive effort into architectural abstractions, applying software engineering best practices and comprehensive unit/integration testing.

Key Gameplay Features

Custom ECS Engine

A pure Swift implementation of the Entity-Component-System pattern, ensuring highly decoupled logic, cache-friendly data structures, and hardware-agnostic runtime systems.

Fluid Twin-Stick Combat

Responsive, native iOS controls supporting virtual analog sticks decoupled via joystick adapters and a command-driven action queue.

Deep Customization & Weapons

A versatile two-weapon loadout system supporting distinct playstyles: Firearms (requiring ammo/reloads), Magic (drawing from regenerating Mana), and resource-free Melee combat.

Technical Architecture & Insights

Our core software engineering goal was to build a robust codebase that prioritizes extensibility, and partitionability. Game logic was isolated from standard iOS rendering layers so that team members could develop core physics/systems and UI/adapters in parallel.

  • Topological System Ordering (DAG): The engine computes system execution order dynamically. Systems explicitly declare dependencies, which are resolved using Kahn's topological sorting algorithm on every frame.
  • In-Place Component Semantics: Components are reference types (classes). Systems query component references from the world and mutate them directly in-place. This facilitates instant runtime state propagation without expensive manual write-back loops.
  • Rigorous Design Patterns Applied:
    • Adapter Pattern: Completely decouples ECS logic from SpriteKit. Rendering and HUD backends are governed by protocols; SpriteKit implementations are injected dynamically at app launch.
    • Factory Pattern: Centralizes entity composition (e.g., EnemyEntityFactory), preventing system logic from directly assembling raw components.
    • Command Pattern: Touch screen and joystick interactions produce discrete Command objects. These are queued and executed linearly during the system tick.
    • Strategy Pattern: Used to abstract procedural layout generation algorithms and flexible enemy behavior AI (e.g., StandardStrategy vs TimidStrategy).
    • Chain of Responsibility: Manages weapons' effects (e.g., ConsumeAmmoSpawnProjectile) in a pipeline where any stage can intercept or block downstream actions.
    • Facade Pattern: Simplified generation, game states, and lockdown routines behind a single, clean interface: LevelOrchestrator.
© 2026 Chan Ger Teck. Thanks for visiting!