EvaluatedApplications.HoloVoxel
1.5.2
dotnet add package EvaluatedApplications.HoloVoxel --version 1.5.2
NuGet\Install-Package EvaluatedApplications.HoloVoxel -Version 1.5.2
<PackageReference Include="EvaluatedApplications.HoloVoxel" Version="1.5.2" />
<PackageVersion Include="EvaluatedApplications.HoloVoxel" Version="1.5.2" />
<PackageReference Include="EvaluatedApplications.HoloVoxel" />
paket add EvaluatedApplications.HoloVoxel --version 1.5.2
#r "nuget: EvaluatedApplications.HoloVoxel, 1.5.2"
#:package EvaluatedApplications.HoloVoxel@1.5.2
#addin nuget:?package=EvaluatedApplications.HoloVoxel&version=1.5.2
#tool nuget:?package=EvaluatedApplications.HoloVoxel&version=1.5.2
HoloVoxel
Beta. The public API may change between versions while we improve it. Breaking changes always come with a new major version, and the release notes say what changed.
A holographic voxel/spatial engine for .NET, built on the Phasor VSA codec. The spatial sibling of HoloDb: where HoloDb stores tables holographically, HoloVoxel stores 3D space. Engine only — no rendering/graphics dependency, headless-verified; you supply the palette and the renderer.
No feature below is gated behind a tier or a license key — every type and method is available to every caller. No source or separate docs ship with the package; this file is the complete reference.
The idea
A chunk of the world is a single Phasor superposition — every voxel bound as position ⊗ content and summed —
not an array of voxels. Reading a voxel is a correlation. Reading it with fewer components gives a cheaper,
fuzzier result, so level-of-detail is the readout itself, not a downsample:
- Near = full component budget → the correlation collapses to a single crisp voxel.
- Far = a few components → the interference of everything that might be there blends into a soft, cheap blur.
"Crisp near, dreamy far" is continuous, with no discrete LOD meshes and no popping. The same dial is detail, compute, and (if you stream it) network bytes.
Table of contents
- Quick start
- Gotchas up front
Block/Blocks— the paletteIWorldSource— the terrain oracle interfaceWorldGen— the built-in procedural generatorRing— flat ↔ cylinder warpHoloWorld— the world / chunk cacheChunk— one chunk's hologram, decode pathsLod— distance budget + confidence-adaptive budget + spatial smoothingHoloModel/ModelVoxel/Creatures— entities- Value types:
Voxel,VoxelColor,SurfaceMesh - Obsolete / removed API
- License
Quick start
dotnet add package EvaluatedApplications.HoloVoxel
using HoloVoxel.Core;
var world = new HoloWorld(seed: 2024);
foreach (var v in world.GetChunk(0, 0).DecodeField(step: 1, components: world.Comps))
DrawCube(v.X, v.Y, v.Z, v.Size, v.R, v.G, v.B); // crisp, full budget: 256 surface cells for a 16x16 chunk
// a distant chunk, decoded cheaply/fuzzily:
foreach (var v in world.GetChunk(40, 0).DecodeField(step: 8, components: 40)) DrawBlob(v);
Gotchas up front
- Coordinates. World/column coordinates (
x,z) are integer world units;yis up. Chunk coordinates (cx,cz) are chunk indices, not world units — world column(cx*16 + lx, cz*16 + lz). A chunk's local index space (used byPosFace-keyed APIs likeModelVoxel) is bounded:lx,lzin[0, HoloWorld.ChunkSize)=[0,16),dy/yin[0, HoloWorld.MaxLayers)=[0,12). AHoloModel/Creaturesvoxel outside that box silently aliases another position's face — keep every voxel inside it. - Chunk size is fixed.
HoloWorld.ChunkSize(16 columns/side) andHoloWorld.ChunkDepth(4 buried layers per column on a full build) areconst, not constructor parameters — every chunk in aHoloWorldis the same size. - LOD semantics: near = crisp, far = fuzzy, and chunks only ever get FINER.
Chunk.EnsureStep/HoloWorld.GetChunkAtnever coarsen an already-finer chunk — a finer hologram already contains every coarser grid position, so decoding atstep >= BuildStepis always valid; decoding atstep < BuildStepis not. Decodecomponents/kis clamped to[8, storedWidth]everywhere — asking for fewer than 8 still reads 8. - Truncated holograms are lossless up to their stored width. A chunk stores only as many components as it
was last built/refined for (
EnsureStep'scomps); reading the first k ≤ that width is bit-identical to reading a full-width store. It never holds more detail than it was asked to. Chunk.Decode/Chunk.Accuracyrequire a full (step == 1) build — they read the per-cell ground truth kept only by a full build (headless verification / argmax use, not the renderer's job).Chunk.FieldConfidenceis empty for any chunk whose per-cell truth wasn't kept — that includes every wall chunk AND any chunk whose first build was coarse (step > 1; coarse builds keep no per-cell truth, only the averaged hologram). For a genuine confidence signal, build/decode atstep = 1and varycomponentsalone.- Thread-safety. Call
HoloWorld.Prewarm()once, single-threaded, before any concurrent chunk work — it fills the bounded position/block face caches up front; after that they're read-only, so parallelGetChunk/GetChunkAt/decode calls are lock-free and race-free.WorldGen.BuildMazeis the same shape: call once on the main thread (after settingXPeriod, before parallel decode) — it precomputes a read-only passage set. Skipping either under concurrent load races a dictionary/field. - Memory scales with decoded detail, not world size. A chunk's hologram is
2 * storedWidthdoubles regardless of how many voxels it represents — a far chunk decoded atcomponents = 40costs a fraction of a near chunk's storage, because that's literally all it was ever built with. - The softmax sharpness (
Beta = 11.0) that turns the interference blend crisp near / fuzzy far is an internal constant, not a public knob — it is not exposed for tuning.
Block / Blocks
The block palette. Block is a byte enum; Air is never stored (it's the absence of a voxel, not a
material).
Block b = Block.Stone;
Console.WriteLine($"{b} = {(byte)b}, name={Blocks.Name[(int)b]}"); // Stone = 3, name=stone
Console.WriteLine(Blocks.Decodable.Length); // 8 (every Block except Air)
var (r, g, bl) = Blocks.Color[(int)Block.Grass]; // 0.37, 0.69, 0.33
| Member | Purpose |
|---|---|
enum Block : byte |
Air=0, Grass, Dirt, Stone, Ore, Sand, Snow, Water, Wall |
Blocks.Decodable |
The 8 non-Air blocks a decoder can resolve to, in enum order. |
Blocks.Name |
Lower-case name per Block value (index by (int)block), including "air". |
Blocks.Color |
(r,g,b) 0..1 tuple per Block value, for a renderer. |
IWorldSource
The terrain oracle a Chunk pulls content through — a pure function of column/cell coordinates.
WorldGen is the built-in implementation; implement this yourself (a tile map, a save file, an in-memory
edit buffer) and hand it to HoloWorld's source constructor overload to drive the same cached,
holographic-LOD engine from your own world data.
sealed class FlatWorldSource : IWorldSource
{
public int Height(int x, int z) => 20;
public Block SolidAt(int x, int y, int z, int height) => y == height ? Block.Grass : Block.Stone;
public bool IsWall(int x, int z) => false;
public int WallHeight(int x, int z) => 0;
}
var flatWorld = new HoloWorld(new FlatWorldSource(), seed: 1);
Console.WriteLine(flatWorld.GetChunk(0, 0).VoxelCount); // 1024 (16x16 columns x ChunkDepth=4)
| Member | Purpose |
|---|---|
int Height(int x, int z) |
Surface height (world units) at column (x, z). |
Block SolidAt(int x, int y, int z, int height) |
The block at a solid cell (y <= height). |
bool IsWall(int x, int z) |
Is this column a hard wall/obstacle (rendered as a box, not terrain)? |
int WallHeight(int x, int z) |
World-units height of the wall box at this column. |
WorldGen
The built-in procedural generator (IWorldSource): wave-based continental/temperature fields select a
Biome, drive Height/SolidAt, and an optional maze of wall structures crosses the land.
var gen = new WorldGen(seed: 7);
Console.WriteLine($"{gen.Seed} {WorldGen.SeaLevel}"); // 7 22
Console.WriteLine($"{gen.BiomeAt(0, 0)} {gen.Height(0, 0)}"); // e.g. Desert 49
gen.Arena = true; // flat, gentle sandbox terrain
Console.WriteLine(gen.Height(0, 0)); // e.g. 21
var race = new WorldGen(seed: 7) { RaceMode = true, NoWalls = true }; // rolling hills + mountain lobes, no maze
Console.WriteLine($"{race.Height(0, 0)} {race.IsWall(16, 0)}"); // e.g. 38 False
var ring = new WorldGen(seed: 7) { XPeriod = 2048 }; // x wraps seamlessly every 2048 world units
ring.BuildMaze(around: 64, zHalfCells: 8); // call once, main thread, before any parallel decode
Console.WriteLine($"{WorldGen.MazeCell} {ring.IsWall(16, 0)} {ring.WallHeight(16, 0)}"); // 16 True e.g. 64
| Member | Purpose |
|---|---|
WorldGen(int seed = 1337) |
Build a generator for the given seed. |
Seed (prop) |
The seed this instance was built with. |
SeaLevel (const = 22) |
World-unit height at/below which a surface cell becomes Water. |
XPeriod (field) |
> 0 makes x periodic with this period (world units) — seamless ringworld wrap. |
Arena (field) |
Flat, gentle grass sandbox terrain (overrides the wave terrain and the maze). |
NoWalls (field) |
Disable the maze of wall structures (pure landscape; used by RaceMode). |
RaceMode (field) |
Low-frequency rolling hills + big mountain-lobe masses, scaled for a flyover view. |
BiomeAt(x,z) |
Which Biome (Ocean/Plains/Desert/Mountains/Snowlands) sits at this column. |
Height(x,z) |
IWorldSource.Height impl — mode-aware (wave / Arena / RaceMode). |
SolidAt(x,y,z,height) |
IWorldSource.SolidAt impl — biome-dependent surface, dirt/sand band, stone+ore below. |
MazeCell (const = 16) |
Grid unit (world units) of one maze room/wall cell. |
BuildMaze(around, zHalfCells) |
Precompute a connected, loop-augmented maze spanning tree over the ring's room grid. Call once, main thread, after setting XPeriod, before parallel decode. Without it, IsWall/WallHeight fall back to a stateless hash rule. |
IsWall(x,z) |
IWorldSource.IsWall impl — maze pillar/passage rule (or the stateless fallback). |
WallHeight(x,z) |
IWorldSource.WallHeight impl — a per-cell uniform level 1..10 (×8 world units). |
Ring
A pure render-space warp: bends flat world space onto the inside of a cylindrical ringworld. The holographic engine still stores/decodes flat chunks — only the final camera/vertex positions are bent, so streaming and chunk logic are unaffected.
var ring = new Ring(radius: 500);
var onRing = ring.ToRing(x: 100, y: 5, z: 0); // flat -> 3D ring position
var backToFlat = ring.ToFlat(onRing.X, onRing.Y, onRing.Z); // 3D ring position -> flat (x,z), e.g. (100, 0)
| Member | Purpose |
|---|---|
Ring(double radius) |
Construct for a ring of the given radius (world units). |
Radius (prop) |
The ring's radius. |
ToRing(x,y,z) |
Flat (along-ring, height, across-width) → 3D position on the ring surface. |
ToFlat(wx,wy,wz) |
Inverse of ToRing's X/Z — maps a 3D ring position (e.g. the camera) back to flat (x,z) for chunk streaming. |
HoloWorld
The world: a cache of Chunks generated on demand, the shared codec, and the shared position/block face
tables every chunk binds into.
var world = new HoloWorld(seed: 2024); // built-in WorldGen, codec width (Dim) defaults to 16384
// var world2 = new HoloWorld(mySource, seed: 2024); // or drive it from your own IWorldSource
Console.WriteLine($"{HoloWorld.ChunkSize} {HoloWorld.ChunkDepth} {HoloWorld.MaxLayers}"); // 16 4 12
Console.WriteLine($"{world.Comps} {world.Gen.Seed} {ReferenceEquals(world.Source, world.Gen)}"); // 8192 2024 True
world.Prewarm(); // fill shared caches BEFORE any parallel chunk work
var chunk = world.GetChunk(0, 0); // full-budget chunk at (0,0)
var coarse = world.GetChunkAt(cx: 0, cz: 0, step: 1, comps: world.Comps); // create-coarse-or-refine
world.Invalidate(0, 0); // drop from cache (editable sources: terrain changed)
var (acc, bytes) = world.CapacityProbe(n: 200, palette: 8, budget: 1024, seed: 1);
Console.WriteLine($"{acc:F1}% {bytes}B"); // e.g. 90.0% 16384B
| Member | Purpose |
|---|---|
HoloWorld(int seed = 1337, int dim = 16384) |
Built-in WorldGen as the terrain source. dim is the Phasor codec width. |
HoloWorld(IWorldSource source, int seed = 1337, int dim = 16384) |
Drive chunks from your own IWorldSource instead of the built-in generator. |
ChunkSize (const = 16) |
Columns per chunk side. |
ChunkDepth (const = 4) |
Surface-band voxels stored per column on a full build. |
MaxLayers (const = 12) |
Vertical index space for position faces (bounds dy/y for Chunk/HoloModel). |
Dim (prop) |
The Phasor codec width this world was constructed with. |
Comps (prop, = Dim/2) |
Number of complex components — the maximum LOD budget. |
Gen (prop) |
The built-in WorldGen (always constructed, even if Source overrides it). |
Source (prop) |
The IWorldSource chunks actually read through (defaults to Gen). |
GetChunk(cx,cz) |
Fetch/create the chunk at full fidelity (step=1, comps=Comps). |
GetChunkAt(cx,cz,step,comps) |
Fetch/create at (at least) the given fidelity — creates coarse if new, refines if coarser than requested, no-ops otherwise. |
Invalidate(cx,cz) |
Drop a chunk from the cache so the next fetch regenerates it (for an editable Source). |
Prewarm() |
Single-threaded fill of the shared position/block face caches. Call once before concurrent chunk generation/decode. |
CapacityProbe(n, palette, budget, seed=1) |
Diagnostic: bind n random position⊗block pairs into one hologram truncated to budget components, argmax-decode all n, return (accuracy%, storeBytes) — measures how much detail a given component budget can actually hold. |
Chunk
One chunk's hologram, at whatever fidelity it was last built/refined to. Obtained from HoloWorld.GetChunk/
GetChunkAt — there is no public reason to new Chunk(...) directly (the constructor is public but
HoloWorld is the intended entry point; it takes a HoloWorld instance as a required argument).
chunk.EnsureStep(step: 1, comps: world.Comps); // refine to at least this fidelity (never coarsens)
Console.WriteLine($"{chunk.Cx} {chunk.Cz} {chunk.BuildStep} {chunk.IsWallCell} {chunk.VoxelCount}");
// colour field (softmax-blended material per cell — crisp near, interference-blurred far)
foreach (var v in chunk.DecodeField(step: 1, components: world.Comps)) { /* v.X,Y,Z,Size,R,G,B */ }
// triangulated surface mesh with analytic per-vertex normals + holographic colour
var mesh = chunk.DecodeMesh(step: 1, components: world.Comps);
Console.WriteLine($"{mesh.VertexCount} {mesh.TriangleCount}"); // e.g. 289 512
// split geometry from colour so a GPU/accelerator can supply the material blend itself
int[] faceIdx = chunk.MeshFaceIndices(step: 1); // dy==0 position-face index per mesh vertex
var colors = new float[faceIdx.Length * 3]; // caller/GPU fills r,g,b per vertex...
var meshFromColors = chunk.DecodeMeshWithColors(step: 1, colors: colors);
// per-surface-cell softmax readout confidence (the adaptive-LOD ambiguity signal)
var confidence = chunk.FieldConfidence(components: world.Comps); // List<(int X, int Z, float Confidence)>
// argmax decode + ground-truth accuracy — full (step==1) builds only, for headless verification
var decoded = chunk.Decode(components: world.Comps); // List<Voxel>
double accFull = chunk.Accuracy(world.Comps); // e.g. 98.5
double acc48 = chunk.Accuracy(48); // e.g. 19.1 (fuzzier at a lower budget)
| Member | Purpose |
|---|---|
Chunk(cx, cz, HoloWorld world, step=1, comps=0) |
Construct directly (normally obtained via HoloWorld instead). |
Cx, Cz (props) |
This chunk's grid coordinates. |
BuildStep (prop) |
Current build fidelity (column spacing bound into the hologram). Only ever gets finer. |
IsWallCell (prop) |
True if this is a solid maze-wall chunk (decoded as a box), not ordinary terrain. |
VoxelCount (prop) |
Number of stored cells (0 unless built at step <= 1, which keeps per-cell truth). |
EnsureStep(step, comps) |
Refine to at least this fidelity if needed; never coarsens. |
DecodeField(step, components) |
Decode as a holographic colour field: List<VoxelColor>, softmax-blended, continuous LOD. Handles wall chunks specially. |
DecodeMesh(step, components) |
Decode as a triangulated SurfaceMesh heightfield with per-vertex holographic colour and shared border vertices (no cracks between neighbouring chunks). |
MeshFaceIndices(step) |
The dy==0 position-face index per DecodeMesh grid vertex, for bulk/GPU colour blending. |
DecodeMeshWithColors(step, colors) |
Same geometry as DecodeMesh, but colour comes from the caller/GPU-supplied colors array instead of being decoded on the CPU. |
FieldConfidence(components) |
Per-surface-cell softmax margin (winner minus runner-up) — List<(int X, int Z, float Confidence)>. Terrain only; empty for wall chunks or any chunk whose first build was coarse. |
Decode(components) |
Argmax decode to List<Voxel> — full (step==1) builds only. |
Accuracy(components) |
% of decoded voxels matching stored ground truth at this budget — full builds only, headless verification. |
Lod
Pure functions for distance-based and confidence-adaptive component budgets, and spatial smoothing for far
decode — no Chunk/HoloWorld access; scheduling policy (when/how often to apply them) is the caller's.
int comps = Lod.Components(distance: 200, maxComps: world.Comps); // e.g. 160 — nearDist=28, exponent=2.0, min=24 by default
float h = Lod.SmoothHeight(world.Source, wx: 100, wz: 0, step: 8); // footprint-averaged height (<=4x4=16 taps); step<=1 is the exact point sample
var confidence = chunk.FieldConfidence(world.Comps);
float avg = Lod.AverageConfidence(confidence, c => c.Confidence); // works on Chunk's 3-tuple or HoloModel's 4-tuple via the selector; empty field -> 1
int adaptive = Lod.AdaptiveComponents(baseComps: comps, avgConfidence: avg, maxComps: world.Comps);
// unchanged at/above confidenceFloor (default 0.35); boosted toward maxComps below it; NEVER less than baseComps
| Member | Purpose |
|---|---|
Components(distance, maxComps, nearDist=28, exponent=2.0, min=24) |
Distance → component budget; continuous, no discrete LOD tiers. |
SmoothHeight(IWorldSource, wx, wz, step) |
Footprint-averaged height for a step-sized far grid (the spatial-coarsening half of far LOD); step<=1 returns the exact point sample unchanged. |
AverageConfidence<T>(field, selector) |
Collapse a FieldConfidence result into one ambiguity signal; empty field → 1 (no data isn't evidence of ambiguity). |
AdaptiveComponents(baseComps, avgConfidence, maxComps, confidenceFloor=0.35, min=24) |
Boost baseComps toward maxComps when confidence is below the floor; never returns less than baseComps. |
HoloModel / ModelVoxel / Creatures
An entity (creature/prop) stored the same holographic way as a chunk: one small hologram, built once from an explicit voxel list and a named palette, decoded through the identical LOD/confidence math as terrain.
// ready-made examples
var (wraithVoxels, wraithPalette) = Creatures.Wraith(); // ~7x11x2 voxel humanoid, 3-material palette
var wraith = new HoloModel(world, wraithVoxels, wraithPalette);
Console.WriteLine($"({wraith.MinX},{wraith.MinY},{wraith.MinZ})..({wraith.MaxX},{wraith.MaxY},{wraith.MaxZ})");
var field = wraith.Decode(step: 1, components: world.Comps); // List<VoxelColor>, local voxel coords
var conf = wraith.FieldConfidence(components: world.Comps); // List<(int X, int Y, int Z, float Confidence)>
var (crystalVoxels, crystalPalette) = Creatures.Crystal(); // single-material gem octahedron
var crystal = new HoloModel(world, crystalVoxels, crystalPalette);
Console.WriteLine(crystal.FieldConfidence(world.Comps)[0].Confidence); // 1 (single material = unambiguous by construction, not +Infinity)
// your own model, built directly from ModelVoxel + a palette
var voxels = new List<ModelVoxel> { new ModelVoxel(0, 0, 0, 0), new ModelVoxel(1, 0, 0, 0) };
var palette = new List<(string name, (float r, float g, float b) color)> { ("probe.mat", (1f, 0f, 0f)) };
var custom = new HoloModel(world, voxels, palette);
| Member | Purpose |
|---|---|
ModelVoxel(int X, int Y, int Z, int Mat) |
One entity voxel: local grid cell (same bounded index space as HoloWorld.PosFace: X,Z<16, Y<12) + palette material index. |
HoloModel(HoloWorld, voxels, palette) |
Build the entity's hologram once from a ModelVoxel list and a (name, color) palette (minted via the world's own codec, never touching terrain blocks). |
MinX,MinY,MinZ,MaxX,MaxY,MaxZ (props) |
Inclusive voxel bounding box, for placement. |
Decode(step, components) |
Decode to List<VoxelColor> — same crisp-near/fuzzy-far LOD math as Chunk.DecodeField. Coarser step keeps a sparser grid of voxels. |
FieldConfidence(components) |
Per-voxel softmax margin, List<(int X, int Y, int Z, float Confidence)> — the HoloModel counterpart of Chunk.FieldConfidence, every voxel (no "surface" concept for an entity). 1 for a single-material palette, 0 for an empty palette. |
Creatures.Wraith() |
Ready-made ~7×11×2 humanoid wraith voxel list + 3-material palette. |
Creatures.Crystal() |
Ready-made ~7×7 octahedron gem voxel list + 1-material palette. |
Value types: Voxel, VoxelColor, SurfaceMesh
// Voxel — Chunk.Decode's argmax result
// readonly record struct Voxel(int X, int Y, int Z, Block Block, float Confidence, int Size = 1)
// VoxelColor — DecodeField/HoloModel.Decode's blended-field render cell
// readonly record struct VoxelColor(int X, int Y, int Z, int Size, float R, float G, float B)
// SurfaceMesh — DecodeMesh/DecodeMeshWithColors's triangulated output
var mesh = chunk.DecodeMesh(step: 1, components: world.Comps);
Console.WriteLine($"{mesh.VertexCount} verts, {mesh.TriangleCount} tris");
float[] pos = mesh.Positions; // 3 floats/vertex
float[] nrm = mesh.Normals; // 3 floats/vertex, analytic (height-gradient) normals
float[] col = mesh.Colors; // 3 floats/vertex, holographic material blend
int[] idx = mesh.Indices; // 3 per triangle
| Type | Purpose |
|---|---|
Voxel |
Decoded argmax result: world position, Block, Confidence (0..1), cube edge Size (1 unless coarse). |
VoxelColor |
A rendered field cell: world position, cube edge Size, and the softmax-blended RGB (0..1) of every candidate — not a decoded block. |
SurfaceMesh |
Interleaved Positions/Normals/Colors (3 floats/vertex) + Indices (3/triangle); VertexCount/TriangleCount convenience props. |
Obsolete / removed API
None. Every public member in this version is current; nothing is marked [Obsolete].
License
Proprietary — this package ships the compiled library only; see LICENSE for the full terms. Installing
and using unmodified copies for internal evaluation and non-commercial development or testing is licensed;
commercial, production, or revenue-generating use requires a separate commercial licence from the owner.
No feature on this page is gated behind a tier or a licence key — every capability described works
identically with or without one. Copyright (c) 2026 Dongyang Stephen Chen, trading as Evaluated
Applications. All rights reserved.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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. |
-
net10.0
- EvaluatedApplications.Phasor (>= 1.4.2)
-
net8.0
- EvaluatedApplications.Phasor (>= 1.4.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.