Files
Commonwealth-Online-Public/docs/phase2-interpolation-testing.md
T
andrew 8dfec0a4b3 Rename project to Commonwealth Online
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.
2026-06-07 16:22:50 +12:00

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

  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:

# 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

# 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.