Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Instances duplicating in Unity Game (Rogue Legacy 2)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> 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

PostPosted: Mon Nov 28, 2022 5:57 pm    Post subject: Instances duplicating in Unity Game (Rogue Legacy 2) Reply with quote

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
View user's profile Send private message
Bloodybone
Newbie cheater
Reputation: 0

Joined: 07 Dec 2016
Posts: 20
Location: Germany

PostPosted: Tue Nov 29, 2022 11:07 am    Post subject: Reply with quote

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
View user's profile Send private message
LocutusOfBlog
How do I cheat?
Reputation: 0

Joined: 28 Nov 2022
Posts: 7
Location: Narnia

PostPosted: Tue Nov 29, 2022 11:55 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites