|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
LocutusOfBlog How do I cheat? Reputation: 0
Joined: 28 Nov 2022 Posts: 7 Location: Narnia
|
Posted: Mon Nov 28, 2022 5:57 pm Post subject: Instances duplicating in Unity Game (Rogue Legacy 2) |
|
|
Background: I have been messing around with editing values and calling methods in Rogue Legacy 2. I specifically wanted to use in-game methods to add items in the game (Specifically: Relics), instead of directly modifying the quantity.
I know I can make an entry in the address list with the address/pointer to the quantity, and I did that successfully.
However, the game does not update for certain things until exit/reload the save.
I was able to successfully call methods to get the items to update properly using mono_invoke_method() on instances of the Relics in the game.
The instances are of the class: RelicObj
This has several methods unique to the game but also derives from System.Object.
The Problem: Sometimes, when I run the code to enumerate the instances and the fields of RelicObj, it creates additional instances. These instances stay even after closing the game and restarting the computer.
This is the general code I use to get the instances/fields/methods:
Code: |
relicObjApplyRelic = mono_findMethod('Assembly-CSharp', 'RelicObj', 'ApplyRelic') --Define ApplyRelic Method
--define friendly(ish) names for the fields
relicTypeFieldName = "<RelicType>k__BackingField"
relicLevelFieldName = "m_level"
--enumerate object instances of class
relicObjInstances = mono_class_findInstancesOfClassListOnly(domain, relicObjClass)
relicFields = mono_class_enumFields(relicObjClass)
for k, v in pairs(relicFields) do
if v.name == relicTypeFieldName then relicTypeOffset = v.offset end
if v.name == relicLevelFieldName then relicLevelOffset = v.offset end
end
|
Sometimes after running the code, the number of instances increases by the original amount (~100). Each instance represents a Relic in the game + a couple of placeholders for some other game code. When the bug happens, it creates duplicate instances of each of these. This is visible on the Mono Dissector and the .NET Info viewer when finding instances. I have verified in the .NET viewer that the new instances are duplicates of the originals by noting that the field values (like RelicType) are identical.
These new instances do not disappear when I close the game, cheatengine, and/or restart the computer. This tells me that they are probably not stored in memory, but possibly somewhere on the disk. If so, where? Where would mono/unity store object instances for a game?
My questions:
1) Is there something obvious in my code that is causing new instances to be created? If so, why does it only happen sometimes and not every time I run the code? I have some intermediate coding knowledge, but I am new to making cheat tables, Cheatengine, Lua, Mono, and Unity.
2) Does anyone know where/how these instances are staying? I have even tried uninstalling the game, deleting the game data directory, and reinstalling.
3) Is there a way to remove them?
Thank you in advance for your help.
|
|
Back to top |
|
|
Bloodybone Newbie cheater Reputation: 0
Joined: 07 Dec 2016 Posts: 20 Location: Germany
|
Posted: Tue Nov 29, 2022 11:07 am Post subject: |
|
|
1) I don't think this code snippet has anything that would create duplicate Objects.
2) If I had to guess the Game has some sort of List/Array or other way to access all of the Relics and when saving the Game it just serializes them and saves them to a file. This would probably be the save file. When you start the Game again it will just deserialize all of them and it doesn't check for duplicates. The save file could be more or less anywhere. Games often like to store save data inside Appdata\Roaming or Local.
3) If you have a way to find all the duplicates and just delete the Objects (calling UnityEngine.Object.Destroy should do the trick). The next time it saves it would then ignore those Objects. Though if it stores them in some List/Array you might also want to find that and remove it from there.
|
|
Back to top |
|
|
LocutusOfBlog How do I cheat? Reputation: 0
Joined: 28 Nov 2022 Posts: 7 Location: Narnia
|
Posted: Tue Nov 29, 2022 11:55 am Post subject: |
|
|
Thanks for the reply, and I completely agree. The code should not create any objects at all. The call to find the instances only gets a list of the addresses of potential instances of that class.
By digging around in the Unity docs and forums, I did find that the game is most likely serializing the objects and storing them in a file (in this case a .rc2dat file). I have ruled out the individual player save files by loading a different save game and still finding the extra instances in CE. I will have to try moving the other .rc2dat files to a backup folder and restarting.
I did try UnityEngine.Object.Destroy for the instances, but it did not change any of them. There seems to be an issue with the garbage collector ignoring them and I think it is because they were being referenced by CE. I remember reading somewhere in the Unity docs that the garbage collector will bypass objects that are still being referenced. What I believe is happening is that in normal gameplay, the game will stop referencing an instance when it no longer needs it, Unity will remove the instance as part of normal garbage collection. The docs said that there is an issue when 2 different things are referencing the object and one of them calls to destroy it, then the garbage collector may permanently ignore it because it is still referenced. This can lead to objects being orphaned. If I am understanding correctly, the Game (which constantly saves to prevent savescumming) is serializing the objects and the dual reference is causing the duplication. The reason why this may be only happening at some points is because the collector has to be doing its check at the same time that CE is referencing the objects and the game is serializing them.
It is crazy, and I still don't understand all of it. I will keep looking into it so I can find a way to prevent the duplication.
_________________
"Mama always told me not to look into the eyes of the sun. But, Mama! That's where the fun is!"
- Albert Einstein |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|