Discord GameSDK - How not to implement it in production


Discord GameSDK - How not to implement it in production

So, hello. I'm NekoFromIT, a infrastructure/services developer at Silverzone. I have participated in the development of this game on the programming side and want to clarify and explain a big mistake I made and also talk about the importance of thorough code reviews and testing.

The mistake

So, as you can see on the game's page, there is a notice about the Discord GameSDK and a misimplementation on our part. The person behind that misimplementation is me, and I take full responsibility about it.

The mistake was made in implementing the Discord GameSDK, as shown in the below figures.

Figure 1: The misimplementation

The figure contains the code that made it to production in the end, which contains a major oversight in the Discord GameSDK initializer

In the above figure, a function call was made to the GameSDK, which was later included in a production build. The instruction that caused this error is:

discord = new Discord.Discord(clientID, (UInt64)Discord.CreateFlags.Default);

which was called in the Unity function Awake(), a special function to run included code on object creation. The code block also includes a failsafe to handle errors in case something goes wrong, but it is inadequate and does not include the Dispose() function for the Discord object. This behaviour results in the application requiring Discord to be running, if it's installed to play. However, for some reason if Discord is not installed, it does not fail and allows a player to play normally.

Figure 2: A decompilation of the published binaries

In the figure is a decompilation of the published binaries, showing the code that caused this error

In the above figure, is the compiled and then decompiled code of the application, taken from the most recent build included on itch.io (v1.0.3.2). It shos the eralier function call in the compiled form:

UnityServiceManager.discord = new Discord.Discord(UnityServiceManager.clientId, 0UL);

which contains the error in the second input variable, 0UL. This is an implementation error resulting in Discord-dependant non-production-ready code.

Mitigation and a fix

We found this mistake and oversight thanks to one player, who was justifiably taken aback by unexpected behaviour. The behaviour in question is the game refusing to start and then launching Discord. Thanks to this player, we were able to catch this mistake early-on and mitigate it nearly immediately. However due to the game jam rules this game participated in, we can not provide the updated binaries (v1.0.3.3) yet.

Figure 3: An improved implementation

In this figure is an improved implementation that mitigates the erro

The above figure contains the updated and improved implementation for the GameSDK initializer, which uses the correct NoRequireFlags implementation, that results in production-ready code that should not require Discord to be running, installed or anything like that. The change in question is:

discord = new Discord.Discord(clientID, (UInt64)Discord.CreateFlags.Default);

The improved implementation also disposes the Discord object for safety if an error is detected by calling discord.Dispose().

Figure 4: The decompiled new implementation

The figure contains a decompilation of the new implementatio

The above figure contains the compiled and then decompiled code of the implementation. As can be seen, the error, caused by 0UL, is now corrected by having 1UL as the parameter.

UnityServiceManager.discord = new Discord.Discord(UnityServiceManager.clientId, 1UL);

What have we learned

I can't say that the team has learned anything. As I said this is entirely my fault and I have reflected on my mistake. We have talked with the rest of the programming side about implementing a code review process and actually using it before production code is approved. I have also learned to remember to test using more possible use cases, as my testing was not sufficient enough to cover this issue.


Why we don't want this issue to happen

The game was never meant to require Discord, only to use Discord's Activites/RPC service as an addition to the experience. And because of this, the issue causes us problems with distribution, as users may not want to use Discord while playing the game.


How these kinds of mistakes can be avoided

I'd say that the best way to avoid mistakes like these is to test thoroughly and review or have a team member review your code before approving it to production.

Another good way would be to test multiple enviroments, like in this case on devices that had Discord installed and running, installed but not running, installed but not logged in and not installed. In this regard I had failed the testing which led to the mistake happening and affecting users.


Tools used for decompilation: JetBrains dotPeek, a free .Net explorer.

Get Zombie Conquest

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.