Runtime proxy spawn: Stage 3 PlaceAtMe
Promote a single runtime-spawned proxy as the preferred active remote-player representation (Stage 3 / 3.7) while preserving the placed reference as a fallback. Updates include: detailed architecture and dev-log additions describing staged diagnostics (3.1–3.7), PlaceAtMe-backed spawn candidate isolation/settle, vanilla/Codsworth diagnostics, console PlaceAtMe testing, near-player visibility holds, and PASS/PARTIAL/FAIL diagnostic outcomes. Code changes (plugin/include & plugin/src): adjust header comment and implement numerous runtime proxy features and diagnostics: new constants, enums, structs, state variables, logging helpers, position/distance helpers, absolute FormID lookup, runtime actor base selection (custom vs vanilla), PlaceAtMe-backed spawn state machine, debug placement/hold timing, candidate snapshot/isolation, promotion to active runtime proxy, and many throttled/logged diagnostics. The placed CK reference remains the fallback if runtime spawn/validation fails. Docs changed: docs/architecture.md and docs/dev-log.md updated to describe the new Stage 3 behavior and testing notes. Files changed: docs/architecture.md, docs/dev-log.md, plugin/include/F4TProxyActorController.h, plugin/src/F4TProxyActorController.cpp. Behavioral notes: single-proxy only (Stage 4 mapping deferred), extensive diagnostic logging added, and in-game validation/testing remains pending.
This commit is contained in:
+103
-24
@@ -26,25 +26,76 @@ both send and receive paths:
|
|||||||
10. The plugin and fake client remove disconnected players from their remote
|
10. The plugin and fake client remove disconnected players from their remote
|
||||||
player tables.
|
player tables.
|
||||||
11. On the game-thread update path, the proxy controller performs a one-shot
|
11. On the game-thread update path, the proxy controller performs a one-shot
|
||||||
runtime spawn diagnostic in `F4TTestCell01` from the resolved
|
runtime spawn in `F4TTestCell01` from the selected runtime actor base. Stage
|
||||||
`F4T_RemotePlayerProxy` actor base. This spawned actor is not yet driven
|
3.7 makes the preferred runtime spawn strategy PlaceAtMe-backed spawning:
|
||||||
from remote-player state.
|
the plugin snapshots existing matching candidates, executes a single
|
||||||
|
`player.placeatme <baseFormId> 1` command, isolates the newly spawned actor
|
||||||
|
by comparing pre/post candidate FormIDs, and lets that actor settle before
|
||||||
|
remote movement begins. The custom `F4T_RemotePlayerProxy` base is attempted
|
||||||
|
first, with Codsworth retained only as a diagnostic fallback.
|
||||||
12. On the same game-thread update path, the plugin reads a copied remote-player
|
12. On the same game-thread update path, the plugin reads a copied remote-player
|
||||||
snapshot and moves the single placed proxy actor in `F4TTestCell01`.
|
snapshot and resolves one active proxy actor. The runtime-spawned actor is
|
||||||
Proxy visual updates are independent from local movement log throttling:
|
preferred when its handle resolves and validates; otherwise the placed
|
||||||
normal movement is smoothed toward the latest target, while cell changes,
|
fallback reference `F4TProxyRemotePlayer01REF` is used. Proxy visual updates
|
||||||
worldspace changes, and teleports snap directly.
|
are independent from local movement log throttling: normal movement is
|
||||||
|
smoothed toward the latest target, while cell changes, worldspace changes,
|
||||||
|
and teleports snap directly.
|
||||||
13. When the selected remote player is missing, disconnected, or not in the same
|
13. When the selected remote player is missing, disconnected, or not in the same
|
||||||
test cell, the game-thread proxy controller moves the single placed proxy to
|
test cell, the game-thread proxy controller moves the active proxy to a
|
||||||
a hidden holding position inside `F4TTestCell01` until a valid same-cell
|
hidden holding position inside `F4TTestCell01` until a valid same-cell
|
||||||
remote player is available again.
|
remote player is available again.
|
||||||
14. As part of the staged runtime proxy actor manager work, the same game-thread proxy
|
14. As part of the staged runtime proxy actor manager work, the same game-thread
|
||||||
controller also logs whether `Fallout4Together_Test.esp` is loaded and
|
proxy controller also logs whether `Fallout4Together_Test.esp` is loaded and
|
||||||
whether the actor base `F4T_RemotePlayerProxy` resolves by editor ID.
|
whether the actor base `F4T_RemotePlayerProxy` resolves by editor ID.
|
||||||
|
15. Stage 3.1 adds a temporary diagnostic layer around the single runtime proxy:
|
||||||
|
post-spawn visibility data, loaded-3D pointer checks where safe, console
|
||||||
|
helper logs, active source logs, and throttled post-movement diagnostics.
|
||||||
|
The diagnostic mode can force the runtime proxy near the local player to
|
||||||
|
prove whether the created actor is visibly renderable.
|
||||||
|
16. Stage 3.2 adds a temporary near-player visibility hold for that same single
|
||||||
|
runtime proxy. During the hold, remote state is still selected and validated,
|
||||||
|
but runtime proxy restore and remote movement are deferred long enough to
|
||||||
|
test whether a runtime-created actor ref can load visible 3D while kept near
|
||||||
|
the local player.
|
||||||
|
17. Stage 3.3 adds a temporary vanilla actor-base diagnostic layer. It attempts
|
||||||
|
to resolve Codsworth as a visible vanilla `TESNPC` candidate, then passes
|
||||||
|
that actor base into the same runtime spawn, handle validation, near-player
|
||||||
|
hold, and visibility diagnostic path. This isolates custom actor-base issues
|
||||||
|
from runtime-spawn/init issues without changing the final architecture.
|
||||||
|
18. Stage 3.4 adds a temporary absolute FormID and existing-reference diagnostic
|
||||||
|
layer. It compares Codsworth base-form runtime spawning against moving the
|
||||||
|
existing placed Codsworth reference near the local player as a visibility
|
||||||
|
control. This separates runtime actor creation/init problems from vanilla
|
||||||
|
actor-base or placed-reference movement problems and does not change the
|
||||||
|
final architecture.
|
||||||
|
19. Stage 3.5 adds a temporary PlaceAtMe-equivalent diagnostic after manual
|
||||||
|
console validation proved `player.placeatme 000179FF 1` can spawn visible
|
||||||
|
Codsworth in `F4TTestCell01`. The plugin executes that console placement path
|
||||||
|
from the local player, resolves the newly created Codsworth actor near the
|
||||||
|
player, and holds/logs it separately from the `CreateReferenceAtLocation`
|
||||||
|
runtime proxy path.
|
||||||
|
20. Stage 3.6 refines that temporary PlaceAtMe diagnostic layer. It snapshots
|
||||||
|
known Codsworth refs before executing `player.placeatme 000179FF 1`, accepts
|
||||||
|
only a newly isolated Codsworth ref for the primary diagnostic, and preserves
|
||||||
|
that actor at the original console-spawned location during a short settle
|
||||||
|
window. This tests whether the actor becomes visible naturally or requires a
|
||||||
|
render/process refresh such as the manually observed pause-menu or alt-tab
|
||||||
|
behavior. Stage 3.6 does not change the final architecture.
|
||||||
|
21. Stage 3.7 promotes the working PlaceAtMe-style spawn pattern into the
|
||||||
|
preferred single runtime proxy spawn path. The proxy controller uses the
|
||||||
|
resolved runtime FormID for `F4T_RemotePlayerProxy` when available, falls
|
||||||
|
back to Codsworth only for diagnostics, defers active proxy selection during
|
||||||
|
candidate isolation and settle, then promotes the settled actor into the
|
||||||
|
existing single-proxy movement pipeline.
|
||||||
|
|
||||||
The Fallout 4 plugin now has a diagnostic-only runtime spawn test, but it still
|
The Fallout 4 plugin now dynamically spawns one runtime proxy actor for remote
|
||||||
does not dynamically spawn actors for remote player representation. The placed
|
player representation in the test cell. The placed proxy reference remains as a
|
||||||
proxy reference remains the active visual representation path.
|
fallback path if runtime spawn, handle validation, actor validation, or lookup
|
||||||
|
fails.
|
||||||
|
|
||||||
|
Stage 4 is still reserved for multiple runtime proxies and a
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping. Stage 3.7 does not add that
|
||||||
|
mapping.
|
||||||
|
|
||||||
## Main Components
|
## Main Components
|
||||||
|
|
||||||
@@ -59,19 +110,41 @@ The native plugin is responsible for:
|
|||||||
- Throttling normal transform sends separately from readable local movement logs
|
- Throttling normal transform sends separately from readable local movement logs
|
||||||
- Receiving server packets on a background thread
|
- Receiving server packets on a background thread
|
||||||
- Storing assigned and remote `playerId` state internally
|
- Storing assigned and remote `playerId` state internally
|
||||||
- Moving the single placed test proxy actor from remote-player state on the game
|
- Moving the single active proxy actor from remote-player state on the game
|
||||||
thread
|
thread, preferring the runtime-spawned actor and falling back to the placed
|
||||||
- Holding that proxy actor at a hidden in-cell position when no valid same-cell
|
reference
|
||||||
remote player should be represented
|
- Holding that active proxy actor at a hidden in-cell position when no valid
|
||||||
|
same-cell remote player should be represented
|
||||||
- Logging staged runtime proxy actor base lookup diagnostics on the same
|
- Logging staged runtime proxy actor base lookup diagnostics on the same
|
||||||
game-thread controller path
|
game-thread controller path
|
||||||
- Attempting one game-thread-only runtime spawn diagnostic from
|
- Attempting one game-thread-only PlaceAtMe-backed runtime spawn from the
|
||||||
`F4T_RemotePlayerProxy` in `F4TTestCell01`
|
selected Stage 3 actor base in `F4TTestCell01`, normally
|
||||||
|
`F4T_RemotePlayerProxy`
|
||||||
|
- Logging temporary Stage 3.1 visibility and movement diagnostics for the single
|
||||||
|
runtime proxy, including active proxy source, runtime FormID, local distance,
|
||||||
|
and safe loaded-3D checks
|
||||||
|
- Holding the single runtime proxy near the local player during temporary Stage
|
||||||
|
3.2 diagnostics so the plugin can determine whether runtime-created actor refs
|
||||||
|
can load visible 3D before remote movement resumes
|
||||||
|
- Temporarily comparing a vanilla visible NPC actor base against the custom
|
||||||
|
proxy actor base during Stage 3.3, while preserving the same runtime spawn
|
||||||
|
path and keeping Stage 4 reserved for later mapping work
|
||||||
|
- Temporarily resolving Codsworth base and placed-reference absolute FormIDs
|
||||||
|
during Stage 3.4, then moving the existing placed reference near the player as
|
||||||
|
a visibility control separate from runtime spawning
|
||||||
|
- Temporarily testing a local-player `player.placeatme`-equivalent console path
|
||||||
|
during Stage 3.5, then comparing the resulting visible actor behavior against
|
||||||
|
the existing `CreateReferenceAtLocation` runtime actor path
|
||||||
|
- Temporarily isolating the newly spawned PlaceAtMe ref during Stage 3.6 and
|
||||||
|
testing render/process settle behavior without changing active proxy mapping
|
||||||
|
- Using Stage 3.7 to isolate a PlaceAtMe-backed runtime proxy, preserve it
|
||||||
|
during a short settle window, and then promote it into the existing
|
||||||
|
single-proxy movement path
|
||||||
|
|
||||||
Planned later:
|
Planned later:
|
||||||
|
|
||||||
- Supporting one proxy actor per represented remote `playerId`
|
- Supporting one proxy actor per represented remote `playerId`
|
||||||
- Driving runtime-spawned proxy actors from remote-player state
|
- Mapping each represented remote `playerId` to its own proxy actor handle
|
||||||
|
|
||||||
### External Server
|
### External Server
|
||||||
|
|
||||||
@@ -123,8 +196,14 @@ Networking thread receives packets
|
|||||||
Networking thread stores remote player state
|
Networking thread stores remote player state
|
||||||
Game update reads a copied remote player snapshot
|
Game update reads a copied remote player snapshot
|
||||||
Game update resolves/logs proxy actor base diagnostics
|
Game update resolves/logs proxy actor base diagnostics
|
||||||
Game update attempts one diagnostic runtime actor spawn in F4TTestCell01
|
Game update selects the Stage 3 runtime actor base
|
||||||
Game update moves the placed test proxy actor
|
Game update attempts one PlaceAtMe-backed runtime actor spawn in F4TTestCell01
|
||||||
|
Game update snapshots matching candidates, isolates the new actor, and waits for the Stage 3.7 settle window
|
||||||
|
Older standalone Stage 3.4/3.6 diagnostics stay disabled while Stage 3.7 is active
|
||||||
|
Game update logs temporary Stage 3.1 runtime visibility diagnostics
|
||||||
|
Game update can temporarily hold the Stage 3.2/3.3 runtime proxy near the local player
|
||||||
|
Game update prefers the validated runtime proxy, or falls back to F4TProxyRemotePlayer01REF
|
||||||
|
Game update moves the selected active proxy actor and logs throttled movement diagnostics
|
||||||
```
|
```
|
||||||
|
|
||||||
The networking receive thread does not directly modify Fallout 4 actors or game
|
The networking receive thread does not directly modify Fallout 4 actors or game
|
||||||
@@ -134,8 +213,8 @@ update path.
|
|||||||
|
|
||||||
## Out Of Scope For Current Prototype
|
## Out Of Scope For Current Prototype
|
||||||
|
|
||||||
- Using runtime-spawned actors for remote player representation
|
|
||||||
- Multiple proxy actors
|
- Multiple proxy actors
|
||||||
|
- `remotePlayerId -> proxy actor handle` mapping before Stage 4
|
||||||
- Animation graph sync or animation application
|
- Animation graph sync or animation application
|
||||||
- Combat sync
|
- Combat sync
|
||||||
- Quest sync
|
- Quest sync
|
||||||
|
|||||||
+533
@@ -1301,6 +1301,539 @@ remote player representation.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Made the single runtime-spawned `F4T_RemotePlayerProxy` actor the preferred
|
||||||
|
active remote player representation in `F4TTestCell01`, while preserving
|
||||||
|
`F4TProxyRemotePlayer01REF` as the placed fallback if runtime spawn or runtime
|
||||||
|
handle validation is unavailable.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `plugin/include/F4TProxyActorController.h`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Reframed the Stage 2 diagnostic runtime handle as the single Stage 3 runtime
|
||||||
|
proxy handle stored in `RE::ObjectRefHandle`.
|
||||||
|
- Added active-proxy selection that revalidates the runtime handle each
|
||||||
|
controller update and prefers it when it resolves as a non-player actor in
|
||||||
|
`F4TTestCell01`.
|
||||||
|
- Falls back to the placed reference path when runtime spawn has not completed,
|
||||||
|
spawn failed, the handle does not resolve, the handle does not resolve as an
|
||||||
|
actor, or runtime actor validation fails.
|
||||||
|
- Kept placed fallback lookup available through `F4TProxyRemotePlayer01REF` and
|
||||||
|
the ESP-local fallback FormID, and prevents placed fallback cell scanning from
|
||||||
|
selecting the runtime-spawned actor by base actor.
|
||||||
|
- Reused the existing single remote-player selection behavior: lowest
|
||||||
|
`playerId` only. Added TODO notes for Stage 4 one-proxy-per-player mapping.
|
||||||
|
- Routed existing smoothing, special movement snapping, same-cell gating,
|
||||||
|
holding-position lifecycle, restore behavior, and sneak-state observation
|
||||||
|
through the selected active proxy.
|
||||||
|
- Did not add visual sneak/crouch application, gameplay sync, animation sync,
|
||||||
|
multi-proxy mapping, protocol changes, networking changes, Python server
|
||||||
|
changes, or fake-client tooling changes.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: launch Fallout 4 through F4SE, load `Fallout4Together_Test.esp`, and
|
||||||
|
`coc F4TTestCell01`.
|
||||||
|
- Pending: confirm runtime actor-base resolution, one runtime spawn, runtime
|
||||||
|
active selection, smooth fake-client movement, special movement snaps,
|
||||||
|
leave-cell holding, return-cell restore, disconnect holding, and sneak-state
|
||||||
|
observation.
|
||||||
|
- Pending: force or observe runtime validation failure and confirm the placed
|
||||||
|
fallback still represents the selected remote player.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- Runtime support is still intentionally single-proxy only.
|
||||||
|
- Runtime proxy actors are held for reuse and are not disabled, deleted, made
|
||||||
|
invisible, or despawned in this milestone.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Run the build and in-game Stage 3 validation checklist.
|
||||||
|
- If Stage 3 is stable, proceed later to Stage 4 multi-proxy mapping with a
|
||||||
|
`remotePlayerId -> proxy actor handle` design.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3.1
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Added a temporary runtime proxy visibility diagnostic layer so the next in-game
|
||||||
|
test can prove whether the single runtime-spawned proxy actor is visibly
|
||||||
|
renderable, loaded, and being moved as expected.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Added post-spawn runtime proxy diagnostics for created ref FormID, actor base
|
||||||
|
FormID, handle value, resolved actor state, parent cell, proxy position, local
|
||||||
|
player position, and local distance.
|
||||||
|
- Added safe diagnostic checks for runtime form created/deleted/disabled flags,
|
||||||
|
available-in-game state, actor visibility, and `Get3D`/`GetFullyLoaded3D`/
|
||||||
|
`GetCurrent3D` pointer availability. Reference enable state remains logged as
|
||||||
|
unavailable rather than guessed.
|
||||||
|
- Added a temporary debug visibility mode,
|
||||||
|
`kDebugForceRuntimeProxyNearLocalPlayer`, which forces the runtime proxy near
|
||||||
|
the local player at X + 350 and Z + 20 after spawn and scales it to 1.5 for
|
||||||
|
easier visual confirmation.
|
||||||
|
- Added the runtime console helper log:
|
||||||
|
`prid <runtimeRef>` followed by `moveto player` or `enable`.
|
||||||
|
- Added explicit active source logs for runtime proxy selection and placed
|
||||||
|
fallback selection.
|
||||||
|
- Added throttled post-restore and post-move diagnostics with proxy source,
|
||||||
|
proxy FormID, assigned remote `playerId`, target remote position, actual proxy
|
||||||
|
position, local player position, local distance, same-cell result, and movement
|
||||||
|
mode (`restore`, `smooth`, or `snap`).
|
||||||
|
- Preserved Stage 3 single-proxy behavior: lowest remote `playerId`, same-cell
|
||||||
|
gating, holding lifecycle, smoothing, snap movement, movement-state
|
||||||
|
observation, placed fallback support, and skipping runtime-created actors
|
||||||
|
during fallback scans.
|
||||||
|
- Did not implement Stage 4 multi-proxy mapping or any
|
||||||
|
`remotePlayerId -> proxy actor handle` table.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: launch two real clients in `F4TTestCell01` and confirm whether the
|
||||||
|
debug-forced runtime proxy appears near the local player.
|
||||||
|
- Pending: use the logged console helper command to run
|
||||||
|
`prid <runtimeRef>`, then `moveto player` or `enable`, to inspect the runtime
|
||||||
|
reference directly.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- Runtime refs are created and moved according to logs, but visual rendering is
|
||||||
|
not yet confirmed in-game.
|
||||||
|
- The Stage 3.1 debug near-player placement and scale are temporary diagnostics
|
||||||
|
and should be disabled after visibility is proven.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Run two real clients, check for the debug-forced runtime proxy near the local
|
||||||
|
player, and try the console `prid <runtimeRef>` helper.
|
||||||
|
- Use the Stage 3.1 logs to decide whether the runtime actor is disabled,
|
||||||
|
missing 3D, unloaded, moving out of view, or valid but not rendered.
|
||||||
|
- Keep Stage 4 reserved for later multi-client
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3.2
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Added a temporary runtime proxy visibility hold so the single runtime-spawned
|
||||||
|
proxy remains near the local player before remote assignment. This should show
|
||||||
|
whether Fallout 4 ever creates visible 3D for the runtime-created actor ref when
|
||||||
|
it is kept in a loaded, nearby location.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Added `kDebugHoldRuntimeProxyNearLocalPlayer` and
|
||||||
|
`kDebugRuntimeProxyHoldSeconds` as temporary Stage 3.2 diagnostics.
|
||||||
|
- When the hold is active, the runtime proxy remains at the near-player debug
|
||||||
|
position for 15 seconds before remote assignment or remote movement resumes.
|
||||||
|
- Deferred runtime proxy restore and smooth/snap remote movement during the hold
|
||||||
|
while preserving remote-player snapshot storage, lowest `playerId` selection,
|
||||||
|
same-cell validation, placed fallback support, and the Stage 3 holding
|
||||||
|
lifecycle outside the hold.
|
||||||
|
- Added repeated hold diagnostics around every 2 seconds with runtime ref FormID,
|
||||||
|
actor base FormID, parent cell, proxy/local positions, local distance, safe
|
||||||
|
form-state checks, `Get3D`/`GetFullyLoaded3D`/`GetCurrent3D`, `IsVisible`,
|
||||||
|
hold elapsed time, hold remaining time, and whether the proxy had to be
|
||||||
|
re-placed near the local player.
|
||||||
|
- Added a hard hold conclusion: `PASS` if any safe 3D or visibility check becomes
|
||||||
|
true, otherwise `FAIL` with a note that placed fallback refs or another actor
|
||||||
|
spawn/init path may be safer before Stage 4.
|
||||||
|
- Kept safe post-spawn initialization limited to calls that build in the current
|
||||||
|
CommonLibF4 setup: `SetPosition`, `SetHeading`, `SetScale`,
|
||||||
|
`initializeScripts = true`, `initiallyDisabled = false`, and guarded
|
||||||
|
`Enable(false)` only if the spawned actor reports disabled. Forced 3D/load
|
||||||
|
update APIs remain logged as unavailable.
|
||||||
|
- Did not implement Stage 4 multi-proxy mapping or any
|
||||||
|
`remotePlayerId -> proxy actor handle` table.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: run two real clients in `F4TTestCell01` and inspect whether the
|
||||||
|
Stage 3.2 hold diagnostics report any `Get3D`, `GetFullyLoaded3D`,
|
||||||
|
`GetCurrent3D`, or `IsVisible` transition to true.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- The issue under investigation remains: runtime refs exist, are selected, and
|
||||||
|
can move in memory, but they may still fail to load visible actor 3D.
|
||||||
|
- The near-player hold is temporary diagnostic behavior and should be removed or
|
||||||
|
disabled after the runtime visibility path is proven or rejected.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Use the Stage 3.2 PASS/FAIL hold conclusion from an in-game test to decide
|
||||||
|
whether runtime-created actors can remain the preferred Stage 3 visual path.
|
||||||
|
- If Stage 3.2 fails, consider placed fallback refs or a different actor
|
||||||
|
spawn/init path before any Stage 4 multi-proxy work.
|
||||||
|
- Keep Stage 4 reserved for later
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3.3
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Added a temporary vanilla visible NPC diagnostic for the Stage 3 runtime spawn
|
||||||
|
path. The controller can now use Codsworth as the default diagnostic actor base
|
||||||
|
instead of `F4T_RemotePlayerProxy`, while keeping the same runtime spawn,
|
||||||
|
handle-validation, near-player hold, and repeated visibility diagnostic path.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Added `kDebugUseVanillaVisibleNpcForRuntimeSpawnTest` and
|
||||||
|
`kDebugVanillaVisibleNpcFormId` for the Stage 3.3 diagnostic. The candidate is
|
||||||
|
treated as Codsworth and resolved safely through the data-handler form lookup
|
||||||
|
path.
|
||||||
|
- Logged the diagnostic actor-base source as either `vanilla diagnostic NPC` or
|
||||||
|
`custom F4T_RemotePlayerProxy` so runtime spawn, visibility diagnostics, and
|
||||||
|
hold conclusions identify which base was tested.
|
||||||
|
- Validated that the Codsworth candidate resolves as `RE::TESNPC`, with logs for
|
||||||
|
resolved FormID, form type, editor ID, display name, and accepted state. If it
|
||||||
|
does not resolve as a valid `TESNPC`, the controller logs the failure and falls
|
||||||
|
back to the normal custom proxy actor base.
|
||||||
|
- Preserved the existing Stage 3 runtime spawn path: the selected `TESNPC*` is
|
||||||
|
passed into the current spawn function, with the same handle validation,
|
||||||
|
runtime proxy state, placed fallback support, Stage 3.2 hold, and repeated
|
||||||
|
diagnostics.
|
||||||
|
- Improved near-player debug placement to prefer forward-vector placement about
|
||||||
|
250 units in front of the local player at `Z + 20`, with a fixed X-offset
|
||||||
|
fallback if heading data is not usable.
|
||||||
|
- Expanded the hold conclusion for the vanilla diagnostic to report `PASS`,
|
||||||
|
`PARTIAL`, or `FAIL` based on whether `IsVisible` becomes true, 3D loads while
|
||||||
|
visibility remains false, or no 3D checks become true.
|
||||||
|
- Did not implement Stage 4 multi-proxy mapping or any
|
||||||
|
`remotePlayerId -> proxy actor handle` table.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: launch Fallout 4 through F4SE, enter `F4TTestCell01`, and confirm
|
||||||
|
`Fallout4Together.log` reports whether the Stage 3.3 vanilla diagnostic is
|
||||||
|
active or fell back to `F4T_RemotePlayerProxy`.
|
||||||
|
- Pending: inspect the hold diagnostics and final PASS/PARTIAL/FAIL result to
|
||||||
|
determine whether the vanilla actor base appears visually through the same
|
||||||
|
runtime spawn path.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- Stage 3.3 is temporary diagnostic behavior and does not prove the final proxy
|
||||||
|
representation path until a runtime actor is visually confirmed in-game.
|
||||||
|
- Stage 4 remains blocked until the visual representation problem is isolated to
|
||||||
|
either the custom actor base or the runtime spawn/init path.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Use the Stage 3.3 log result to decide whether to investigate
|
||||||
|
`F4T_RemotePlayerProxy` in Creation Kit or revisit the runtime spawn/init path
|
||||||
|
before any Stage 4 work.
|
||||||
|
- Keep Stage 4 reserved for later
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3.4
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Added an absolute FormID and existing-reference visibility diagnostic for
|
||||||
|
Codsworth. Stage 3.4 compares resolving Codsworth as a runtime spawn base against
|
||||||
|
moving the existing placed Codsworth reference near the local player as a
|
||||||
|
separate visibility control.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Added `kDebugUseExistingVanillaRefVisibilityTest`,
|
||||||
|
`kDebugCodsworthBaseFormId`, and `kDebugCodsworthRefFormId` for the Stage 3.4
|
||||||
|
diagnostic.
|
||||||
|
- Added absolute FormID lookup diagnostics for Codsworth base `000179FF` and
|
||||||
|
Codsworth placed ref `0001CA7D`, including requested FormID, resolved FormID,
|
||||||
|
form type, editor ID, display name, and whether the result casts to
|
||||||
|
`RE::TESNPC`, `RE::Actor`, or `RE::TESObjectREFR`.
|
||||||
|
- Updated the vanilla runtime-spawn diagnostic to use the Codsworth base only if
|
||||||
|
absolute FormID lookup resolves `000179FF` as `RE::TESNPC`. If it does not
|
||||||
|
resolve, the system logs the failure and keeps falling back to
|
||||||
|
`F4T_RemotePlayerProxy`.
|
||||||
|
- Added an existing placed-ref visibility control that moves the resolved
|
||||||
|
Codsworth placed reference near the local player for the diagnostic hold
|
||||||
|
duration, logs the same 3D/visibility checks, and defers normal proxy movement
|
||||||
|
while the control is active.
|
||||||
|
- Stored Codsworth's original position and original cell ID where available, then
|
||||||
|
attempts to restore the original position at the end of the control hold.
|
||||||
|
Cross-cell restoration remains logged as unavailable rather than guessed.
|
||||||
|
- Added a Stage 3.4 PASS/PARTIAL/FAIL conclusion to distinguish existing placed
|
||||||
|
ref visibility from runtime actor creation/init problems.
|
||||||
|
- Preserved the custom runtime proxy path, placed fallback support, same-cell
|
||||||
|
gating, lowest remote `playerId` selection, smoothing, snap movement, holding
|
||||||
|
lifecycle, remote state handling, fake client behavior, and server protocol.
|
||||||
|
- Did not implement Stage 4 multi-proxy mapping or any
|
||||||
|
`remotePlayerId -> proxy actor handle` table.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: launch Fallout 4 through F4SE, enter `F4TTestCell01`, and confirm
|
||||||
|
`Fallout4Together.log` shows absolute lookup diagnostics for `000179FF` and
|
||||||
|
`0001CA7D`.
|
||||||
|
- Pending: confirm that a resolved Codsworth base is used for the vanilla
|
||||||
|
runtime-spawn diagnostic, or that the custom proxy fallback is logged clearly.
|
||||||
|
- Pending: confirm that a resolved Codsworth placed ref is moved near the local
|
||||||
|
player and reports a Stage 3.4 PASS/PARTIAL/FAIL conclusion.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- Stage 3.4 is temporary diagnostic behavior and does not establish the final
|
||||||
|
remote player representation architecture.
|
||||||
|
- The existing placed-ref movement control only runs if `0001CA7D` resolves as
|
||||||
|
`RE::Actor`; if it resolves only as `RE::TESObjectREFR`, movement and
|
||||||
|
`IsVisible` diagnostics are logged as unavailable because those APIs are not
|
||||||
|
exposed on `TESObjectREFR` in the current CommonLibF4 setup.
|
||||||
|
- If only position restore is available, the diagnostic logs that cell restore is
|
||||||
|
unavailable rather than attempting a risky cross-cell move.
|
||||||
|
- Stage 4 remains blocked until visible representation is confirmed.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Use the Stage 3.4 control result to determine whether to investigate runtime
|
||||||
|
actor creation/init, the custom proxy actor base, or the visibility/placement
|
||||||
|
check itself before any Stage 4 work.
|
||||||
|
- Keep Stage 4 reserved for later
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3.5
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Added a temporary PlaceAtMe-equivalent diagnostic after manual console validation
|
||||||
|
confirmed `player.placeatme 000179FF 1` spawns visible Codsworth in
|
||||||
|
`F4TTestCell01`. The new diagnostic uses the local player as the placement
|
||||||
|
reference and compares that path against the existing `CreateReferenceAtLocation`
|
||||||
|
runtime spawn path.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Added `kDebugUseConsolePlaceAtMeSpawnTest` and
|
||||||
|
`kDebugPlaceAtMeActorBaseFormId` for the Stage 3.5 diagnostic.
|
||||||
|
- Uses the exposed CommonLibF4 `RE::Console::ExecuteCommand(const char*)`
|
||||||
|
wrapper to execute `player.placeatme 000179FF 1` once from the game-thread
|
||||||
|
proxy controller path.
|
||||||
|
- Snapshots pre-existing Codsworth candidate actors in the current cell before
|
||||||
|
executing the command, then scans the current cell for a newly created
|
||||||
|
Codsworth actor near the local player.
|
||||||
|
- Stores the resolved actor handle and runs a separate 15-second visibility hold
|
||||||
|
with repeated diagnostics for position, local-player distance, created/deleted
|
||||||
|
state, disabled state, available-in-game state, `Get3D`,
|
||||||
|
`GetFullyLoaded3D`, `GetCurrent3D`, and `IsVisible`.
|
||||||
|
- Defers normal proxy movement while the Stage 3.5 hold is active, without
|
||||||
|
changing remote state receive/update, placed fallback support, or the existing
|
||||||
|
Stage 3 runtime proxy path.
|
||||||
|
- Reports a Stage 3.5 PASS/PARTIAL/FAIL conclusion to distinguish the
|
||||||
|
local-player console placement path from `CreateReferenceAtLocation` runtime
|
||||||
|
spawning.
|
||||||
|
- Did not implement Stage 4 multi-proxy mapping or any
|
||||||
|
`remotePlayerId -> proxy actor handle` table.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: launch Fallout 4 through F4SE, enter `F4TTestCell01`, and confirm
|
||||||
|
`Fallout4Together.log` shows the Stage 3.5 console command execution.
|
||||||
|
- Pending: confirm the diagnostic resolves a spawned Codsworth actor near the
|
||||||
|
local player and reports a Stage 3.5 PASS/PARTIAL/FAIL conclusion.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- Stage 3.5 intentionally uses the console placement path as a temporary
|
||||||
|
diagnostic because manual validation proved that path can spawn visible
|
||||||
|
Codsworth. It is not the final proxy architecture.
|
||||||
|
- The diagnostic leaves the PlaceAtMe-spawned actor in the session; no safe
|
||||||
|
cleanup/despawn path is introduced in this stage.
|
||||||
|
- Stage 4 remains blocked until visible representation is confirmed and the
|
||||||
|
preferred spawn/init path is selected.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Compare the Stage 3.5 PlaceAtMe result against the existing
|
||||||
|
`CreateReferenceAtLocation` result to decide whether to replace the runtime
|
||||||
|
spawn path or investigate initialization differences before Stage 4.
|
||||||
|
- Keep Stage 4 reserved for later
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3.6
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Refined the PlaceAtMe-equivalent diagnostic so it isolates the Codsworth ref
|
||||||
|
created by the latest `player.placeatme 000179FF 1` command instead of
|
||||||
|
accidentally latching onto an older runtime Codsworth candidate.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Added Stage 3.6 constants for candidate isolation, post-spawn settle time, and
|
||||||
|
candidate search timeout.
|
||||||
|
- Snapshots known Codsworth candidates before executing PlaceAtMe, logging the
|
||||||
|
candidate count, FormIDs, 3D state, visibility, and position.
|
||||||
|
- Executes `player.placeatme 000179FF 1` once per diagnostic attempt, then polls
|
||||||
|
for a Codsworth actor whose FormID was not present in the pre-spawn snapshot.
|
||||||
|
- Logs each considered candidate with old/new status, position, distance from
|
||||||
|
the local player, loaded-3D checks, and `IsVisible`.
|
||||||
|
- Holds a newly isolated PlaceAtMe actor at its original console-spawned location
|
||||||
|
during the initial settle window instead of immediately moving it near the
|
||||||
|
player or assigning it as the active remote proxy.
|
||||||
|
- Reports a Stage 3.6 PASS/PARTIAL/FAIL conclusion and reminds manual testers
|
||||||
|
that pause-menu or alt-tab visibility changes point toward render/process
|
||||||
|
update flushing rather than actor-base selection.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: launch Fallout 4 through F4SE, enter `F4TTestCell01`, and confirm the
|
||||||
|
log shows a Stage 3.6 pre-placeatme snapshot, one command execution, new
|
||||||
|
candidate isolation, settle diagnostics, and a final PASS/PARTIAL/FAIL result.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- Stage 3.6 is still diagnostic-only and leaves the PlaceAtMe-spawned actor in
|
||||||
|
the session.
|
||||||
|
- Manual testing showed newly spawned Codsworth may appear only after opening
|
||||||
|
the pause menu or alt-tabbing, so render/process refresh behavior remains the
|
||||||
|
main open question.
|
||||||
|
- Stage 4 remains blocked until visible proxy spawning is fully understood.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Use the Stage 3.6 logs to determine whether PlaceAtMe visibility depends on a
|
||||||
|
delayed render/process update before selecting a final runtime proxy spawn
|
||||||
|
strategy.
|
||||||
|
- Keep Stage 4 reserved for later
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-02 - Runtime Proxy Spawning Stage 3.7
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
Made the preferred Stage 3 runtime proxy spawn path PlaceAtMe-backed instead of
|
||||||
|
`CreateReferenceAtLocation`, reusing the successful Stage 3.6 candidate
|
||||||
|
isolation and settle window before the actor is promoted into normal remote
|
||||||
|
movement.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
|
||||||
|
- `plugin/src/F4TProxyActorController.cpp`
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
- Added Stage 3.7 constants for enabling PlaceAtMe-backed runtime spawning,
|
||||||
|
trying the custom proxy base first, retaining a Codsworth diagnostic fallback,
|
||||||
|
and controlling candidate search/settle timings.
|
||||||
|
- Resolves `F4T_RemotePlayerProxy` through the existing plugin-local FormID path
|
||||||
|
and uses the resolved runtime FormID in `player.placeatme <baseFormId> 1`.
|
||||||
|
- Snapshots existing actors matching the selected base before spawning, then
|
||||||
|
polls for a newly isolated actor whose FormID was not present in the snapshot.
|
||||||
|
- Preserves the isolated actor at its original PlaceAtMe spawn location during
|
||||||
|
the settle window and defers active proxy selection/remote movement until the
|
||||||
|
settle completes.
|
||||||
|
- Promotes the settled actor into the existing single runtime proxy handle so
|
||||||
|
same-cell gating, lowest remote `playerId` selection, restore movement,
|
||||||
|
smoothing, snap movement, holding lifecycle, and movement-state observation
|
||||||
|
continue through the existing Stage 3 path.
|
||||||
|
- Skips the old `CreateReferenceAtLocation` runtime spawn when Stage 3.7 is
|
||||||
|
enabled, while keeping that code path available behind the Stage 3.7 guard.
|
||||||
|
- Disables the standalone Stage 3.4 existing-ref control and Stage 3.6 Codsworth
|
||||||
|
diagnostic while Stage 3.7 is active so they do not interfere with proxy
|
||||||
|
spawning.
|
||||||
|
- Leaves the placed CK fallback proxy available if PlaceAtMe-backed spawning
|
||||||
|
fails.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Ran `xmake build` from `plugin`; it succeeded.
|
||||||
|
- Pending: launch Fallout 4 through F4SE, enter `F4TTestCell01`, and confirm the
|
||||||
|
log shows Stage 3.7 custom proxy base resolution, one PlaceAtMe command per
|
||||||
|
attempt, candidate isolation, settle diagnostics, promotion, and normal remote
|
||||||
|
movement after promotion.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
- Codsworth fallback is diagnostic-only and indicates the custom
|
||||||
|
`F4T_RemotePlayerProxy` base still needs Creation Kit investigation if it is
|
||||||
|
the only PlaceAtMe-backed actor that becomes active.
|
||||||
|
- Stage 3.7 remains single-proxy only. It does not add a
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
- Stage 4 remains blocked until single PlaceAtMe-backed proxy movement is
|
||||||
|
verified in game.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
- Test the custom PlaceAtMe-backed proxy in game with remote movement and compare
|
||||||
|
behavior against the Codsworth fallback if needed.
|
||||||
|
- Keep Stage 4 reserved for later
|
||||||
|
`remotePlayerId -> proxy actor handle` mapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Entry Template
|
## Entry Template
|
||||||
|
|
||||||
Use this format for future updates:
|
Use this format for future updates:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace F4T::ProxyActorController
|
namespace F4T::ProxyActorController
|
||||||
{
|
{
|
||||||
// Game-thread-only actor controller for proxy diagnostics and the active placed proxy test actor.
|
// Game-thread-only actor controller for the single active runtime proxy and placed fallback.
|
||||||
// Networking threads must only update plain remote-player state.
|
// Networking threads must only update plain remote-player state.
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user