Glimmer Chain is a skill-based 2D platformer where you control a robot powered by a hook and chain. Jump and use the chain to complete levels.
Glimmer Chain is a skill-based 2D platformer where you control a robot powered by a hook and chain. Jump and use the chain to complete levels.
The project began in June 2022 and was released on April 9, 2024. It was developed using a custom engine
I built from scratch in C++, with a team of three: an artist, a composer, and myself.
The engine is based on my shared codebase, Silver Engine, where you can find more information about its development.
I had the following roles in the development:
I'm also the owner and handled all the marketing, although that wasn't part of the development process.
People often ask me: Why didn't you use an existing game engine?
Part of it is because I really enjoy it and wanted to have a finished and polished product made from scratch in my Portfolio. I wanted to face all the
challenges head-on and learn from them to be better prepared for larger projects in the future.
There are also practical reasons:
In a physics-based game, where smooth and responsive gameplay relies entirely on physics,
having full control is crucial. That's why I developed my own physics engine.
To ensure consistency across players, I've implemented a fixed physics frame rate of 120 updates per second.
Additionally, since the ranking requires a fully deterministic simulation, this approach guarantees reproducible results.
The only dynamic entity in the scene is the player, who has a rectangular collider and a rotation determined by velocity.
This necessitated oriented collision detection and resolution, though kinetic energy calculations were not required.
A fully realistic swinging simulation isn't necessary—in fact, it would hinder smooth gameplay.
Instead, the grappling mechanic is divided into two distinct components: swinging and bending.
Swinging: When the distance between the hook point and the player exceeds the rope length, all forces acting parallel to the rope
are canceled. To enable movement, a force is applied perpendicular to the rope.
Bending: This is more complex. Each physics update performs a raycast, and if a collision is detected, the hook point is adjusted
to the nearest corner. To undo bending, the system tracks the angle and rotation direction (clockwise or counterclockwise).
A threshold mechanism ensures that if the player swings past a certain limit, the hook point resets to the previous position.
The robot is the only dynamic entity, except for the particles in the ending animation.
In Glimmer Chain, you can replay your records for every level, but there's also a global
ranking where players compete for the top positions and can watch each other's runs.
Recording every play as a video would be impractical, so instead, the game stores user input and uses
it to reproduce the exact same replay every time. This requires the simulation to be completely deterministic,
meaning that physics and gameplay mechanics must always behave the same way and run at a fixed update rate.
The game uses SteamAPI to manage the leaderboards, but Steam imposes a 256-byte limit on custom leaderboard entry data.
To work around this, I developed a custom compression algorithm that converts an array of user actions into a compact buffer.
This system only fails if the compressed data still exceeds 256 bytes, but this is a rare scenario.
I find it fascinating how, within such a small space, it's possible to store enough information to
perfectly replicate a human's entire playthrough of Glimmer Chain.
As I explained before, Glimmer Chain's simulation updates at a fixed rate
of 120 times per second, while rendering remains frame rate independent.
For lower frame rates, there's not much that can be done—latency naturally increases
as the frame rate drops. However, for higher frame rates (or when the simulation runs
in slow motion for debugging purposes, such as in the video),
the rendering system uses the latest simulation data and, based on the elapsed time, predicts the player's position.
This technique creates a smoother visual effect, reducing perceived latency and giving players a more responsive experience.
The video illustrates this effect: the player moves smoothly, while the green collider,
which follows the fixed frame rate, appears to "pop" due to lack of interpolation.
In the game industry, retained mode systems dominate. If you're used to working with third-party
game engines like Unity, Unreal, or Godot, the concept of immediate mode might seem almost
magical—or even impractical from a performance standpoint.
The key difference between immediate mode and retained mode API design lies in lifetime management.
In a retained mode API, objects must be explicitly created and destroyed.
For example, in Unity, rendering a sprite requires a SpriteRenderer component
attached to a GameObject. This approach has drawbacks, particularly in dynamically drawn elements
In these scenarios, you must manually handle object lifetimes, storing them in arrays or other
objects and ensuring proper cleanup, a tedious and error-prone process.
An immediate mode API, on the other hand, eliminates this complexity.
Instead of persisting objects, every frame the Sprites are "created" and "freed". Every call to a function like "draw_sprite"
writes data into a linear buffer, and at the end of the frame, a single counter set to 0 clears everything.
This makes the system stateless, flexible, and lightweight.
In Glimmer Chain, every entity is drawn dynamically each frame.
Each entity type has a callback function that issues all the necessary "draw_sprite" calls.
Examples of Immediate Mode in Action:
By leveraging immediate mode rendering, Glimmer Chain achieves better performance, simplified object management, and smoother animations—all without the overhead of a traditional retained mode system.
Something you get when making a game from scratch is discovering unique ways of doing things.
Creating a retained mode particle system, like the one used in Unity, typically requires a lot
of infrastructure: a format specification to describe how particles are emitted and updated,
serialization and deserialization logic with versioning and data maintenance, and an editor to
visualize and tweak parameters. And even then, such a system quickly runs into limitations
depending on how the format is designed.
This approach makes sense if you're working with complex particles or
if you want non-programmer artists to be able to define them freely.
In Glimmer Chain, however, there's no need for such complexity.
The particles are simple and fully defined by code.
Thanks to the flexibility of the immediate mode rendering system and some
ideas inspired by procedural generation, you can define a particle effect using just a function.
This function takes a seed (a 64-bit number) and a timer, and produces a visual effect through a few "draw_sprite" calls.
Because the random functions are deterministic when using the same seed, the result is always the same
without needing external data, complicated formats, or the overhead of maintaining editors and file compatibility.
For a basic example, imagine a particle effect where multiple particles are emitted and each one performs a simple linear interpolation between two points:
void draw_particles_with_linear_interpolation(v2 position, u64 seed, f32 timer) { set_seed(seed); u32 number_of_particles = u32_random_range(10, 12); for (i32 i = 0; i < number_of_particles; i++) { f32 angle = f32_random_range(0.f, TAU); f32 distance = f32_random_range(2.f, 3.f); f32 duration = f32_random_range(1.5f, 2.5f); f32 size = f32_random_range(0.5f, 0.8f); if (timer > duration) continue; // Particle is finished v2 target = position + v2_direction(angle) * distance; f32 normalized_timer = timer / duration; f32 n = f32_pow(normalized_timer, 0.5f); // Apply a curve to the interpolation v2 current_position = v2_lerp(position, target, n); Color color = RED; color.a = 1.f - normalized_timer; draw_sprite(current_position, size, color); } }
Glimmer Chain was showcased at IndieDevDay 2024 in Barcelona, where I had the incredible opportunity to watch people play live. Seeing their reactions in real time was an amazing experience and a huge source of motivation for me.
A few dedicated Glimmer Chain players engaged in an intense competition for the top spots in the rankings.
After an update that improved the camera, one of them went on a streak,
breaking 92% of the world records and even posted a video of his performance on YouTube!
Code Sample: simulation.cpp
Steam Page: https://store.steampowered.com/app/2286720/Glimmer_Chain/