LaneDibello / Kotor-Randomizer

The Kotor Randomizer. A randomizer for Star Wars: Knights of the Old Republic. Intended for challenge runs and general fun.
4 stars 1 forks source link

Item shuffle causes invisible npcs and game crash #68

Closed glasnonck closed 3 years ago

glasnonck commented 3 years ago

This issue is similar to #51.

A crash occurred when entering Gadon's office and getting to the point in the conversation that automatically starts where Gadon speaks. Gadon was also invisible. Investigation led to conclude that his Light Battle Armor (g_a_class7001) was replaced with Darth Revan's Robes (g_a_mstrrobe06). These have caused issues before on certain character models. Further testing revealed that the same can be said about the Star Forge Robes (g_a_mstrrobe07) - if certain characters wear that item, they become invisible and cause the game to crash if spoken to.

Testing has not revealed why only certain models are broken by these items. For example, consider three NPCs Belaya, Crattis, and Deesra in the Jedi Enclave (danm13) as they represent the three types of character models I've identified so far.

  1. Crattis - These models remain consistent no matter what armor they have equipped; there is no change in their appearance. Furthermore, they aren't broken when they wear either of the problem robes.
  2. Belaya - These models change in appearance when wearing various armors and have a default look when the armor slot is empty. They aren't broken when they wear the problem robes and their appearance is that of the default.
  3. Deesra - These models change in appearance like the previous type and have a default with no armor. However, they go invisible and can cause a crash if they wear a problem robe.

The problem with type 3 remains even if their appearance is changed to a different model (e.g., Deesra is given Crattis's appearance but still breaks if wearing Revan's Robes). This happened with the run in question where Gadon crashed the game. His appearance was shuffled through model rando to be 346 (Commoner_Dirty_Mal_White) in his office and 490 (Sith_Mal_White_02) in the Bek Base instead of his normal 389 (Unique_Gadon) and he still crashed the game. This led me to believe that the crash isn't related to the model so much as the character itself.

This idea was strengthened in another test: two captives within the Sith Academy use the same appearance (and thus model) - kor35_captive9 and kor35_victim. Captive9 is the one who fights with the sith duelist in a cutscene. Victim is the mandalorian they're questioning to find a cache. When their armor is changed, their appearance doesn't change either. Furthermore, when they were both equipped with Darth Revan's Robe, only Captive9 turned invisible and caused a crash (only if you interact with him before he is killed in the cutscene).

Further testing is needed to determine what is causing these crashes.

LaneDibello commented 3 years ago

Doing some comparisons between Deesra and Crattis (who have nearly identical appearance info). I found that the main difference between the two is that Deesra's "Disarmable" boolean field is set to False. This rule does not hold for the Captive9/Victim example who are both Disarmable.

Another difference between the two is that Crattis is wearing nothing by default, whereas Dessra has Jedi robes. Meanwhile, victim is wearing nothing by default, and Captive9 come equipped with battle armor. Perhaps, the crash only occurs for people who were previously wearing something else?

Similarly Gadon also has an item equipped by default.

LaneDibello commented 3 years ago

When you were doing this testing, putting armor onto these various models, what was the method by which you were equipping these items?

glasnonck commented 3 years ago

I just used Kotor Tool to add a custom item to their armor slot, saved the new character information to a folder, and copied that to the Override directory to see how the game reacted.

I also tested matching specific bits of Deesra's information to Crattis - appearance, body bag, disarmable, and portrait. (I changed body bag because his standard appearance uses a different bag than Crattis.) Changing each of these individually to match didn't prevent Deesra from becoming broken.

glasnonck commented 3 years ago

A couple other things I forgot to mention.

I also tested Tariga in the Sith Academy since he has appearance 490 (Sith_Mal_White_02). He didn't break when I gave him armor, and he also didn't start with any armor equipped. I'm not sure this point is the issue, however, since Belaya starts wearing a Jedi Robe and still works fine when equipped with the special robes.

One of the Hidden Beks in Indy's seed was also invisible inside the Bek Base, and interacting with them caused the game to crash. I wonder if that would also be a good place to test the effects on various characters. Edit: Each of the ambient Beks have a different armor setup - one is wearing no armor and one is wearing the same armor as Gadon, thus the invisible model and crash. I haven't tested it specifically, but that's my theory looking over the spoiler and worn armor.

LaneDibello commented 3 years ago

IIRC Override is not a very reliable method for modifying character data, especially those stored in RIMs. When I'm home later today, I'll see about testing some of these cases, and see if I report similar results

glasnonck commented 3 years ago

I guess it makes sense that the mechanism could be different between the two. We have a couple other ways we could test the changes then. The first would be to match the mechanism of Item Randomization by modifying chitin.key. The second would be to modify the UTC files stored within the _s.rim files of interest like we do within Model Randomization. Both might reveal useful information, but I think the first method would be more accurate in replicating the issue we see currently.

Edit: I just realized that the first method alone would mean we couldn't really test giving these bad items to a character who doesn't wear any armor by default. We'll probably need to use a mixed approach in some cases to fully understand.

LaneDibello commented 3 years ago

Welp, after building 3 new duplicate modules of danm13, each with Crattis, Belaya, and Deesra respectively with the Revan Robes equipped. And like, with your initial tests, only Deesra experienced the crash, while Belaya and Crattis were fine... Which is very curious. Further testing incoming.

glasnonck commented 3 years ago

I built a Sith Academy rim with both the captive and the victim wearing Revan Robes with the same result as before: Captive is invisible and can cause a crash, victim is visible and doesn't crash.

glasnonck commented 3 years ago

New test, I overwrote the victim's rFile with that of the captive. The victim is now invisible, has an icon over where he should be that reads "Captive Republic Soldier," and the terminal says the interrogation cage is empty (probably a script looking for a certain tag which is now missing). But I can't interact with him to cause the game to crash.

LaneDibello commented 3 years ago

I figured out the issue: The culprit is the feat "Proficiency All". All the characters that experienced the crash had this feat. Not to mention whenever I added this feat to a character and then gave them the robes, they had the same issue.

glasnonck commented 3 years ago

After a bit more testing, we determined that the characters who could equip the item didn't have a value assigned in the modelj and texj columns of appearance.2da. These columns are in charge of modeling and texturing the Revan Robes which had been causing issues. Adding a value to this cell for each appearance allows them to wear the robes without crashing the game.

glasnonck commented 3 years ago

A similar fix should also allow players to give armor to darth bandon if he's in their party. By default, his appearance has no value for model and textures b through j. I haven't tested this yet.