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.