SetNet.GeoData 1.2.0

dotnet add package SetNet.GeoData --version 1.2.0
                    
NuGet\Install-Package SetNet.GeoData -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SetNet.GeoData" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SetNet.GeoData" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="SetNet.GeoData" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SetNet.GeoData --version 1.2.0
                    
#r "nuget: SetNet.GeoData, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SetNet.GeoData@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SetNet.GeoData&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=SetNet.GeoData&version=1.2.0
                    
Install as a Cake Tool

SetNet.GeoData

Server-side world geometry for SetNet — walkability, line-of-sight, pathable queries.

The server's knowledge of the scene: where can you stand, what blocks sight or movement, where is the ground. One interface, IGeoData, backed by three implementations:

  • GridGeoData — a 2.5D nav-grid (walkable/blocked cells + ground height). Cheap, and easy to bake automatically from colliders. Single-surface (one height per cell).
  • LayeredGridGeoData — a multi-storey nav-grid (the classic Lineage-2-style "geodata"): a cell can hold several stacked walkable layers, so you get floors, bridges and overpasses without a nav-mesh. Every query is height-aware. This is the grid answer to етажність.
  • NavMeshGeoData — a nav-mesh (triangles + adjacency). Precise for irregular 3D worlds; exposes portals so SetNet.PathFinding can funnel a smooth path. Also Y-aware for multi-storey.
IGeoData geo = GeoDataFile.LoadFromFile("world.geo");   // baked once (see SetNet.GeoData.Unity)

bool stand   = geo.IsWalkable(pos);
bool canSee  = geo.LineOfSight(mob, player);       // "can A see B"
bool canWalk = geo.CanWalkStraight(from, to);      // "can I walk straight there"
Vec3 snapped = geo.SampleNearestWalkable(offMesh);
RaycastHit h = geo.Raycast(origin, dir, 50f);

Build a grid by hand (or from a baker):

var geo = new GridGeoDataBuilder(origin: Vec3.Zero, cellSize: 1f, width: 64, depth: 64)
    .Fill((x, z) => (walkable: !IsWall(x, z), blocked: IsWall(x, z), height: 0f))
    .Build();
GeoDataFile.SaveToFile(geo, "world.geo");

Or a nav-mesh from triangles (e.g. an exported engine NavMesh):

var geo = NavMeshGeoData.FromTriangles(vertices, triangleIndices);

Height, stairs & multi-storey (етажність)

  • Height differences & slopes — every representation carries real heights. SampleHeight returns the ground Y; MaxStep bounds how big a height change between adjacent cells still counts as walkable.

  • Stairs / steps — a staircase is just a run of surfaces each within MaxStep of the next (grid/layered grid), or connected triangles (nav-mesh). CanWalkStraight enforces the step limit so an agent won't "walk straight" up a cliff.

  • Multi-storey / overhangs on a GRID (a bridge over a road, a building's floors stacked at the same XZ) — use LayeredGridGeoData. Each cell holds one or more height layers; every query carries the agent's Y and resolves to the layer nearest that height, so an agent on the ground floor never snaps onto the deck above it. This is how L2-style servers do floors without a nav-mesh:

    var geo = new LayeredGridGeoDataBuilder(Vec3.Zero, cellSize: 1f, width: 64, depth: 64)
        .SetMaxStep(1.1f)                 // one stair step
        .AddLayer(cx, cz, height: 0f)     // ground floor at this cell
        .AddLayer(cx, cz, height: 4f)     // upper storey stacked at the SAME cell
        // .SetWall(cx, cz)               // a full-height wall (blocks sight + movement at every height)
        .Build();
    
    geo.SampleHeight(new Vec3(x, 0.1f, z));   // -> 0   (nearest layer to y=0.1 = ground)
    geo.SampleHeight(new Vec3(x, 3.8f, z));   // -> 4   (nearest layer to y=3.8 = upper storey)
    Pathfinding.For(geo).FindPath(groundPos, upperPos);   // climbs the stairs between floors
    

    Movement/height queries are fully layer-accurate. Line-of-sight is occluded by wall cells and by any floor whose height lies strictly between the two endpoints and that the ray passes through (so you can't see a target on the storey above through the floor) — for arbitrary opaque ceilings/soffits use a nav-mesh.

  • Multi-storey on a NAV-MESHNavMeshGeoData is Y-aware too: TriangleAt/SampleHeight/IsWalkable resolve to the floor nearest the query's Y, and CanWalkStraight (bounded by WalkYTolerance) won't jump between storeys through the air. Bake it from an engine NavMesh (which already models floors) via SetNet.GeoData.Unity.

  • Plain GridGeoData is single-surface (one height per cell) — great for terrain with slopes/steps; for overlapping floors reach for LayeredGridGeoData or the nav-mesh.

See the runnable World example (dotnet run --project examples/World -- floors) for a two-storey grid + cross-floor pathfinding.

Sectored worlds (zones / sectors)

A big world is usually split into sectors (zones), each baked separately. SectoredGeoData stitches them into one seamless IGeoData, dispatching each query to the sector that owns the point — walkability, height, sight and can-walk-straight all work across sector borders:

var world = new SectoredGeoDataBuilder()
    .Add("x0_z0", GeoDataFile.LoadFromFile("world_x0_z0.geo"))
    .Add("x1_z0", GeoDataFile.LoadFromFile("world_x1_z0.geo"))
    .Build();

// …or, from a baked manifest (the Unity sector baker writes one) — loads every sector in one call:
IGeoData world = GeoDataManifest.Load("world.geomap");

world.IsWalkable(p);                                   // routed to the owning sector
SetNet.PathFinding.Pathfinding.For(world).FindPath(a, b);   // paths across sectors (delegates within, stitches at borders)

Sectors can be a mix of grid / layered / nav-mesh, and can even stack in Y (a dungeon under a field). Pathfinding within a sector is exact (its native pathfinder, built once and reused); cross-sector routing walks the sector graph and stitches per-sector paths through the shared borders. Bake sectors + the manifest automatically with the Unity tool.

Notes

  • Server-side library, no wire protocol — the world is server-authoritative; clients render replicated state, they don't query GeoData over the network.
  • Engine-agnostic — depends only on SetNet, ships its own Vec3; convert at the edges. The Unity tool bakes a GeoDataFile from a scene's NavMesh or colliders.
  • Foundation for SetNet.PathFinding and SetNet.Mobs.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.1

    • No dependencies.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on SetNet.GeoData:

Package Downloads
SetNet.PathFinding

Pathfinding for SetNet over SetNet.GeoData: A* on a nav-grid and A*+funnel on a nav-mesh behind one IPathfinder, plus a PathFollower that walks an entity along the result (speed, arrival, waypoint advance). Server-side, engine-agnostic; feeds SetNet.Mobs movement. Depends on SetNet + SetNet.GeoData.

SetNet.Locomotion

A unified server-side movement simulator for SetNet: one system advances the position of everything that moves (players, mobs, NPCs, projectiles) along pathfound routes at a fixed rate — with automatic subscription (create a Mover and it's already ticking). It replicates NOTHING: you read positions and replicate them your own way, and a Started hook fires when a mover gets a new destination so you can send just the point to clients (L2-style, client re-paths locally). Depends on SetNet + SetNet.GeoData + SetNet.PathFinding.

SetNet.Mobs

Server-authoritative hostile AI entities for SetNet. One IMobBrain per mob type (aggressive, passive-retaliate, ranged/kiting, caster) — or compose one from behaviour components — behind a uniform tick loop that handles perception, threat, movement (via SetNet.PathFinding, straight-line fallback), ability cooldowns/casts/telegraphs, damage, death and respawn. Replication is a seam (IMobReplication, no-op default; poll MobServer.Mobs or handle MobMoved) — a StateSync adapter ships separately as SetNet.Mobs.StateSync. server.UseMobs() + client.UseMobs(). Rides the unified SetNet.Protocol on the Channels.Mobs channel. Depends on SetNet + SetNet.GeoData + SetNet.PathFinding (NOT StateSync).

SetNet.Hitscan

Server-authoritative hitscan (instant-hit) shooting for SetNet. The hit test is fully pluggable through the IHitDetector interface — bring your own collision (implement it yourself), or compose the shipped detectors: GeoData world raycast + sphere targets. Ray/HitResult primitives + a Hitscan resolver (ignore-shooter, range, on-hit callback, events). Depends on SetNet.GeoData (Vec3 + IGeoData).

SetNet.NPC

Interactive non-living entities for SetNet (vendors, buffers, teleporters, quest-givers). One INpcBehaviour per NPC type behind a uniform interact request/response — the framework standardizes registration, spawning, zone interest, and the interact round-trip; behaviours just write the interaction logic and return an optional Capability hand-off (e.g. "vendor:blacksmith") so the client opens its existing domain UI. server.UseNpc() + client.UseNpc(). Rides the unified SetNet.Protocol on the Channels.Npc channel. Depends on SetNet + SetNet.GeoData (Vec3).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 409 8/5/2026