
H I V E - Synthetic Environments
HIVE is a DIS-compliant simulation platform for unmanned swarm operations. Built on Tauri, React, and Rust, it generates standards-compliant IEEE 1278.1 entities with full NATO APP-6D symbology, simulates multi-sensor payloads across configurable threat environments, and streams live telemetry to EdgeSense for AI-driven operational picture simplification. Dozens of drones carrying CBRN, EO/IR, thermal, and RF sensors produce thousands of data points per second. HIVE bridges that complexity to a local LLM through EdgeSense, distilling noisy sensor feeds into one actionable paragraph a commander can act on. Designed for extensibility — supporting additional PDU types, HLA federation, waypoint guidance, and third-party simulator interoperability — HIVE serves as both a standalone simulation tool and a synthetic environment for testing AI-enabled C2 concepts.
Key Features
Tech Stack
Image Gallery







Loading updates...
Project Roadmap
Upcoming Features
Known Issues
Downloads
H I V E - V1.0.1 Synthetic Environment: Apple Silicon (MacOS)
Project Challenges
1. Rust Async and the Tick Loop
Getting the tick loop correct took longer than expected. The fundamental tension is that the tick loop runs continuously on a Tokio task whilst Tauri command handlers need to acquire the same RwLock
An earlier approach that cloned the full entity list per tick for sensor evaluation was allocating ~1.4 MB per tick at 1,000 entities. Moving to in-place mutation and dirty tracking eliminated that entirely.
2. DIS PDU Byte Layout
IEEE 1278.1 is an unforgiving standard. An off-by-one in a field offset produces silently malformed PDUs that external simulators either discard or misinterpret. The 144-byte Entity State PDU was validated field-by-field against the standard's byte offset table, then verified by connecting HIVE to VBS and checking that entity markings, positions, and force IDs were rendered correctly on the external side. The lesson: keep the byte offset table in the codebase (it now lives in the DIS Standard settings page) and test against a real external tool early.
3. Coordinate Systems
Three coordinate systems are in play simultaneously: local ENU (canvas display), WGS84 LLA (scenario origin, GPS readings), and ECEF geocentric (DIS PDU positions). Getting the transforms right — particularly the ENU → ECEF conversion via the flatearth.rs and ecef.rs modules — required careful handling of the geodetic datum. Errors here manifest as entities appearing hundreds of kilometres from where they should be in external simulators.
4. Sensor Physics Calibration
Writing physically-grounded sensor equations is straightforward. Making them produce operationally meaningful values at realistic entity counts and separations took significant calibration. The radar range equation initially produced Rmax values in the hundreds of kilometres for modern C-UAS radars — technically correct but unrealistic without multipath, clutter, and atmospheric attenuation. The minDetectableRcs threshold was the key parameter for bringing detection ranges into the expected operational envelope.
5. TypeScript / Rust Interface Boundary
Serde's default serialisation for Rust enums uses variant names as strings ("Friendly", "FPW") whilst the TypeScript entity model uses numeric enums for UI convenience. The denormalizeEntity function in ScenarioManager.tsx handles the re-serialisation before sending to Rust. This boundary caused a subtle bug — numeric enum values were being sent to the Rust savescenariocmd, which expected string variant names, silently producing invalid scenario files. Finding it required reading the Serde deserialisation output carefully.
6. ICloud Drive and the Build Pipeline
The project lives under iCloud Drive, which causes issues with Tauri's build tooling — the dist.mjs build script detects iCloud Drive and copies the source to a temp directory before building to avoid path encoding problems. This adds a step but the approach is robust enough to rely on.
Project Solutions & Learnings
Rust is genuinely excellent for simulation engines. The combination of zero-cost abstractions, fearless concurrency (the RwLock pattern was directly informed by the borrow checker refusing unsafe patterns), and performance without a GC made the tick loop reliable in a way that would have been much harder to achieve in Node or Python. The initial investment in learning Rust pays back quickly once the patterns are established.
The settings panel as living documentation is underrated. Rather than a separate docs site that inevitably drifts from the implementation, embedding the technical reference (sensor equations, PDU byte layouts, engine architecture) directly in the application means it is always in sync with the code. It is also genuinely useful at a training event where participants want to understand what they are looking at.
Invest in the physics early, even if you simplify. Starting with the radar range equation and FSPL model — rather than a simple distance threshold — meant that sensor behaviour was explainable and calibratable from day one. Operators can reason about detection ranges using physical intuition. Arbitrary thresholds are much harder to reason about and calibrate.
DIS interoperability requires external validation. Testing PDU emission against tcpdump and checking hex dumps is necessary but not sufficient. Connecting to a real external simulator (VBS in this case) and watching entities appear — or not — is the only reliable validation. Building this test into the development workflow early would have saved time.
The frontend-presentational / backend-computational split is worth enforcing strictly. There were several temptations to push small calculations (entity distance, formatting helpers) into TypeScript for convenience. Resisting that kept the TypeScript lean and the Rust testable. The Rust unit tests for dead reckoning, sensor evaluation, and GPS jamming degradation are only possible because the logic is entirely in Rust.
