Adventures in Modding
Due to some other games, I recently (like within the past 2-3 weeks) became interested in Unity Engine modding via injection. First by using IPA and then finally by using BepInEx. At first, I made a (heroic, I thought) attempt trying to add rudimentary VR support (by way of VRGIN) to From the Depths, but alas my C#/.NET/Unity/VR skills are still too low. FtD's Unity version is far too advanced of what VRGIN supports, even after trying various other forks/continuations.
A few days ago, I started from zero again: with just BepInEx installed. And then I set forth to make my first mod — the lifelong (ha ha) dream of being able to exfiltrate data generated by Lua scripts. I've needed such a feature for a long time now, especially for my more experimental scripts (such as the neural-net driven rocket aiming script). It sucked needing to relearn/retrain the script every time the vehicle was loaded/put into play. So it would be very useful to extract the training set (or even the final weights) and then hardcode them into a "production" version of the script.
Turned out much easier than I thought, since I simply patched 3 existing Lua methods:
- Log — To save data (as a string)
- ClearLogs — To clear anything saved
- Crash — To dump all saved strings to a file (in the place where the game usually saves Lua scripts) and then clear the saved strings
Very easy to do. Simply made use of Harmony.
Then, I thought, I would really like that Lua method to fetch the current wave height under a given point. I could just patch an existing method (like
GetTerrainAltitudeForPosition), but then I'd have to take care when I used those methods in my scripts. So instead, I would try to inject a new method.
Yes, I know Gladyon (the prolific-modder-turned-dev) had a framework for injecting Lua methods. But I felt like I really needed to learn how to do it on my own. And so yesterday, off I went, delving heavily into Mono.Cecil, Harmony, SLua.
- I stubbed my new method (called
- Also stubbed the SLua "generated" method into
Lua_LuaBinding, complete with attributes.
- Because I'm not a masochist that likes to deal with IL, I patched the actual implementations in using Harmony.
- And then, after some head-scratching, I realized I needed to also insert the new method into
LuaBinding's metatable on the Lua side.
And it worked. Calling
I:HelloThere() from a Lua box would generate the proper response in the console (I simply made it use
Console.WriteLine for simplicity...) I was successful.
But then I realized, all I really need to do is step #4. So that will be my next attempt, after devising a simple framework to inject Lua methods...