Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. Missing collider on floor:
#![allow(unused)]
fn main() {
world.core.set_collider(floor, ColliderComponent::new_cuboid(50.0, 0.5, 50.0));
}
  1. 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);
}
  1. 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

  1. 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);
    }
}
}
  1. Call update each frame:
#![allow(unused)]
fn main() {
fn run_systems(&mut self, world: &mut World) {
    update_animation_players(world, dt);
}
}
  1. 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

  1. 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());
}
  1. Check audio feature is enabled:
nightshade = { git = "...", features = ["engine", "wgpu", "audio"] }
  1. Verify file format: Supported formats are WAV, OGG, MP3, FLAC.

Performance Issues

Low frame rate

  1. Check entity count:
#![allow(unused)]
fn main() {
println!("Entities: {}", world.core.query_entities(RENDER_MESH).count());
}
  1. Disable expensive effects:
#![allow(unused)]
fn main() {
world.resources.graphics.ssao_enabled = false;
world.resources.graphics.bloom_enabled = false;
}
  1. Reduce shadow quality:
#![allow(unused)]
fn main() {
world.resources.graphics.shadow_map_size = 1024; // Default is 2048
}
  1. Use simpler colliders:
#![allow(unused)]
fn main() {
world.core.set_collider(entity, ColliderComponent::new_cuboid(1.0, 1.0, 1.0));
}

Memory usage high

  1. Despawn unused entities:
#![allow(unused)]
fn main() {
world.despawn_entities(&[entity]);
}
  1. Unload unused textures:
#![allow(unused)]
fn main() {
world.resources.texture_cache.clear_unused();
}
  1. Use smaller textures for distant objects.

Stuttering / hitching

  1. 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) {
    // ...
}
}
  1. 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

  1. Normal maps inverted: Some tools export Y-flipped normals. Check your export settings.

  2. sRGB vs Linear: Base color textures should be sRGB. Normal/metallic/roughness should be linear.

  3. 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.enabled in 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:

  1. Check the GitHub Issues
  2. Search existing issues for similar problems
  3. Create a new issue with:
    • Nightshade version
    • Platform (OS, GPU)
    • Minimal code to reproduce
    • Error message or screenshot