CallExtension in DayZ
One of my least favorite changes between Arma 3 modding and DayZ modding is that the developers of DayZ insist that the game only be modded in the way that they deem correct. One example of this is the removal, and refusal to re-implement, the callExtension functionality that is so widely used in Arma 3. Those who have played Arma, you’ll know that many game modes exist that require a database, such as Life or KoTH. These games are only possible in Arma thanks to the callExtension method allowing modders to create database connection libraries. extDB3 is the extension that makes this possible. One last example before moving on, Task Force Arrowhead Radio is a mod that significantly improves the radio and voice communication in the game. Military Ops and community use this mod heavily because of the massive improvement. Once more, only possible with callExtension.
callExtension is a scripting command in the Arma series of games. It allows SQF, script, to run native C++ (or C#) from a custom created library. This is extremely useful for adding functionality that the base game doesn’t support. Sadly, most extensions are blocked by BattlEye and therefore cannot run on the client (TFAR being an exception to this rule).
Anyway back on track. Since the developers of DayZ continued to not add this vital functionality, I decided I would take the time to create an implementation myself. I called it Infinity as with it you have infinite modding opportunities (kinda lame lol). I want to walk you through how I created this.
In order for a native (c++) mod to function, we need a way to load custom code into the server executable. For this, I originally chose to use the BIDebugEngine trick. This trick is an artifact the devs used to leave in the DayZ production server and client executables. The game would automatically load any library in the root folder called BIDebugEngine. Here is the decompiled code from DayZServer_x64.exe that shows how it worked:
Note: shortly after releasing infinity, the developers of DayZ removed the code above. Infinity now includes a library loading executable to load BIDebugEngine.dll on the server.
In order to add callExtension to the scripting framework, I need to create a custom proto native command. If you want an example of a proto native, look at the Print function in DayZ. So first step, we need to figure out how to register our own script functions. We can achieve this by understanding how DayZServer initializes the games native methods. Taking a look at that:
In the InitModules method, we can see a standard call to RegisterFunction. This registers our script command with a native C++ method to execute when it’s called. There are, however, a few more complex ways to add script commands. Here is an example of the Math library. Notice how we first register the class, then each function is registered with an argument being that class.
So, the best approach to registering functions I can see is to hook this InitModules method and call register ourselves with our own custom functions. For this, I made use of MinHook which made hooking DayZ methods super simple.
Here we are using minhook to hook initmodules:
Here we are registering our functions for callExtension:
Wait! We need to go over how to replicate the RVExtension implementation!
Now we need to develop the C++ functions that our proto native definitions will be linked too. These functions need to have the same limitations and the same scope of functionality as the Arma 3 script command does. Here is the code I came up with to implement the pre-v1.67 definition:
One unique aspect here is reducing how much memory we leak on each RVExtension call. Sadly, we can’t destroy the buffer that stores our result until after we hand it back to Enforce. So to keep the leak as small as possible, we copy the result from RVExtension back to a buffer that is just large enough to fit it.
Now I am going to skip the other neat parts of the Infinity library. I may end up doing a video just discussing it in more detail for those interested. If/When I do that, it’ll go on the following page. For now, let us assume that we’ve successfully registered our script functions. Let’s take a look at the DayZ Mod that needs to go with it.
At the bottom, you can see our registered proto native functionality. I created this Extension class to help wrap up using these methods. Using this mod in conjunction with our BIDebugEngine library, we can copy+paste Arma 3 extensions into DayZ and use their functionality for our own servers. Horray!
Seriously though, this is something I have been begging the DayZ developers to implement. Obviously I have not heard anything back, but the developers going out of their way to remove BIDebugEngine.dll from the game sends a strong message that they do not want to encourage this style of modding. Actually, when I first worked on this library in 2018, Bohemia Interactive sent me a cease and desist letter. I really think they are taking the wrong approach in this aspect, but I will continue to maintain the library and github as they have really no legal grounds to prevent me from distributing the source code. Just note that if you do decide to use Infinity, BI probably won’t want to monetize your server (though let’s be honest they rarely do any diligence on who has monetization rights and who doesn’t).