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.
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.
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.
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().
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
Zombie Conquest
Zombie Conquest, a take on classic Tower Defense games, where you are the attacker instead. GMTK2023 submission.
Status | Released |
Authors | Silverzone, nekofromit, iskela06, KoppiSs, George Kab, slimerplanet |
Genre | Strategy, Adventure |
Tags | 2D, 8-Bit, Pixel Art, Singleplayer, Sprites, Top-Down, Zombies |
Languages | English |
Leave a comment
Log in with itch.io to leave a comment.