PROBLEMS
WORTH SOLVING.
As a programmer and game designer on OUT-VOID, I built
the overall architecture, level generation, NavMesh-driven
enemy AI and the portal spawners.
CHALLENGE 01
Runtime levels that the AI can navigate
- PROBLEM
-
Levels are assembled at runtime, so there is no
NavMesh baked in the editor for enemies to path on,
and building everything in one frame would freeze
the loading screen.
- SOLUTION
-
The first prototype generated a 5×5 tile grid
procedurally: weighted tiles (rifts, dunes, rough or
smooth ground), random 90° rotations and a
single-pass rule that keeps rifts from touching. The
current build places an authored map per level from
level data, with randomized player and portal spawn
points. In both versions
NavMeshSurface.BuildNavMesh()
bakes navigation right after the map exists, inside
a staged coroutine that yields between steps and
drives the loading bar.
- RESULT
-
The runtime bake takes 100–150 ms at level load, the
loading screen stays responsive, and gameplay holds
a stable 60 FPS.
// MapManager.cs (excerpt): build the level in stages, one frame apart
GenerarMapa(); // instantiate this level's map
barraCargaEscena.value = 0.3f;
yield return null;
ActualizarNavMesh(); // navSurface.BuildNavMesh()
barraCargaEscena.value = 0.5f;
yield return null;
SpawnearJugador();
SpawnearPortales();
CHALLENGE 02
Enemies that fall from portals onto the NavMesh
- PROBLEM
-
Enemies drop out of portals in mid-air, but a
NavMeshAgent that isn't on the NavMesh
can't move, and landing on clutter or a ledge can
leave it stuck.
- SOLUTION
-
Enemies fall with a Rigidbody while their agent is
disabled. When they touch the ground,
NavMesh.SamplePosition finds the nearest
walkable point within 4 m and a sphere check confirms
there is room. Only then does the body turn kinematic
and the agent get enabled and warped onto that point.
The Kamikaze then alerts by sight or proximity,
chases, and arms for 1.2 s with an accelerating
emissive blink before its explosion.
- RESULT
-
Enemies land with physical weight and reliably hand
over to pathfinding, and the blink gives players a
readable window to react.
// Kamikaze.cs (simplified): physics → NavMesh handoff on landing
if (!haAterrizado && collision.gameObject.CompareTag("Suelo"))
{
if (NavMesh.SamplePosition(transform.position, out NavMeshHit hit, 4.0f, NavMesh.AllAreas)
&& !Physics.CheckSphere(hit.position, 0.8f, capaObstaculos))
{
haAterrizado = true;
agent.enabled = true;
agent.Warp(hit.position);
rb.isKinematic = true;
}
}
CHALLENGE 03
Scattering props on the real terrain
- PROBLEM
-
Every level needs decoration that sits on the actual
ground surface, not floating or buried, without
placing each object by hand.
- SOLUTION
-
Random points inside the ground's bounds cast rays
downward and only accept hits on the ground collider;
each hit spawns a random prop with a random rotation.
Placement has an attempt budget (15 tries per object)
so it always terminates, and some props are limited
to slopes under 15°.
- RESULT
-
Each run gets varied decoration that follows the
terrain, and level loading can never hang in a
placement loop.