Overview
Project Description
Gauntlet was a solo programming project where I built core gameplay support systems in C, including UI, level parsing, and enemy spawning logic.
Programming Project
A solo C project with custom HUD elements, data-driven level creation, and safer enemy spawner logic.
Overview
Gauntlet was a solo programming project where I built core gameplay support systems in C, including UI, level parsing, and enemy spawning logic.
Technical Block
Picture Block
Snippet Block
/// @brief Spawn an enemy into one of the 8 neighboring tiles around the spawner if there is a free tile.
/// @param sp
static void _spawnEnemyFromSpawner(EnemySpawner* sp)
{
if (sp == NULL || _enemyCount >= MAX_ENEMIES)
return;
int baseTx = (int)(sp->position.x / TILE_SIZE);
int baseTy = (int)(sp->position.y / TILE_SIZE);
// 8 neighbors around the spawner. Nothing in the center.
const int offsets[8][2] = {
{ -1, -1 }, { 0, -1 }, { 1, -1 },
{ -1, 0 }, { 1, 0 },
{ -1, 1 }, { 0, 1 }, { 1, 1 }
};
int candidateTx[8];
int candidateTy[8];
int candidateCount = 0;
// Scan for valid neighbor tiles.
for (int k = 0; k < 8; ++k)
{
int nx = baseTx + offsets[k][0];
int ny = baseTy + offsets[k][1];
if (_isSpawnerTile(nx, ny))
continue;
if (_isCollectibleTile(nx, ny))
continue;
char tile = tilemapGet(&_level, nx, ny);
if (tile != '.')
continue;
// Candidate spawn position.
float x = (nx + 0.5f) * TILE_SIZE;
float y = (ny + 0.5f) * TILE_SIZE;
// If spawn position is blocked, then don't spawn an enemy there.
if (_isSpawnBlockedAt(x, y))
continue;
candidateTx[candidateCount] = nx;
candidateTy[candidateCount] = ny;
candidateCount++;
}
// None are valid? Then don't spawn an enemy.
if (candidateCount == 0)
return;
// Pick a random candidate.
int choiceIndex = rand() % candidateCount;
int nx = candidateTx[choiceIndex];
int ny = candidateTy[choiceIndex];
Coord2D pos;
pos.x = (nx + 0.5f) * TILE_SIZE;
pos.y = (ny + 0.5f) * TILE_SIZE;
_spawnEnemyAt(pos);
}
Description Block
This function controls how enemy generators spawn new enemies. Each generator sits on the tile map, so the first step is converting its world-space position into tile coordinates. From there, the function checks the eight neighboring tiles around the generator. The system builds a list of valid spawn locations. It rejects tiles that contain another spawner, collectibles, walls, doors, or other blocked positions. Once all valid neighboring tiles are collected, the function randomly picks one and spawns the enemy in the center of that tile.
Gallery

