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.
9.1 KiB
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):
# 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
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:
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
- Start Fallout 4 with F4SE
- Load into a game with open space (avoid dungeons)
- 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:
- Have fake client move in a small circle around you
- 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:
- Run fake client for 30 seconds with slow movement
- Observe proxy actor
- 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:
- Start 2-4 fake clients
- Each sends unique movement patterns
- 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:
- Monitor FPS with 4 remote players
- Should be similar to Phase 1 (baseline)
- Interpolation adds minimal CPU load (just lerp math)
Command to simulate:
# 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:
- Run fake client for 2 minutes straight
- Monitor memory usage
- 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:
- Ensure Phase 1 (descriptor-based animation) is working
- Run Phase 2 interpolation in parallel
- 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:
- Check that
AddWaypoint()is being called - Verify
Update()is called beforeSetPosition() - Check that
shouldSnapisn't overriding interpolation
Issue: Proxy Moves Too Slowly
Cause: Alpha blend factor too small Fix:
- Increase waypoint update rate (more frequent updates = smoother)
- Check tick calculation (verify currentTick is advancing)
Issue: Memory Grows Over Time
Cause: Waypoints not being popped Fix:
- Verify
Update()is cleaning up old waypoints - 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
- If interpolation works: Move to Phase 3 or other features
- If issues found: Document in dev-log.md and fix
- Performance baseline: Record FPS with 1, 2, 4 remote players
Quick Start Commands
# 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.