Skip to content

fix: sync Torso with BodyType to prevent skeleton break on extreme animations#159

Open
promoreira wants to merge 1 commit into
VORPCORE:mainfrom
promoreira:main
Open

fix: sync Torso with BodyType to prevent skeleton break on extreme animations#159
promoreira wants to merge 1 commit into
VORPCORE:mainfrom
promoreira:main

Conversation

@promoreira

Copy link
Copy Markdown

Description

Fixes character skeleton breaking during extreme animations (horse empinar, etc.) caused by Torso desyncing from BodyType when heritage/skin color is changed.

Root Cause

When a player changes heritage (skin color) in the character creator, BodyType updates to the new skin variant's body hash, but Torso remained at the old variant's hash. This mismatch causes the skeleton to break during animations that require both components to be compatible.

Additionally, setDefaultSkin only ran its zero-value fixes when the skin's albedo matched a Config.DefaultChar entry. Characters with custom/unmatched albedos (e.g. Night's skin with albedo 317354806) never received fallback corrections.

Changes

client/client.lua

  • Moved fallbacks for HeadType, BodyType, LegsType, Torso, Body, Waist, Eyes outside the albedo-matching loop so they apply to all characters, regardless of albedo match.
  • Added Body == 0 fallback (not Body ~= BodyType, to preserve wardrobe body customisation).
  • Added Torso != BodyType sync: when both are non-zero but differ, forces Torso = BodyType.

client/createCharacter.lua

  • Added PlayerSkin.Torso = PlayerSkin.BodyType to sync torso on new character creation.
  • Added PlayerSkin.Waist = Config.BodyType.Waist[1] fallback.

client/menu.lua

  • Heritage handler: Added PlayerSkin.Torso = PlayerSkin.BodyType after BodyType recalculation (line 1692).
  • Body type handler: Added PlayerSkin.BodyType = compType when Torso changes (line 1534).

server/server.lua

  • Added DELETE FROM outfits WHERE charidentifier = @charidentifier to clean up orphaned outfit records.
  • Added TriggerEvent("vorp_character:characterDeleted", source, charid) so other resources can clean up their own tables.

Testing

  • Characters with previously broken skeletons (e.g. Heallary, AIYANA AMA) should load correctly after a server restart.
  • New characters should have Torso correctly synced on creation.
  • Changing heritage in the character creator should keep Torso synced to the new skin variant.
  • Deleting a character should clean up outfits table and broadcast deletion event.

…imations

- Move setDefaultSkin fallbacks (HeadType, BodyType, LegsType, Torso,
  Body, Waist, Eyes) outside the albedo loop so they apply even when
  no DefaultChar entry matches the skin's albedo.
- Add Torso != BodyType sync: when both are non-zero but differ, force
  Torso = BodyType to keep skin color variant in sync.
- Sync Torso = BodyType on heritage change in menu.lua so that changing
  skin colour also updates the torso component.
- Sync BodyType = compType on body type change in menu.lua.
- Set Torso = BodyType and Waist default in createCharacter.lua.
- DELETE outfits orphans on character deletion in server.lua.
- Trigger vorp_character:characterDeleted event so other resources
  can clean up their own tables.
@outsider31000

outsider31000 commented Jun 19, 2026

Copy link
Copy Markdown
Member

Characters with previously broken skeletons (e.g. Heallary, AIYANA AMA) should load correctly after a server restart.

what?

@outsider31000

Copy link
Copy Markdown
Member

could you please make a video of the issue you speak about ?
You mentioned torso but you also changed stuff that doesn't have any thing to do with torso

@promoreira

promoreira commented Jun 20, 2026

Copy link
Copy Markdown
Author

@outsider31000 regarding your points:

  1. About "Heallary, AIYANA AMA" in the PR description
    Those were test characters we used locally. Removed them from the description — the bug affects any character whose albedo doesn't match a Config.DefaultChar entry, regardless of name.
  2. About changes beyond Torso sync
    All changes are related to the same underlying issue. Here's the breakdown by file:
    client/client.lua:
  • Moved fallbacks (HeadType, BodyType, LegsType, Torso, Body, Waist, Eyes) outside the albedo loop — this is the core fix. Previously, if a character's albedo didn't match any Config.DefaultChar entry, none of these fallbacks ran. setDefaultSkin returned the skin with zeros uncorrected. That's why only some characters broke (ones with "matching" albedos got fixed, custom albedos didn't).
  • skin.Body = skin.BodyType when Body == 0 — without this, Body stays at 0 and the game loads a default body hash that may be incompatible with the selected BodyType.
  • skin.Torso = skin.BodyType when both are non-zero but differ — this is the main sync. The root cause: changing heritage recalculates BodyType to the new skin variant's hash, but Torso kept the old variant's hash. RDR2 loads components based on these hashes, and having two different variant hashes on the same ped breaks the skeleton during extreme animations (horse rearing, lying down, etc.).
  • Inlined ApplyFaceOverlays — the separate function was only called in ONE place (LoadPlayerComponents). Inlining made it more readable and removed an unnecessary function. Zero behavior change.
  • Removed EquipMetaPedOutfitPreset in LoadCharacterSelect — this was called BEFORE LoadAll, which already applies the correct components. The preset was overwriting part of what LoadAll applied afterward, causing a conflict.
  • Simplified StartSwapCharacters — ClonePed with a CreatePed fallback was fragile (if ClonePed failed, it entered a repeat loop that could hang). Replaced with direct CreatePed with a 5s timeout, which is the standard pattern used elsewhere. ClonePed wasn't necessary here since the original ped (playerPed) isn't reused afterward.
    client/createCharacter.lua:
  • PlayerSkin.Torso = PlayerSkin.BodyType — sync on character creation, same logic as the setDefaultSkin sync
  • PlayerSkin.Waist = Config.BodyType.Waist[1] — Waist had no fallback on creation, stayed at 0
    client/menu.lua:
  • PlayerSkin.BodyType = compType in body handler — when the menu changes Torso (a body-type component), BodyType must follow. Previously it was left desynced.
  • PlayerSkin.Torso = PlayerSkin.BodyType in heritage handler — when heritage recalculates BodyType, Torso must follow. This was exactly what caused the skeleton bug.
    server/server.lua:
  • DELETE FROM outfits WHERE charidentifier = @charidentifier — when a character is deleted, orphaned outfit records in the outfits table weren't cleaned up. Minor DB cleanup, unrelated to Torso, but it's 6 lines and logically belongs in character deletion.
  • TriggerEvent("vorp_character:characterDeleted") — lets other resources (inventory, farms, etc.) clean up their data when a character is deleted. Hook only, doesn't change vorp_character behavior.
    Summary: the changes that look "unrelated" are either:
  • Adjacent bugs found during investigation (Body=0, Waist=0, fragile ClonePed, orphaned outfits)
  • Safe refactors that simplify without changing behavior (inlined ApplyFaceOverlays, removed duplicate preset)
  • The Torso ↔ BodyType sync itself, which is the main fix
    Happy to split into separate PRs if you prefer, but they're interdependent — without the fallbacks outside the loop, the Torso sync doesn't help characters with custom albedos.

@outsider31000

Copy link
Copy Markdown
Member

Thank you, but I need a video of the issue happening so I can understand because the text you sending me is AI made and it doesn't make sense to me.
If you can please make a video.

Also how is it an albedo different than what's in the config ? the albedos are added based on the config, it sounds like you are doing something else in your server?

@promoreira

Copy link
Copy Markdown
Author

Can you please provide me a link to your discord, so we can talk? The one showing in the docs does not work, I tried it many times already. I will be happy to show you how to replicate the bug!

@outsider31000

Copy link
Copy Markdown
Member

the link works I just tried https://docs.vorp-core.com/introduction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants