python-tcod Documentation

repository·main·Indexed 19 days ago

https://github.com/libtcod/python-tcod

The official Python cffi port of the libtcod library, providing tools for roguelike development including terminal emulation, font handling, and pathfinding. It features a high-performance API with numpy array attributes, automatic memory management, and support for BDF Unicode fonts. The library includes a modern API and a deprecated legacy API (libtcodpy) for backward compatibility.

Tokens
47.2K
Snippets
158
Records
221
Agent score
66%

What's inside python-tcod

  1. Use Line of Sight (LOS) with tcod.los

    main
    The tcod.los module provides functionality for calculating Line of Sight (LOS) in a grid-based environment. This is typically used in roguelikes to determine which tiles or entities are visible to a player or NPC based on field-of-view algorithms.
  2. Use pathfinding with tcod.path

    main
    The tcod.path module provides tools for pathfinding within a grid-based environment. It allows you to calculate paths between points while accounting for obstacles and movement costs. Use the classes and functions provided in this module to implement navigation for entities in your game.
  3. Use the tcod.render extension for console rendering

    main
    The tcod.render module provides an extension for console rendering in python-tcod. It allows for advanced rendering capabilities beyond basic character placement, typically used to manage complex console states or specialized rendering logic within a tcod application.
  4. Generate noise maps with tcod.noise

    main
    The tcod.noise module provides tools for generating noise maps, which are commonly used in procedural content generation for terrain, clouds, or other natural-looking patterns. The module contains various noise map generators that can be used to create stochastic textures or heightmaps.
  5. Understand the libtcod font file naming convention

    main

    The fonts provided in this directory follow a specific naming pattern: <font_name><font_size>_<type>_<layout>.png.

    Type

    • aa: 32-bit PNG with an alpha channel (antialiased).
    • gs: 24-bit or greyscale PNG.

    Layout

    • as: Standard ASCII layout.
    • ro: Standard ASCII layout in row format.
    • tc: TCOD layout.
  6. Manage global mutable variables with a dedicated module

    main

    For variables that need to be accessible across multiple modules (like the tcod context or the ECS registry), create a top-level module (e.g., g.py).

    To avoid runtime crashes while maintaining type safety, use type hints for variables that will be assigned in other modules (like main.py) without assigning them a value in the global module itself.

    """This module stores globally mutable variables used by this program."""
    
    from __future__ import annotations
    
    import tcod.context
    import tcod.ecs
    
    context: tcod.context.Context
    """The window managed by tcod."""
    
    world: tcod.ecs.Registry
    """The active ECS registry and current session."""
  7. Implement a game state with on_draw and on_event

    main

    To create an interactive game, you should implement a state class (often using attrs) that manages game data and handles rendering and input.

    Key methods to implement:

    • on_draw(self, console: tcod.console.Console) -> None: Responsible for drawing the current state onto the provided console. Use console.print(x, y, "char") for simple drawing.
    • on_event(self, event: tcod.event.Event) -> None: Responsible for reacting to user input. It is recommended to use Python's structural pattern matching (match event:) to handle different event types like tcod.event.Quit or tcod.event.KeyDown.
    import attrs
    import tcod.console
    import tcod.event
    
    @attrs.define()
    class ExampleState:
        player_x: int
        player_y: int
    
        def on_draw(self, console: tcod.console.Console) -> None:
            console.print(self.player_x, self.player_y, "@")
    
        def on_event(self, event: tcod.event.Event) -> None:
            match event:
                case tcod.event.Quit():
                    raise SystemExit
                case tcod.event.KeyDown(sym=tcod.event.KeySym.LEFT):
                    self.player_x -= 1
                # ... other keys
  8. Identify keyboard event types using KeySym, Scancode, and Modifier

    main

    When handling keyboard events, tcod provides three distinct ways to identify keys:

    • KeySym: Represents keys based on their character glyph (e.g., the 'A' key). This is typically used for text input or standard game controls.
    • Scancode: Represents keys based on their physical location on the keyboard. This is useful for controls that should remain consistent regardless of the user's keyboard layout (e.g., WASD movement).
    • Modifier: Represents keyboard modifier keys like Shift, Ctrl, or Alt.
  9. Implement Menu UI with MenuItem and ListMenu

    main

    To create a menu system, you can implement a protocol-based approach using MenuItem and ListMenu.

    • MenuItem Protocol: Defines the interface for menu items. Any class implementing this must provide on_event(event) to handle interactions and on_draw(console, x, y, highlight) to render the item.
    • SelectItem: A concrete implementation of MenuItem that represents a clickable/selectable label. It triggers a callback when the user presses RETURN, RETURN2, KP_ENTER, or performs a MouseButtonUp with the LEFT button.
    • ListMenu: A State subclass that manages a collection of MenuItem objects. It handles navigation via DIRECTION_KEYS, mouse motion for selection, and provides an on_cancel method (typically returning Pop()) triggered by ESCAPE or a right-click.
    from typing import Protocol
    import tcod.console
    import tcod.event
    from game.state import State, StateResult
    
    class MenuItem(Protocol):
        def on_event(self, event: tcod.event.Event) -> StateResult:
            ...
        def on_draw(self, console: tcod.console.Console, x: int, y: int, highlight: bool) -> None:
            ...
    
    class SelectItem: # Implementation of MenuItem
        def on_event(self, event: tcod.event.Event) -> StateResult:
            # Handles RETURN or MouseButton.LEFT
            ...
        def on_draw(self, console: tcod.console.Console, x: int, y: int, highlight: bool) -> None:
            # Renders the label
            ...
  10. Manage game states using a stack (Pushdown Automata)

    main

    Representing states as a stack (a list where the last item is the active state) allows you to implement features like popup windows, sub-menus, or prompts easily. When a new state is Pushed, it sits on top of the previous state; when it is Poped, the previous state becomes active again.

    To implement this, maintain a global list of states (e.g., g.states: list[State]) and use a state transition function to process StateResult objects.

  11. Handle events in tcod

    main

    tcod provides two primary ways to handle events in your main loop:

    1. Blocking Loop: Use tcod.event.wait() to pause execution until at least one event is processed. This is efficient for turn-based games.
    2. Non-blocking Loop: Use tcod.event.get() to retrieve all pending events and continue execution immediately. This is necessary for real-time games.

    Important: Always call context.convert_event(event) on received events. This method translates raw window events into tcod events with correct tile coordinates for mouse interactions.