# SPATTRIS (#MWDJ25 entry) mechanic breakdown

**URL:** <https://forum.defold.com/t/spattris-mwdj25-entry-mechanic-breakdown/81628>\
**Category:** The Defoldmine\
**Created:** [September 24, 2025, 12:57pm UTC](https://forum.defold.com/t/spattris-mwdj25-entry-mechanic-breakdown/81628 "2025-09-24T12:57:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![leshido](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/leshido/32/40994_2.png) [@leshido](https://forum.defold.com/u/leshido)\
**Post date:** [September 24, 2025, 12:57pm UTC](https://forum.defold.com/t/spattris-mwdj25-entry-mechanic-breakdown/81628/1 "2025-09-24T12:57:14Z")

</div>

Hey! Long time follower, first time poster. 👋

Recently submitted my first solo entry for the **#MadeWithDefold Jam 2025** (Thanks @Pawel for organizing it, had lots of fun!) and a few people asked how the mechanic was made. Since the forum proved to be such a tremendous source of knowledge for me, I figured I might as well share my process here for anyone else who might find it interesting.

 ![](https://forum-defold-uploads.b-cdn.net/original/3X/5/7/5782dc23c1a0fce2d6dfcf5b4f4e2b7fbbb1ed81.png)

## The Game

For a while I had this idea of a Tetris-like game where instead of the usual tiles, players need to stack random physics-enabled blobs of color and create clusters that span across the board. This year’s theme **“Twist on a Classic”** was the perfect excuse to try that mechanic and see how it goes.

![](https://forum-defold-uploads.b-cdn.net/original/3X/4/9/49f28a1a7abda7c65ee9902230aaf5d48da8bbba.gif)

🕹 Check out [SPATTRIS by leshido](https://leshido.itch.io/spattris)

## Development

Technically, I guess there are 2 aspects to this merging mechanic that are worth explaining: the visual “blobby” shader, and the physics based logic. There’s also the GameBoy postprocess effect applied which might not be directly related to the mechanic but I think helps tie everything together nicely.

So, let’s delve in.

### Physics

 ![](https://forum-defold-uploads.b-cdn.net/original/3X/0/c/0c1efa0e8cf3ef99234809ddc56d1b992997d3e1.png)

Each blob the game drops is actually made of 4 separate “ball” game objects. The balls have 2 collision objects, one of type Dynamic to control their movement and collisions, and one slightly bigger of type Trigger used in the linking process. Each trigger is assigned a certain physics group and mask, corresponding to the different blob colors. Once a trigger event fires, I `create_joint` on the 2 colliding objects to constrain their movements with a “rope”, essentially gluing them together. I also keep track of these links in a table and use it later to check each resulting cluster to see if it touches both walls.

### Visuals

 ![](https://forum-defold-uploads.b-cdn.net/original/3X/a/6/a6c32d90649df7910210fdfed6b0674fb2c6794c.png)

The blobbing effect involves a custom render script and materials. Each ball is assigned a sprite with a radial gradient in one of the three RGB primary colors. The sprites are configured to use the “screen” blending mode and a material which for the most part is an exact copy of the builtin sprite material, except it uses a different tag. Instead of the default “tile” rendering predicate, they’ll be rendered at an earlier pass to an intermediate render target. I won’t bother with the details on how to achieve this, but I can point to the [Post Processing](https://defold.com/examples/render/post_processing/) example project which for me was a very clear and concise introduction to rendering targets. The relevant code in the `update()` function looks like this:

```lua
-- Draw blobs to another canvas
render.enable_state(graphics.STATE_BLEND)
render.set_render_target(self["rt_blobs"])
render.clear({[render.BUFFER_COLOR_BIT] = vmath.vector4(0, 0, 0, 0)})
render.draw(predicates["blob"])
render.set_render_target(self["rt_world"])
render.disable_state(graphics.STATE_BLEND)

```

_NOTE: “rt\_blobs” and “rt\_world” are render targets created in the init() phase_

![Example of using a step function (in Affinity Photo)](https://forum-defold-uploads.b-cdn.net/original/3X/e/9/e9e4d80807c1acb986f46225a3989de493e543d6.gif)

With the balls all rendered to an off-screen texture, a model is used to actually display them. This is handled by the model’s material, in which a glsgl `step()` function is used to limit the values of the gradients and create the signature metaball/blobby effect. Because the balls can only ever be either Red, Green or Blue, the step function essentially joins them in 3 distinct groups. Something like this:

```glsl
mediump vec4 tex_sample = texture(texture_sampler, var_texcoord0.xy);
mediump vec4 stepped_sample = step(0.5, tex_sample);
out_fragColor = stepped_sample;

```

Finally, I took @MasterMind’s [Gradient Map sample project](https://github.com/FlexYourBrain/sample_gradientmap-shader?tab=readme-ov-file) as reference and modified it to be used as a full screen postprocess effect. Combining it with a stepped 4 color “gradient” instantly made everything feel more gameboy-y. It also allowed me to work simply in greyscale for the entire game’s assets, knowing the coloring will be handled by the shader.

![The 4-color "gradient" used in the effect](https://forum-defold-uploads.b-cdn.net/original/3X/9/9/994c1bfd7da1ce581ee3f02ee571fa7b3ee357e8.png)

## Conclusion

That’s it! Thank you for reading, I hope this was a helpful breakdown. It was my first time using Defold for anything more than simple prototypes and I learned a lot doing so. Highly recommend giving the Jam a try next year 😃

---

<div class="post-metadata">

**Author:** ![Pawel](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/pawel/32/24623_2.png) [@Pawel](https://forum.defold.com/u/Pawel)\
**Post date:** [September 24, 2025, 1:13pm UTC](https://forum.defold.com/t/spattris-mwdj25-entry-mechanic-breakdown/81628/2 "2025-09-24T13:13:52Z")

</div>

Thank you for sharing! Great idea for a game and great “feel” ❤

Do you think the speed of the falling blocks can be reduced at the begining so that players have more control over where the blobs land?

---

<div class="post-metadata">

**Author:** ![leshido](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/leshido/32/40994_2.png) [@leshido](https://forum.defold.com/u/leshido)\
**Post date:** [September 25, 2025, 6:21am UTC](https://forum.defold.com/t/spattris-mwdj25-entry-mechanic-breakdown/81628/3 "2025-09-25T06:21:38Z")

</div>

I’m sure it can! I have a few improvements in mind, hoping to release a post-jam version sooner than later 😅

---

<div class="post-metadata">

**Author:** ![amel](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/amel/32/27475_2.png) [@amel](https://forum.defold.com/u/amel)\
**Post date:** [September 30, 2025, 5:49am UTC](https://forum.defold.com/t/spattris-mwdj25-entry-mechanic-breakdown/81628/4 "2025-09-30T05:49:07Z")

</div>

Thanks for sharing! Very fun to play 😄
