Skip to content

Modules

MasterLaplace edited this page Feb 27, 2026 · 6 revisions

Modules

The LplPlugin engine is organized into 16 independent static libraries (lpl-<name>), each with its own xmake.lua, include/lpl/<name>/ headers, and src/ implementations. The engine/ module serves as the top-level facade that aggregates all others.

Build target naming: Each module compiles to lpl-<name> (e.g., lpl-core, lpl-math, lpl-ecs). Code style: SOLID principles, Doxygen /**@ documentation, .inl inline files, guard clauses, no inline comments.


1. core/ — Platform Abstraction

Target: lpl-coreNo dependencies

Platform types, assertions, compile-time utilities, and logging foundations. This is the leaf dependency of the entire module graph.


2. math/ — Mathematical Types

Target: lpl-mathlpl-core

Vec3, Quat, BoundaryBox, Fixed32, CORDIC trigonometry — all without external dependencies (no GLM).

Features:

  • All operators annotated __host__ __device__ (LPL_HD) for CUDA compatibility
  • Deterministic fixed-point arithmetic (Fixed32) for cross-platform physics validation
  • Custom CORDIC implementations for sin/cos/atan2

API:

  • Vec3: +, -, *, /, +=, dot(), cross()
  • Quat: identity(), * (Hamilton), rotate(Vec3)
  • BoundaryBox: contains(Vec3) — inclusion test for migration

3. memory/ — Allocators

Target: lpl-memorylpl-core

PinnedAllocator: STL allocator using cudaHostAlloc (mapped + portable) so that std::vector buffers are directly GPU-accessible via PCIe zero-copy.

Fallback: Without nvcc, uses standard malloc/free.

Usage: All SoA vectors in Partition use PinnedAllocator<T>:

std::vector<Vec3, PinnedAllocator<Vec3>> _positions[2];

4. container/ — Data Structures

Target: lpl-containerlpl-core, lpl-math

FlatAtomicsHashMap

Lock-free hash map specialized for world chunk storage.

  • Contiguous pool: all Partition objects live in a contiguous array (cache-friendly)
  • 64-bit atomic packed entries: [Morton Key (42 bits) | Pool Index (22 bits)]
  • Open addressing: linear probing with tombstones
Operation Guarantee Mechanism
get() Wait-Free Atomic read
insert() Lock-Free Atomic CAS + SpinLock for pool
remove() Lock-Free Atomic TOMBSTONE + slot recycling
forEach() Thread-Safe Copy _activeSlots under lock

Morton Encoding

Encode 2D/3D coordinates into scalar keys preserving spatial locality (Z-order curve).

  • encode2D(x, y) → 32-bit key (world chunks)
  • encode3D(x, y, z) → 63-bit key (octree)
  • Bias for negative coordinates: +2²⁰ offset

5. concurrency/ — Threading Primitives

Target: lpl-concurrencylpl-core

SpinLock

std::atomic_flag + _mm_pause() — RAII LocalGuard, ~100ns latency under short contention. One per chunk.

ThreadPool

Fixed workers (hardware_concurrency()), supports enqueue (returns std::future) and enqueueDetached (fire-and-forget). Used by SystemScheduler and WorldPartition.


6. ecs/ — Entity Component System

Target: lpl-ecslpl-core, lpl-math, lpl-memory, lpl-container, lpl-concurrency

EntityRegistry

Central registry — sparse set with generational IDs.

  • smartId = (generation << 14) | slot (18-bit gen + 14-bit slot)
  • O(1) lookup: publicId → slot → chunkKey
  • Capacity: 10,000 simultaneous entities, 1,000,000 max public IDs

Partition (Chunk ECS)

Per-chunk SoA container with double buffering, physics, and migration.

SoA Structure:

  • Hot data [2] (PinnedAllocator): positions, velocities, forces
  • Cold data: ids, rotations, masses, sizes, health, neuralControls
  • Metadata: adaptive sparse set _idToLocal, BoundaryBox, SpinLock, FlatDynamicOctree
Method Description
addEntity(snapshot) Thread-safe insertion into BOTH buffers
removeEntityById(id, writeIdx) O(1) swap-and-pop on BOTH buffers
physicsTick(dt, out, wIdx) Gravity + semi-implicit Euler + migration (CPU)
syncBuffers(writeIdx) Copy hot data write→read (memcpy)
setNeuralControl(id, ...) Update BCI data for an entity

Dynamic Octree

Full rebuild each frame. Internal radix sort (4 passes × 16-bit) on 3D Morton keys. Adaptive: brute-force N² for ≤32 entities, octree beyond.


7. physics/ — Physics & World Management

Target: lpl-physicslpl-ecs, lpl-math, lpl-container

WorldPartition

Main orchestrator — manages chunks, migration, entity registry, and global double buffering.

step(deltatime) Flow:

forEach chunk → physicsTick (CPU, 2 passes forward+backward)
Final phase: Re-insert migrating entities (getOrCreateChunk + addEntity + updateChunkKey)
GC: Remove empty chunks

Collision (AABB)

  • Minimum penetration axis → collision normal
  • Newton impulse with restitution (e=0.5)
  • Iterative solver (4 complete passes)
  • Auto wake on collision

8. net/ — Networking

Target: lpl-netlpl-core, lpl-math, lpl-memory, lpl-container, lpl-concurrency, lpl-ecs

Network (Transport)

Three modes (résolution automatique) :

  • Kernel driver (production): open("/dev/lpl0")mmap(LplSharedMemory) → zero-copy RX/TX
  • Socket fallback (serveur dev): socket UDP standard
  • Socket forcé (-DLPL_USE_SOCKET, client/Android): socket UDP uniquement
Method Description
network_init() Open driver (or create socket)
network_consume_packets(queue) Drain RX ring/socket → PacketQueue
send_connect/welcome/inputs/state() Typed send methods

PacketQueue

Thread-safe typed queues: ConnectEvent, WelcomeEvent, StateUpdateEvent, InputEvent.

SessionManager

Handles client connections server-side. handleConnections() + broadcast_state().

Systems

Factory functions (Systems:: namespace) returning SystemDescriptor for the scheduler:

  • NetworkReceiveSystem, SessionSystem, InputProcessingSystem, MovementSystem, PhysicsSystem, WelcomeSystem, StateReconciliationSystem, BroadcastSystem

9. gpu/ — GPU Compute

Target: lpl-gpulpl-core, lpl-math

CUDA lifecycle and physics kernel implementation. PhysicsKernel.cu handles gravity and semi-implicit Euler integration on SoA buffers.

Ported: PhysicsGPU.cu from legacy → PhysicsKernel.cu (SoA float arrays).


10. input/ — Input Management

Target: lpl-inputlpl-core, lpl-math

InputManager

Unified input state per entity (keys, axes, neural). Used on both server (authoritative from network) and client (local from input devices + BCI).

Method Description
setKeyState(entityId, key, pressed) Update key state
setNeural(entityId, alpha, beta, conc, blink) Update neural data
computeMovementVelocity(entityId, ...) WASD → velocity + neural modulation

Neural speed scale: concentration [0..1] → scale [0.70x .. 1.30x]. Blink jump with rising-edge detection.


11. render/ — Vulkan Renderer

Target: lpl-renderlpl-core, lpl-math, lpl-memory (+ vulkan-hpp, ImGui)

Vulkan rendering pipeline ported from the VkWrapper project. Includes:

  • Vulkan device/instance/swapchain management
  • Graphics pipeline setup
  • ImGui integration (GLFW + Vulkan backend)
  • Texture loading, model loading

Note: The Vulkan dependency is optional. Use xmake f --renderer=n to completely disable Vulkan and GLFW for headless server builds.


12. audio/ — Spatial Audio

Target: lpl-audiolpl-core

Architecture stub for spatial audio integration. Not yet implemented.


13. haptic/ — Haptic Feedback

Target: lpl-hapticlpl-core

Architecture stub for haptic/vestibular feedback (GVS, tFUS). Not yet implemented.


14. bci/ — Brain-Computer Interface

Target: lpl-bcilpl-core, lpl-math, lpl-input

Merged module combining the adapter layer (src/bci/) and the full DSP pipeline from plugins/bci/. Organized into sub-directories:

Sub-directory Content
src/source/ OpenBCI driver, BrainFlow, LSL, CSV sources
src/dsp/ FFT, windowing, PSD extraction
src/metric/ SignalMetrics (Schumacher), StabilityMetric
src/math/ Covariance, Riemannian geometry
src/stream/ LSL outlet
src/openvibe/ OpenViBE box algorithm stubs
tests/ 24 unit tests (SignalMetrics + RiemannianGeometry)

Key APIs:

OpenBCIDriver

  • Serial capture: 33-byte packets, 8 channels, 250 Hz
  • 24-bit ADS1299 parsing with sign extension
  • FFT (256 pts, Hann window) → PSD per channel
  • Concentration ratio (Beta / (Alpha + Beta)) with EMA smoothing
  • Eye blink detection via thresholding

SignalMetrics

  • schumacher()$R(t) = \frac{1}{N_{ch}} \sum_{i=1}^{N_{ch}} \int_{40}^{70} PSD_i(f,t), df$ — muscle tension
  • integrale() — discrete PSD integration
  • sliding_window_rms() — RMS over sliding window
  • compute_baseline() — mean + σ calibration

RiemannianGeometry

  • compute_covariance() — SPD matrix with Bessel correction
  • riemannian_distance()$\delta_R = \sqrt{\sum_i \ln^2(\lambda_i)}$ — cognitive state change
  • mahalanobis_distance()$D_M$ anomaly detection
  • Jacobi eigenvalue decomposition — no external dependency

NeuralMetrics

  • from_state() — normalized struct with muscle_alert threshold

Note: Several sources (BrainFlowSource, LslSource, OpenBciSource) and advanced math (Covariance, Riemannian) are excluded from the build pending Eigen/Boost/liblsl/BrainFlow integration.


15. serial/ — Serial Port

Target: lpl-seriallpl-core

Serial port abstraction for USB communication (used by BCI driver for /dev/ttyUSB0).


16. engine/ — Engine Facade

Target: lpl-engine → ALL other modules

Top-level facade that depends on all 15 other modules. Provides the Core class — the single entry point for the engine.

Core owns by composition:

  • WorldPartition, Network, SystemScheduler, InputManager, PacketQueue, SessionManager

Game loops:

  • run(threaded) — fixed 60Hz server loop
  • runVariableDt(computeDt, onPostLoop) — variable client loop

Lifecycle: Constructor → registerSystem()buildSchedule()run()stop() → Destructor

SystemScheduler

ECS scheduler with automatic component dependency analysis (DAG) and two execution phases:

  • PreSwap: mutation of write buffer (network, inputs, physics)
  • PostSwap: reading of stable read buffer (broadcast, render, camera)

Systems declaring the same write component are serialized; reads are parallelized.


kernel/ — Linux Kernel Module

Not an xmake target — compiled separately via kernel build system.

lpl_kmod.c

Bidirectional zero-copy network gateway:

RX Path: Netfilter hook NF_INET_PRE_ROUTINGskb_copy_bits()RxPacketNF_DROP TX Path: kernel thread lpl_tx_workerkernel_sendmsg() → UDP

Shared Memory (LplSharedMemory):

  • mmap() on char device /dev/lpl0
  • vmalloc_user() allocation
  • RxRingBuffer rx (4096 slots) + TxRingBuffer tx (4096 slots)
  • Atomic head/tail + cache-line padding

lpl_protocol

Shared structures between kernel (C) and userspace (C++23):

Structure Description
RingHeader head + tail + cache-line padding
RxPacket src_ip + src_port + length + data[256]
TxPacket dst_ip + dst_port + length + data[256]
LplSharedMemory RxRingBuffer rx + TxRingBuffer tx
ComponentID TRANSFORM, HEALTH, VELOCITY, MASS, SIZE, NEURAL

ioctl: LPL_IOC_KICK_TX — wakes the kernel TX thread.

Messages: MSG_CONNECT (0x10), MSG_WELCOME (0x11), MSG_INPUT (0x12), MSG_STATE (0x13)


Tech Stack & Build | Next: Architectural Decisions

Clone this wiki locally