Project Log: Labyrinthine Echoes
Date: October 25, 2025 Author: (Your Name) Project: Project: Labyrinthine Echoes (2D Procedural Roguelite)
This is the first dev log for my new personal project, Labyrinthine Echoes. The primary goal is to build a small, tight, 2D roguelite focused on procedural generation and simple AI.
Demo Video
A not real description of a random not related video found in YouTube
Core Concept
The player explores a series of procedurally generated dungeon floors. The core loop is built around exploration, risk-vs-reward combat, and light resource management.
Key Features (The "Must-Haves")
- Infinite Floors: Using procedural generation (starting with Binary Space Partitioning) to create unique maps.
- Turn-Based Movement: Classic roguelike grid-based movement.
- Simple AI: Enemies that can patrol and chase the player using A* pathfinding.
- Fog of War: The map is revealed as the player explores.
Technical Stack
The game is being built from scratch in C++ to get a better handle on low-level game logic.
- Language: C++17
- Library: SFML (for rendering, input, and audio)
- Compiler:
g++/Clang++ - Build System: CMake
- Version Control: Git
Design Note: The choice to avoid a big engine (like Unity or Godot) is intentional. The main goal is learning the systems, not shipping a product fast.
Code Snippets & Early Progress
I've started by defining the basic data structures for the map and the entities.
1. The `Tile` Struct
This is the fundamental building block of the entire world. It needs to know its type (wall/floor) and its visibility state for the fog of war.
// src/Map/Tile.h
#pragma once
enum class TileType {
WALL,
FLOOR,
STAIRS_DOWN,
STAIRS_UP
};
struct Tile {
TileType type = TileType::WALL;
bool isExplored = false; // Has the player seen this tile before?
bool isVisible = false; // Is the tile currently in the player's line of sight?
// Pathfinding data (for A*)
int gCost = 0;
int hCost = 0;
Tile* parent = nullptr;
int getFCost() const { return gCost + hCost; }
};
2. Base `Entity` Class (Partial)
This will be the base class for the Player and all Monster types. Using a virtual update function will let us handle game ticks cleanly.
// src/Entity/Entity.h
#pragma once
#include <SFML/System/Vector2i.hpp>
#include <string>
class Entity {
public:
Entity(int x, int y, char glyph, std::string name)
: pos(x, y), glyph(glyph), name(name) {}
virtual ~Entity() = default;
// Pure virtual function makes this an abstract class
virtual void update() = 0;
// Public attributes for easy access (for a simple project)
sf::Vector2i pos;
char glyph; // The character to render (e.g., '@' for player)
std::string name;
int hp = 10;
int maxHp = 10;
};
Project Milestones
Here's the high-level roadmap I'm tracking.
| Feature | Status | Priority |
|---|---|---|
| Basic SFML Window | ✅ Done | High |
Tile and Entity Structs |
✅ Done | High |
| Map Generation (BSP) | ⏳ In Progress | High |
| Player Movement | ⏳ In Progress | High |
| Field of View (FOV) | ❌ Not Started | Medium |
| A* Pathfinding | ❌ Not Started | Medium |
| Basic Combat | ❌ Not Started | Low |
Next Steps
The immediate next step is to finish the Binary Space Partitioning (BSP) algorithm. Right now, it successfully divides the space, but I still need to implement the "room carving" and "corridor connection" logic. After that, I'll get the player character (@) moving around the generated map.