# GECS Troubleshooting Guide

> **Quickly solve common GECS issues**

This guide helps you diagnose and fix the most common problems when working with GECS. Find your issue, apply the solution, and learn how to prevent it.

## 📋 Quick Diagnosis

### My Game Isn't Working At All

**Symptoms**: No entities moving, systems not running, nothing happening

**Quick Check**:

```gdscript
# In your _process() method, ensure you have:
func _process(delta):
    if ECS.world:
        ECS.world.process(delta)  # This line is critical!
```

**Missing this?** → [Systems Not Running](#systems-not-running)

### Entities Aren't Moving/Updating

**Symptoms**: Entities exist but don't respond to systems

**Quick Check**:

1. Are your entities added to the world? `ECS.world.add_entity(entity)`
2. Do your entities have the right components? Check system queries
3. Are your systems properly organized in scene hierarchy? Check default_systems.tscn

**Still broken?** → [Entity Issues](#entity-issues)

### Performance Is Terrible

**Symptoms**: Low FPS, stuttering, slow response

**Quick Check**:

1. Enable profiling: `ECS.world.enable_profiling = true`
2. Check entity count: `print(ECS.world.entity_count)`
3. Look for expensive queries in your systems

**Need optimization?** → [Performance Issues](#performance-issues)

## 🚫 Systems Not Running

### Problem: Systems Never Execute

**Error Messages**:

- No error, but `process()` method never called
- Entities exist but don't change

**Solution**:

```gdscript
# ✅ Ensure this exists in your main scene
func _process(delta):
    ECS.process(delta)  # This processes all systems

# OR if using system groups:
func _process(delta):
    ECS.process(delta, "physics")
    ECS.process(delta, "render")
```

**Prevention**: Always call `ECS.process()` in your main game loop.

### Problem: System Query Returns Empty

**Symptoms**: System exists but `process()` never called

**Diagnosis**:

```gdscript
# Add this to your system for debugging
class_name MySystem extends System

func _ready():
    print("MySystem query result: ", query().execute().size())

func query():
    return q.with_all([C_ComponentA, C_ComponentB])
```

**Common Causes**:

1. **Missing Components**:

   ```gdscript
   # ❌ Problem - Entity missing required component
   var entity = Entity.new()
   entity.add_component(C_ComponentA.new())
   # Missing C_ComponentB!

   # ✅ Solution - Add all required components
   entity.add_component(C_ComponentA.new())
   entity.add_component(C_ComponentB.new())
   ```

2. **Wrong Component Types**:

   ```gdscript
   # ❌ Problem - Using instance instead of class
   func query():
       return q.with_all([C_ComponentA.new()])  # Wrong!

   # ✅ Solution - Use class reference
   func query():
       return q.with_all([C_ComponentA])  # Correct!
   ```

3. **Component Not Added to World**:

   ```gdscript
   # ❌ Problem - Entity not in world
   var entity = Entity.new()
   entity.add_component(C_ComponentA.new())
   # Entity never added to world!

   # ✅ Solution - Add entity to world
   ECS.world.add_entity(entity)
   ```

## 🎭 Entity Issues

### Problem: Entity Components Not Found

**Error Messages**:

- `get_component() returned null`
- `Entity does not have component of type...`

**Diagnosis**:

```gdscript
# Debug what components an entity actually has
func debug_entity_components(entity: Entity):
    print("Entity components:")
    for component_path in entity.components.keys():
        print("  ", component_path)
```

**Solution**: Ensure components are added correctly:

```gdscript
# ✅ Correct component addition
var entity = Entity.new()
entity.add_component(C_Health.new(100))
entity.add_component(C_Position.new(Vector2(50, 50)))

# Verify component exists before using
if entity.has_component(C_Health):
    var health = entity.get_component(C_Health)
    health.current -= 10
```

### Problem: Component Properties Not Updating

**Symptoms**: Setting component properties has no effect

**Common Causes**:

1. **Getting Component Reference Once**:

   ```gdscript
   # ❌ Problem - Stale component reference
   var health = entity.get_component(C_Health)
   # ... later in code, component gets replaced ...
   health.current = 50  # Updates old component!

   # ✅ Solution - Get fresh reference each time
   entity.get_component(C_Health).current = 50
   ```

2. **Modifying Wrong Entity**:

   ```gdscript
   # ❌ Problem - Variable confusion
   var player = get_player_entity()
   var enemy = get_enemy_entity()

   # Accidentally modify wrong entity
   player.get_component(C_Health).current = 0  # Meant to be enemy!

   # ✅ Solution - Use clear variable names
   var player_health = player.get_component(C_Health)
   var enemy_health = enemy.get_component(C_Health)
   enemy_health.current = 0
   ```

## 💥 Common Errors

### Error: "Cannot access property/method on null instance"

**Full Error**:

```
Invalid get index 'current' (on base: 'null instance')
```

**Cause**: Component doesn't exist on entity

**Solution**:

```gdscript
# ❌ Causes null error
var health = entity.get_component(C_Health)
health.current -= 10  # health is null!

# ✅ Safe component access
if entity.has_component(C_Health):
    var health = entity.get_component(C_Health)
    health.current -= 10
else:
    print("Entity doesn't have C_Health!")
```

### Error: "Class not found"

**Full Error**:

```
Identifier 'ComponentName' not found in current scope
```

**Causes & Solutions**:

1. **Missing class_name**:

   ```gdscript
   # ❌ Problem - No class_name declaration
   extends Component
   # Script exists but can't be referenced by name

   # ✅ Solution - Add class_name
   class_name C_Health
   extends Component
   ```

2. **File not saved or loaded**:

   - Save your component script files
   - Restart Godot if classes still not found
   - Check for syntax errors in the component file

3. **Wrong inheritance**:

   ```gdscript
   # ❌ Problem - Wrong base class
   class_name C_Health
   extends Node  # Should be Component!

   # ✅ Solution - Correct inheritance
   class_name C_Health
   extends Component
   ```

## 🐌 Performance Issues

### Problem: Low FPS / Stuttering

**Diagnosis Steps**:

1. **Enable profiling**:

   ```gdscript
   ECS.world.enable_profiling = true

   # Check processing times
   func _process(delta):
       ECS.process(delta)
       print("Frame time: ", get_process_delta_time() * 1000, "ms")
   ```

2. **Check entity count**:
   ```gdscript
   print("Total entities: ", ECS.world.entity_count)
   print("System count: ", ECS.world.get_system_count())
   ```

**Common Fixes**:

1. **Too Many Entities in Broad Queries**:

   ```gdscript
   # ❌ Problem - Overly broad query
   func query():
       return q.with_all([C_Position])  # Matches everything!

   # ✅ Solution - More specific query
   func query():
       return q.with_all([C_Position, C_Movable])
   ```

2. **Expensive Queries Rebuilt Every Frame**:

   ```gdscript
   # ❌ Problem - Rebuilding queries in process
   func process(entities: Array[Entity], components: Array, delta: float):
       var custom_entities = ECS.world.query.with_all([C_ComponentA]).execute()

   # ✅ Solution - Use the system's query() method (automatically cached)
   func query():
       return q.with_all([C_ComponentA])  # Automatically cached by GECS

   func process(entities: Array[Entity], components: Array, delta: float):
       # Just process the entities passed in - already filtered by query
       for entity in entities:
           # Process entity...
   ```

## 🔧 Integration Issues

### Problem: GECS Conflicts with Godot Features

**Issue**: Using GECS entities with Godot nodes causes problems

**Solution**: Choose your approach consistently:

```gdscript
# ✅ Approach 1 - Pure ECS (recommended for complex games)
# Entities are not nodes, use ECS for everything
var entity = Entity.new()  # Not added to scene tree
entity.add_component(C_Position.new())
ECS.world.add_entity(entity)

# ✅ Approach 2 - Hybrid (good for simpler games)
# Entities are nodes, use ECS for specific systems
var entity = Entity.new()
add_child(entity)  # Entity is in scene tree
entity.add_component(C_Health.new())
ECS.world.add_entity(entity)
```

**Avoid**: Mixing approaches inconsistently in the same project.

### Problem: GECS Not Working After Scene Changes

**Symptoms**: Systems stop working when changing scenes

**Solution**: Properly reinitialize ECS in new scenes:

```gdscript
# In each main scene script
func _ready():
    # Create new world for this scene
    var world = World.new()
    add_child(world)
    ECS.world = world

    # Systems are usually managed via scene composition
    # See default_systems.tscn for organization

    # Create your entities
    setup_entities()
```

**Prevention**: Always initialize ECS properly in each scene that uses it.

## 🛠️ Debugging Tools

### Enable Debug Logging

Add to your project settings or main script:

```gdscript
# Enable GECS debug output
ECS.set_debug_level(ECS.DEBUG_VERBOSE)

# This will show:
# - Entity creation/destruction
# - Component additions/removals
# - System processing information
# - Query execution details
```

### Entity Inspector Tool

Create a debug tool to inspect entities at runtime:

```gdscript
# DebugPanel.gd
extends Control

func _on_inspect_button_pressed():
    var entities = ECS.world.get_all_entities()
    print("=== ENTITY INSPECTOR ===")

    for i in range(min(10, entities.size())):  # Show first 10
        var entity = entities[i]
        print("Entity ", i, ":")
        print("  Components: ", entity.components.keys())
        print("  Groups: ", entity.get_groups())

        # Show component values
        for comp_path in entity.components.keys():
            var comp = entity.components[comp_path]
            print("    ", comp_path, ": ", comp)
```

## 📚 Getting More Help

### Community Resources

- **Discord**: [Join our community](https://discord.gg/eB43XU2tmn) for help and discussions
- **GitHub Issues**: [Report bugs](https://github.com/csprance/gecs/issues)
- **Documentation**: [Complete Guide](../DOCUMENTATION.md)

### Before Asking for Help

Include this information in your question:

1. **GECS version** you're using
2. **Godot version** you're using
3. **Minimal code example** that reproduces the issue
4. **Error messages** (full text, not paraphrased)
5. **Expected vs actual behavior**

### Still Stuck?

If this guide doesn't solve your problem:

1. **Check the examples** in [Getting Started](GETTING_STARTED.md)
2. **Review best practices** in [Best Practices](BEST_PRACTICES.md)
3. **Search GitHub issues** for similar problems
4. **Create a minimal reproduction** and ask for help

---

_"Every bug is a learning opportunity. The key is knowing where to look and what questions to ask."_
