Replace occurrences of "Fallout 4 Together" with "Commonwealth Online" across docs and testing guidance. Add Interface assets and tooling: MainMenu/Pipboy SWFs, translation/fonts, exported scripts (Interface/exported/scripts/MainMenu.as) and a PATCH_MainMenu_Multiplayer.md describing how to add a Multiplayer menu entry that calls root.f4se.plugins.commonwealthOnline.openManager(). Also add build/run batch scripts and apply assorted updates to README, plugin, server and protocol documentation/source to align with the rename and UI changes.
366 lines
9.1 KiB
Markdown
366 lines
9.1 KiB
Markdown
# Phase 2: Interpolation System Testing Guide
|
|
|
|
## Overview
|
|
|
|
Phase 2 tests the waypoint-based smooth movement interpolation system. This replaces direct position application with time-based lerp between waypoints, resulting in smoother remote player movement.
|
|
|
|
**Prerequisites:**
|
|
- F4T plugin built with interpolation system (just completed ✓)
|
|
- Fallout 4 running with F4SE
|
|
- Network relay server running (`python server.py`)
|
|
- Fake client ready (`python server/fake_client.py`)
|
|
|
|
---
|
|
|
|
## Architecture Review
|
|
|
|
Before testing, understand what we're testing:
|
|
|
|
### Current System (Pre-Phase 2)
|
|
```
|
|
Remote Player Update
|
|
↓
|
|
GetRuntimeProxyVisibleTargetPosition()
|
|
↓
|
|
targetPosition = direct network position
|
|
↓
|
|
SetPosition(targetPosition) ← IMMEDIATE, no lerp
|
|
↓
|
|
Result: Jittery/choppy movement on low update rates
|
|
```
|
|
|
|
### New System (Phase 2)
|
|
```
|
|
Remote Player Update
|
|
↓
|
|
GetRuntimeProxyVisibleTargetPosition()
|
|
↓
|
|
AddWaypoint(targetPosition, angleZ, currentTick) → InterpolationComponent
|
|
↓
|
|
InterpolationSystem::Update(currentTick)
|
|
↓
|
|
Lerp between waypoints if tick is between them
|
|
↓
|
|
SetPosition(interpolatedPosition) ← SMOOTH, tick-based
|
|
↓
|
|
Result: Smooth movement even on low update rates
|
|
```
|
|
|
|
---
|
|
|
|
## Testing Phase 2.1: Interpolation System Unit Test
|
|
|
|
### Goal
|
|
Verify interpolation math works correctly before testing in-game.
|
|
|
|
### Test: Manual Interpolation Check
|
|
|
|
Create a simple test script (`test_interpolation.py`):
|
|
|
|
```python
|
|
# Pseudo-code showing what Phase 2 does
|
|
# Position at tick 100: (1000, 2000, 500)
|
|
# Position at tick 200: (1100, 2050, 550)
|
|
|
|
# At tick 150 (halfway):
|
|
# alpha = (150 - 100) / (200 - 100) = 0.5
|
|
# interpolated_x = 1000 + (1100 - 1000) * 0.5 = 1050
|
|
# interpolated_y = 2000 + (2050 - 2000) * 0.5 = 2025
|
|
# interpolated_z = 500 + (550 - 500) * 0.5 = 525
|
|
|
|
# Result: (1050, 2025, 525) ← smooth midpoint
|
|
```
|
|
|
|
**Expected behavior:** Movement is linear blend between waypoints.
|
|
|
|
---
|
|
|
|
## Testing Phase 2.2: In-Game Setup
|
|
|
|
### Setup Step 1: Start Relay Server
|
|
|
|
```bash
|
|
cd f:\Repos\Commonwealth-Online\server
|
|
python server.py
|
|
```
|
|
|
|
Expected output:
|
|
```
|
|
Server listening on 127.0.0.1:7777
|
|
Waiting for connections...
|
|
```
|
|
|
|
### Setup Step 2: Start Fake Client
|
|
|
|
In a new terminal:
|
|
|
|
```bash
|
|
cd f:\Repos\Commonwealth-Online\server
|
|
python fake_client.py
|
|
```
|
|
|
|
Expected output:
|
|
```
|
|
Connecting to server...
|
|
Connected successfully
|
|
Fake player registered with ID: <player_id>
|
|
```
|
|
|
|
### Setup Step 3: Launch Fallout 4
|
|
|
|
1. Start Fallout 4 with F4SE
|
|
2. Load into a game with open space (avoid dungeons)
|
|
3. Check console for F4T startup messages
|
|
|
|
Expected log output:
|
|
```
|
|
[Local Player ID: X] F4T Plugin initialized
|
|
[Local Player ID: X] Proxy controller ready
|
|
```
|
|
|
|
---
|
|
|
|
## Testing Phase 2.3: Basic Interpolation Test
|
|
|
|
### Test: Remote Player Walks in Circle
|
|
|
|
This verifies waypoint buffering and interpolation.
|
|
|
|
**Setup:**
|
|
1. Have fake client move in a small circle around you
|
|
2. Watch the proxy actor move
|
|
|
|
**Expected Behavior (PRE-Phase 2):**
|
|
- Proxy position updates in discrete jumps
|
|
- Movement appears jittery/choppy
|
|
- Proxy teleports between waypoints
|
|
|
|
**Expected Behavior (POST-Phase 2):**
|
|
- Proxy moves smoothly
|
|
- Movement is continuous, not jerky
|
|
- Smooth arc instead of sharp jumps
|
|
|
|
**How to Verify:**
|
|
1. Run fake client for 30 seconds with slow movement
|
|
2. Observe proxy actor
|
|
3. Compare smoothness to pre-Phase 2 behavior
|
|
|
|
**Log Indicators:**
|
|
```
|
|
[Local Player ID: 0] First smoothed runtime proxy movement for remote player X: actor=FORMID, alpha=0.15.
|
|
```
|
|
|
|
This log should appear once per remote player.
|
|
|
|
---
|
|
|
|
## Testing Phase 2.4: Movement Speed Variations
|
|
|
|
### Test: Fast vs Slow Movement
|
|
|
|
**Objective:** Verify interpolation works across movement speeds.
|
|
|
|
**Test Case 1: Slow Movement**
|
|
- Fake client walks slowly (1-2 units/sec)
|
|
- Expected: Smooth continuous movement
|
|
- Should NOT have position snapping
|
|
|
|
**Test Case 2: Fast Movement**
|
|
- Fake client sprints (100+ units/sec)
|
|
- Expected: Fast smooth movement
|
|
- No lag or skipping
|
|
|
|
**Test Case 3: Teleport**
|
|
- Fake client teleports 500 units away
|
|
- Expected: Proxy snaps (shouldSnap=true for teleport movement type)
|
|
- Movement type check happens first, no interpolation
|
|
|
|
---
|
|
|
|
## Testing Phase 2.5: Multiple Remote Players
|
|
|
|
### Test: Interpolation with 2-4 Remote Players
|
|
|
|
**Setup:**
|
|
1. Start 2-4 fake clients
|
|
2. Each sends unique movement patterns
|
|
3. Observe all proxies
|
|
|
|
**Expected Behavior:**
|
|
- Each proxy interpolates independently
|
|
- No interaction/interference between proxies
|
|
- Each has its own InterpolationComponent
|
|
- Smooth movement for all
|
|
|
|
**Performance Check:**
|
|
1. Monitor FPS with 4 remote players
|
|
2. Should be similar to Phase 1 (baseline)
|
|
3. Interpolation adds minimal CPU load (just lerp math)
|
|
|
|
**Command to simulate:**
|
|
```bash
|
|
# Terminal 1: Start main relay
|
|
python server.py
|
|
|
|
# Terminal 2-5: Start 4 fake clients
|
|
python fake_client.py
|
|
python fake_client.py
|
|
python fake_client.py
|
|
python fake_client.py
|
|
```
|
|
|
|
---
|
|
|
|
## Testing Phase 2.6: Waypoint Queue Management
|
|
|
|
### Test: Verify Waypoint Cleanup
|
|
|
|
**Objective:** Ensure old waypoints are cleaned up, not accumulated.
|
|
|
|
**How to Check:**
|
|
1. Run fake client for 2 minutes straight
|
|
2. Monitor memory usage
|
|
3. Should be stable (not growing)
|
|
|
|
**What's Happening:**
|
|
```
|
|
Tick 100: Add waypoint
|
|
Tick 101-150: Lerp between waypoint 0 and 1
|
|
Tick 151: Pop waypoint 0 (cleanup!)
|
|
Tick 151: Add new waypoint
|
|
Tick 152-200: Lerp between waypoint 0 and 1 (still 2 max)
|
|
```
|
|
|
|
The InterpolationSystem::Update() automatically pops old waypoints when they're consumed.
|
|
|
|
---
|
|
|
|
## Testing Phase 2.7: Rotation Interpolation
|
|
|
|
### Test: Verify Smooth Rotation
|
|
|
|
**Objective:** Test angle lerp with wrap-around handling.
|
|
|
|
**Test Case 1: Normal Rotation**
|
|
- Remote player rotates from 0° to 90°
|
|
- Expected: Smooth rotation from 0° → 45° → 90°
|
|
|
|
**Test Case 2: Wrap-Around**
|
|
- Remote player rotates from 350° to 10° (crossing 0°)
|
|
- Expected: Shortest path rotation (350° → 0° → 10°), not 350° → 180° → 10°
|
|
- Our `LerpRotation()` handles this
|
|
|
|
**Visual Check:**
|
|
- Watch proxy heading as it turns
|
|
- Should be smooth, not jerky
|
|
- Should take shortest angular path
|
|
|
|
---
|
|
|
|
## Testing Phase 2.8: Integration with Animation Sync
|
|
|
|
### Test: Interpolation + Descriptor-Based Animation
|
|
|
|
**Setup:**
|
|
1. Ensure Phase 1 (descriptor-based animation) is working
|
|
2. Run Phase 2 interpolation in parallel
|
|
3. Fake client walks around you
|
|
|
|
**Expected Behavior:**
|
|
- Remote player position interpolates smoothly
|
|
- Remote player animation (Speed, isSprinting) syncs correctly
|
|
- No conflicts between systems
|
|
|
|
**Verification:**
|
|
```
|
|
[Local Player ID: 0] Runtime proxy animation sync initial for remote player X:
|
|
moving=true, sprinting=false, graphSpeed=55.0, direction=0.123
|
|
```
|
|
|
|
This should still appear alongside interpolation.
|
|
|
|
---
|
|
|
|
## Testing Checklist
|
|
|
|
- [ ] **Unit Test**: Lerp math is correct (waypoint positions smooth)
|
|
- [ ] **Single Player**: Fake client walks, proxy moves smoothly
|
|
- [ ] **Slow Movement**: Proxy glides smoothly at 1-2 units/sec
|
|
- [ ] **Fast Movement**: Proxy glides smoothly at 100+ units/sec
|
|
- [ ] **Multiple Players**: 2-4 proxies move smoothly independently
|
|
- [ ] **Memory**: Stable after 2+ minutes (no memory growth)
|
|
- [ ] **Rotation**: Proxy heading rotates smoothly
|
|
- [ ] **Wrap-Around**: Rotation handles 0°↔360° correctly
|
|
- [ ] **Integration**: Works with Phase 1 animation sync
|
|
- [ ] **Snapping**: Teleports still snap (movement type check first)
|
|
|
|
---
|
|
|
|
## Debugging: Common Issues & Fixes
|
|
|
|
### Issue: Proxy Still Jerky After Phase 2
|
|
|
|
**Cause:** Interpolation not being called
|
|
**Fix:**
|
|
1. Check that `AddWaypoint()` is being called
|
|
2. Verify `Update()` is called before `SetPosition()`
|
|
3. Check that `shouldSnap` isn't overriding interpolation
|
|
|
|
### Issue: Proxy Moves Too Slowly
|
|
|
|
**Cause:** Alpha blend factor too small
|
|
**Fix:**
|
|
1. Increase waypoint update rate (more frequent updates = smoother)
|
|
2. Check tick calculation (verify currentTick is advancing)
|
|
|
|
### Issue: Memory Grows Over Time
|
|
|
|
**Cause:** Waypoints not being popped
|
|
**Fix:**
|
|
1. Verify `Update()` is cleaning up old waypoints
|
|
2. Check that TimePoints.pop_front() is being called
|
|
|
|
### Issue: Rotation Wraps Incorrectly
|
|
|
|
**Cause:** LerpRotation() not handling 0°/360° boundary
|
|
**Fix:**
|
|
- This is handled in our implementation
|
|
- If still wrong, check angle units (radians vs degrees)
|
|
|
|
---
|
|
|
|
## Next Steps After Testing
|
|
|
|
1. **If interpolation works:** Move to Phase 3 or other features
|
|
2. **If issues found:** Document in dev-log.md and fix
|
|
3. **Performance baseline:** Record FPS with 1, 2, 4 remote players
|
|
|
|
---
|
|
|
|
## Quick Start Commands
|
|
|
|
```bash
|
|
# Terminal 1: Start relay server
|
|
cd f:\Repos\Commonwealth-Online\server
|
|
python server.py
|
|
|
|
# Terminal 2: Start fake client (single remote player)
|
|
cd f:\Repos\Commonwealth-Online\server
|
|
python fake_client.py
|
|
|
|
# In-game: Launch F4T and observe proxy movement
|
|
```
|
|
|
|
---
|
|
|
|
## Expected Logs for Phase 2
|
|
|
|
When interpolation is active, look for:
|
|
|
|
```
|
|
[Local Player ID: 0] First smoothed runtime proxy movement for remote player 1: actor=0x14003ED8, alpha=0.15.
|
|
[Local Player ID: 0] Moved runtime proxy actor 0x14003ED8 from remote player 1 state for the first time: X=1234.56, Y=2345.67, Z=-100.00, AngleZ=1.570, flags1=00000000, flags2=00000000.
|
|
```
|
|
|
|
These confirm the proxy is spawned and moving smoothly.
|