Wednesday, 17 June 2026

Ambulance Life: A Paramedic Simulator


Ambulance Life: A Paramedic Simulator is the first simulation game in which you experience every aspect of a paramedic’s life. Your objective? Quickly reach the accident site at the wheel of your ambulance. Your mission? Take care of the injured and apply first aid. Each accident is different. It's up to you to adapt and make the right choices while being fast and efficient.

Fact Sheet

Company:  Aesir Interactive

Engine: Unreal Engine 5

Platforms: Steam, XBox Series X|S, PS5 

Release: Feb 6, 2025

Team Size: 15-30

Systems I owned: City Generation (Houdini + Unreal Tooling), Traffic & Pedestrian Simulation, Callout Generation

My Work

Procedural city generation in Houdini. By far the hardest part was adding elevation. The City Sample is entirely flat, and once terrain has height it cascades through everything: streets have to follow the ground, sidewalks follow the streets, and buildings, foundations, entrances, parks, parking lots, and plazas all have to adapt to sit correctly on uneven ground. Holding that dependency chain together across the whole city was the core problem. On top of elevation I added a lot the sample doesn't have: one-way streets, proper turns (the sample only models intersections, with no turns off the highway), points of interest, suburban areas, bridges, and tunnels. I also split the city into four areas that could each be regenerated independently, so a change to one part didn't force a full rebuild, and generated both a landscape heightmap and a simplified mesh version of the world for the in-game map screen.

Editor tooling for city fine-tuning. The Houdini generation was powerful but destructive, so at a certain point we froze it and I moved the fine-tuning work into editor tooling that let the team adjust the city directly without regenerating. That covered lowering sidewalks, extending streets and traffic, and adding pedestrian paths through parks and plazas.

Gameplay-reactive traffic with MassTraffic. The game's callouts and events needed to block or alter traffic on demand, so I built a volume system on top of MassTraffic and ZoneGraph. Designers could pre-place these volumes in the editor or spawn them at runtime, and each one could block or affect traffic in its area in a few ways: changing the lane annotations on the ZoneGraph so agents treated those lanes differently, detecting and redirecting traffic agents already inside the volume, or recycling agents back into the pool, rather than destroying them, when they fell within it. That let an event cleanly close a street or clear a parking lot while the surrounding simulation kept running and routed around it.


Post Mortem

This one I'm still torn on. Houdini was an understandable choice under the constraints we had: a tight timeframe, and the City Sample gave us a lot of tooling out of the box. The downside only became clear over time. Because I was modifying a destructive Houdini pipeline so heavily, with elevation and everything that depended on it, art and level design were blocked from implementing content for a long stretch while they waited on those pipeline improvements.

If I started over, I'd weigh that bottleneck far more heavily. I might still reach for Houdini, but I'd resist modifying the generation itself and instead push changes to the content side: new kits, meshes, road and building styles to move it away from the stock City Sample look, since art had to produce that content for the new areas, POIs, and suburbs regardless. The better answer is probably to take the City Sample more or less as-is and do most of the modifications as editor-side extensions on top of it. That's exactly what we shifted to after the freeze, and the difference was immediate: the content teams could work in parallel with me on the tooling instead of waiting behind it.

I'd also evaluate breaking the Houdini pipeline into smaller, more granular stages, so a designer could regenerate a single building, street segment, or park without rerunning the whole city. It's a natural extension of the chunked, four-area generation I already built, just at a much finer grain. The catch is that decomposing each piece cleanly is a lot of work in itself, so it would have to be weighed against the iteration time it would save. Either way, the underlying lesson is the same: a non-destructive, extensible pipeline that lets people regenerate small pieces independently keeps the whole team unblocked, and I'd design for that from the start.