Example: Ashfall Courier
A delivery game about crossing a volcanic city before the ash buries the last road.
Fictional example project used to preview the layout. Every area is filled so you can see all sections.
- Role
- Producer, Narrative Designer & Gameplay Programmer
- Type
- Game jam
- Status
- Released
- Period
- 2025
- Team
- 4 people
- Genre
- Narrative action
- Platforms
- PC, Web
- Engine
- Unity
Game Production
Ran the 48-hour jam plan, cut scope at the right moments and kept the team in sync.
Responsibilities
- Defined the scope and a three-milestone plan
- Ran stand-ups every 6 hours
- Owned the build and submission
Highlights & results
- Shipped on time with every core feature
- Top 10% in "Theme" out of 900 entries
- Methodology
- Kanban with timeboxed milestones
- Team coordinated
- 4 people
Documents
Tools
- HacknPlan
- Discord
- Google Sheets
Evidence
Narrative Design
Wrote the courier's radio dialogue and the notes players find along the routes.
Responsibilities
- World premise and tone
- 40 lines of branching radio dialogue
Highlights & results
- Players quoted the ending in most reviews
- Narrative structure
- Linear core with branching radio calls
Script excerpt
DISPATCH: You're late again, courier. COURIER: The road's gone. I'm taking the rooftops. DISPATCH: ...Then don't look down. The ash remembers footsteps.
Tools
- Ink
Gameplay Programming
Built the movement controller and the dynamic ash system that closes roads over time.
Responsibilities
- Character controller
- Ash spread simulation on a grid
Highlights & results
- Stable 60 FPS on the WebGL build
Systems implemented
- Character controller with ledge grab
- Grid-based ash spread
- Delivery timer and scoring
Languages
- C#
Technical challenge & solution
The ash spread made the WebGL build stutter. I moved it to a fixed tick spread across frames, which removed the spikes.
Code sample
void Tick()
{
// Spread to a budget of cells per frame to avoid spikes.
for (int i = 0; i < cellsPerFrame && frontier.Count > 0; i++)
{
var cell = frontier.Dequeue();
foreach (var n in grid.Neighbours(cell))
if (grid.TryIgnite(n)) frontier.Enqueue(n);
}
}Tools
- Unity
- C#