Star Fusion

Completed in 2025 | Godot

A space-themed 3D shoot 'em up that scrolls vertically through waves of enemies and environmental hazards, culminating in a multi-stage boss fight. Inspired by classics like Xenon 2: Megablast and Hudson Soft's Star Soldier: Vanishing Earth.

My Role

As a solo project, I was both a developer and 3D artist.

Code

  • Player controlled spaceship movement
  • Enemy waves
  • Power-ups
  • Multi-stage boss fight

Art

  • Modelled + textured all 3D assets, including the map, player, enemy and boss models

A Problem I Solved

With the game viewport and background scrolling at the same speed, space felt artificially small and the game feel suffered. I solved this using two separate SubViewports composited together: one rendering the scrolling background map, and one rendering the main gameplay layer (player, enemies etc). Because each SubViewport updates independently, I could scroll the background at a slower rate than the gameplay layer, creating the parallax effect that made the background planets feel distant and vast, while keeping player movement and combat feeling responsive.

Screenshots

Star Fusion screenshot 1
Star Fusion screenshot 2
Star Fusion screenshot 3
Star Fusion screenshot 4

Tags

3DSoloGodotShoot em up

Let’s Clean the Beach

Completed in 2025 | Unity

An immersive VR game that gamifies beach cleanup to raise awareness about ocean pollution. Built for the Meta Quest 3 using the Unity XR interaction toolkit.

My Role

I took on dual role of developer and 3D artist

Code

  • Seagull AI (see/think/act cycle)
  • VR collisions and player setup
  • Regular play testing

Art

  • Modelled + textured all tools and environment assets
  • Rigged + animated NPC models

A Problem I Solved

Setting up player collisions in VR were unreliable and tricky. Since the physical body collider was a separate object from the camera rig, it either lagged behind head movement or updated at the wrong point in the frame, causing it to clip through walls and obstacles or separate from where the player actually was. I solved this with an additional script that tracks the camera rig position with a fixed offset, updating in LateUpdate rather than Update. Since LateUpdate runs after all camera movement for the frame has been processed, the body collider always reflects true final position of the player. This eliminated the lag and mismatch that was causing the collision bugs.

Screenshots

Let’s Clean the Beach screenshot 1
Let’s Clean the Beach screenshot 2
Let’s Clean the Beach screenshot 3
Let’s Clean the Beach screenshot 4

Tags

3DTeam ProjectMeta QuestVR

Frog Game

Completed in 2026 | Unity

A 2D game where you play as a frog navigating varied terrain to catch flies while avoiding snakes. Built on a provided base project, the focus was implementing and comparing advanced AI and pathfinding systems including FSM enemy behavior, fly flocking, and multiple A* variants.

My Role

Implemented a variety of AI and pathfinding systems on top of a provided base project, including

  • Snake FSM
  • Fly flocking forces and behavior
  • Varying terrain impacting frog and snake movement speed
  • Provided the 2D assets for varying terrain
  • Implemented varying heuristics to support A* i.e ALT algorithm + terrain weight based
  • Jump Point Search
  • Dijkstra’s for preprocessing ALT algorithm node distances

A Problem I Solved

Preprocessing landmark distances for ALT was fast, but looking them up during search was not as with multiple landmarks and hundreds of nodes, scanning for the right distance on every heuristic call added real overhead to each pathfinding query. I solved this with a nested dictionary, Dictionary<Vector2, Dictionary<Vector2, float>>, keyed by landmark then by node. Each lookup becomes two direct hash reads instead of a search, so retrieving a precomputed distance during A* is effectively instant regardless of graph size. This ensured I made the most of the ALT algorithm's strength in staying cheap to query at the expense of a one-time Dijkstra preprocessing cost

Screenshots

Frog Game screenshot 1
Frog Game screenshot 2
Frog Game screenshot 3
Frog Game screenshot 4

Tags

2DTeam ProjectPathfindingA*FSM

The Legend of Scuba

Completed in 2026 | Unity

A 2D dungeon crawler where a player navigates procedurally generated rooms, collects keys, avoids enemies, and finds the exit. Built as a team project with a focus on training a ML agent to complete the core gameplay loop via curriculum learning. Heavily inspired by the Legend of Zelda 1.

My Role

Took on dual role of developer and 2D artist

Code

  • Enemy FSM
  • Extended procedural generation with corner cutting
  • Trained ML agent on enemy killing behavior via curriculum learning

Art

  • Made + animated all map, enemy, player and GUI sprites using Piskel

A Problem I Solved

As part of our curriculum learning approach, teaching the agent to kill enemies was saved for last. We reasoned that the navigation skills learned in earlier stages (seeking keys and doors, avoiding obstacles) would transfer well to this final behavior. However this meant the agent needed to learn an entirely new behavior largely from scratch, on top of an already complex environment. I tackled this through a fine-grained staged approach, introducing only one new variable at a time. I started with a single static enemy in a static room that dealt no damage, rewarding the agent on contact and ending the episode immediately. From there I gradually increased complexity - moving enemies, multiple enemies, enemies that damage the player - changing only one variable per stage. I also tweaked the ML agent hyperparams to support this, increasing the beta value early in training to encourage the agent to explore new behaviors rather than defaulting to previously learned patterns.

Screenshots

The Legend of Scuba screenshot 1
The Legend of Scuba screenshot 2
The Legend of Scuba screenshot 3
The Legend of Scuba screenshot 4

Tags

2DTeam ProjectML Agent