GoRogue Documentation

repository·master·Indexed 19 days ago

https://github.com/chris3606/gorogue

A library providing tools for building roguelike games. Documentation includes a comprehensive upgrade guide from version 1.x to 2.0, detailing breaking changes to Coord (now a value type), the refactored GameObject and Map systems using IGameObject, updated FOV input types, and the implementation of a type-safe component system via IHasComponents and ComponentContainer.

Tokens
25K
Snippets
55
Records
121
Agent score
68%

What's inside GoRogue

  1. What is GoRogue and its core purpose

    master

    GoRogue is a .NET Standard 2.1 library designed as a collection of tools, data structures, and algorithms for creating 2D grid-based games.

    Important Distinction: GoRogue is not a full game engine. It does not provide rendering or audio capabilities. It is intended to be paired with a framework or engine that handles those aspects (e.g., SadConsole, MonoGame, Unity, Godot, or Stride).

  2. Understand the GoRogue library design categories

    master

    GoRogue distinguishes between two main categories of features to balance flexibility with structured development:

    1. Core Features: Located in the root GoRogue namespace and its sub-namespaces (excluding GoRogue.GameFramework). These are generic data structures and algorithms (e.g., ISpatialMap implementations) designed to be minimally intrusive. They do not enforce a specific game architecture or data storage model, making them suitable for any game type.

    2. Game Framework Features: Located in the GoRogue.GameFramework namespace. These features combine core features into a coherent, concrete structure. They are designed to provide a ready-to-use framework that applies to many common game use cases.

  3. Implement Parent-Aware Components

    master

    To create components that are aware of the object they are attached to, use the interfaces and classes in the GoRogue.Components.ParentAware namespace.

    Key Types

    • IObjectWithComponents: Defines a GoRogueComponents property of type IComponentCollection. Use this for objects that own a component collection.
    • IParentAwareComponent: Specifies a Parent field of type object?.
    • ParentAwareComponentBase: A base class that implements IParentAwareComponent and provides events for attachment/detachment.
    • ParentAwareComponentBase<T>: A generic version that automatically casts the Parent field to type T, avoiding manual casting.

    Automatic Parent Assignment

    When constructing a ComponentCollection, you can pass an optional object? parameter. If provided, this object is automatically assigned to the Parent field of any IParentAwareComponent added to the collection. The Parent is set to null when the component is removed.

  4. Use translation steps to bridge data between generation steps

    master

    When custom or arranged generation steps use different data formats, you can use 'translation steps' to convert data from one component type to another. These steps are located in the GoRogue.MapGeneration.Steps.Translation namespace.

    For example, if one step produces an ItemList<Rectangle> and the next step requires an ItemList<Area>, you can insert a RectanglesToAreas translation step between them to ensure compatibility.

  5. Handle movement restrictions on Layer 0 (Terrain)

    master

    The IsStatic flag has been removed from GameObject.

    In GoRogue 3, movement restrictions for terrain are enforced by the Map itself:

    • If an object is on layer 0 of a map and you attempt to move it, the Map will throw an exception.
    • Objects on layer 0 that are not currently added to a Map can be moved freely.

    This change allows for more convenient object creation via factories, as you no longer need to know the exact position at construction time to set a static flag.

  6. How the Map Generation framework works

    master

    GoRogue's map generation system is built on a component-based architecture using a GenerationContext. The system consists of three main pillars:

    1. Framework: A flexible environment where you can develop arbitrary algorithms. It uses a ComponentCollection to manage map data, allowing steps to add or modify components without strict schema requirements.
    2. GenerationSteps: Self-contained units of logic (found in the GoRogue.MapGeneration.Steps namespace) that perform specific tasks like placing rooms or generating tunnels. A step's OnPerform method operates on a GenerationContext, reading existing components and adding or modifying others.
    3. Generator: A wrapper around a GenerationContext and a sequence of GenerationStep objects. When generator.Generate() is called, it executes the steps in the order they were added.

    Note on Safety: It is recommended to use generator.ConfigAndGenerateSafe(...) instead of Generate(). This method includes exception handling for RegenerateMapException. If a step fails and indicates an invalid map state, the generator will clean the data, recreate the steps, and attempt generation again.

  7. Manage effect lifecycles with EffectTrigger

    master

    An EffectTrigger acts as a managed container for Effect instances. It handles the execution and automatic removal of effects based on their duration.

    Key Functionalities:

    • Adding Effects: Use Add(Effect effect) to add an effect to the trigger. The effect will be executed the next time TriggerEffects() is called.
      • Note: Adding an effect with a duration of 0 (instant or already expired) will throw an exception.
    • Executing Effects: Call TriggerEffects() to execute all currently active effects in the list. This method:
      1. Calls Trigger() on each effect.
      2. Decrements durations.
      3. Removes effects whose duration has reached 0.
      4. Respects the cancelTrigger flag: if an effect sets this to true, no subsequent effects in that specific TriggerEffects() call will run.

    Duration Constants:

    When constructing an Effect, use these constants for the duration parameter:

    • EffectDuration.Instant: The effect executes once and does not use the duration system.
    • EffectDuration.Infinite: The effect stays in the EffectTrigger indefinitely until manually removed or its duration is set to 0 within its own OnTrigger implementation.
    EffectTrigger trigger = new EffectTrigger();
    trigger.Add(new DamageEffect(monster, 10));
    trigger.TriggerEffects();
  8. Understand the Refactored Effects System

    master

    The effects system has been moved to the GoRogue.Effects namespace and refactored to improve performance and usability.

    Standard Effects

    Effect and EffectTrigger no longer take type parameters.

    • Triggering: Effect.Trigger and Effect.OnTrigger now use an out bool parameter. Set this to true if you want to cancel the trigger.
    • Convenience: An overload of Effect.Trigger exists that takes no parameters for instantaneous effects where cancellation is not required.
    • Triggering multiple effects: EffectTrigger.TriggerEffects handles the internal boolean logic for you.

    Advanced Effects (for custom parameters)

    If you need to pass custom parameters to an effect (the functionality provided by Effect<T> in version 2), use the new advanced classes:

    • AdvancedEffect<TTriggerArgs>
    • AdvancedEffectTrigger<TTriggerArgs>

    These classes allow TTriggerArgs to be any type (value or reference) while maintaining the out bool cancellation mechanism.

  9. Configure SenseSource intensity and resistance

    master

    In GoRogue 2.0, SenseSource allows for arbitrary starting intensities.

    • Intensity: The Intensity property (defaults to 1.0) determines the starting strength of the source.
    • Resistance: Resistance maps can contain any positive double value.

    Behavior by Source Type:

    • RIPPLE (and variations): The resistance value is subtracted from the source value as it spreads. A source with an Intensity of 2.5 can pass through two cells with 1.0 resistance, but a third cell with 1.0 resistance will block it completely.
    • SHADOW: A cell blocks the source if its resistance value is greater than or equal to the source's starting Intensity. If the resistance is less than the Intensity, it does not block.
  10. Understand ShaiRandom bounded generation contracts

    master

    ShaiRandom uses an "inner/outer" bound model rather than a "min/max" model. This allows bounds to cross, which was not permitted in Troschuetz.

    Single Bound Functions

    If a function takes one bound, it is treated as an outer bound relative to 0:

    • bound > 0: Returns [0, bound)
    • bound == 0: Returns 0
    • bound < 0: Returns (bound, 0]

    Two Bound Functions

    If a function takes two bounds, the first is the inner and the second is the outer:

    • inner < outer: Returns [inner, outer)
    • inner == outer: Returns inner
    • inner > outer: Returns (outer, inner]

    Note on Inclusivity: The rules above apply to standard functions like NextInt. Functions with Inclusive or Exclusive in their name (e.g., NextInclusiveDouble) follow their own specific contracts defined in the API documentation.

  11. Use AutoSyncSpatialMaps for automatic position synchronization

    master

    In GoRogue 3, spatial maps can automatically keep an object's internal Position property in sync with the map's internal record. To use this, ensure your objects implement the IPositionable interface, which requires a Position property and specific events that fire when the position changes.

    Available auto-syncing map variants:

    • AutoSyncSpatialMap
    • AutoSyncMultiSpatialMap
    • AutoSyncLayeredSpatialMap

    When using these, you can modify the Position property directly or use the spatial map's Move functions; both actions will update both the object's field and the map's record automatically.