SetNet.GeoData
1.2.0
dotnet add package SetNet.GeoData --version 1.2.0
NuGet\Install-Package SetNet.GeoData -Version 1.2.0
<PackageReference Include="SetNet.GeoData" Version="1.2.0" />
<PackageVersion Include="SetNet.GeoData" Version="1.2.0" />
<PackageReference Include="SetNet.GeoData" />
paket add SetNet.GeoData --version 1.2.0
#r "nuget: SetNet.GeoData, 1.2.0"
#:package SetNet.GeoData@1.2.0
#addin nuget:?package=SetNet.GeoData&version=1.2.0
#tool nuget:?package=SetNet.GeoData&version=1.2.0
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 soSetNet.PathFindingcan 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.
SampleHeightreturns the ground Y;MaxStepbounds how big a height change between adjacent cells still counts as walkable.Stairs / steps — a staircase is just a run of surfaces each within
MaxStepof the next (grid/layered grid), or connected triangles (nav-mesh).CanWalkStraightenforces 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 floorsMovement/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-MESH —
NavMeshGeoDatais Y-aware too:TriangleAt/SampleHeight/IsWalkableresolve to the floor nearest the query's Y, andCanWalkStraight(bounded byWalkYTolerance) won't jump between storeys through the air. Bake it from an engine NavMesh (which already models floors) viaSetNet.GeoData.Unity.Plain
GridGeoDatais single-surface (one height per cell) — great for terrain with slopes/steps; for overlapping floors reach forLayeredGridGeoDataor 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 ownVec3; convert at the edges. The Unity tool bakes aGeoDataFilefrom a scene's NavMesh or colliders. - Foundation for SetNet.PathFinding and SetNet.Mobs.
License
MIT
| Product | Versions 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. |
-
.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 |