Neutralize runtime proxy actors and docs
Add a safe neutralization pass for Stage 4 runtime proxy actors and document the change. Introduces NeutralizeProxyActor and supporting helpers (ProxyNeutralizationReason, GetProxyNeutralizationReasonLabel, FormatPosition, IsProxyMovementPackageType, IsProxyFleeOrAlarmPackageType) plus kProxyNeutralizationInterval and a compile-time gate kEnableProxyAIMovementIntentSuppression (default=false). Adds SuppressProxyAIMovementIntent (default-disabled due to a crash observed during testing) which attempts safe package/process interruption using only confirmed CommonLibF4 APIs (EndInterruptPackage, InitiateDoNothingPackage, SetAvoidanceDisabled, command/process handle clears) and extensive throttled logs and TODOs for further unsafe changes. Neutralization is invoked after spawn promotion, on slot reassignment, during active maintenance, and while holding. Updates plugin logic to call neutralization at these points. Updates docs/architecture.md and docs/dev-log.md with the design, testing notes, and rationale (including the safety gate and next steps). Builds succeed; manual in-game validations are still pending.
This commit is contained in:
+31
-11
@@ -41,59 +41,69 @@ both send and receive paths:
|
||||
player's current valid transform before spawning and moves the isolated
|
||||
runtime actor to that transform immediately, so normal remote representation
|
||||
does not visually start at the local player offset.
|
||||
14. Proxy visual updates are independent per slot. Normal movement is smoothed
|
||||
14. Runtime proxies receive a small game-thread neutralization pass when a
|
||||
PlaceAtMe-backed actor is promoted, when a reusable slot is reassigned, while
|
||||
active on a throttle, and when moved or kept in holding. The pass only uses
|
||||
confirmed CommonLibF4 actor APIs/fields to stop combat, clear combat target
|
||||
handles, reset safe hostile/attack state, suppress combat-oriented process
|
||||
flags, clear exposed AI process movement targets, and attempt safe
|
||||
package/pathing interruption with a do-nothing package when pathing, flee,
|
||||
alarm, bump, or package movement intent is observed. It does not disable,
|
||||
hide, delete, despawn, alpha-fade, or force animation graph events on the
|
||||
actor.
|
||||
15. Proxy visual updates are independent per slot. Normal movement is smoothed
|
||||
toward that player’s latest target, while `cell_change`, `worldspace_change`,
|
||||
and `teleport` snap directly. Sneak state is still observed and logged only;
|
||||
no visual crouch/sneak application is attempted.
|
||||
15. When a remote player leaves the cell or disconnects, only that player’s
|
||||
16. When a remote player leaves the cell or disconnects, only that player’s
|
||||
runtime proxy is moved to the hidden holding position inside
|
||||
`F4TTestCell01`. Runtime actors are not disabled or deleted. Connected
|
||||
players who leave the cell keep their slot reserved, while disconnected
|
||||
held slots become reusable only after the configured grace period. Runtime
|
||||
slots use per-slot holding positions with spacing and a game-thread
|
||||
correction check so held actors do not stack or drift back into view.
|
||||
16. The placed fallback reference `F4TProxyRemotePlayer01REF` remains a single
|
||||
17. The placed fallback reference `F4TProxyRemotePlayer01REF` remains a single
|
||||
backup representation. If runtime spawning fails for one deterministic
|
||||
selected remote player, the fallback can represent that one player only; it
|
||||
is not used for multiple remote players.
|
||||
17. As part of the staged runtime proxy actor manager work, the same game-thread
|
||||
18. As part of the staged runtime proxy actor manager work, the same game-thread
|
||||
proxy controller also logs whether `Fallout4Together_Test.esp` is loaded and
|
||||
whether the actor base `F4T_RemotePlayerProxy` resolves by editor ID.
|
||||
18. Stage 3.1 adds a temporary diagnostic layer around the single runtime proxy:
|
||||
19. 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.
|
||||
19. Stage 3.2 adds a temporary near-player visibility hold for that same single
|
||||
20. 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.
|
||||
20. Stage 3.3 adds a temporary vanilla actor-base diagnostic layer. It attempts
|
||||
21. 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.
|
||||
21. Stage 3.4 adds a temporary absolute FormID and existing-reference diagnostic
|
||||
22. 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.
|
||||
22. Stage 3.5 adds a temporary PlaceAtMe-equivalent diagnostic after manual
|
||||
23. 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.
|
||||
23. Stage 3.6 refines that temporary PlaceAtMe diagnostic layer. It snapshots
|
||||
24. 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.
|
||||
24. Stage 3.7 promotes the working PlaceAtMe-style spawn pattern into the
|
||||
25. 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
|
||||
@@ -139,6 +149,14 @@ The native plugin is responsible for:
|
||||
`F4T_RemotePlayerProxy`
|
||||
- Capturing the remote player's current valid transform before Stage 4 runtime
|
||||
spawn and applying it as soon as the PlaceAtMe-backed actor is isolated
|
||||
- Neutralizing only resolved runtime proxy actors on the game-thread controller
|
||||
path after spawn promotion, during reusable-slot reassignment, periodically
|
||||
while active, and while held so they remain passive visual puppets rather than
|
||||
independent combat actors
|
||||
- Suppressing exposed AI movement intent for runtime proxies by clearing safe
|
||||
process target handles and using validated package interruption/do-nothing
|
||||
calls when combat, pathing, flee/alarm, bump, or package movement state is
|
||||
observed
|
||||
- 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
|
||||
@@ -219,6 +237,8 @@ Game update attempts at most one PlaceAtMe-backed runtime actor spawn at a time
|
||||
Game update snapshots matching candidates, isolates the new actor, and waits for the settle window
|
||||
Game update moves isolated Stage 4 runtime spawn candidates to the remote player's current transform
|
||||
Game update stores promoted runtime actors as ObjectRefHandle values in slots
|
||||
Game update neutralizes resolved runtime proxy actors after spawn promotion, reuse, active throttled checks, and holding
|
||||
Game update suppresses exposed AI movement/pathing intent without forcing animation graph events
|
||||
Game update moves each valid proxy from its assigned remote player state
|
||||
Game update holds only proxies whose assigned remote player left the cell or disappeared
|
||||
Game update corrects held proxy slots back to their per-slot hidden positions
|
||||
|
||||
+179
@@ -1969,6 +1969,185 @@ proxy cap forever.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-03 - Proxy AI Movement Intent Crash-Safety Gate
|
||||
|
||||
### Summary
|
||||
|
||||
Default-disabled the experimental AI movement/pathing/package suppression path
|
||||
after manual testing showed a crash during runtime proxy spawn/settle with a fake
|
||||
client connected.
|
||||
|
||||
### Files Changed
|
||||
|
||||
- `plugin/src/F4TProxyActorController.cpp`
|
||||
- `docs/dev-log.md`
|
||||
|
||||
### Details
|
||||
|
||||
- Added `kEnableProxyAIMovementIntentSuppression = false` so the risky follow-up
|
||||
suppression path is compiled behind an explicit safety flag.
|
||||
- Gated the `SuppressProxyAIMovementIntent(...)` calls from
|
||||
`NeutralizeProxyActor(...)` so the default runtime path no longer executes
|
||||
pathing status checks, package interruption, do-nothing package calls,
|
||||
command clearing, or AI process movement target writes.
|
||||
- Preserved the earlier neutralization behavior that was working better:
|
||||
`StopCombat()` only after `IsInCombat()`, combat target reset, attack/hostile
|
||||
flag reset, passive actor values, combat-oriented process flags, and throttled
|
||||
logs.
|
||||
- Left runtime proxy spawning, per-`playerId` slots, spawn-at-remote-position,
|
||||
movement smoothing/snapping, held/reusable lifecycle, placed fallback behavior,
|
||||
networking, protocol, Python server, and fake-client tooling unchanged.
|
||||
- Added a TODO in code noting that AI movement intent suppression caused a crash
|
||||
and must be re-investigated in smaller isolated steps before it is enabled
|
||||
again.
|
||||
|
||||
### Testing
|
||||
|
||||
- Ran `xmake build` from `plugin`; it succeeded and rebuilt
|
||||
`Fallout4Together.dll`.
|
||||
- Pending manual validation: start server, add fake client, connect Fallout 4,
|
||||
and confirm runtime proxy spawn/settle no longer crashes.
|
||||
- Pending manual validation: re-test multiple clients, movement, held/reusable
|
||||
lifecycle, and attack/bump behavior.
|
||||
|
||||
### Known Issues
|
||||
|
||||
- Attacking or bumping a proxy may still briefly trigger walk-away animation
|
||||
intent because the experimental movement/pathing/package suppression is now
|
||||
disabled by default for crash safety.
|
||||
- Runtime actors are still held instead of safely despawned or deleted.
|
||||
|
||||
### Next Steps
|
||||
|
||||
- Re-test the fake-client spawn path immediately.
|
||||
- Revisit AI movement intent suppression later with a diagnostics-only pass first,
|
||||
then re-enable one write/call at a time if each step is stable in-game.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-03 - Proxy AI Movement Intent Suppression Patch
|
||||
|
||||
### Summary
|
||||
|
||||
Reduced the remaining autonomous walk-away/flee animation intent that could play
|
||||
after a runtime proxy was attacked or bumped, while keeping transform authority
|
||||
driven by `RemotePlayerState`.
|
||||
|
||||
### Files Changed
|
||||
|
||||
- `plugin/src/F4TProxyActorController.cpp`
|
||||
- `docs/architecture.md`
|
||||
- `docs/dev-log.md`
|
||||
|
||||
### Details
|
||||
|
||||
- Added `SuppressProxyAIMovementIntent(...)` and call it through the existing
|
||||
`NeutralizeProxyActor(...)` path after spawn promotion, reusable slot
|
||||
reassignment, throttled active maintenance, combat neutralization, combat
|
||||
target clearing, and holding.
|
||||
- The helper uses only exposed CommonLibF4 APIs/fields: pathing status checks,
|
||||
`SetAvoidanceDisabled(true)`, `EndInterruptPackage(false)`,
|
||||
`InitiateDoNothingPackage()`, command clearing, and safe `AIProcess` target
|
||||
handle resets.
|
||||
- Detects flee/alarm/search/avoid/bump/travel/follow/patrol-style package types
|
||||
when exposed through the current package and logs throttled suppression events.
|
||||
- Leaves transform smoothing, snapping, spawn-at-remote-position, held slots,
|
||||
reusable slots, placed fallback behavior, networking, protocol, Python server,
|
||||
fake-client tooling, gameplay sync, and animation sync unchanged.
|
||||
- Added TODOs for movement-controller, actor-mover, procedure-index, preferred
|
||||
speed, and animation-layer resets because no clearly safe direct path-cancel
|
||||
or animation reset API has been validated yet.
|
||||
|
||||
### Testing
|
||||
|
||||
- Ran `xmake build` from `plugin`; it succeeded and rebuilt
|
||||
`Fallout4Together.dll`.
|
||||
- Pending manual validation: attack a runtime proxy and confirm walk-away
|
||||
animation intent is gone or reduced.
|
||||
- Pending manual validation: bump a runtime proxy and confirm no persistent
|
||||
autonomous walk/flee animation overrides remote-state transform control.
|
||||
- Pending manual validation: re-test multiple clients, spawn-at-remote-position,
|
||||
smoothing, snap movement types, held/disconnected/reusable slots, and Leave
|
||||
Cell / Return To Cell.
|
||||
|
||||
### Known Issues
|
||||
|
||||
- Runtime actors are still held instead of safely despawned or deleted.
|
||||
- Direct movement-controller/path-destination clearing is still not implemented
|
||||
because the local CommonLibF4 headers do not expose a validated safe API for it.
|
||||
- If the engine keeps an animation-layer response active after package
|
||||
suppression, a future patch may need a narrowly validated animation reset that
|
||||
does not block remote-driven animation sync.
|
||||
|
||||
### Next Steps
|
||||
|
||||
- Manually validate attack and bump behavior in `F4TTestCell01`.
|
||||
- If walk-away animation still persists, inspect runtime logs for pathing,
|
||||
package type, process target, and no-safe-API messages before adding deeper AI
|
||||
or animation control.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-03 - Runtime Proxy Neutralization Pass
|
||||
|
||||
### Summary
|
||||
|
||||
Added a safe runtime proxy actor neutralization pass so Stage 4 runtime proxies
|
||||
remain passive visual representations controlled by remote player state instead
|
||||
of entering persistent NPC combat or pursuit behavior.
|
||||
|
||||
### Files Changed
|
||||
|
||||
- `plugin/src/F4TProxyActorController.cpp`
|
||||
- `docs/architecture.md`
|
||||
- `docs/dev-log.md`
|
||||
|
||||
### Details
|
||||
|
||||
- Added `NeutralizeProxyActor(...)` on the game-thread proxy controller path and
|
||||
only call it on resolved runtime proxy slot actors, never the local player.
|
||||
- Neutralization now runs after runtime proxy spawn promotion, when reusable
|
||||
slots are reassigned, periodically while active, and when proxies are moved or
|
||||
kept in holding.
|
||||
- The helper uses confirmed available CommonLibF4 actor APIs/fields to stop
|
||||
combat, clear the current combat target handle, reset safe attack/hostility
|
||||
flags, set passive aggression/confidence/assistance actor values, and suppress
|
||||
combat-oriented AI process flags.
|
||||
- Kept runtime proxies renderable and reusable. No `Disable()`, `Enable()`,
|
||||
alpha/invisibility, `SetWantsDelete`, deletion, protocol, networking, Python
|
||||
server, fake-client, gameplay sync, animation sync, combat sync, inventory
|
||||
sync, quest sync, settlement sync, or placed fallback changes were made.
|
||||
- Added TODOs for package/procedure clearing and collision/stagger suppression
|
||||
because no clearly safe CommonLibF4 API has been validated for those yet.
|
||||
|
||||
### Testing
|
||||
|
||||
- Ran `xmake build` from `plugin`; it succeeded and rebuilt
|
||||
`Fallout4Together.dll`.
|
||||
- Pending manual validation: attack a runtime proxy and confirm it does not chase
|
||||
or attack the local player.
|
||||
- Pending manual validation: bump a runtime proxy and confirm no persistent AI
|
||||
behavior overrides remote-state transform control.
|
||||
- Pending manual validation: re-test multiple clients, spawn-at-remote-position,
|
||||
smoothing, `cell_change`/`worldspace_change`/`teleport` snapping,
|
||||
held/disconnected/reusable slots, and Leave Cell / Return To Cell.
|
||||
|
||||
### Known Issues
|
||||
|
||||
- Runtime actors are still held instead of safely despawned or deleted.
|
||||
- Package/procedure clearing and collision/stagger suppression need further
|
||||
investigation before adding more invasive AI control.
|
||||
- The placed fallback remains single-player only by design.
|
||||
|
||||
### Next Steps
|
||||
|
||||
- Run the manual attack/bump validation in `F4TTestCell01`.
|
||||
- If proxies can still enter transient stagger animations, investigate a
|
||||
separate collision/stagger-safe puppet-control pass that does not block future
|
||||
animation sync.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-03 - Held Runtime Proxy Stability Patch
|
||||
|
||||
### Summary
|
||||
|
||||
Reference in New Issue
Block a user