156 lines
6.2 KiB
Markdown
156 lines
6.2 KiB
Markdown
# Investigation Handoff: Dorf Job Queue System
|
|
|
|
## Current State
|
|
|
|
### System Overview
|
|
This is a dwarf (dorf) simulation with a job queue system, think dwarf fortress in a chunked world a la minecraft. We are early in development and are currently debugging the job queue system. The expected DEMO flow is:
|
|
1. ONE FellTree job should always exist (when none is in progress)
|
|
2. When a tree falls, X logs spawn, each creating a HaulCargo job
|
|
3. All available dorfs (not busy felling) should take HaulCargo jobs based on the jobs priorities
|
|
4. No dorfs should be idle while haul jobs exist to assign
|
|
|
|
### Latest Test Results (output15.log)
|
|
- **Progress**: One tree successfully chopped, one haul completed!
|
|
- **Improvement**: The `is_standable` cargo fix and `ambulatory.target` clearing fix allowed dorfs to path to cargo
|
|
- **Remaining Issue**: Only 2 of 5 dorfs participated; others froze with stale targets from previous Idle task
|
|
|
|
### Fixes Applied This Session
|
|
|
|
1. **is_standable for Cargo Tiles** (`src/world/tiles/tilemap.rs` line 311-319)
|
|
- Added: `if self.cargo_tiles.contains_key(&world_pos) { return true; }`
|
|
- Cargo (logs, rocks, ores) is now standable - dorfs can walk on cargo to pick it up
|
|
|
|
2. **Clear ambulatory.target on Job Assignment** (`src/entities/tasks/job_pathfinding.rs` line 305)
|
|
- Added: `ambulatory.target = None;` when assigning new task
|
|
- Fixes "Lost Signal" bug where old Idle task targets persisted
|
|
|
|
### Known Issues After Fixes
|
|
|
|
1. **Some dorfs still freeze** - 3 of 5 dorfs had stale targets and weren't moving
|
|
2. **Z-level spawn delay** - Dorfs fall ~4 seconds before becoming standable (expected)
|
|
3. **Distances don't decrease** - Some dorfs show arrival checks with unchanging dist_sq
|
|
|
|
## Root Cause Analysis
|
|
|
|
### Issue 1: "Lost Signal" Bug (FIXED)
|
|
When `job_pathfinding.rs` assigns a new task to a dorf, it clears `queue` and sets `state` to Pending, but was NOT clearing `ambulatory.target`. The old target from the Idle task persisted, causing pathfinding to route to the wrong location.
|
|
|
|
**Fix**: Clear `ambulatory.target = None` in job assignment.
|
|
|
|
### Issue 2: Cargo Not Standable (FIXED)
|
|
The `is_standable()` function checked floor/fixture bitsets but ignored the `cargo_tiles` HashMap. Logs couldn't be stood on for pickup.
|
|
|
|
**Fix**: Check `cargo_tiles.contains_key()` first in `is_standable()`.
|
|
|
|
### Issue 3: Target Not Being Set (POSSIBLE)
|
|
When `ambulatory.target = None`, the executor should set target from approach in `HaulStep::MovingToCargo`. But if pathfinding clears the target before executor sets it, dorfs freeze.
|
|
|
|
**Potential fix**: Ensure executor sets target before depending on it.
|
|
|
|
## Key Files Modified
|
|
|
|
```
|
|
src/world/tiles/tilemap.rs - Added cargo check to is_standable()
|
|
src/entities/tasks/job_pathfinding.rs - Clear ambulatory.target on assign
|
|
```
|
|
|
|
## Key Files to Investigate
|
|
|
|
### Job Systems
|
|
```
|
|
src/entities/tasks/job_pathfinding.rs - Job assignment, candidate filtering
|
|
src/entities/tasks/job_queue.rs - Job queue state management
|
|
src/entities/tasks/executor.rs - Task execution (ChopTree, HaulCargo)
|
|
src/entities/tasks/demo.rs - FellTree job creation logic
|
|
```
|
|
|
|
### Pathfinding & Movement
|
|
```
|
|
src/entities/shared_systems/pathfinding.rs - Entity movement, is_standable checks
|
|
src/world/tiles/tilemap.rs - is_standable(), find_nearest_free_cargo_tile()
|
|
```
|
|
|
|
## Debug Logs Present
|
|
|
|
```rust
|
|
// job_pathfinding.rs - Assignment success
|
|
info!("[PATHFIND] SUCCESS: Assigned job {:?} to dorf {:?} with approach {:?}", job_id, dorf_entity, approach_target);
|
|
|
|
// executor.rs - HaulCargo arrival check
|
|
info!("[HAUL] {:?} arrival check: approach={:?} dist_sq={} arrive_sq={} transform={:?}", entity, approach, dist_sq, arrive_sq, transform.truncate());
|
|
|
|
// executor.rs - ChopTree state
|
|
info!("[EXECUTOR] ChopTree {:?}: trunk_pos={:?} approach={:?} target={:?}", entity, trunk_pos, approach, ambulatory.target);
|
|
```
|
|
|
|
## Key Patterns to Watch
|
|
|
|
### Arrival Distance Check
|
|
- `arrive_sq = (ITILE_SIZE * 1.5)^2 = 576.0` (square pixels)
|
|
- `dist_sq` must be <= 576 to transition to PickingUp
|
|
- If `dist_sq` doesn't change between frames, dorf isn't moving
|
|
|
|
### Stale Target Pattern
|
|
```
|
|
approach=IVec3(A, B, C) target=Vec3(X, Y, Z) where (X,Y,Z) != (A,B,C)
|
|
```
|
|
This shows the target doesn't match the approach - old target persists.
|
|
|
|
## Remaining Investigation
|
|
|
|
### Why Some Dorfs Freeze
|
|
|
|
1. **Check if target is set** from approach in executor when `target.is_none()`:
|
|
- executor.rs lines 502-516 sets target from approach
|
|
- If pathfinding clears target between frames, executor needs to re-set it
|
|
|
|
2. **Check movement system** - Is `current_path` being populated?
|
|
- pathfinding.rs line 659: returns if `current_path.is_none()`
|
|
- Need to see if paths are being calculated
|
|
|
|
3. **Check if dorfs are falling** - falling clears target and path:
|
|
- pathfinding.rs lines 654-656: clears target when not standable
|
|
|
|
### Why Different Distances Between Dorfs
|
|
|
|
Looking at output15.log output15:
|
|
- dorf 8891v0: `dist_sq=2007296.0` → `dist_sq=2049280.0` (distances INCREASING!)
|
|
- dorf 8890v0: `dist_sq=848896.0` (constant - not moving)
|
|
- dorf 8888v0: `dist_sq=312320.0` (constant - not moving)
|
|
- dorf 8889v0: `dist_sq=726016.0` (constant - not moving)
|
|
|
|
The distances are NOT DECREASING, meaning dorfs are not pathing/moving toward cargo.
|
|
|
|
## Possible Quick Fixes to Try
|
|
|
|
1. **Force target recalculation** in executor when arrival check fails:
|
|
```rust
|
|
if dist_sq > arrive_sq && ambulatory.target.is_none() {
|
|
// Force re-path
|
|
ambulatory.current_path = None;
|
|
}
|
|
```
|
|
|
|
2. **Check path validity** before arrival distance check
|
|
|
|
3. **Log current_path** to see if paths are being generated
|
|
|
|
## Commands to Run
|
|
|
|
```bash
|
|
# Check target vs approach mismatch
|
|
grep -E "approach=.*target=" output15.log | head -20
|
|
|
|
# Check if paths are being generated
|
|
grep -E "current_path|path_index" output15.log | head -20
|
|
|
|
# Check distances over time
|
|
grep -E "arrival check.*dist_sq" output15.log | grep "8891v0" | head -10
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
1. **Investigate why dist_sq doesn't decrease** - dorfs aren't moving toward cargo
|
|
2. **Check if current_path is populated** - paths may not be calculated
|
|
3. **Verify pathfinding generates valid paths** during falling/in-air
|
|
4. **Check why some dorfs get correct targets and others don't** |