Troubleshooting
Common issues and their solutions.
Compilation Errors
"feature X is not enabled"
You're using a feature that isn't enabled in your Cargo.toml. Add the required feature:
nightshade = { git = "...", features = ["engine", "wgpu", "physics", "audio"] }
See Feature Flags for the complete list.
"cannot find function spawn_cube_at"
Import the prelude:
#![allow(unused)] fn main() { use nightshade::prelude::*; }
"the trait State is not implemented"
Ensure your game struct implements all required methods:
#![allow(unused)] fn main() { impl State for MyGame { fn title(&self) -> &str { "My Game" } fn initialize(&mut self, world: &mut World) {} fn run_systems(&mut self, world: &mut World) {} } }
"nalgebra_glm vs glam conflict"
Nightshade uses nalgebra_glm exclusively. Don't mix with glam:
#![allow(unused)] fn main() { // Correct use nalgebra_glm::Vec3; // Wrong - will cause type mismatches use glam::Vec3; }
Runtime Errors
"No suitable adapter found"
Your GPU doesn't support the required graphics API.
Windows:
- Update graphics drivers
- Install Vulkan Runtime from https://vulkan.lunarg.com/
- Try forcing DX12:
WGPU_BACKEND=dx12 ./game.exe
Linux:
- Install Vulkan drivers:
sudo apt install mesa-vulkan-drivers - Verify with
vulkaninfo
macOS:
- Ensure macOS 10.13+ (Metal required)
- Check System Report > Graphics for Metal support
"Entity not found"
You're accessing an entity that was despawned or never existed:
#![allow(unused)] fn main() { // Check entity exists before access if world.has_entity(entity) { if let Some(transform) = world.core.get_local_transform(entity) { // Safe to use } } }
"Texture not found"
The texture path is incorrect or the file doesn't exist:
#![allow(unused)] fn main() { import_gltf_from_path(std::path::Path::new("assets/models/character.glb")); // Correct import_gltf_from_path(std::path::Path::new("/home/user/game/assets/models/character.glb")); // Avoid absolute paths }
Physics objects fall through floor
Common causes:
- Missing collider on floor:
#![allow(unused)] fn main() { world.core.set_collider(floor, ColliderComponent::new_cuboid(50.0, 0.5, 50.0)); }
- Objects spawned inside each other:
#![allow(unused)] fn main() { // Spawn above the floor, not at y=0 transform.translation = Vec3::new(0.0, 2.0, 0.0); }
- High velocity causing tunneling:
#![allow(unused)] fn main() { // Enable CCD for fast objects let mut body = RigidBodyComponent::new_dynamic(); body.ccd_enabled = true; world.core.set_rigid_body(entity, body); }
Animation not playing
- Check animation name exists:
#![allow(unused)] fn main() { if let Some(player) = world.core.get_animation_player_mut(entity) { // List available animations for name in player.available_animations() { println!("Animation: {}", name); } } }
- Call update each frame:
#![allow(unused)] fn main() { fn run_systems(&mut self, world: &mut World) { update_animation_players(world, dt); } }
- Animation player is on child entity:
#![allow(unused)] fn main() { // glTF animations are often on child nodes for child in world.resources.children_cache.get(&model_root).cloned().unwrap_or_default() { if let Some(player) = world.core.get_animation_player_mut(child) { player.play("idle"); } } }
No audio output
- Create an AudioSource entity:
#![allow(unused)] fn main() { let sound = world.spawn_entities(AUDIO_SOURCE | LOCAL_TRANSFORM | GLOBAL_TRANSFORM, 1)[0]; world.core.set_audio_source(sound, AudioSource::new("shoot").playing()); }
- Check audio feature is enabled:
nightshade = { git = "...", features = ["engine", "wgpu", "audio"] }
- Verify file format: Supported formats are WAV, OGG, MP3, FLAC.
Performance Issues
Low frame rate
- Check entity count:
#![allow(unused)] fn main() { println!("Entities: {}", world.core.query_entities(RENDER_MESH).count()); }
- Disable expensive effects:
#![allow(unused)] fn main() { world.resources.graphics.ssao_enabled = false; world.resources.graphics.bloom_enabled = false; }
- Reduce shadow quality:
#![allow(unused)] fn main() { world.resources.graphics.shadow_map_size = 1024; // Default is 2048 }
- Use simpler colliders:
#![allow(unused)] fn main() { world.core.set_collider(entity, ColliderComponent::new_cuboid(1.0, 1.0, 1.0)); }
Memory usage high
- Despawn unused entities:
#![allow(unused)] fn main() { world.despawn_entities(&[entity]); }
- Unload unused textures:
#![allow(unused)] fn main() { world.resources.texture_cache.clear_unused(); }
- Use smaller textures for distant objects.
Stuttering / hitching
- Avoid allocations in run_systems:
#![allow(unused)] fn main() { // Bad - allocates every frame let entities: Vec<Entity> = world.core.query_entities(LOCAL_TRANSFORM).collect(); // Good - iterate directly for entity in world.core.query_entities(LOCAL_TRANSFORM) { // ... } }
- Preload assets in initialize:
#![allow(unused)] fn main() { fn initialize(&mut self, world: &mut World) { spawn_cube_at(world, Vec3::new(0.0, 1.0, 0.0)); } }
Visual Issues
Objects are black
Missing or incorrect lighting:
#![allow(unused)] fn main() { spawn_sun(world); world.resources.graphics.ambient_light = [0.1, 0.1, 0.1, 1.0]; }
Objects are too bright / washed out
Adjust tonemapping and color grading:
#![allow(unused)] fn main() { world.resources.graphics.color_grading.tonemap_algorithm = TonemapAlgorithm::Aces; world.resources.graphics.color_grading.brightness = 0.0; }
Textures look wrong
-
Normal maps inverted: Some tools export Y-flipped normals. Check your export settings.
-
sRGB vs Linear: Base color textures should be sRGB. Normal/metallic/roughness should be linear.
-
Texture coordinates flipped: glTF uses top-left origin. Some models may need UV adjustment.
Z-fighting (flickering surfaces)
Surfaces too close together:
#![allow(unused)] fn main() { // Increase near plane camera.near = 0.1; // Instead of 0.01 // Or separate surfaces more floor_transform.translation.y = 0.0; decal_transform.translation.y = 0.01; // Slight offset }
WebAssembly Issues
"WebGPU not supported"
- Use Chrome 113+ or Edge 113+
- Firefox requires enabling
dom.webgpu.enabledin about:config - Safari support is limited
Assets fail to load
WASM can't access the filesystem. Serve assets via HTTP:
<script>
// Assets must be fetched, not loaded from disk
fetch('assets/model.glb')
.then(response => response.arrayBuffer())
.then(data => { /* use data */ });
</script>
Performance worse than native
Expected. WebGPU has overhead. Reduce quality settings:
#![allow(unused)] fn main() { #[cfg(target_arch = "wasm32")] { world.resources.graphics.ssao_enabled = false; world.resources.graphics.shadow_map_size = 512; } }
Getting Help
If your issue isn't listed here:
- Check the GitHub Issues
- Search existing issues for similar problems
- Create a new issue with:
- Nightshade version
- Platform (OS, GPU)
- Minimal code to reproduce
- Error message or screenshot