← Back to Projects

Programming Project

Gauntlet

A solo C project with custom HUD elements, data-driven level creation, and safer enemy spawner logic.

Role: Solo Developer

Used: C, OpenGL Wrapper

Duration: 3 weeks

Gauntlet image

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.

Technical Block

Technical Focus

  • Custom UI for health, score, keys, and inventory information
  • Text parsing system for tile locations and types
  • Data-driven level creation workflow for faster iteration
  • Enemy spawners with checks to avoid walls, entities, and invalid spawn tiles while still using RNG

Picture Block

Screenshot

Gauntlet image

Snippet Block

Code Snippet


/// @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

Enemy Spawner Logic

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

Images