Contributor Name Saif Kandil
GitHub k0T0z
LinkedIn saifkandil02
Organization The ENIGMA Team
Organization GitHub enigma-dev
Project Description Steam Workshop SDK/Third Party Integration For ENIGMA
Primary Mentor's GitHub
Secondary Mentor's GitHub
Repositories Worked On
Issues Worked On

Completed work

Final Project Structure

Layer 1: Steamworks SDK
Layer 2: Steam Binder
Layer 3: Game Client
Layer 4: Steamworks Extension
                        
    Steamworks
    ├── gameclient
       ├── steambinder
          ├── SteamFake
             └── sdk
                 ├── public
                 │   └── steam    
                 │       ├── *.h
                 │       └── *.cpp    
                 
                 └── README.md  
          
          ├── SteamvXXX
             └── sdk
                 ├── public
                 │   └── steam    
                 │       └── *.h    
                 
                 └── Readme.txt    
          
          ├── .gitignore
          ├── steambinder.h
          └── steambinder.cpp
       
       ├── utils
       │   ├── *.h
       │   └── *.cpp
       
       ├── gameclient.h
       ├── gameclient.cpp
       ├── *.h
       └── *.cpp
    
    ├── steamworks_demo
    │   ├── *
    │   └── demo.project.gmx
    
    ├── .gitignore
    ├── About.ey
    ├── implement.h
    ├── include.h
    ├── CMakelists.txt
    ├── Makefile
    ├── README.md
    ├── *.svg
    ├── steamworks.h
    ├── steamworks.cpp
    ├── *.h
    └── *.cpp
                        
                    

Work To Be Done

  • Lobbies API
  • Cloud API (My only missed goal)
  • DLC API
  • UGC API
  • Inventory API
  • Networking API
  • Input API
  • Utils API
  • Fixing the memory leak inside the Fake API. Check Steamworks/gameclient/SteamFake/sdk/public/steam/fake_steam_api_internal.cpp
  • Implementing a new draw function for drawing leaderboards.
  • Getting an AppId and upload a game on Steam for testing.
  • Cleaning up and organizing the new Async System to match Robert's needs.
  • There is a bunch of TODOs in the #2350's description that need to be done as well.
  • Currently, all the documentation is in the code files, it should exists in the docs/Wiki/Category:Function:ENIGMA as well.
  • Adding support for other platforms in the Steam Binder as it currently supports Ubuntu Linux only. Testing Steamworks extension on other Linux distros is the easier part. Windows requires MSVC support for ENIGMA which is a project on its own. Upgrading the engine's build system from GNU Make to CMake will make it more easier (#2334). Currently, ENIGMA is failing on macOS which means we can't test the Steamworks extension on it yet.
  • Implement user functions related to #2349.
  • Work on LGM and RGM GUI with the Steamworks extension.
  • currently, ENIGMA's asset array class doesn't support pointers, so maybe we need to look into that as well.

List of merged patches

Patch Link Description
#2335 (Unrelated) Created 2 user functions for dealing with short JSONs and fixed #2339. Actually, I need to look more into this later because I may need to redefine what is a short JSON. I found out that for example, consider this short JSON: [ [ 1 , 2 ] , 2 ], what will be its JSON? It can be { " 0 " : { " 0 " : 1 , " 1 " : 2 }, " 1 " : 2} or [ { " 0 " : 1 , " 1 " : 2 } , 2 ]. Two different outputs for the same input. This is a complete miss!!!
#2340 (Unrelated) This issue was becasue of a newer GCC version used.
#2341 (Unrelated) This issue was becasue of a newer GCC version used.
#2352 (Related) The json_encode() function was unimplemented.
#2353 (Related) In this one, I provided a fix for a weird issue that I explained here GSoC '23 - Week 11 & 12: Divergence? or... and using std::sstream instead of std::string in my use case is better as recommended by Josh.
#2355 (Related) This one is related to #2354. I provided a fix for the issue related to Json extension.
#2357 (Related) Fixed another bug found in the Json extension. Overall, with this #2358 merged, the Json extension is now fully functional.
#2360 (Related) In #2335, I provided a fix for #2339 but it was wrong solution. This patch fixes the issue with the right and perfect solution.
#2297 (Unelated) This is my first patch when I started working on ENIGMA. It's simple cleaning for dead files.

Note that related/unrelated means that the patch is related/unrelated to the Steam SDK integration project.

List of unmerged patches

Patch Link Description
#2358 (Related) The json_encode() function requires a recursive algorithm to handle nested JSONs. Solutions to this are theoretical till now. Currently, the function will print the ID of any nested JSON instead of printing the JSON itself.
#2361 (Related) The Social API requires the buffer work from the previous GSoC 2022 project as the current buffer work is completely broken. The Data Buffers / Serialization project is the one. This code is merged into AST-Generation branch so I had to test my Social API inside that branch. My both PRs in the Completed Work section are intended to be merged into master branch. After discussing with Dhruv (Original author of the buffer work), he suggested to split the buffer work into a separate PR and merge it into master branch. So, I created a new PR for the buffer work.
#2337 (Unrelated) Before getting familiar with pacman, I downloaded GTest and built it from source. I got only the *.a files with no *.dlls. ENIGMA links to *.dlls so the code crashes obviously. I provided my report for rpjohnst and he suggested to use pacman as it downloads the *.dlls as well. The thing is using the dll, GTest will be linked dynamically. Also, using the .a, GTest will be linked statically. So that patch changes the way we link GTest which are two different approaches with pros and cons. I don't think this should be merged.
#2334 (Unrelated) This is related to #2286. This is my PR for upgrading the build system from GNU Make to CMake. This was my Google Summer of Code 2022 project before getting rejected. I intend to work on it after stabilizing the Steamworks extension.
#2333, 2321, and #2314 (All unrelated) No longer needed PRs, these are just was for testing things out.

Note that related/unrelated means that the patch is related/unrelated to the Steam SDK integration project.

Other patches

Patch Link Description
#2356 (Related) There was a missing function that I requested from Robert and actually there was no problem with not adding it because I can just use instance_create() and set the depth.
#2349 (Related) This PR is for firing events from the Steamworks extension manually. The functions are not implemented yet. These are just useful constants for the user to use. Also Robert submitted this PR. Actually, this is a TODO that I mentioned in the work to be done.

Challenges faced and Learnt Lessons

  • I started working on Windows on this project until I faced an ABI (Application Binary Interface) problem. I explained this problem in my proposal and expected that I won't face it but I did. I spent nearly 3-5 days trying to figure out where is the problem until my mentor suggested building the same code using GCC and MSVC. As expected the code worked well on MSVC but it gives SEGMENTATION FAULT on GCC. I switched to Linux after this problem.
  • Implementing a new Async system for ENIGMA. As the old Async system is not thread safe. Robert helped with implementing the new one.
  • Solving CI problem by 2 steps:

    1. Creating the Steamworks Fake API.
    2. Creating Stubs for the Steamworks and DataStructures extensions.

    There are 2 approaches when creating the Fake API:

    1. Linking the libsteam_api.so statically in the Makefile file.
    2. Linking a Fake API (AKA Mocking) statically in the Makefile file and load the real libsteam_api.so dynamically at runtime.

    I started with the first approach until I realized the CI problem. The CI needs to know which API (Fake/Real API) to link statically. We want to link the Fake API when running tests (GTests and SOGs (Single Object Games)) but at the same time we want to link the Real API when running a real game. There is only one solution for this problem:

    1. Sending a flag when running tests to indicate that we are running tests and we need to link the Fake API. When running from the IDE, this flag won't be sent so we will link the Real API.

    Instead, fundies suggested the second approach. This approach requires adding another layer between the Steamworks SDK and Game Client layers. I will call this layer Steam Binder.

  • Implementing the Steamworks Fake API. I had to dig deeper into Steamworks official headers to understand how the API works and then mock main interfaces.

Steam SDK Integration Demo On YouTube

Acknowledgement

الحَمْدُ لِله دائما وأبدا

First things first, Thanks to everyone who has contributed to the success of my Google Summer of Code 2023 project. This journey would not have been possible without the support, guidance, and collaboration of many individuals and organizations.

First and foremost, I would like to extend my deepest appreciation to Robert, Josh, Russell (rpjohnst), Patrick (Hugar), and Greg (fundies), my mentors throughout this program. Their expertise, patience, and continuous guidance have been invaluable. I have learned immeasurable skills and insights under their mentorship.

Thank you.