Google Summer of Code is a global program focused on bringing more student developers into open source software development. Students work with an open source organization on a 3 month programming project during their break from school.
Short Projects
SFXR Integration / API

Integrate the SFXR UI into RGM, and the SFXR audio generation routines as a library in ENIGMA.

SFXR is DrPetter's sound-effect generator; it's used quite often in competitions such as the Ludum Dare as it is an extremely useful tool for prototyping. You can find a copy of its source code both on its homepage and at this Git mirror, with work towards a Qt version already having happened in this repository.

Integrating SFXR into ENIGMA brings a couple of benefits:

Because there are lots of versions of SFXR available, including a Qt version, it's up to the proposer of this project to determine the best starting point and path forward. The two primary options are as follows:

To extend this project with machine learning, a contributor would need to propose a plan to obtain label data. Examples of this plan:

Mentors: Josh, Greg
Difficulty: Small (depending on proposed scope)
Expected size: 90h (can be grown in scope to fit 175h or even 350h with ML)
Skills required: C++ fundamentals, Qt (for IDE integration)

Long Projects
Steam Workshop SDK/Third Party Integration - Final phase

ENIGMA currently lacks third party integration with various digital distribution platforms such as Steam, Xbox, or Origin. First class support for these services would make it easier for Indie developers to publish ENIGMA created games. Developers would like for it to be easier to monetize their games and enable them to release bigger and better updates to their users. Compatibility with existing GameMaker API would be a secondary priority, as GameMaker only supports Steam officially.

Impact

This part will allow developers to create a multiplayer games that can be saved on cloud using Steam features.

Milestones

This is the second part of #1881, where you will complete the implementation of Steamworks extension to give ENIGMA's users full integration of Steamworks SDK into their games. Main PRs: #2343 and #2350 (check the work done in there).

Note that the contributor will need this previous work for Dhruv Chawla (here) and this PR #2361. The buffer work is merged into AST-Generation, which means most of the work will be in there. Also, you will have to refactor the whole demo game as it's not created for AST-Generation branch but for master.

The contributor should build ENIGMA on Linux first. You can then build the extension after following instructions inside this README.md file. Currently, no other OS is supported as the binder only supports Linux. DON'T forget to work on top of this PR #2363, until it's merged.

The contributor will need to work on RGM to implement the required UI for the extension. Example: the app_id textEdit widget.

  1. The contributor may warm up by implementing the json_encode() in this PR: #2358 or by implementing a new draw function for viewing a nice leaderboard and populate it with the already implemented leaderboard API in GSoC'23, or do both 😅.
  2. Implement the authentication capabilities.
  3. Implement the Lobbies API.
  4. Implement the Cloud API.
  5. Implement the Inventory API.
  6. Implement the Networking API.
  7. After each API is implemented, you will need to write tests and implement the Fake SDK.
  8. There are a bunch of other APIs, but I mark them as stretched goals for now as the above APIs will require a proper testing approach without the need for uploading a game onto Steam store.

Mentors: Robert, Josh
Difficulty: Medium - Hard
Expected size: 350h
Skills required: C++ fundamentals, Web/HTTP API, JSON, testing fundamentals, and Qt.
Skills preferred: Knowledge of batch API requests and Steam Workshop profile is ideal.

Add Network Play using Buffers
## Description
This project aims to add network play capabilities to the Enigma game engine, enabling developers to create online multiplayer games. The network play functionality will be achieved by leveraging the existing buffers used for game state to send and receive game data over the network.

Goals

Benefits

Expected Outcome

Mentors: Greg, Robert, Josh
Difficulty: Medium
Expected size: 350h
Preferred Skills:

Real-Time Debugging and State Rewinding in Enigma Game Engine with GUI Debugger
## Description
This project aims to enhance the functionality of the Enigma game engine by adding a comprehensive GUI debugger that allows developers to manipulate instance variables in real-time and rewind the game state to a previous point in time.

Goals

Benefits

Stretch Goal

Mentors: Greg, Robert, Josh
Difficulty: Medium
Expected size: 350h
Preferred Skills:

Implement the new parser
# Finish creation of the new EDL parser

Last year's project, titled "Data Buffers/Serialization", led to a complete
rewrite of the EDL (ENIGMA Development Language) parser. As it stands, the
parser can parse most of the EDL language, with some features which are
incomplete marked as "Unimplemented".

Mentors: Josh, Greg
Difficulty: Medium/Hard
Expected size: 350h
Skills required: C++ fundamentals, compiler fundamentals

Dynamic Asset Reloading
Currently the compiler only supports loading of game assets (that are included in your game file) by compressing and attaching them to the executable, This process is slow, error-prone, and cumbersome to work with since the metadata written to the executable is in binary form and not easy for the user to find. The compiler is also required to redundantly rewrite the same assets every time, even if they haven't changed. Ideally, we would like to make this step optional and instead write codegen in text format for the necessary metadata needed to load the resources and compile that into the game.

We would also like to support resource groups so that a user may load and unload specific resources at certain times, i.e, load_resource_group(level1) loading all of the resources contained in the level1 group. The groups would be specified by full or relative tree paths from the root of their project. Relative paths would make sense in the current executable context (e.g, if the function is called from a script, object, or room, etc). Groups are primarily created and organized through a frontend editor, like RadialGM, and the metadata for them is included in the tree node protocol buffer used by the compiler.

Milestones

  1. The contributor would start by working on #1878 to become familiar with our asset storage container. It's a simple class that just needs to replace existing uses of STD map and vector, to centralize the logic and behavior of asset allocation in memory.
  2. They could incrementally move on to #1500 and rewriting the compiler's resource writing modules to produce C++ code for the structures containing the metadata. They would update the corresponding engine structures to reflect the change by using external linkage to use them in the engine.
  3. To cap off, they would add a new module for writing a structure of the tree node with the other resource writing modules. A new API would have to be provided in the Universal System for accessing the tree node data.

Mentors: Josh, Greg
Difficulty: Hard
Expected size: 350h
Skills required: C++ fundamentals
Skills preferred: Experience with resource management in video game engines

Previous Year's Projects
\n
GSoC Final Evaluation: Steam Workshop SDK/Third Party Integration

Closes #1881. This is the second part of my first PR #2343.

This PR is part of the Google Summer of Code 2023 program.

I will be updating my Logs inside my domain.

Note: ✔️ means that SOG/unit tests for the corresponding function are provided.


Leaderboards API


Social API


Cloud API


Must Be Done Before Merging:

✅ Adding support for other platforms in the Makefile file.
✅ Switching the Default property in the Steamworks & Json extensions YAML file to false.
✅ Switching the cxxflags property in Compilers/Linux/gcc.ey to -fdiagnostics-color=always.
⬜ Reviewing all error messages and documentation in newly added files.
✅ Adding the license to all newly added files.
✅ Providing installation instructions for all platforms.
✅ Modifying the extension to call steam_init(); automatically when enabled.
✅ Match all naming conventions with GMS's Steamworks extension.
⬜ Testing the APIs with the latest version of Steamworks SDK, Steam, OS version, etc.
⬜ Must test all EDL scripts in the example game provided.
⬜ Providing SOG/unit tests for all functions written (this need to be studied carefully as in order to test the C++ wrapper tester must have steam installed and running or I may use mocks).
✅ Clearing garbage files.
DEBUG_MESSAGE() must exist only in APIs files. Try to remove it from wrapper files. Try to make the wrapper independent on ENIGMA.
✅ Fix example game background design.
⬜ Update the example game to match the latest version of GMS Steamworks extension.

✅ The compiler must write a file next to the exe.
⬜ Review includes.

✅ Commit the example game again and remove it from .gitignore file.
⬜ The extension and the example must be compatible with GameMaker.
⬜ Set the title for Steamworks demo to Created with ENIGMA.
⬜ Monitor GMS's terminal behavior.


Dependencies:


Good to have:

⬜ Test the changes with RGM.
⬜ Solve all build warnings.

GSoC Part 1 & 2: Binary Buffer functions, Serialization and Deserialization
This pull request marks the completion of my GSoC Project for Summer 2022, and contains all the commits pertaining to my changes in both the pull requests for Part 1 and Part 2 of my project, which are:

Aside from these, I also made the following pull requests which got merged:

Also, I made the following pull requests which did not get merged:

I tracked my progress approximately weekly on my personal blog: https://dc03.github.io/

GSoC project: Tiled compatibility support Enigma
### In A Nutshell - This project implements two importers: .tmx/.tsx file importers in RadialGM and .egm file importer in Tiled

My GSoC project spans into three PRs in three different projects of two separate organizations. The two organizations involved are Enigma-dev and Tiled. fundies and Josh are my mentors from Enigma-dev and bjorn is my mentor from Tiled.

Requirement: You have to use Arch linux OS specifically, as Enigma-dev's RadialGM only compiles in Arch linux at the time of writing these steps. Compiling RadialGM can be tough, so feel free to ping in enigma-dev discord server.

Steps to test the project:

  1. Compile Enigma-dev's RadialGM project and Tiled projects. (Note that Enigma-dev's enigma-dev project is a submodule of RadialGM so it gets included with RadialGM)
  2. Open terminal and change directory to RadialGM, checkout to PR #228
  3. Change directory to RadialGM/Submodules/enigma-dev, checkout to PR #2302
  4. Setup a system environment variable named ENIGMA_PATH and set its value to RadialGM/Submodules/enigma-dev. This path will be used by Tiled editor's "enigma" plugin.
  5. Change directory to Tiled, checkout to PR #3435
  6. Compile RadialGM and Tiled projects separately
  7. Run RadialGM project to open RadialGM editor, test the TMX importer by importing some .tmx file
  8. Run Tiled project to open Tiled editor, enable "enigma" plugin by checking it in Edit-Preferences-Plugins tab and finally test the EGM importer by importing some .egm file

Short demo video of the final outcome: https://www.youtube.com/watch?v=ZUJd5VhqQo8
Weekly project work logs: https://kartikshrivastava.github.io/

Completed list of tasks in GSoC coding period:

Tiled TMX and TSX importer support status in RadialGM and enigma-dev:

Enigma's EGM importer support status in Tiled:

Follow-up list of subtasks after GSoC:

Android GSoC 2021
# Final Report: Android Support for ENIGMA (GSoC 2021)

ORGANIZATION: The ENIGMA Team

Mentors:

My GSoC project (#1880) included mainly 3 tasks:


TASK 1: SHADER FIX

In task 1 I started with some bug fixes like Refactoring for GLES build
which included:


This fix was needed because OpenGL-Common has shared code between GLES and all OpenGL and some functions were only available in OpenGL, not GLES because of which they were giving errors.


After this the next bug I fixed was the Scaling issue and presence of garbage in the android build which included :


For fixing the scaling issue I had to modify few functions such as window_get_width() & window_get_height() with the idea of using SDL_GL_GetDrawableSize() instead of SDL_GetWindowSize().
Since resizing window is not possible in android I modified initGameWindow() as well by removing the macro since we do not need it anymore.


For fixing the garbage issue I added some new functions like graphics_remove_garbage() in Platforms\SDL\event.cpp and d3d_enable_scissor_test() in OpenGL-Common\d3d.cpp.

static void graphics_remove_garbage(float x, float y, float width, float height) {
  graphics_set_viewport(x,y,width,height);
  enigma_user::d3d_enable_scissor_test(false);
  enigma_user::draw_clear(enigma_user::window_get_color());
}
void d3d_enable_scissor_test(bool enable) {
  if(enable==true)
     glEnable(GL_SCISSOR_TEST);
  else
     glDisable(GL_SCISSOR_TEST);
}


I modified the windowsResized() function in event.cpp used the graphics_remove_garbage() function inside it and the d3d_enable_scissor_test() was simply used to enable and disable the scissor test.

A scissor test is what tells the GPU to stay within a particular rectangle when filling. It's an optimization (which may or may not matter when already specifying a viewport). Once enabled, pixels outside the scissor box(drawing area) will be discarded, removing the garbage around our game.

Below is the comparison of what it looked like before and after adding these changes and building the game again:

game screenshots:

BEFORE AFTER

Both the scaling and garbage issues were fixed.


After this, I started my first task for which I created a sample game with some sprites and circles and added different colors to them just to see the error in our shader.
Below is the difference between Android and Windows before the shader fix :

Windows:

Android:

After this, my mentors suggested that I should learn GLSL so I learned few concepts of GLSL like swizzling, samplers, etc and I got to know that we can access all the 4 components of a vec4 in any order you want.

My fix for the Shader issue was using "TexColor = texture( en_TexSampler, v_TextureCoord.st ) * v_Color;" for OpenGL and "TexColor.bgra = texture( en_TexSampler, v_TextureCoord.st ).rgba * v_Color;" for GLES. I did this by storing these strings in a common variable texColorString which I added in OpenGL-Common/shader.h and I used this variable in the raw string which is returned in getDefaultFragmentShader function.

@RobertBColton tested these changes and below are the test results:


Shader fix commits: b8ec0bf

Task 1 completed.


TASK 2: ADDING A NEW AUDIO SYSTEM

We needed a new audio system that was able to work for android, so I created an SDL audio system with the help of SDL_mixer

I used SDL_mixer docs to get all the functions I need for this audio system like :

First I created SoundResource.h which has the sound structure and some functions like update, destroy etc. Then I created SDLsystem which has audiosystem_initialize() which is responsible for initializing the SDL mixer api using Mix_OpenAudio and loading support for different audio sample formats using Mix_Init.

After this I added sound functions in SDLbasic.cpp like sound_exists, sound_add, sound_play, sound_delete, sound_stop, sound_loop and few more. These functions are common for all the audio systems. I used AssetArray for sounds because it is easy to access sound objects using the id.

For example below is my sound_play function which uses an SDL_mixer function,

bool sound_play(int sound) {
  const Sound& snd = sounds.get(sound);
  if (Mix_PlayChannel(-1,snd.mc, 0) == -1) { return false; }
  return true;
}

In the function above, sounds is the AssetArray of Sound objects and I use the id passed as a parameter to get the Sound. The sound structure has a chunk pointer(mc) and Mix_PlayChannel is the mixer function for playing the chunk on a channel. The other basic functions are made using the same approach.


Once I finished the basic functions I started the audio functions. For audio functions, I added SoundChanel.h which had the SoundChannel structure which looked like

struct SoundChannel {
  Mix_Chunk *mchunk;
  int soundIndex;
  double priority;
};


SoundChannel is being used because most of the audio functions for the SDL audio system use channel id instead of sound id.
Just like sound functions the audio functions are common for all the audio systems. I created SDLadvanced.cpp
and added audio functions like audio_exists, audio_add, audio_play_sound, audio_stop_sound and few more.
The audio functions are made using the logic I used for sound functions. For example:

sound_ispaused:

bool sound_ispaused(int sound) {
  const Sound& snd = sounds.get(sound);
  int channel_count = Mix_AllocateChannels(-1);
  for(int i = 0;i <= channel_count ; i++) {
    if (Mix_GetChunk(i) == snd.mc && Mix_Paused(i) == 1) { return true; }
  }
  return false;
}


audio_is_paused:

bool audio_is_paused(int index) {
  if (index >= AUDIO_CHANNEL_OFFSET) {
    return Mix_Paused(index - AUDIO_CHANNEL_OFFSET);
  }
  const Sound& snd = sounds.get(index);
  for(size_t i = 0; i < sound_channels.size() ; i++) {
    if (sound_channels[i]->mchunk == snd.mc && Mix_Paused(i) == 1) { return true; }
  }
  return false;
}

logic is the same but one uses only sound while the other uses both sound and channel structures.

This is because sound basic is not intended to be multichannel, but advanced audio is intended to take full advantage of SDL_mixer. Audio functions are positional multichannel audio (much more powerful) & sound functions are kept for backwards compatibility. The audio_play_sound function returns the channel id, that way the user can store the id of the channel in a variable then all the volume/pan/stop/pause functions will take both sound id and sound channel id. Using the advanced audio functions, the user gets full control over each channel.

After finishing the required functions for both SDLbasic.cpp and SDLadvanced.cpp I started testing for both windows and android and I was able to hear the audio for both windows and android builds.

The tests were successful for FLAC, MP3, OGG, WAV audio file formats.


Audio system commits: c87994f, 0d55208

Task 2 completed.


TASK 3: ADDING THE TILT FEATURE

@fundies provided some useful links for this task like:
SDL_android.c & SDLActivity.java

after going through these files we decided to use Android_JNI_GetAccelerometerValues.

I started task 3 by first adding android.cpp in Platforms\SDL\Android and added 3 functions device_get_tilt_x, device_get_tilt_y & device_get_tilt_z and included SDL_android.h which is a requirement for Android_JNI_GetAccelerometerValues.
Then I added override CXXFLAGS += -I$(ENIGMA_ROOT)/android/external/SDL2/src/core/android/ & SOURCES += $(wildcard Platforms/SDL/Android/*.cpp) to the makefile present in Platforms\SDL. Below is the implementation of device_get_tilt_x

float device_get_tilt_x()
{ 
  float Values[3],tilt_x;
  Android_JNI_GetAccelerometerValues(Values);
  tilt_x = Values[0];
  return tilt_x;

}

The other 2 functions are similar to this and the only change is that tilt_y returns Values[1] and tilt_z returns Values[2].


I added the tilt feature in the first audio system commit: c87994f

Task 3 completed.


What's left / What will be done after GSoC?

Polygon Collision Detection GSOC 2021

Polygon based Collision Detection System, GSOC 2021

This pull request contributes to the collision detection system (#1882) in the ENIGMA, adding a completely new feature of using polygons for detecting collisions instead of the other two options available, BBOX, and Precise. It uses simple or complex polygons to mask objects for collisions while extending the interface for the Collision Detection System that is used by PRECISE and BBOX collision Systems and also provides Polygons as separate resources that can be used for Collisions and Drawing.

1. Noteworthy Changes

1.1. Polygons

I added a new class of Engine resources to use, Polygons, which are closed shapes defined by a set of points that can be assigned to objects for detecting collisions.

Added the file polygon.h which complete Interface for Creating, Editing, and Manipulating Polygons inside GML Scripts, with functions that can be extended to IDE as well like LGM or RGM. These functions are the main interface for ENIGMA users to use the new system. Some of the noteworthy functions in this are:

Finally, it includes a complete API interface for Attaching and Transforming Polygons with Objects and Instances.

1.2. Collision Detection

The main collision detection function works in 6 layers inside the ENIGMA's engine and is listed down from core to interface:

1.3. Triangulation

For the collision system to support concave polygons, they need to be first decomposed into smaller convex polygons that can be used by the SAT layer. Concave to Convex Polygon Decomposition using simple Triangulation methods, to handle collision checks for Concave Polygons.

1.4. Drawing

I added general methods for Drawing Polygons, with options for colors, outline, and their Axis Aligned Bounding Boxes (AABB). All code added in the file Graphics_Systems\General\GSpolygon.h. These functions are interface and can be directly called from GML scripts inside ENIGMA. All the functions work by first fetching the polygon points and computing the transformed points from the transformation that the callee provides.

1.5. Testing

Added Testcases Game inside the Tests directory, which encompasses Polygon collision checks for all major functions. The game file is found at CommandLine/testing/Tests/polygon_collision.gmx. The test cases test for all of the interface functions mentioned above for three different sets of polygons:

1.6. Miscellaneous Changes

2. Benchmarking

The collision system PR won't be complete without some stress tests and benchmarking against other collision systems.

  1. The first benchmark test is done using multiple diamonds as instances and objects and checking for collision against a rectangle. Below are the results obtained after running an averaging over 15 compilations.
collision_rectangle benchmark
Branch Time CPU RAM (MB) GPU RAM (MB)
Polygon ➖ 113 ➖ 11.2 ➖ 176.3
Precise 🔺 119 ➖ 11.3 (-/+ 2) 🔺 412.3
BBOX 🔻 080 ➖ 10.6 (-/+ 2) 🔻 139.5
The results shows that the Polygon collision system performs almost the same in terms of time complexity against the Precise system, providing the same level of accuracy in collision detection while using fewer GPU resources.
  1. The second benchmark test is done using a concave polygon shape and a diamond, and testing for collision against them. The results are obtained over 15 compilations, and are shown below:
place_free benchmark
Branch Time CPU RAM (MB) GPU RAM (MB)
Polygon ➖ 131 ➖ 12.0 ➖ 80.1
Precise 🔻 084 ➖ 13.5 (-/+ 2) 🔺 98.8
BBOX 🔻 043 ➖ 13.2 (-/+ 2) 🔻 90.2
The test performs adequate in the Polygon collision system, give great accuracy and a reduce amount of GPU usage as compared to Precise System.

3. Demonstrations

  1. The first demonstration of the system can be downloaded from: https://drive.google.com/file/d/1oIUjVktzTAFgk4xev5Yjpp0fyZRfCKHZ/view?usp=sharing
    It consists of a single room with 3 different objects sharing the same base polygon (box). The demo shows the movement, collision, transformations, and robustness of the system. MinMax Projection from Ellipse
  2. The second demonstration can be downloaded from: https://drive.google.com/file/d/1zREl5gK6-_pZx5LNvL3W_sOLei9hcGxA/view?usp=sharing
    This demo consists of 2 concave polygons, a shape, and a star, running collision detection against each other and against an ellipse. The demo showcases the movement, collision, and transformations for a concave polygon.
    MinMax Projection from Ellipse

4. Future Work

Some of the work that was not covered in the time period of GSOC, and is left are as below

How to Get Involved?