bracket-lib

repository·master·Indexed 23 days ago

https://github.com/amethyst/bracket-lib

A modular roguelike toolkit and general-purpose game logic library (formerly RLTK) providing tools for pathfinding, geometry, noise generation, and terminal rendering. It includes specialized crates such as bracket-color for RGB/HSV color management, bracket-geometry for 2D/3D coordinates and shapes, bracket-noise (a port of FastNoise), and bracket-embedding for embedding resources into binaries.

Tokens
36.1K
Snippets
56
Records
269
Agent score
81%

What's inside bracket-lib

  1. What is bracket-lib

    master

    bracket-lib (formerly known as RLTK - The RogueLike Toolkit) is a library designed primarily for building roguelikes and terminal-based games. It focuses on providing a user-friendly interface for beginners while offering the flexibility to scale into more advanced rendering techniques like layering and sprites.

    Key characteristics include:

    • Platform Agnostic Rendering: Provides virtual consoles across various platforms, including the web and major operating systems.
    • Architectural Flexibility: It does not enforce a specific game architecture. You can use Entity Component Systems (ECS), manual tick methods, or embedded scripting.
    • Extensibility: Supports advanced rendering features like layering and sprites without compromising its core goal of being an accessible teaching tool.
  2. What is bracket-terminal?

    master

    bracket-terminal is a library that provides a virtual ASCII/Codepage-437 terminal with support for tile graphics, multiple layers, and a built-in game loop. It is designed for grid-based games (like Roguelikes) and handles keyboard and mouse input.

    Key advantages over direct console rendering include:

    • Game-loop based: Ideal for frame-oriented programming.
    • Consistent Rendering: Codepage-437 emulation is sprite-based on graphical back-ends, ensuring consistent font rendering across platforms.
    • Layering: Supports multiple layers that can use different font or sprite files.
    • Post-processing: Includes retro screen effects like scan lines and screen burn.
  3. Configure back-ends for bracket-terminal

    master

    bracket-terminal supports several rendering back-ends. Note that feature names may differ depending on whether you are using bracket-terminal directly or via bracket-lib.

    Back-endDescriptionFeatures
    OpenGLDefault back-end; works on most platforms.Full support (layers, post-processing)
    WebGLFor WebAssembly (WASM) targets.Full support
    webgpuUses Vulkan, Metal, or WebGPU.Everything except post-processing
    crosstermRuns in existing native terminals.No graphical features (Note: use cross_term if using bracket-terminal directly)
    cursesRuns in *NIX or pdcurses on Windows.No graphical features

    Important Configuration: If you are using the webgpu back-end, you must add resolver = 2 to your Cargo.toml file to allow wgpu to perform platform selection.

  4. Implement Map Indexing with Algorithm2D and Algorithm3D

    master

    To use geometry and pathfinding functions with your own data structures, you must implement the Algorithm2D (for 2D grids) or Algorithm3D (for 3D grids) traits. This allows bracket-lib to interact with your data without knowing its internal storage format.

    By implementing Algorithm2D, you gain access to default implementations for:

    • in_bounds(Point): Checks if a point is within map dimensions.
    • point2d_to_index(Point) -> usize: Converts a 2D coordinate to an array index (assumes column-major striding).
    • index_to_point2d(usize) -> Point: Converts an array index back to a 2D coordinate.

    If your data uses a different striding logic, you can override these default implementations.

    struct TestMap{};
    impl BaseMap for TestMap {}
    impl Algorithm2D for TestMap{
        fn dimensions(&self) -> Point {
            Point::new(2, 2)
        }
    }
  5. What are Fancy Consoles

    master

    Fancy consoles act as a bridge between traditional gridded consoles and sprite graphics. Unlike standard consoles that use a fixed grid, fancy consoles are sparse, meaning they store characters to be rendered rather than a rigid grid. This allows for:

    • Smooth Movement: Characters can be placed at fractional coordinates using floating-point values.
    • Overlays: Characters can be overlaid on top of one another.
    • Transformations: Characters can be rotated and scaled independently.
    • Z-Ordering: You can control the rendering order of glyphs.
  6. How layering works in Bracket-terminal

    master

    Layering allows you to stack multiple consoles on top of one another. Each console can have its own tile size, offset, or scale.

    Rendering Order: Consoles are rendered in the order they are initialized. The first console created is the bottom-most layer, and each subsequent console is drawn on top of the previous ones. This allows you to separate concerns, such as using one tileset for the map, another for characters, and a text-based font for the HUD.

  7. How the GameState and main_loop work together

    master

    In bracket-lib, the application lifecycle is managed by the main_loop.

    • State Structure: You define a custom struct (e.g., State) to hold all data that must persist across frames (like player position, scores, or timers).
    • GameState Trait: You implement this trait for your state. The core method is tick(&mut self, ctx: &mut BTerm), which is called by the library every time a new frame is rendered.
    • Execution: Once main_loop(context, state) is called, the library takes control of the execution flow, repeatedly invoking your tick function and providing a BTerm context for rendering and input handling.
  8. Implement alpha blending and sparse consoles

    master
    You can achieve complex visual layering by enabling alpha blending on a sparse console that overlays a simple console. This allows for transparency and different font styles across layers. The alpha and sparse examples demonstrate these capabilities.
  9. Understand Console types in Bracket-terminal

    master

    A console represents a grid of cells addressed by x and y coordinates. Bracket-terminal provides several specialized console types depending on your rendering needs:

    • Simple Consoles: Store an internal vector representing every tile in the grid. Best for large layers that cover most of the screen. They can optionally have a background; if no background is provided, they do not overwrite content in layers beneath them.
    • Sparse Consoles: Store only a list of characters and their specific addresses. Best for drawing a few items on top of a simple console to save resources.
    • Fancy Consoles: Similar to sparse consoles but support advanced features like fractional coordinates and character rotation.
    • Sprite Consoles: Render sprites from a sprite sheet using pixel coordinates rather than tile coordinates.
    • Virtual Consoles: These are not rendered directly but can store massive amounts of data. They are useful for large logs or documentation, which can then be windowed and rendered to a visible console.
  10. Working with multiple console layers

    master
    When using multiple layers, you must explicitly activate the layer you wish to draw to using ctx.set_active_console(index). Most draw commands are sent to the currently active console. It is recommended to call ctx.set_active_console(0) at the end of your tick to ensure you return to the default layer for the next pass.