Repository navigation
Conversation
Adds Gameplay:bUseLegacyHandPose (off by default) to ServerSettings and a ToggleLegacyHandPose console command that flips it for every connected player at runtime through the existing settings broadcast. On, VR clients use the original hand pose sync: no body poses are captured, sent or relayed, and hands are not synced while a weapon is drawn. The following commit is what reads it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GLbDoEM12w8cqAb9MnBTPC
Shows every VR player's tracked VRIK body on the other clients instead of the stock animation: head, arms, hands, spine, legs and the held weapon, while Tilted keeps the actor's identity, equipment, AI, collision and root position. On by default; F10 still switches the display back to the game's own animation at runtime, and the server's bUseLegacyHandPose restores the original hand pose sync for everybody. - Capture (sender): a post-VRIK/HIGGS callback reads the local skeleton through a guarded reader and sends RequestBodyPose at ~30 Hz, unreliable. The server checks ownership, schema, clock, order and rate before relaying NotifyBodyPose to players in range, and relays nothing while bUseLegacyHandPose is on. - Presentation (receiver): the pose is retargeted onto the remote actor's own reference skeleton and written to the bones and the flattened bone tree from the render hook, before the hand pose pass. A re-apply on the BSFlattenedBoneTree vtable's three downward-pass slots (pinned by RVA, signature and RTTI; refused loudly on any mismatch) restores the written pose after the job-thread animation pass, which removes the one-frame flash between tracked and animated pose. - HandPoseService stays the fallback for any puppet the body lane is not writing, behind an ownership latch. In body mode hands keep syncing while drawn and the received grip is applied to the attachment node; in legacy mode the original drawn rule and head tracking are unchanged. - VR only (#if TP_SKYRIMVR at every new call site; the SE path is unchanged). Tests cover the codec, relay decision, history, composition, post-pass registry, readers, latch and settings on the wire. Both client and server must run this build (BUILD_COMMIT check). Built on the HandPoseService by Sergei Kazakov. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GLbDoEM12w8cqAb9MnBTPC
The VRIK body pose now shows the swing on other players, so the attack animation replayed on a hit (added in 984bf95) is no longer needed and fights the pose. Only the Actor.cpp hook is removed; the rest of that commit (struct offsets, activation guard, dump flags, tools) stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UVeCPjbR9c2doxTDCJa3p6
Since the inventory, magic, skills, favorites, map, container, tween, message box, tutorial and console menus no longer pause the game in VR (UI.cpp kAllowList), VRIK's menu pose kept going out as the player's body and the other player saw a twisted body while one was open. While one is open the body stream now sends an explicit loss, with or without a new capture, and resumes only from a capture taken after the update that saw the menu close; the hand/head lane sends no hands and no head, at once on the menu change even when the hands were already off, so the receiver shows the game's animation, as for tracking loss. Both log the menu on change. Also logs, VR only, the player's health, open menu and position when it goes down and when the bleedout respawn starts and returns: on 2026-10-03 a player went down with no damage seen while the inventory was open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UVeCPjbR9c2doxTDCJa3p6
When the body lane cannot write a puppet (2026-10-03: every frame refused with missing-skin-detail after a rebuild), the legacy hand lane took over and posed the arms with a weapon drawn: the arms collapsed into the torso with the sword at the shoulder. In body mode that fallback now leaves a drawn weapon to the game's animation, decided from the sender's own drawn state, which the hand pose messages now carry and send at once on change (RequestHandPose/ NotifyHandPose Drawn, relayed by the server). When it ends with a sheathe, nothing is resolved or posed until the receiver's copy has read sheathed for 4.5 s, then the arms are re-resolved with a fresh rest. Legacy mode is unchanged. Also logs, VR only, the puppet's worn armor when a body refusal streak starts (BODY remote_worn, re-armed per rebuilt tree) and the sender's worn armor on change, the first sample per connection always (BODY local_worn), so a skin refusal can be traced to what each side wears. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UVeCPjbR9c2doxTDCJa3p6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
For humans
Other VR players show their VRIK pose (head, hands, arms, body, legs, held weapon), also with weapons drawn. It comes from headset and controllers only. On by default, VR only.
New since your 10-02 notes: with a menu open (inventory, magic, map...), the other player sees the game's idle, not a twisted body. The attack animation on a melee hit is removed. A body that cannot be posed with a weapon drawn shows the game's animation, not collapsed arms.
Turn off: F10 (only this client), or
bUseLegacyHandPose=true//ToggleLegacyHandPoseon the server (everyone). Needs: client and server from this build; VRIK and HIGGS 1.10.10 on the sender.Not done yet: handshake height, arrow on the bow, sheathed weapon at the hip. Missing armor after a door is fixed separately in #14.
For LLMs / agents (detailed)
Commits (base
5ab99be4, head80a04c67; build token0.0.1-37-g80a04c67)60d1e996 feat: server setting bUseLegacyHandPose for VR pose sync. AddsServerSettingsfieldGameplay:bUseLegacyHandPose(default false) and the console commandToggleLegacyHandPose(typed/ToggleLegacyHandPose), which rebroadcasts settings.edb057ee feat: vr full-body tracking for other players. The feature. The commit title says "full-body"; it means VRIK's IK body, not tracker-based FBT.91c87fb9 fix: remove synthesised vr melee attack action(maintainer request, 10-02). Removes only theActor.cpphook from 984bf95 that replayed an attack animation when the local player landed melee damage; the rest of that commit stays.aba2981f fix: vr menus do not send the menu pose as the player's body(maintainer report "inventory breaks both poses"). Since fix: vr unpaused menus (skills, map, input and melee block) #10'sUI.cppkAllowList, the inventory, magic, skills, favorites, map, container, tween, message box, tutorial and console menus no longer pause the game, so VRIK's in-menu pose went out as the body. While one is open the body stream sends an explicit loss (SourceStream::BuildaSuppressed, fenced so only a capture taken after the update that sees the close resumes), and the hand/head lane sends no hands and no head (a menu change forces the send). Also logs, VR only, health/menu/position when the player goes down and around the bleedout respawn (PlayerService,ActorValueService).80a04c67 fix: body-mode fallback leaves a drawn weapon to the animation. When the body lane cannot write a puppet (refused, not yet acquired, or stopped), the legacy hand lane used to pose drawn arms and collapsed them into the torso. In body mode that fallback now leaves a drawn weapon to the game's animation, decided from the SENDER's drawn state: newDrawnfield inRequestHandPose/NotifyHandPose, relayed by the server, sent at once on change. After a sheathe nothing is resolved until the receiver's copy has read sheathed for 4.5 s, then the arms are re-resolved with a fresh rest. Legacy mode unchanged. Diagnostics:BODY remote_worn(puppet's worn armor when a refusal streak starts) andBODY local_worn(sender's worn armor on change, first sample always).Totals vs base: 63 files, +8,626/-269. The wire format changed again (
Drawn), so client and server must both come from this build.Testing done
TPTests); the VR client and server build; the changed client units compile for SE (compile only, not linked or run on SE).bDisableCollisionBetweenOtherCharactersAndObjects=true), door trips, idle on tracking loss, the legacy toggle, the map menu.BODY menu:lines). Favorites was not exercised. A melee hit on an NPC showed no canned swing on the watching seat.BODY remote_worn/local_worn) plus owner observations showed armor present in the inventory but not drawn on rebuilt copies; the separate gear-redraw fix restored it.Known issues
HandPoseService(reader and ownership latch), keeps posing the head alone when hands are absent (possible head jut on idle entry) and keeps the original one-frame flicker.[critical] Hand sync: ... cached bone pointers ... no longer pointline: a guard re-resolving a detached subtree, not a failure; too loud.Found upstream, not caused by this PR
missing-skin-detail NPC L Toe0). Fixed in the separate PR VR: other players' worn armor is not drawn when they wear no torso armor #14 (fix/vr-remote-gear-redraw).DetachHandItemsskips drawn spawn requests and bodies with no equipped weapon or shield, without logging; whether that is the cause is unproven.CharacterService).Data flow
GameWinMain, reads the local skeleton through a guarded reader (BodyReadMemory.h,BodyProbeMemory.h,ReadProbe.h) and sendsRequestBodyPoseunreliable with a 33 ms minimum interval. While a kAllowList menu is open it sends an explicit loss instead.CharacterService). Ownership, schema, clock, order and rate checks, thenNotifyBodyPoseto players in range; nothing whilebUseLegacyHandPoseis true.NotifyHandPosenow relaysDrawn.BodyPoseService). Retarget onto the remote actor's own reference skeleton (BodyReferenceSkeleton,BodyPoseComposition.h); write bones and the flattened bone tree from the render hook. A body is admitted only when every retail finger, forearm twist and toe bone is consumed by a verified skin (prevents the partial-skin limb warping).BodyPostPass). Thunks onBSFlattenedBoneTreevtable slots0x2d/0x2e/0x2f(VR0x140CB0030/60/90, pinned by RVA, 27-byte signature and RTTI name; refuses loudly on mismatch) re-apply the last published pose after the job-thread recompute, validated against the live tree and a 64-unit fresh-root guard.HandPoseService). The hand pose path covers any puppet the body lane is not writing, behindHandPoseLatch.h. In body mode a drawn weapon there is left to the game's animation (HandPoseLatch::DrawnFallbackIdle).Log lines (client
tp_client.log)BODY startup: post-VRIK capture registered once before GameWinMain; schema=2 world axes,BODY POSTPASS mode=on|off|refused ....Pose sync mode: body|legacy (server bUseLegacyHandPose=0|1).BODY status remote= actor= reason= frames= writes= refusals= ... pp_calls= pp_reapplies= .... Healthy:refusals,pp_stale,pp_busy,pp_overlap,publish_fail,unmappedare 0;pp_movedbursts at doors are expected.BODY source sent= captured= gaps= lost= capture_us_max= state= reason= native=.BODY menu: <Menu> open, local body pose suppressed (sent as a loss)/... closed, local body pose resumes from a capture taken after this;Hand sync: local hands are now not synced (... menu open, no head sent: <Menu>).Hand sync: actor X has a weapon drawn and no body write this frame; its animation owns it until a body write or a sheathe,Hand sync: actor X sheathe settled after the drawn fallback; re-resolving its arms with a fresh rest.BODY native_detail scope=remote actor= reason=missing-skin-detail ... bone=,BODY remote_worn remote= actor= worn=[...],BODY local_worn worn=[...].BODY receiver OFF|ON ...,Pose sync: displaying other players' tracked pose is now OFF|ON. Sending is unchanged.Review provenance
🤖 Generated with Claude Code
https://claude.ai/code/session_014b5v4UAeR2a8gR537GMuvi