-
-
Notifications
You must be signed in to change notification settings - Fork 0
Getting Started
This page is the shortest reliable path from package install to your first successful grid lookup.
The default and recommended model is:
- create a
GridWorld - add one or more grids to that world
- resolve positions and apply mutations against that same world
Keep these rules in mind before writing any code:
-
GridWorldis the runtime owner of grid state. -
GridConfigurationis input data. Bounds are snapped when a world normalizes and registers the grid. - Core grid math uses
FixedMathSharptypes such asFixed64andVector3d. - Dispose or reset a world explicitly when you need a clean boundary.
dotnet add package GridForgeGridForge brings in its core math and collection dependencies through NuGet, so you do not need to wire those up manually in a normal .NET project.
Most first-use examples will start with these imports:
using System;
using FixedMathSharp;
using GridForge;
using GridForge.Configuration;
using GridForge.Grids;
using SwiftCollections.Diagnostics;GridWorld owns voxel size, spatial hashing, active grids, and top-level world-space lookup for one isolated world.
using GridWorld world = new GridWorld();This uses the library defaults:
- Voxel size:
1 - Spatial hash cell size:
50
GridConfiguration defines the world-space bounds of the grid plus the scan-cell size used for scan overlays.
GridConfiguration config = new GridConfiguration(
new Vector3d(-10, 0, -10),
new Vector3d(10, 0, 10));
if (!world.TryAddGrid(config, out ushort gridIndex))
throw new InvalidOperationException("Failed to add grid.");
VoxelGrid grid = world.ActiveGrids[gridIndex];
Console.WriteLine($"Grid {grid.GridIndex}");
Console.WriteLine($"Bounds: {grid.BoundsMin} -> {grid.BoundsMax}");
Console.WriteLine($"Dimensions: {grid.Width} x {grid.Height} x {grid.Length}");Notes:
- Bounds are inclusive. With a voxel size of
1, a grid from-10to10spans21voxels on that axis. - The default
scanCellSizeis8, and it is measured in voxels, not world units. - The world normalizes and snaps bounds during registration using that world's voxel size.
Once a grid is registered, the most common runtime lookup is resolving a world position into both the containing grid and the voxel at that position.
Vector3d queryPosition = new Vector3d(2, 0, -3);
if (world.TryGetGridAndVoxel(queryPosition, out VoxelGrid resolvedGrid, out Voxel voxel))
{
Console.WriteLine($"Grid: {resolvedGrid.GridIndex}");
Console.WriteLine($"Voxel index: {voxel.Index}");
Console.WriteLine($"Voxel world position: {voxel.WorldPosition}");
Console.WriteLine($"Blocked: {voxel.IsBlocked}");
Console.WriteLine($"Occupied: {voxel.IsOccupied}");
}Use these helpers based on what you need:
-
world.TryGetGrid(...)when you only need the containing grid -
world.TryGetVoxel(...)when you only need the voxel -
world.TryGetGridAndVoxel(...)when you need both in one lookup
When you need finer spatial resolution, configure the world up front and then create grids against that setup.
using GridWorld fineWorld = new GridWorld((Fixed64)0.5, spatialGridCellSize: 64);
GridConfiguration fineGrid = new GridConfiguration(
new Vector3d(-4, 0, -4),
new Vector3d(4, 0, 4),
scanCellSize: 4);Practical rule of thumb:
- Voxel size controls world-space precision.
- Scan cell size controls how many voxels are grouped together for scan queries.
GridForge logging is routed through GridForgeLogger. By default, the library emits Warning and Error level messages.
GridForgeLogger.MinimumLevel = DiagnosticLevel.Info;
GridForgeLogger.LogHandler = (level, message, source) =>
{
Console.WriteLine($"{level} [{source}] {message}");
};For diagnostics in library or tool code, use interpolated helper calls such as GridForgeLogger.Channel.Warn($"..."); disabled diagnostic levels skip formatted expression evaluation.
Because a GridWorld owns mutable runtime state, cleanup should be deliberate.
world.Reset(); // Clears registered grids but keeps the world active
world.Reset(deactivate: true); // Clears state and marks the world inactiveIn most application code and tests, using GridWorld world = new GridWorld(); is simpler and safer.
- Reusing one world across unrelated scenarios without a matching reset or disposal
- Forgetting that bounds are snapped to the world's voxel size
- Treating
scanCellSizeas a world-unit measurement instead of a voxel count - Using
TryGetGrid(...)when you actually needTryGetGridAndVoxel(...) - Holding onto pooled query results longer than the immediate operation
- Home for the project-wide mental model
- Core Concepts for the vocabulary of worlds, grids, voxels, scan cells, blockers, occupants, and partitions
- Common Workflows for task-oriented examples beyond the first grid
- Architecture Overview when you want to understand where behavior lives in the codebase