# libtcod: a true colour console and pathfinding for roguelikes

> libtcod is a C and C++ library for roguelike developers, offering a true colour console, pathfinding, field of view and a set of utilities that roguelikes keep reimplementing. It is BSD licensed, it builds with CMake, and it can be consumed through Vcpkg, a submodule or FetchContent, with the README steering most people away from the pre-built binaries.

**libtcod/libtcod** — A collection of tools and algorithms for developing traditional roguelikes.  Such as field-of-view, pathfinding, and a tile-based terminal emulator.

- Repository: https://github.com/libtcod/libtcod
- Stars: 1,238 · Forks: 80
- Language: C
- License: BSD-3-Clause
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/libtcod-libtcod

## The parts every roguelike ends up writing

libtcod is described as a free, fast, portable and uncomplicated API for roguelike developers, providing a true color console, pathfinding, field of-view, and a few other utilities frequently used in roguelikes.

That list is a description of a genre's shared infrastructure. A roguelike needs a console that can draw coloured cells, because ASCII map characters alone cannot express what these games want to show. It needs pathfinding, because a player character moves through a grid and the game has to know how. And it needs a field of view, because a torchlight radius is the entire visual language of the genre.

Every one of those is a component with a decade of accumulated edge cases behind it. A field of view algorithm has to handle corners, walls, and the question of whether a wall corner blocks light. A pathfinder has to handle unreachable targets and produce the kind of path a player will accept. A console layer has to deal with terminals that do not support the features you want.

The library is written in C, with a C++ interface, and the topics list covers C99, C++ and both c-library and cpp-library tags, along with noise generator, pathfinding algorithms and fov algorithms. The C base is what makes it portable to the wide range of platforms roguelike developers build on, and the C++ wrapper is what makes it pleasant to use from a modern project.

## Four ways to link it, and the one the README steers you to

The getting started section covers four options, and the differences between them matter more than usual for a C library.

Vcpkg is the package manager route. libtcod is included as a port, you install it through Vcpkg, and then link the library using a CMake script as you normally would for that package manager. The README suggests forking a template project if you plan to start a project with this setup.

As a submodule is described as the best option for testing the development versions. You add the libtcod repository as a submodule and add that directory to a CMake script with add_subdirectory, which means the library is built from source as part of your project and you can point at any commit.

FetchContent is the modern CMake answer, and the README gives the block:

```cmake
cmake_minimum_required(VERSION 4.2)
include(FetchContent)

FetchContent_Declare(
    libtcod
    GIT_REPOSITORY https://github.com/libtcod/libtcod
    GIT_SUBMODULES ""
    GIT_TAG main  # Replace with desired version-tag or git-reference
)
FetchContent_MakeAvailable(libtcod)
```

and then the linking is the ordinary line:

```cmake
target_link_libraries(${PROJECT_NAME} PRIVATE libtcod::libtcod)
```

The comment in the FetchContent block is the important part, since GIT_TAG main pulls the development branch, and a project that wants reproducibility replaces it with a version tag or a git reference.

Compiling from source is listed last and is only recommended for libtcod developers, with the details in CONTRIBUTING.md, which is also where the dependency configuration is documented for the other routes.

## The pre-built binary warning, and the runtime you still have to ship

The section on pre-built binaries is the most opinionated part of the README, and it says three things.

First, it is not recommended, because those releases are unwieldy, are more difficult to update, and are less cross-platform. Second, in bold, do not upload binary files to your projects source repository. Third, for C and C++ programmers, Windows and MacOS binaries are available from the GitHub Releases page.

So the binaries exist, they are there for a reason, and the project would rather you did not use them. The reasoning is coherent for a C library: the platform runtimes are where the pain is, and a static binary from a release page rarely matches the runtime your user already has.

The last paragraph is the concrete warning. As a C++ library, you may need to distribute the appropriate runtime with your program, such as the Visual Studio 2015 runtimes, or else the program will fail to run. That is the failure mode nobody wants to discover from a bug report, and it is the reason the packaging-focused routes exist at all: a package manager handles the runtime question, a pre-built zip does not.

The same runtime advice is the reason the samples are useful. On Windows, the README says that downloading the pre-compiled binaries and running the included samples.exe, compiled from the C source, should be representative of the other versions.

## The documentation is incomplete, and the README says so

The documentation section is refreshingly blunt. The latest documentation is on Read the Docs, and then: it is incomplete, so most people will want to read the 1.6.4 documentation instead.

That is a real gap, and telling a reader to read the docs for a version from several years ago is an unusual admission. But for a stable C library with a long history, the old documentation is often the complete one, and the new one is the one that tracks the current API. The sensible approach for an adopter is to read both, treating the 1.6.4 manual as the explanation of the algorithms and the current manual as the description of the interface.

There is also a language split. Python users should use the python-tcod documentation, which is a separate project, and the sample application is provided in Python through that project.

The sample application is the library's best teaching tool, and the README explains why. It comes with implementations in C, in C++ and in Python, each providing a decent overview of the basic features in an interactive fashion, and each should be identical for the most part. That last property is the point: a feature demonstrated in one language is a feature you can rely on existing in the others, so the sample doubles as a portability test.

The repository makes the same point in its structure, with samples/ containing not only the three language versions but a set of focused demos, apfviewer.cpp, and directories for frost, hmtool, navier, rad, ripples, weather and worldgen.

## Where libtcod is the wrong choice

The first wrong-tool case is a Python project. The library is C with a C++ layer, and while there is a Python binding, the README routes Python users to python-tcod and its own documentation, which is where the Python API, its samples and its release cadence live. A Python team should start there rather than binding the C library themselves.

The second is a project that is not a roguelike. The centre of this library is the console abstraction, a true colour terminal with the cell-oriented drawing model that tile games use. A web game, a 3D game or an application with a normal GUI has no use for it, and there is no subset of libtcod that makes sense to extract.

The third is a team that needs a maintained, packaged dependency with a support commitment. The README routes bug reports and feature requests to the GitHub issues page and small questions to the #libtcod channel on the Roguelikes Discord or Libera.Chat IRC, which is a healthy community for a niche library. But the releases are irregular, the newest listed is 2.2.2 from January 2026, and the pre-built binary story is one the project itself discourages, so a commercial team is expected to build from source and own that.

The fourth is a team that wants the algorithms without the console. Field of view and pathfinding are the reusable parts, and there are standalone implementations of both, but adopting libtcod for them means taking the whole library.

## BSD-3-Clause, version 2.2.2, and a project that keeps its C core

The project is licensed BSD-3-Clause, with LICENSE.txt at the repository root, and it also carries a LIBTCOD-CREDITS.txt file for attribution of the work that came before it. For a library that has been embedded in a great many game projects, a permissive licence with a credits file is the combination you want.

The release history is short. The versions are 2.2.2 from 2026-01-06, 2.2.1 and 2.2.0 both from 2025-09-05. So two releases landed on the same day in September 2025, and the newest is a patch in January 2026. The repository is not archived and the last push was on 2026-10-17, so the work continues between releases, and there is a CHANGELOG.md for the details.

The tooling shows a project that takes its own quality seriously. There is a.clang-format and a.clang-tidy for the C and C++ code, a.pre-commit-config.yaml, a.readthedocs.yaml for the documentation build, a codecov badge and a GitHub workflow for the builds, a Repology badge showing how the library is packaged across distributions, and a vcpkg.json with a vcpkg/ directory so the port is maintained in the same tree.

There are two more packaging routes in the tree that the README does not push. A conanfile.py at the root and another in samples/ means the library is also consumable through Conan, which is worth knowing if your build system already speaks it, and the samples/ directory carries its own conanfile.py, which suggests the samples are meant to be built and run independently of the main tree.

The one structural thing to notice is the separation between the library and the samples, with the samples carrying their own CMakeLists.txt, their own README and their own packaging. The library is the product, and the samples are the demonstration, and they are versioned apart.

## Conclusion

Adopt libtcod if you are writing a roguelike in C or C++ and want a console abstraction, a pathfinder and a field of view that you did not have to write, and link it through Vcpkg or FetchContent rather than shipping pre-built binaries. Do not adopt it for a Python project, since the README points Python users at python-tcod, and do not adopt it for a project that is not a roguelike or a similar tile-based game, since the console model is the centre of the library. Before you build, read CONTRIBUTING.md for the dependency configuration, check that your toolchain can build the samples, and note that the current documentation is incomplete, with the 1.6.4 manual remaining the more complete reference.

## FAQ

### What does libtcod provide for roguelike development?

A true color console, pathfinding, field-of-view, and a few other utilities frequently used in roguelikes. The README describes it as a free, fast, portable and uncomplicated API, written in C with a C++ interface.

### How do I include libtcod in a CMake project?

Three routes are documented. Vcpkg, where libtcod is a port you install and link normally, a git submodule added with add_subdirectory, which is described as the best option for testing development versions, or FetchContent, using FetchContent_Declare with the repository url and a GIT_TAG you replace with a version tag or git reference, then linking with libtcod::libtcod.

### Should I use the pre-built libtcod binaries?

The README says not to: those releases are unwieldy, harder to update and less cross-platform, and it adds a bold instruction not to upload binary files to your project source repository. It also warns that as a C++ library you may need to distribute the appropriate runtime, such as the Visual Studio 2015 runtimes, or the program will fail to run.

### Where is the libtcod documentation?

The latest documentation is on Read the Docs, but the README warns it is incomplete and suggests most people should read the 1.6.4 documentation instead. Python users are pointed at the python-tcod documentation instead.

### What licence is libtcod released under?

BSD-3-Clause, with LICENSE.txt at the repository root alongside a LIBTCOD-CREDITS.txt file. The most recent release is 2.2.2, dated 2026-01-06, and the last push was on 2026-10-17.

## Sources

- [Issues](https://github.com/libtcod/libtcod/issues)
- [libtcod/libtcod on GitHub](https://github.com/libtcod/libtcod)
- [License: BSD-3-Clause](https://github.com/libtcod/libtcod/blob/main/LICENSE)
- [README](https://github.com/libtcod/libtcod/blob/main/README.md)
- [Releases](https://github.com/libtcod/libtcod/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/libtcod-libtcod
