### Basic GoRogue Main Function Example Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/getting-started.md This code snippet demonstrates a basic usage of GoRogue by creating a map and printing it to the console. It serves as a verification step after installing the NuGet package. ```csharp var map = new GoRogue.Map(20, 10, 1, DistanceMeasurement.Chebyshev, PointHashers.DefaultHasher); // Fill map with "true" values map.ApplyToAll(cell => cell.IsWalkable = true); // Print map to console for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { Console.Write(map.GetCell(x, y).IsWalkable ? 'T' : 'F'); } Console.WriteLine(); } Console.WriteLine("\nMap generated successfully!"); ``` -------------------------------- ### List Shuffle Example (GoRogue 3) Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/2-to-3-upgrade-guide.md Shows how to shuffle a list using the new extension method syntax in GoRogue 3. Requires importing the ShaiRandom namespace. ```csharp using ShaiRandom; var myList = new List { 1, 2, 3, 4, 5 }; IEnhancedRandom myRNG = GlobalRandom.DefaultRNG; myList.Shuffle(myRNG); // myList is now shuffled ``` -------------------------------- ### Required Includes for GoRogue Example Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/getting-started.md These using statements are required for the GoRogue example code to function correctly. Ensure they are present in your Program.cs file. ```csharp using GoRogue; using GoRogue.MapGeneration; using GoRogue.MapGeneration.Context; using GoRogue.MapGeneration.Steps; using SadRogue.Primitives.PointHashers; using System; using System.Collections.Generic; using System.Linq; ``` -------------------------------- ### Using Generation Steps for Map Creation Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/map-generation.md Demonstrates how to create a simple map generation algorithm by chaining built-in steps. This example generates rooms and then connects them with tunnels. ```csharp var generator = new Generator(new Random().NextLong()); generator.AddSteps ( DefaultAlgorithms.Rooms(new RectanglesToAreas(null), new RectanglesToAreas(null)), DefaultAlgorithms.ConnectRooms(new RectanglesToAreas(null), new RectanglesToAreas(null)) ); generator.GenerateSafe(new RegenMapConfig( new BasicMapGenContext(new Rectangle(0, 0, 50, 50)), new DefaultMapGenState() )); ``` -------------------------------- ### Creating a Custom Grid View with GridViewBase Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/grid-view-concepts.md This example demonstrates how to create a custom grid view by inheriting from GridViewBase and implementing the Point-based indexer. ```csharp using GoRogue.MapViews; using SadRogue.Primitives; public class CustomGridView : GridViewBase { public override int Width { get; } public override int Height { get; } public CustomGridView(int width, int height) { Width = width; Height = height; } public override int this[Point pos] { get { // Implement custom logic here // Example: return a value based on coordinates return pos.X + pos.Y * Width; } } } ``` -------------------------------- ### Demonstrating Viewport Usage with GoalMap Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/grid-view-concepts.md This example shows how to use a Viewport to create a GoalMap on a smaller portion of a larger grid view, highlighting viewport semantics and limitations. ```csharp using GoRogue.GameFramework; using GoRogue.MapGeneration; using GoRogue.MapGeneration.Context; using GoRogue.MapViews; using SadRogue.Primitives; // Assume Map is a GoRogue.Map type // Assume GoalMap is a GoRogue.MapGeneration.GoalMap type // Create a large map var map = new Map(100, 100, 1, DistanceMeasurement.Chebyshev, فونی: null); // Add some walls to the map for (int x = 0; x < map.Width; x++) { map.Set(x, 0, true); map.Set(x, map.Height - 1, true); } for (int y = 0; y < map.Height; y++) { map.Set(0, y, true); map.Set(map.Width - 1, y, true); } // Create a viewport for a 20x20 area in the center of the map var viewport = new Viewport(map, new Rectangle(40, 40, 20, 20)); // Create a GoalMap for the viewport var goalMap = new GoalMap(viewport, (pos) => !map[pos], DistanceMeasurement.Chebyshev); // The goalMap now contains distances from the nearest wall within the viewport's coordinate space. // Note that goalMap[x, y] will access the viewport's coordinate space, not the original map's. // To access the original map, you would need to translate coordinates: // var originalMapValue = map[viewport.TranslatePoint(new Point(x, y))]; ``` -------------------------------- ### Creating a Custom Grid View with GridView1DIndexBase Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/grid-view-concepts.md This example shows how to create a custom grid view by inheriting from GridView1DIndexBase and implementing the 1D indexer. ```csharp using GoRogue.MapViews; using SadRogue.Primitives; public class CustomGridView1D : GridView1DIndexBase { public override int Width { get; } public override int Height { get; } public CustomGridView1D(int width, int height) { Width = width; Height = height; } public override int this[int index] { get { // Implement custom logic here based on the 1D index // Example: return a value based on the index return index; } } } ``` -------------------------------- ### Create and Configure GoRogue Project with Dotnet CLI Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/getting-started.md Commands to create a new .NET console project and install the GoRogue NuGet package. Ensure you specify the version for prerelease packages. ```bash dotnet new console -o GoRogueTestProject cd GoRogueTestProject dotnet add package GoRogue -v 3.0.0-beta08 ``` -------------------------------- ### Required GoRogue Using Statements Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/getting-started.md These 'using' statements are necessary for the provided GoRogue code examples to function correctly. ```csharp using GoRogue; using GoRogue.MapGeneration; using GoRogue.MapGeneration.Contexts; ``` -------------------------------- ### Effect Triggers and Durations Example Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/effects-system.md Demonstrates creating an EffectTrigger with instantaneous, damage-over-time, and infinite damage-over-time effects. Use this to manage and apply various types of effects to entities. ```csharp var monster = new BasicMonster(new Coord(10, 10)); // Instantaneous effect var instantaneousDamageEffect = new Damage(5); var instantaneousTrigger = new EffectTrigger(instantaneousDamageEffect); Console.WriteLine("Triggering instantaneous effect..."); instantaneousTrigger.TriggerEffects(monster); Console.WriteLine($"An effect triggered; monster now has {monster.HP} HP."); // Damage-over-time effects var damageOverTimeEffect = new Damage(5, 3); var infiniteDamageEffect = new Damage(5, -1); var durationTrigger = new EffectTrigger(damageOverTimeEffect, infiniteDamageEffect); Console.WriteLine("\nAdded some duration-based effects; current effects: " + string.Join(", ", durationTrigger.ActiveEffects.Select(e => e.ToString()))); for (int i = 1; i <= 3; i++) { Console.WriteLine($"Press enter to trigger round {i}:"); Console.ReadLine(); Console.WriteLine($"Triggering round {i}...."); durationTrigger.TriggerEffects(monster); Console.WriteLine($"Current Effects: [" + string.Join(", ", durationTrigger.ActiveEffects.Select(e => e.ToString())) + "]"); } Console.WriteLine($"Current Effects: [" + string.Join(", ", durationTrigger.ActiveEffects.Select(e => e.ToString())) + "]"); Console.WriteLine("Press enter to trigger round 4:"); Console.ReadLine(); Console.WriteLine("Triggering round 4...."); durationTrigger.TriggerEffects(monster); Console.WriteLine($"Current Effects: [" + string.Join(", ", durationTrigger.ActiveEffects.Select(e => e.ToString())) + "]"); ``` -------------------------------- ### RNG Extensions for Custom Types Example (GoRogue 3) Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/2-to-3-upgrade-guide.md Illustrates how to use random-oriented methods on GoRogue-defined types in GoRogue 3. Requires importing the ShaiRandom.Generators namespace. ```csharp using ShaiRandom.Generators; var myList = new List { 1, 2, 3, 4, 5 }; var myRect = new Rectangle(0, 0, 10, 10); IEnhancedRandom myRNG = GlobalRandom.DefaultRNG; var itemFromList = myList.RandomElement(myRNG); var positionFromRect = myRect.RandomPosition(myRNG); ``` -------------------------------- ### GetFirstOrNew Component Example Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/map-generation.md Demonstrates using GenerationContext.GetFirstOrNew to retrieve an existing component or create and add a new one if it's not present. Useful when a generation step requires a component for output but doesn't need its initial data. ```csharp public class MyGenerationStep : GenerationStep { public override IEnumerable OnPerform(GenerationContext context) { // Get the map view component, or create and add one if it doesn't exist. var mapView = context.GetFirstOrNew(() => new MapNavigationView(context.Map.Width, context.Map.Height)); // Get the room list component, or create and add one if it doesn't exist. var roomList = context.GetFirstOrNew(() => new RoomList()); // ... generation logic using mapView and roomList ... yield break; // No stages in this example } } ``` -------------------------------- ### LambdaGridView Example: Tile Array to Grid View Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/grid-view-concepts.md Demonstrates using LambdaGridView to create a grid view from an array of tile structures. Be mindful of performance implications as the provided function is called for every grid access. ```csharp var tiles = new Tile[100]; // ... initialize tiles ... var gridView = new LambdaGridView(new Point(10, 10), pos => tiles[pos.X + pos.Y * 10]); // Accessing a tile value Tile tile = gridView[new Point(5, 5)]; ``` -------------------------------- ### Basic Damage Effect Example Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/effects-system.md Defines a simple `Effect` subclass to apply damage to a `Monster`'s HP. This example demonstrates subclassing `Effect` and implementing the `OnTrigger` method for a basic damage effect. ```csharp public class DamageEffect : Effect { public int DamageAmount { get; private set; } public DamageEffect(string name, int duration, int damageAmount) : base(name, duration) { DamageAmount = damageAmount; } protected override void OnTrigger(IStep step) { // In a real game, you'd likely have a way to get the target of the effect. // For this example, we'll assume a global or easily accessible target. // For demonstration purposes, let's assume a Monster class exists with an HP field. // Example: // Monster target = GetTarget(); // target.HP -= DamageAmount; // For this example, we'll just print to console. System.Console.WriteLine($"Applying {DamageAmount} damage. Remaining duration: {RemainingDuration}"); } } // Example usage: // var damageEffect = new DamageEffect("Minor Damage", EffectDuration.Instant, 10); // damageEffect.Trigger(); // Triggers the effect immediately // var lingeringDamageEffect = new DamageEffect("Burn", 5, 5); // var trigger = new EffectTrigger(); // trigger.Add(lingeringDamageEffect); // for (int i = 0; i < 6; i++) // Trigger 6 times to show duration decrease and expiry // { // trigger.TriggerEffects(); // } ``` -------------------------------- ### Implement 1D Indexer for Custom IMapView Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/1-to-2-upgrade-guide.md Implement the 1D indexer for custom IMapView or ISettableMapView classes to support 1D array access. This example shows how to delegate to a 2D indexer. ```CSharp class MyMapView : IMapView { /* Existing functions from implementation using GoRogue 1.0 here */ public bool this[int array1DIndex] => this[Coord.ToCoord(array1DIndex, Width)]; } ``` -------------------------------- ### ArchivalWrapper Example Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/2-to-3-upgrade-guide.md Demonstrates how ArchivalWrapper can be used to reproduce random number sequences for debugging and testing. It wraps an existing random number generator and allows for the creation of a KnownSeriesRandom instance that mirrors the generator's output. ```csharp var rng = new ArchivalWrapper(new FileRandom("myseed.txt")); // Use rng in some algorithm var value1 = rng.RandomInt(); var value2 = rng.RandomInt(); // Create a KnownSeriesRandom that will produce the exact same sequence var reproducibleRng = rng.CreateKnownSeriesRandom(); // Verify the sequence Assert.AreEqual(value1, reproducibleRng.RandomInt()); Assert.AreEqual(value2, reproducibleRng.RandomInt()); ``` -------------------------------- ### LambdaTranslationGridView Example: Tile to Terrain Type Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/grid-view-concepts.md Shows how to use LambdaTranslationGridView to map values from one type to another. This example translates Tile instances to a terrain type for a grid view. ```csharp var tiles = new Tile[100]; // ... initialize tiles ... var translationView = new LambdaTranslationGridView(new Point(10, 10), (pos, tile) => tile.Terrain); // Accessing a translated terrain value TerrainType terrain = translationView[new Point(5, 5)]; ``` -------------------------------- ### Basic GoRogue Initialization in Program.cs Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/getting-started.md Replace the Main function in Program.cs with this code to initialize GoRogue and demonstrate basic grid creation. Ensure required 'using' statements are present. ```csharp using GoRogue; using GoRogue.MapGeneration; using GoRogue.MapGeneration.Contexts; Console.WriteLine("Creating map..."); // Create a new map generation context var context = new MapGenerationContext(10, 10); // Add a basic map generator to the context context.AddStep(BasicGenerator.Create); // Generate the map context.GenerateMap(); // Get the generated map var map = context.GetMap(); Console.WriteLine("Map created!"); // Print the map to the console for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { Console.Write(map.Get(x, y) ? "T" : "F"); } Console.WriteLine(); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); ``` -------------------------------- ### Sense Mapping with Recursive Shadowcasting and Ripple Sources Source: https://context7.com/chris3606/gorogue/llms.txt Demonstrates setting up a SenseMap with multiple sources (torchlight and lantern) and calculating visibility. Shows how to read results, update source positions, and remove sources. ```csharp using GoRogue.SenseMapping; using GoRogue.SenseMapping.Sources; using SadRogue.Primitives; using SadRogue.Primitives.GridViews; // Resistance map: 0.0 = no resistance (open), 1.0 = fully blocking var resistance = new ArrayView(30, 20); foreach (var pos in resistance.Positions()) resistance[pos] = 0.0; resistance[10, 5] = 1.0; // a wall // Create the sense map var senseMap = new SenseMap(resistance); // Add a torchlight source using recursive shadow-casting var torch = new RecursiveShadowcastingSenseSource( position: new Point(8, 8), radius: 6, distanceCalc: Distance.Chebyshev); senseMap.AddSenseSource(torch); // Optional: second source (ripple algorithm) var lantern = new RippleSenseSource( position: new Point(20, 10), radius: 5, distanceCalc: Distance.Chebyshev, rippleType: RippleType.Loose); senseMap.AddSenseSource(lantern); // Calculate — can run sources in parallel with ParallelCalculate = true senseMap.ParallelCalculate = true; senseMap.Calculate(); // Read results double brightness = senseMap.ResultView[new Point(8, 8)]; // 1.0 IEnumerable lit = senseMap.CurrentSenseMap; // all lit positions IEnumerable newlyLit = senseMap.NewlyInSenseMap; // lit since last calc // Move source and recalculate torch.Position = new Point(12, 8); senseMap.Calculate(); IEnumerable nowDark = senseMap.NewlyOutOfSenseMap; // Remove source senseMap.RemoveSenseSource(lantern); ``` -------------------------------- ### Basic Factory Usage with LambdaBlueprints Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/factories.md Demonstrates the simplest way to use the factory system by creating a `Factory` with `LambdaFactoryBlueprint` instances. This is suitable when blueprints have no state or wrapper code. ```csharp var factory = new Factory(); factory.RegisterBlueprint(new LambdaFactoryBlueprint("Orc", () => "An Orc")); factory.RegisterBlueprint(new LambdaFactoryBlueprint("Goblin", () => "A Goblin")); string orc = factory.Create("Orc"); // "An Orc" string goblin = factory.Create("Goblin"); // "A Goblin" ``` -------------------------------- ### Generate Map Stage-by-Stage Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/map-generation.md Use Generator.ConfigAndGetStageEnumeratorSafe() to get an enumerator for executing generation steps one at a time. This method handles RegenerateMapException and ensures steps are added. ```csharp foreach (var stage in generator.ConfigAndGetStageEnumeratorSafe()) { // Perform actions based on the current stage // e.g., check if map has changed, react to specific stages } ``` -------------------------------- ### Initialize and Manage Map with GameObjects Source: https://context7.com/chris3606/gorogue/llms.txt Create a Map with specified dimensions and layers, then populate it with terrain and entities. ```csharp using GoRogue.GameFramework; using SadRogue.Primitives; using SadRogue.Primitives.GridViews; // Create a 50×30 map: 1 terrain layer + 2 entity layers, 8-directional var map = new Map( width: 50, height: 30, numberOfEntityLayers: 2, distanceMeasurement: Distance.Chebyshev); // --- Terrain (layer 0) --- // Fill with wall tiles first for (int x = 0; x < 50; x++) for (int y = 0; y < 30; y++) { var wall = new GameObject(new Point(x, y), layer: 0, isWalkable: false, isTransparent: false); map.SetTerrain(wall); } // Carve out a room for (int x = 1; x < 10; x++) for (int y = 1; y < 10; y++) { var floor = new GameObject(new Point(x, y), layer: 0, isWalkable: true, isTransparent: true); map.SetTerrain(floor); } // --- Entities (layer 1+) --- var player = new GameObject(new Point(5, 5), layer: 1, isWalkable: false, isTransparent: true); map.AddEntity(player); var monster = new GameObject(new Point(7, 7), layer: 1, isWalkable: false, isTransparent: true); map.AddEntity(monster); // Move entity player.Position = new Point(6, 5); // FOV — PlayerFOV auto-updates PlayerExplored map.PlayerFOV.Calculate(player.Position, radius: 8, Radius.Square); bool isVisible = map.PlayerFOV.BooleanResultView[new Point(7, 7)]; // Pathfinding var path = map.AStar.ShortestPath(player.Position, monster.Position); // Query entities at a position foreach (var obj in map.GetObjectsAt(new Point(6, 5))) Console.WriteLine(obj.Layer); // Remove entity map.RemoveEntity(monster); ``` -------------------------------- ### Factory Usage with Subclassed Factory Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/factories.md Shows how to create a subclass of `Factory` and use its methods as creation functions. This approach is cleaner for more complex creation logic. ```csharp public class MyEnemyFactory : Factory { public MyEnemyFactory() { RegisterBlueprint(new LambdaFactoryBlueprint("Orc", OrcCreator)); RegisterBlueprint(new LambdaFactoryBlueprint("Goblin", GoblinCreator)); } private string OrcCreator() => "An Orc"; private string GoblinCreator() => "A Goblin"; } var factory = new MyEnemyFactory(); string orc = factory.Create("Orc"); // "An Orc" ``` -------------------------------- ### Parent-Aware Component Setup Source: https://context7.com/chris3606/gorogue/llms.txt Illustrates how components inheriting from ParentAwareComponentBase automatically manage their Parent property. The OnAdded and OnRemoved methods are called when the component is attached to or detached from an entity. ```csharp // --- Parent-aware components --- // Components inheriting ParentAwareComponentBase get their // Parent property set automatically when added. class LoggingComponent : ParentAwareComponentBase { protected override void OnAdded() => Console.WriteLine($"Attached to {Parent!.Name}"); protected override void OnRemoved() => Console.WriteLine("Detached."); } var entity = new MyEntity(); entity.GoRogueComponents.Add(new LoggingComponent()); // prints "Attached to ..." ``` -------------------------------- ### Subclass TranslationGridView Example: Tile to Terrain Type Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/grid-view-concepts.md Illustrates implementing custom translation logic by subclassing TranslationGridView. This approach provides an alternative to LambdaTranslationGridView for more complex translation scenarios. ```csharp public class MyTerrainTranslationView : TranslationGridView { public MyTerrainTranslationView(ISettableGridView source) : base(source) { } protected override TerrainType TranslationGet(Tile value) { return value.Terrain; } } // Usage: var tiles = new Tile[100]; // ... initialize tiles ... var gridView = new ArrayView(new Point(10, 10), tiles); var translationView = new MyTerrainTranslationView(gridView); TerrainType terrain = translationView[new Point(5, 5)]; ``` -------------------------------- ### Create Map Instance Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/fov.md Generates a sample map with walls on the edges and floors in the interior. This map structure is used to demonstrate FOV calculations. ```csharp var map = new Map(11, 11); // Walls for (int i = 0; i < map.Width; i++) { map[i, 0] = new Tile { IsTransparent = false }; map[i, map.Height - 1] = new Tile { IsTransparent = false }; } for (int i = 0; i < map.Height; i++) { map[0, i] = new Tile { IsTransparent = false }; map[map.Width - 1, i] = new Tile { IsTransparent = false }; } // Floors for (int x = 1; x < map.Width - 1; x++) { for (int y = 1; y < map.Height - 1; y++) { map[x, y] = new Tile { IsTransparent = true }; } } ``` -------------------------------- ### Register and Create Objects with Factory Source: https://context7.com/chris3606/gorogue/llms.txt Use Factory to register named blueprints and create instances. Implement IFactoryObject to automatically set DefinitionID. ```csharp using GoRogue.Factories; // --- Factory (no creation-time arguments) --- record Tile(char Glyph, bool Walkable) : IFactoryObject { public string DefinitionID { get; set; } = ""; } var tileFactory = new Factory { new LambdaFactoryBlueprint("Floor", () => new Tile('.', true)), new LambdaFactoryBlueprint("Wall", () => new Tile('#', false)), new LambdaFactoryBlueprint("Water", () => new Tile('~', false)), }; Tile floor = tileFactory.Create("Floor"); Console.WriteLine(floor.DefinitionID); // "Floor" (set automatically) ``` -------------------------------- ### Accessing FOV Results as Booleans Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/fov.md Use the BooleanResultView property to get a grid view indicating visibility. True means visible, false means not visible. This is useful for direct display or logic. ```csharp var fov = new FOV(map, new Point(5, 5)); fov.CalculateFOV(); // Access results as a boolean grid foreach (var pos in map.Tiles.Enumerate()) { if (fov.BooleanResultView[pos]) { Console.Write("* "); } else { Console.Write("- "); } if (pos.X == map.Width - 1) Console.WriteLine(); } ``` -------------------------------- ### A* Pathfinding on a Grid Source: https://context7.com/chris3606/gorogue/llms.txt Find the shortest path between two points on a grid using A*. Supports 4/8-way movement, optional tile weights, and custom heuristics. Ensure the walkability map is correctly set up. ```csharp using GoRogue.Pathing; using SadRogue.Primitives; using SadRogue.Primitives.GridViews; // Build a walkability map (true = walkable) var walkable = new ArrayView(20, 20); foreach (var pos in walkable.Positions()) walkable[pos] = true; walkable[10, 5] = false; // place a wall // 8-directional pathfinding var astar = new AStar(walkable, Distance.Chebyshev); Path? path = astar.ShortestPath(new Point(0, 0), new Point(19, 19)); if (path != null) { Console.WriteLine($"Path length: {path.Length}"); Console.WriteLine($"Path cost: {path.Cost}"); foreach (Point step in path.Steps) // excludes start Console.WriteLine(step); foreach (Point step in path.StepsWithStart) // includes start Console.WriteLine(step); path.Reverse(); // O(1) reversal } // With weighted tiles (e.g. difficult terrain = weight 2.0) var weights = new ArrayView(20, 20); foreach (var pos in weights.Positions()) weights[pos] = 1.0; weights[5, 5] = 2.0; // slow tile var astarWeighted = new AStar(walkable, Distance.Chebyshev, weights, minimumWeight: 1.0); Path? weightedPath = astarWeighted.ShortestPath(0, 0, 19, 19); ``` -------------------------------- ### Configure Generation Step Parameters Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/map-generation.md Use C#'s initializer list syntax to set custom values for generation step parameters like `MinRooms` and `MaxRooms`. Improper values will raise an `InvalidConfigurationException` upon calling `generator.Generate`. ```csharp var generator = new RoomGenerationSettings() { MinRooms = 10, MaxRooms = 20, // ... other settings }; var mapGen = new MapGeneration(); mapGen.Add(new Rooms(generator)); // ... other steps ``` -------------------------------- ### Accessing Derived Types from Map in GoRogue 2.0 Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/1-to-2-upgrade-guide.md When retrieving objects from a Map in GoRogue 2.0, use the generic overload of 'GetObjects' to specify the desired derived type. This ensures you only get objects that can be cast to that type. ```C# foreach (var mObject in myMap.GetObjects(myPos)) ``` -------------------------------- ### Advanced Factory with Parameterized Creation Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/factories.md Demonstrates using `AdvancedFactory` to pass parameters to the creation process. The `Create` function accepts an additional parameter type, which is then passed to the blueprint. ```csharp public class AdvancedFactoryExample { public static void Run() { var factory = new AdvancedFactory(); factory.RegisterBlueprint(new LambdaAdvancedFactoryBlueprint("Player", (point) => $"Player at {point}")); string player = factory.Create(new Point(10, 20), "Player"); // "Player at (10, 20)" } } ``` -------------------------------- ### Custom Factory Blueprint Implementation Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/factories.md Illustrates creating a custom blueprint by subclassing `FactoryBlueprint` to handle state, advanced customization, or parameterization. This provides more control over the blueprint's behavior. ```csharp public class MyCustomBlueprint : FactoryBlueprint { private readonly int _strength; public MyCustomBlueprint(string type, int strength) : base(type) { _strength = strength; } public override string Create() => $"A creature of strength {_strength}"; } var factory = new Factory(); factory.RegisterBlueprint(new MyCustomBlueprint("StrongCreature", 100)); string creature = factory.Create("StrongCreature"); // "A creature of strength 100" ``` -------------------------------- ### Accessing DoubleResultView in GoRogue FOV Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/fov.md Use DoubleResultView to get a grid of double values representing FOV. Locations outside FOV return 0.0, the origin returns 1.0, and other visible locations return a value between 0.0 and 1.0, indicating proximity to the origin. This is useful for effects like "dimming" cells based on distance. ```csharp using GoRogue.FOV; // Assuming 'fov' is an instance of a class implementing IReadOnlyFOV // For example: // var map = new ArrayMap(11, 11); // var fov = new BasicFOV(map); // fov.Calculate(new Point(5, 5)); var doubleResultView = fov.DoubleResultView; ``` -------------------------------- ### Implement IGameObject with Backing Field Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/1-to-2-upgrade-guide.md Demonstrates how to implement the IGameObject interface by forwarding calls to a private backing field of type GameObject. This is useful when you cannot inherit directly from GameObject. ```CSharp class MyBaseObject : ClassINeedToInheritFrom, IGameObject { private IGameObject _backingField; public MyBaseObject(Coord pos, int layer, bool isStatic, bool isWalkable, bool isTransparent) { _backingField = new GameObject(pos, layer, this, isStatic, isWalkable, isTransparent) } /* Implements IGameObject by forwarding the function calls to the corresponding function in _backingField. * Many IDEs can generate these automatically. */ } ``` -------------------------------- ### Build and Use Dijkstra Maps (GoalMap/FleeMap) Source: https://context7.com/chris3606/gorogue/llms.txt Use GoalMap for entities to find paths towards a goal, and FleeMap to move away from threats. Requires a GridView of GoalState. Update the map when goals or obstacles change. ```csharp using GoRogue.Pathing; using SadRogue.Primitives; using SadRogue.Primitives.GridViews; // Build a GoalState map: Goal = target, Obstacle = wall, Clear = open floor var stateMap = new ArrayView(20, 20); foreach (var pos in stateMap.Positions()) stateMap[pos] = GoalState.Clear; stateMap[10, 10] = GoalState.Goal; // monster's target stateMap[5, 5] = GoalState.Obstacle; // wall var goalMap = new GoalMap(stateMap, Distance.Chebyshev); // Monster at (3,3) moves toward goal Direction nextStep = goalMap.GetDirectionOfMinValue(new Point(3, 3)); Console.WriteLine($"Move: {nextStep}"); // e.g. Direction.UpRight // Update after goal or obstacles change stateMap[10, 10] = GoalState.Clear; stateMap[15, 8] = GoalState.Goal; // goal moved goalMap.Update(); // recalculate everything (obstacles + goals changed) // goalMap.UpdatePathsOnly(); // faster — only goal positions changed // FleeMap: entity moves AWAY from all goals (treats them as threats) using var fleeMap = new FleeMap(goalMap, magnitude: 1.2); Direction fleeDir = fleeMap.GetDirectionOfMinValue(new Point(9, 9)); Console.WriteLine($"Flee: {fleeDir}"); // FleeMap auto-updates when goalMap.Update() is called ``` -------------------------------- ### Implementing NewlySeen and NewlyUnseen with Set Difference Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/fov.md Implement `NewlySeen` and `NewlyUnseen` by storing the previous FOV calculation's `HashSet` and using set difference logic. This requires overriding `OnReset` to manage the state transitions. ```C# private HashSet _currentFOV = new HashSet(); private HashSet _previousFOV = new HashSet(); public IEnumerable CurrentFOV => _currentFOV; // We can now implement NewlySeen and NewlyUnseen using set difference public override IEnumerable NewlySeen => _currentFOV.Where(pos => !_previousFOV.Contains(pos)); public override IEnumerable NewlyUnseen => _previousFOV.Where(pos => !_currentFOV.Contains(pos)); protected override void OnReset() { // Reset result views however is needed // Store previous FOV so we can calculate NewlySeen and NewlyUnseen (_previousFOV, _currentFOV) = (_currentFOV, _previousFOV); _currentFOV.Clear(); } ``` -------------------------------- ### Basic ComponentCollection Operations Source: https://context7.com/chris3606/gorogue/llms.txt Shows how to add, retrieve, and remove components from a ComponentCollection. Components can be retrieved by type or by an optional tag. Use 'GetFirst' for single components and 'GetAll' for multiple. ```csharp using GoRogue.Components; // --- Basic add / get / remove --- var components = new ComponentCollection(); var health = new HealthComponent(100); var stamina = new StaminaComponent(50); var equipped = new EquipmentComponent(); components.Add(health); components.Add(stamina, tag: "stamina"); components.Add(equipped, tag: "equipment"); // Retrieve by type (returns first, respecting ISortedComponent order) var hp = components.GetFirst(); // returns health // Retrieve by tag var stam = components.GetFirst("stamina"); // Check existence bool hasHp = components.Contains(); // true bool hasItem = components.Contains("tagged"); // false // Get all of a type IEnumerable all = components.GetAll(); // Remove components.Remove(equipped); components.Remove("stamina"); // remove by tag ``` -------------------------------- ### Map Generation Usings Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/map-generation.md Includes necessary namespaces for GoRogue map generation. ```csharp using GoRogue.MapGeneration; using GoRogue.MapGeneration.ContextComponents; using GoRogue.MapGeneration.Steps; using GoRogue.MapGeneration.Generators; using GoRogue.MapGeneration.IntGrid; using SadRogue.Primitives.GridViews; using SadRogue.Primitives; using System.Collections.Generic; using System.Linq; ``` -------------------------------- ### Component Inheritance and Interface Handling Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/1-to-2-upgrade-guide.md Illustrates how the component system handles inheritance and interfaces. Components of a derived type are correctly returned when requesting a base type or interface. ```CSharp interface IZ {} class A : IZ {} class B : A {} ``` -------------------------------- ### Using 1D Indexers with GoRogue Map Views Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/1-to-2-upgrade-guide.md Demonstrates how to use the new 1D indexers available on all IMapView and ISettableMapView implementations, including built-in types like ArrayMap and LambdaTranslationMap. This allows for array-style access to map elements using a calculated 1D index. ```CSharp ArrayMap boolMap = new ArrayMap(10, 10); int index = Coord.ToIndex(2, 3, boolMap.Width); // 1D index for position (2, 3) Console.WriteLine(boolMap[index]); // This indexer is present in all IMapViews and ISettableMapViews, not just ArrayMap LambdaTranslationMap intMap = new LambdaTranslationMap(boolMap, b => b ? 1 : 0); Console.WriteLine(intMap[index]); ``` -------------------------------- ### Pause Generation Step via Enumerable Source: https://github.com/chris3606/gorogue/blob/master/GoRogue.Docs/articles/howtos/map-generation.md Illustrates how to break a generation step into stages using C#'s yield return functionality. This allows pausing generation at specific points, useful for debugging or creating animations. The Generator.ConfigAndGenerateSafe method automatically executes all stages. ```csharp public class PlaceRoomsStep : GenerationStep { public override IEnumerable OnPerform(GenerationContext context) { var map = context.Map; var roomList = context.GetFirst(); for (int i = 0; i < 10; ++i) // Place 10 rooms { // ... logic to create and place a room ... // For simplicity, assume 'newRoom' is created and added to roomList // and its tiles are set on the map. Room newRoom = new Room(new Rectangle(10, 10, 5, 5)); // Example room roomList.Add(newRoom); // ... set tiles on map ... // Yield return after each room is placed to allow pausing. yield return newRoom; } } } ```