Repository navigation
Asset Pipeline
SparkEngine's AssetPipeline wires runtime loading, streaming, caching, and management for mesh, texture, and WAV audio assets. It provides synchronous and asynchronous entry points, an LRU cache with configurable memory budgets, hot reloading for development, and background streaming threads. Other asset kinds named by its enums and data structures are schema surfaces, not implemented LoadAsset() branches.
stable-v1 support boundary:
stable-v1is blocked and uncertified; its exact host is Windows 11 x64. Source presence and format parsing do not certify a format, backend, or authoring workflow for release use.
Source: SparkEngine/Source/Graphics/AssetPipeline.h
The sixteen Assets/Models/MMO props now have distinct Blender-authored
geometry, UVs, normals and same-name material libraries, with original paths
and bounds preserved. Editable source, pinned authoring instructions and
SHA-256 provenance are in Art/Blender/MMO.
The legacy generator validates these exports before any writes and preserves
them. CTest registers source-contract and generator regressions; sixteen
production CPU importer cases verify the complete kit. This is a focused
asset-quality checkpoint, not Windows/D3D11, installed-content or release
qualification. The wider baseline audit still
requires visual and contextual review of the remaining assets.
┌─────────────────────────────────────────────────────────────────────┐
│ Game Code │
│ LoadMesh() / LoadTexture() / LoadAudio() / LoadAssetAsync() │
├──────────────────────────────┬──────────────────────────────────────┤
│ AssetPipeline │ Console Integration │
│ (orchestrator, metrics, │ Console_ListAssets() │
│ hot reload, discovery) │ Console_GetAssetInfo() │
├──────────────────────────────┤ Console_LoadAsset() │
│ │ Console_ForceGC() │
│ Sync Loading Async Queue │ Console_SetCacheSize() │
│ │ │ ├──────────────────────────────────────┤
│ v v │ │
│ ┌─────────────────────┐ │ │
│ │ Format Loaders │ │ │
│ │ OBJ mesh path │ │ │
│ │ native FBXImporter │ │ │
│ │ cgltf static mesh │ │ │
│ │ texture loaders │ │ │
│ │ WAV loader │ │ │
│ └─────────┬───────────┘ │ │
│ v │ │
│ ┌─────────────────────┐ │ │
│ │ AssetCache (LRU) │ │ │
│ │ m_maxMemory (512MB)│ │ │
│ │ hit/miss tracking │ │ │
│ └─────────────────────┘ │ │
│ v │ │
│ ┌─────────────────────┐ │ │
│ │ D3D11 GPU Upload │ │ │
│ │ Vertex/Index Bufs │ │ │
│ │ Texture SRVs │ │ │
│ └─────────────────────┘ │ │
└──────────────────────────────┴──────────────────────────────────────┘
| Type | Responsibility |
|---|---|
AssetPipeline |
Main system: loading, caching, streaming, hot reload, metrics |
Asset |
Abstract base class for all loaded assets |
MeshAsset |
Loaded mesh with vertex/index buffers on GPU |
TextureAsset |
Loaded texture with SRV on GPU |
AudioAsset |
Loaded audio data (PCM samples) |
AssetCache |
LRU eviction cache with configurable memory budget |
AssetMetadata |
Per-asset metadata: GUID, path, size, checksum, dependencies |
AssetLoadRequest |
Async load request with callbacks |
MeshAssetData |
CPU-side mesh data (vertices, indices, bounds) |
AnimationAssetData |
Animation-shaped CPU data schema; no LoadAsset() branch or model-import handoff currently consumes it |
Only MeshAsset, TextureAsset, and AudioAsset are constructed by the Windows and Linux AssetPipeline::LoadAsset() switches. The remaining enum values and data schemas are placeholders until a loader and runtime handoff are wired.
| Value | Description |
|---|---|
Unknown |
Type not yet determined |
Mesh |
3D model geometry |
Texture |
2D texture image |
Material |
Material definition placeholder (not loaded by LoadAsset()) |
Audio |
Sound data |
Animation |
Animation clip placeholder (not loaded by LoadAsset()) |
Prefab |
Entity prefab template placeholder (not loaded by LoadAsset()) |
Scene |
Scene definition placeholder (not loaded by LoadAsset()) |
Shader |
Shader program placeholder (not loaded by LoadAsset()) |
Font |
Font asset placeholder (not loaded by LoadAsset()) |
| Value | Description | Use Case |
|---|---|---|
Low |
Background loading, not time-sensitive | Distant LODs, preloading |
Normal |
Standard priority | Most game assets |
High |
Load soon, needed for gameplay | Weapons, nearby enemies |
Critical |
Load immediately, block if needed | Player model, UI textures |
| Value | Description |
|---|---|
Unloaded |
Asset not in memory |
Loading |
Currently being loaded |
Loaded |
Fully loaded and usable |
Failed |
Load failed (file not found, corrupt, etc.) |
Evicted |
Was loaded but evicted from cache |
These entries describe observed source paths, not a stable-v1 support matrix.
| Format | Description | Library | Loader Method |
|---|---|---|---|
.obj |
Static Wavefront OBJ geometry | tinyobjloader in the general mesh/scene and non-Windows paths; a limited parser in the Windows MeshAsset path |
MeshAsset::Load() / LoadOBJ()
|
.fbx |
Native binary FBX parsing; the non-Windows mesh path consumes geometry only |
FBXImporter (no external FBX SDK) |
Native importer source; not wired into the Windows stable-v1 MeshAsset path |
.gltf / .glb
|
Validated static triangle geometry; skins, animations, morph targets, sparse accessors, and required extensions are rejected | cgltf | LoadGLTFStaticMesh() |
| Format | Description | Library |
|---|---|---|
.png |
Lossless compressed | stb_image |
.jpg |
Lossy compressed | stb_image |
.tga |
Targa | stb_image |
.bmp |
Bitmap | stb_image |
.hdr |
High Dynamic Range | stb_image |
| Format | Description | Library |
|---|---|---|
.wav |
RIFF/WAVE runtime asset loading | WAV loader; playback factory selects XAudio2 on Windows, OpenAL on non-Windows, then Null |
These formats are handled by other subsystems or represented by schema; they are not additional AssetPipeline::LoadAsset() branches.
| Format | Description |
|---|---|
.scene / .json
|
JSON scene files |
.prefab |
Prefab templates |
.snav |
Binary NavMesh data |
| Format | Description |
|---|---|
.hlsl |
HLSL shader source |
.glsl |
GLSL shader source |
.cso |
Compiled DirectX bytecode |
.spv |
SPIR-V bytecode |
Assets/assets.integrity.json records SHA-256 hashes for the first-party
Assets/ tree. Git treats Assets/** as opaque bytes (-text), except
.obj and .mtl files which are text-normalized to LF (text eol=lf).
The manifest hashes describe the checkout bytes after normalization. Verify
the repository baseline and template lock completeness with:
python3 tools/asset-integrity/verify_asset_integrity.py check-all --repo-root .
python3 tools/asset-integrity/verify_asset_integrity.py verify Assets/assets.integrity.json --root AssetsThe explicit --root is authoritative; manifest metadata cannot redirect the
scan. Verification rejects traversal and Windows path aliases, reparses,
non-regular files, incomplete declarations, resource-limit violations, and a
file that changes while it is read. This is a repository-content gate, not yet
proof that the same verified snapshot was consumed by package assembly.
Assets/
├── Models/ # 3D model files (.obj, .fbx, .gltf)
├── Scenes/ # Scene files (.scene, .json)
├── Scripts/ # AngelScript files (.as)
├── Textures/ # Texture files (.png, .jpg, .tga)
├── Audio/ # Sound files (.wav)
├── NavMeshes/ # Navigation mesh files (.snav)
├── Prefabs/ # Prefab templates (.prefab)
└── Cinematics/ # Cinematic sequences (.seq)
Shaders/
├── HLSL/ # DirectX shaders
├── GLSL/ # OpenGL shaders
└── Compiled/ # Pre-compiled bytecode
struct MeshAssetData
{
struct Vertex
{
XMFLOAT3 position; // World-space position
XMFLOAT3 normal; // Surface normal
XMFLOAT3 tangent; // Tangent for normal mapping
XMFLOAT2 texCoord0; // Primary UV channel
XMFLOAT2 texCoord1; // Secondary UV channel (lightmaps)
XMFLOAT4 color; // Vertex color
XMUINT4 boneIndices; // Skeletal bone indices (up to 4 bones)
XMFLOAT4 boneWeights; // Bone influence weights
};
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
std::vector<uint32_t> submeshes; // Submesh start indices
XMFLOAT3 boundingBoxMin; // AABB minimum
XMFLOAT3 boundingBoxMax; // AABB maximum
float boundingSphereRadius; // Bounding sphere radius
XMFLOAT3 boundingSphereCenter; // Bounding sphere center
};The declared fields cover:
- Static meshes (position, normal, tangent, UVs, color)
- Skeletal meshes (adds boneIndices and boneWeights for up to 4 bone influences)
- Lightmapped meshes (uses texCoord1 for lightmap UVs)
AnimationAssetData is a data schema only. The current AssetPipeline does not load AssetType::Animation, and the model format paths do not convert or register this structure with AnimationManager.
struct AnimationAssetData
{
struct Keyframe
{
float time; // Time in seconds
XMFLOAT3 position; // Translation
XMFLOAT4 rotation; // Quaternion rotation
XMFLOAT3 scale; // Scale
};
struct AnimationTrack
{
std::string boneName; // Target bone name
std::vector<Keyframe> keyframes; // Keyframes sorted by time
};
std::string name; // Clip name (e.g. "walk", "idle")
float duration; // Total duration in seconds
float ticksPerSecond; // Animation sample rate
std::vector<AnimationTrack> tracks; // Per-bone keyframe tracks
};struct AssetMetadata
{
std::string guid; // Unique asset identifier
std::string filePath; // Original file path
std::string name; // Human-readable name
AssetType type; // Asset type enum
size_t fileSize; // File size in bytes
size_t memorySize; // GPU/CPU memory footprint
uint64_t lastModified; // File modification timestamp
std::string checksum; // Content hash for change detection
std::vector<std::string> dependencies; // Other assets this depends on
LoadingPriority priority; // Loading priority
StreamingState state; // Current streaming state
std::unordered_map<std::string, std::string> customProperties;
};struct AssetLoadRequest
{
std::string assetPath; // File path to load
AssetType expectedType; // Expected type (for validation)
LoadingPriority priority; // Queue priority
std::function<void(std::shared_ptr<void>)> onLoaded; // Success callback
std::function<void(const std::string&)> onError; // Error callback
bool blocking = false; // Block calling thread until done
};All asset types derive from Asset:
class Asset
{
public:
Asset(const std::string& path, AssetType type);
virtual ~Asset() = default;
const std::string& GetPath() const;
AssetType GetType() const;
bool IsLoaded() const;
const AssetMetadata& GetMetadata() const;
virtual HRESULT Load(ID3D11Device* device) = 0;
virtual void Unload() = 0;
virtual size_t GetMemoryUsage() const = 0;
protected:
std::string m_path;
AssetType m_type;
bool m_loaded;
AssetMetadata m_metadata;
};class MeshAsset : public Asset
{
public:
MeshAsset(const std::string& path);
HRESULT Load(ID3D11Device* device) override;
void Unload() override;
size_t GetMemoryUsage() const override;
const MeshAssetData& GetMeshData() const;
ID3D11Buffer* GetVertexBuffer() const;
ID3D11Buffer* GetIndexBuffer() const;
uint32_t GetVertexCount() const;
uint32_t GetIndexCount() const;
};Holds both CPU-side MeshAssetData and GPU-side ComPtr<ID3D11Buffer> for vertex and index buffers.
class TextureAsset : public Asset
{
public:
TextureAsset(const std::string& path);
HRESULT Load(ID3D11Device* device) override;
void Unload() override;
size_t GetMemoryUsage() const override;
ID3D11ShaderResourceView* GetSRV() const;
uint32_t GetWidth() const;
uint32_t GetHeight() const;
};Holds ComPtr<ID3D11Texture2D> and ComPtr<ID3D11ShaderResourceView> for GPU texture access.
class AudioAsset : public Asset
{
public:
AudioAsset(const std::string& path);
HRESULT Load(ID3D11Device* device) override;
void Unload() override;
size_t GetMemoryUsage() const override;
const std::vector<uint8_t>& GetAudioData() const;
uint32_t GetSampleRate() const;
uint32_t GetChannels() const;
uint32_t GetBitsPerSample() const;
};Stores raw PCM audio data in a std::vector<uint8_t>.
LRU eviction cache for managing loaded assets within a memory budget:
class AssetCache
{
public:
AssetCache(size_t maxMemoryMB = 512);
void SetMaxMemory(size_t maxMemoryMB);
size_t GetMaxMemory() const;
size_t GetCurrentMemory() const;
void AddAsset(std::shared_ptr<Asset> asset);
std::shared_ptr<Asset> GetAsset(const std::string& path);
void RemoveAsset(const std::string& path);
void EvictLRU(); // Evict least-recently-used asset
void Clear(); // Remove all cached assets
// Statistics
uint32_t GetCacheHits() const;
uint32_t GetCacheMisses() const;
float GetHitRatio() const;
};struct CacheEntry // (private)
{
std::shared_ptr<Asset> asset;
uint64_t lastAccessed; // Timestamp of last access
size_t accessCount; // Total access count
};The cache uses std::unordered_map<std::string, CacheEntry> keyed by asset path. When memory exceeds m_maxMemory, EvictLRU() removes the least-recently-accessed entry.
| Default | Value | Description |
|---|---|---|
| Max memory | 512 MB | Configurable via SetMaxMemory()
|
| Eviction policy | LRU | Least Recently Used based on lastAccessed
|
AssetPipeline pipeline;
HRESULT hr = pipeline.Initialize(device, context);
pipeline.Update(deltaTime); // Call each frame for async loading + hot reload
pipeline.Shutdown();// Generic load (auto-detect type)
auto asset = pipeline.LoadAsset("Assets/Models/crate.obj");
// Type-specific loads
auto mesh = pipeline.LoadMesh("Assets/Models/character.fbx");
auto texture = pipeline.LoadTexture("Assets/Textures/brick_albedo.png");
auto audio = pipeline.LoadAudio("Assets/Audio/explosion.wav");// Generic async with callbacks
AssetLoadRequest request;
request.assetPath = "Assets/Models/large_building.fbx";
request.expectedType = AssetType::Mesh;
request.priority = LoadingPriority::Normal;
request.onLoaded = [](std::shared_ptr<void> asset) { /* ready */ };
request.onError = [](const std::string& error) { LOG_ERROR(error); };
pipeline.LoadAssetAsync(request);
// Type-specific async
pipeline.LoadMeshAsync("Assets/Models/enemy.fbx",
[](std::shared_ptr<MeshAsset> mesh) {
// Mesh is ready for rendering
});
pipeline.LoadTextureAsync("Assets/Textures/terrain.png",
[](std::shared_ptr<TextureAsset> tex) {
// Texture is ready
});// Query
auto asset = pipeline.GetAsset("Assets/Models/crate.obj");
bool loaded = pipeline.IsAssetLoaded("Assets/Models/crate.obj");
// Unload
pipeline.UnloadAsset("Assets/Models/crate.obj");
pipeline.UnloadAllAssets();pipeline.SetCacheSize(1024); // Set cache to 1024 MB
pipeline.EvictUnusedAssets(); // Remove assets with zero references
// Preload a batch of assets (async)
pipeline.PreloadAssets({
"Assets/Models/weapon_rifle.fbx",
"Assets/Textures/weapon_rifle_albedo.png",
"Assets/Textures/weapon_rifle_normal.png",
"Assets/Audio/rifle_fire.wav"
});pipeline.EnableBackgroundStreaming(true);
pipeline.SetStreamingThreadCount(4); // 4 worker threads
bool streaming = pipeline.IsBackgroundStreamingEnabled();
int threads = pipeline.GetStreamingThreadCount();// Bind and draw a mesh
pipeline.BindMesh("Assets/Models/crate.obj");
pipeline.BindMaterial("Assets/Materials/crate_mat.json");
pipeline.DrawBoundMesh();// Scan a directory for assets of a specific type
auto meshFiles = pipeline.ScanDirectory("Assets/Models/", AssetType::Mesh);
// Returns: ["Assets/Models/crate.obj", "Assets/Models/character.fbx", ...]
// Auto-detect asset type from file extension
AssetType type = pipeline.DetectAssetType("Assets/Textures/brick.png");
// Returns: AssetType::TextureAssetMetadata meta = pipeline.GetAssetMetadata("Assets/Models/crate.obj");
// meta.guid, meta.fileSize, meta.memorySize, meta.checksum, meta.dependencies
pipeline.RefreshAssetMetadata("Assets/Models/crate.obj"); // Re-scan filepipeline.EnableHotReloading(true);
// Called internally by Update(), but can be triggered manually:
pipeline.CheckForChangedAssets();When enabled, Update() periodically checks file timestamps against m_fileTimestamps. Changed files are automatically reloaded. Supports:
- Texture files (.png, .jpg, .tga, .bmp, .hdr)
- Shader source files (.hlsl, .glsl)
- AngelScript files (.as)
- Scene files (.scene, .json)
struct AssetMetrics
{
uint32_t totalAssets; // Total registered assets
uint32_t loadedAssets; // Currently loaded in memory
uint32_t pendingRequests; // Waiting in the load queue
uint32_t failedLoads; // Failed load attempts
size_t memoryUsage; // Current memory usage (bytes)
size_t maxMemoryUsage; // Peak memory usage (bytes)
float averageLoadTime; // Average load time (ms)
float cacheHitRatio; // Cache hit ratio (0.0 - 1.0)
uint32_t streamingThreads; // Active streaming threads
bool backgroundLoading; // Background loading enabled
};
AssetMetrics metrics = pipeline.GetMetrics();When background streaming is enabled, worker threads run LoadingThreadFunction() in a loop:
LoadingThreadFunction():
while (!m_shouldStop):
lock(m_queueMutex)
wait(m_queueCondition) until queue non-empty or stop
pop request from m_loadQueue
unlock
load asset from disk (CPU)
upload to GPU (may need main thread for D3D11)
invoke request.onLoaded or request.onError callback
update metrics
DetectAssetTypeFromExtension() maps file extensions to AssetType:
| Extensions | AssetType |
|---|---|
.obj, .fbx, .gltf, .glb
|
Mesh |
.png, .jpg, .tga, .bmp, .hdr
|
Texture |
.wav |
Audio |
.hlsl, .glsl, .cso, .spv
|
Shader |
.scene, .json
|
Scene |
.prefab |
Prefab |
.anim |
Animation |
CheckForChangedAssets():
for each (path, oldTimestamp) in m_fileTimestamps:
newTimestamp = GetFileTimestamp(path)
if newTimestamp != oldTimestamp:
reload asset at path
update m_fileTimestamps[path]
The pipeline tracks memory at two levels:
-
Per-asset: Each
Assetsubclass reportsGetMemoryUsage()(GPU + CPU) -
Cache-level:
AssetCachesums all entries and enforces the memory budget
When the cache exceeds its budget, EvictLRU() removes the least-recently-accessed assets that have no active shared_ptr references outside the cache.
| Level | Description |
|---|---|
| Low | Quarter resolution, basic filtering |
| Medium | Half resolution, bilinear filtering |
| High | Full resolution, anisotropic filtering |
| Ultra | Full resolution, max anisotropic filtering |
Best for simple static meshes with basic materials:
auto mesh = pipeline.LoadMesh("Assets/Models/crate.obj");
// Parses: vertex positions, normals, texture coordinates
// Generates: tangents, bounding box/sphereFBXImporter is a native binary FBX parser with no external FBX SDK dependency. Its result type exposes meshes, bones, and animations, but the current MeshAsset integration validates without requiring a skeleton or animation and copies only geometry on the non-Windows path. The Windows MeshAsset path has no FBX branch.
There is no current conversion or registration handoff from FBXImportResult to AnimationManager. End-to-end FBX skeletal or animation ingestion is therefore absent from this pipeline rather than an implied feature of the result structures.
auto mesh = pipeline.LoadMesh("Assets/Models/weapon.gltf");
// Parses validated static triangle geometry: POSITION, NORMAL,
// TEXCOORD_0, and optional unsigned indices.LoadGLTFStaticMesh() is deliberately a static-mesh subset. It rejects skins, animations, morph targets, sparse accessors, non-triangle primitives, and required extensions; it does not import PBR material or texture graphs.
The canonical Blender-authored static fixture lives in Tests/Fixtures/GLTFStaticMesh/BlenderBox/ with an editable compressed .blend, reproducible author/export script, GLB, and hash-bound provenance. GLTFStaticMesh_LoadsBlenderAuthoredStaticBox exercises the production CPU loader against its nonuniform applied-transform box: exported axis-converted bounds, flat normals, all six faces' geometric-corner/UV associations, triangle winding/area, and indices. This establishes the documented static attribute contract only; D3D11 rendering, scene-node transforms, skeletal data, animation, and packaged-content certification remain separate requirements.
| Format path | Data handed to MeshAssetData
|
Current limit |
|---|---|---|
| OBJ | Positions, normals, texture coordinates, and triangle indices | Static geometry path; parser details vary by platform/caller |
| Native FBX | Geometry on the non-Windows MeshAsset path |
No Windows MeshAsset branch and no AnimationManager handoff |
| cgltf | Static triangle positions, normals, one UV set, and indices | Skins, animations, morph targets, and PBR material graphs are not ingested |
| Scenario | Behavior |
|---|---|
| File not found | Returns nullptr (sync) or invokes onError callback (async) |
| Corrupt file data |
Load() returns failure HRESULT; asset marked StreamingState::Failed
|
| GPU buffer creation fails |
HRESULT propagated; asset not marked as loaded |
| Cache memory exceeded | LRU eviction triggered automatically |
| Hot reload file changed | Asset reloaded; old GPU resources released via ComPtr ref counting |
| Async load thread crash | Thread isolation; error logged, other threads continue |
| Unknown file extension |
DetectAssetType returns AssetType::Unknown
|
| Parameter | Default | Description |
|---|---|---|
| Cache size | 512 MB |
AssetCache max memory budget |
| Streaming threads | Platform-dependent | Set via SetStreamingThreadCount()
|
| Hot reload | Enabled | File timestamp polling each frame |
| Load queue | Priority-ordered | Higher priority requests served first |
-
Preload critical assets during loading screens with
PreloadAssets() -
Set appropriate priorities: Use
Criticalfor player/weapon assets,Lowfor distant scenery - Monitor cache hit ratio: Below 0.5 suggests the cache is too small or assets churn too fast
- Disable hot reloading in shipping builds to avoid file timestamp overhead
-
Use
.gltf/.glbonly for the implemented static subset; validate authoring output against the rejected-feature list - Batch directory scans during loading rather than at runtime
| Component | Thread Safety | Details |
|---|---|---|
AssetPipeline |
Partially thread-safe |
m_assetsMutex protects the asset map; m_queueMutex protects the load queue |
AssetCache |
Thread-safe |
m_mutex protects all cache operations |
Asset::Load() |
Not thread-safe | D3D11 device calls must happen on the main thread or deferred context |
| Hot reload | Main thread only |
CheckForChangedAssets() reads file timestamps on the main thread |
| Metrics | Thread-safe |
m_metricsMutex protects metric reads/writes |
Background Thread: Main Thread:
Read file from disk (safe) pipeline.Update(dt)
Parse mesh data (safe) -> complete pending GPU uploads
Queue GPU upload request -> invoke onLoaded callbacks
-> check hot reload timestamps
GPU resource creation (ID3D11Device::CreateBuffer, CreateTexture2D) must be called from the main thread or a deferred context. Background threads handle only CPU-side file I/O and parsing.
asset_list # List all loaded assets with type and memory
asset_info <path> # Show detailed metadata for a specific asset
asset_load <path> # Load an asset synchronously
asset_unload <path> # Unload a specific asset
asset_cache_size <MB> # Set cache size in MB
asset_gc # Force garbage collection of unreferenced assets
asset_streaming <on|off> # Enable/disable background streaming
asset_threads <count> # Set number of streaming threads
asset_scan <directory> # Scan directory and report found assets
asset_hot_reload <on|off> # Enable/disable hot reloading
asset_preload <directory> # Preload all assets in a directory
asset_reload_all # Force reload all loaded assets
| Symptom | Possible Cause | Solution |
|---|---|---|
Asset returns nullptr
|
File path wrong or file missing | Verify path relative to working directory |
| Texture appears black | SRV creation failed | Check HRESULT from Load(); verify D3D11 device |
| Mesh has no vertices | File format not supported or corrupt | Check file extension; try re-exporting from DCC tool |
| Async callback never fires | Background streaming disabled | Call EnableBackgroundStreaming(true)
|
| Memory usage grows unbounded | Cache not configured | Set appropriate cache size with SetCacheSize()
|
| Hot reload not working | Hot reloading disabled | Call EnableHotReloading(true); ensure Update() called each frame |
| Load takes too long | Too few streaming threads | Increase with SetStreamingThreadCount()
|
| Cache hit ratio is 0 | Assets loaded but not accessed through cache | Use GetAsset() for subsequent accesses |
| FBX skeleton or clips are unavailable | No current importer-to-AnimationManager handoff |
A separately verified conversion tool would be required to produce .skel/.sanim; this pipeline does not provide that conversion |
| glTF skin, animation, morph, or material data is unavailable | The cgltf path intentionally loads static geometry only | Export a static triangle mesh subset; use separately wired systems for other data |
std::string AssetTypeToString(AssetType type); // "Mesh", "Texture", etc.
AssetType StringToAssetType(const std::string& str); // Reverse lookup
std::string StreamingStateToString(StreamingState state); // "Loaded", "Failed", etc.
std::string LoadingPriorityToString(LoadingPriority p); // "Low", "Normal", etc.- Rendering and Graphics -- Material and texture systems
-
Animation -- Runtime
.skel/.sanimasset boundary - Shader Pipeline -- Shader compilation
- Scene Management -- Scene file loading
- Audio -- Audio asset formats and loading
- Terrain and Procedural Generation -- Terrain asset streaming
- Entity Component System -- Component-based asset references
Published from 2b03dc797148. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers