Repository navigation
Engine Concepts
This page explains the main parts of NWBLot before going into file-level detail.
NWBLot can be understood as three connected workflows:
- Build-time asset work
- Runtime world work
- Runtime rendering work
The build-time workflow turns authored content into stable binary data. The runtime world workflow creates and updates scene state. The runtime rendering workflow turns that scene state into GPU work.
The asset workflow starts from authored content:
.nwb / .slang / .slangi / .bind / .surface / .bxdf -> asset pipeline -> cooked volume
The pipeline is responsible for validation. That includes asset metadata, shader compilation, material interface binding, typed material layout, material surface and BXDF source resolution, mesh payload packing, dependency tracking, and deterministic output.
The runtime benefits from that work because it can load known binary formats instead of re-validating every source format during startup.
flowchart LR
Authored["Authored files"]
Cooker["Pipeline validation"]
Binary["Cooked binary records"]
Runtime["Typed runtime loading"]
Authored --> Cooker --> Binary --> Runtime
The world workflow starts when the loader creates the project context and calls project callbacks.
loader -> ProjectRuntimeContext -> project callbacks -> ECS world
The ECS world owns scene state. Systems update that state or derive runtime caches from it.
Core ECS only provides the generic entity/component/system mechanism. Engine content such as scene transforms, renderable objects, models, skinning, CSG, and UI lives in implementation modules.
flowchart LR
Loader["Loader"]
Context["ProjectRuntimeContext"]
Project["Project callbacks"]
World["ECS World"]
Systems["Systems tick and prepare state"]
Loader --> Context --> Project --> World --> Systems
The renderer workflow starts from ECS state and typed assets:
ECS state + material assets + mesh assets + shader archive -> renderer passes -> selected graphics backend
The graphics provider is selected at compile time through neutral RHI contracts and selected headers. Vulkan is the default and only implemented provider; Metal remains an unsupported future extension. Selection preserves concrete calls without adding runtime dispatch. See Architecture for the include boundary.
The renderer is material-driven. Renderable entities reference material and mesh/model data. Renderer systems resolve those assets, prepare GPU resources, choose feature paths, and record command lists.
The renderer can use different GPU paths based on device features:
- native mesh shaders when supported and enabled
- compute/vertex emulation when native mesh shaders are not active
- hardware ray tracing when acceleration structures, RT pipelines, and ray query support exist
- software BVH shadow traversal when hardware RT is unavailable or not selected for that path
flowchart LR
ECS["ECS state"]
Assets["Typed assets"]
Archive["Shader archive"]
Renderer["Renderer systems"]
Backend["Selected graphics backend"]
Present["Presented frame"]
ECS --> Renderer
Assets --> Renderer
Archive --> Renderer
Renderer --> Backend --> Present
The source tree has a clear ownership structure:
-
globalis the low-level utility layer. -
coreis reusable engine infrastructure. -
implis concrete engine content and rendering behavior. -
pipelineis the cook workflow:dependency_computer,asset_builder, andasset_gatherer. -
loaderis the runtime shell. -
Testbedis the current project. -
testscontains regression and smoke coverage. -
utilitiescontains standalone tools.
The most important split is the core service layer versus impl.
The core service layer should stay generic. It lives under core and owns asset management, ECS mechanics, graphics abstraction, CPU and GPU task scheduling, frame/window control, the IFilesystem volume interface, crash handling, telemetry, and logging.
impl owns concrete engine behavior. It provides asset types, material/shader cooking, scene systems, renderer systems, model/skinning systems, CSG, and UI integration.
The intended data direction is one-way:
source assets -> cooked volumes -> typed assets -> ECS state -> renderer state -> GPU
Runtime systems should not silently move backward in that chain. For example:
- runtime graphics should consume cooked SPIR-V bytecode, not compile Slang source
- renderer material binding uses typed cooked metadata and generated typed accessors
- project assets should be loaded through
AssetManager, not by ad hoc filesystem reads - shared shader ABI constants should come from shared headers, not duplicated runtime definitions
This rule keeps the runtime predictable and makes tests able to verify cook output, asset loading, material binding, and renderer behavior independently.
At startup:
-
loaderinitializes engine services. -
loadermounts the cookedgraphicsvolume. -
loaderregisters asset codecs. -
loaderloads shader archive records. -
loaderbuildsProjectRuntimeContext. -
Testbedcreates an ECS world. - Engine systems load assets and prepare runtime resources.
-
core/framedrives update and rendering.
During a frame:
- platform and input state update
- project update callback runs
- ECS systems tick
- render passes prepare resources
- command lists are recorded and submitted through the GPU task scheduler
- swapchain presentation finishes the frame
- telemetry and frame graph data are collected when enabled
CPU work during those steps uses the frame-owned CpuTaskScheduler. GPU recording, submission, and device waits use the peer GpuTaskScheduler. See CPU Task Scheduler and GPU Task Graph.
The detailed versions of those two flows are Runtime Boot and Renderer Frame Flow.
- Start Here
- Build and Verification
- Platform and GPU Support
- Graphics Device Selection
- Testbed
- Glossary
- Code Reading Guide
- Architecture
- Engine Concepts
- Asset Flow
- Frame Life Cycle
- Runtime Boot
- Project API
- Runtime and ECS
- CPU Task Scheduler
- Asset Pipeline
- Texture Conversion
- FBX to NWB Conversion
- Asset Types
- Cooked Volumes
- Filesystem
- Shader and Material System
- Mesh Model and Skinning