Screen Tearing / Wavy Effect in GameMaker Studio 2 (using Surfaces)

After playing Environmental Station Alpha, I decided I wanted to implement the screen tearing effect Hempuli is using in his game. I didn’t know how he achieved it so I had to start from scratch and think about different approaches.

Knowing nothing about shaders, I was left with surfaces. I jotted down some code and immediately hit a wall; after asking around in the yoyogames forums, reading other’s comments, I could finally come up with a pretty decent solution.

Actual Code

I wrote the code so it could be easily hackable. This goes into the create event of your game controller object.
// handy shorter names
dw = display_get_width()
dh = display_get_height()

tearings_surface  	= surface_create(dw, dh)    // We'll draw on this surface
tearings_y          = 0
band_num            = 16                        // How many bands you want on screen
band_height         = dh / band_num
tearings_x_offset   = 32                        // How much you want to displace the bands horizontally
tearing_speed       = 4                       	// Change this to speed up/slow down the tearings
I place the following code inside a draw_post event of my controller.
// Create surface if it doesn't exits
if !surface_exists(tearings_surface)
	tearings_surface = surface_create(display_get_width(), display_get_height())
// Let's set the target to our surface
draw_clear_alpha(c_black, 0)

// We draw parts of our application surface on tearings surface
for (var current_band = 0; current_band < band_num * 2; current_band++)
	draw_surface_part(application_surface, 0, band_height * current_band - tearings_y, dw, band_height, sin( (degtorad(360) / band_num ) * current_band) * tearings_x_offset , band_height * current_band - tearings_y)

// Always reset the target surface

// Draw the actual surface
draw_surface_stretched(tearings_surface, -tearings_x_offset, 0, dw + tearings_x_offset * 2, dh)

// Move the Tearings
tearings_y = (tearings_y + tearing_speed) % (band_height * band_num)

That's it.

And this is how I make that effect. I will implement a similar version for vertical tearings (for underwater levels? maybe?). Hope you find it useful.

A note about surfaces: remember to free the surfaces if you don’t need them anymore, otherwise it will lead to memory leaks.

Guide to develop low resolution 2D platformers with smooth movement and pixel perfect collisions in GameMaker Studio 2 (with slopes)

Low resolution is great. It saves CPU power, especially with the collision code I talk about in this article, and it makes it easier to work with the project (like when building huge rooms or making edits to sprites). You’ll see that sometimes there’s little to no reason to scale up your sprites. It’s just a waste of resources.

With the collision code I use objects move by whole pixels. This makes for perfect collisions but it usually leads to jittery movements. Luckily there’s a simple solution.

The Movement and Collision Code

This is the most practical collision code I ever came across on the web. I read about it some time ago on Zack Bell‘s blog and I subsequently adapted it slightly to suit my needs. It basically remains the go-to code for 2D low res platformers. It’s like… unbeatable. Think holy grail of platformer movement and collision.

I’m using the following hierarchy.

  |_ obj_slope

You can use a different hierarchy for your collisions, just adapt the scr_platformer_move code. I’m using fall through platforms so I use the obj_solid_top.

This script must be called from the create event of your active/moving objects.

/// @desc       Initialize Platformer Vars
/// @func       scr_platformer_init()

/// This script is usually called in the create event

// Initialize the variables used for movement code
xVel = 0                // X Velocity
yVel = 0                // Y Velocity

xVelSub = 0             // X Sub-pixel movement
yVelSub = 0             // Y Sub-pixel movement

This code should run at the end of your movement velocities calculations. Ideally at the end of your object’s step event (normal step event is fine).

(open in pastebin)

Collision Masks

It’s of fundamental importance that you take extra care when dealing with collision masks. Make sure they behave the expected way especially when flipping your objects around. Most of the times the error lies in the origin or in the symmetry of a mask.

Wrong Collision Mask

Here’s a sample of a wrong collision mask. Counter intuitively I placed the origin in the exact middle of the mask. It will result in asymmetric mask behavior when mirroring it (i.e. when turning left or right in the game). This mask will create collision issues and probably get objects stuck inside walls or slopes. 

This mask is wrong.

Correct Collision Mask

It took me a while to understand how the origin pointer looks and behaves. This is a centered, symmetric collision mask… I’ll be honest: it absolutely doesn’t look like that to me. But trust me, this is the right one.

This mask is correct.

Let's fix the jittery movement!

It’s all about surfaces. We need to:

  1. Disable the automatic drawing of the application surface.
  2. Resize the application surface to the correct, hi resolution size.
  3. Draw our sprites with sub-pixel offsets.
  4. Draw the stretched application surface manually in a post_draw event.


Can you see what’s going on here? Objects still move by whole pixels. Their collisions are still being calculated for whole numbers only. Still, we draw the sprites with sub-pixel precision!

The loops for collision checks have to run for very low numbers/distances. This means ultra-smooth movement, ultra high performances and very low disk/ram resource usage (compared to up-scaled pixel art).

Still jittery on slopes? Let's fix it

If you download the attached project you’ll see how I solved the slopes jittery movement. 

I’m using simple trigonometry to find the Y position given the X position on a slope. I’m still using whole pixels to compute collisions but I use the following snippet just to draw the sprite of the player.

// Check for slope offset
slope = collision_rectangle(bbox_left, bbox_bottom +1, bbox_right, bbox_bottom + 1, obj_slope, true, true)

if slope
    var slope_height    = abs(slope.bbox_bottom - slope.bbox_top)
    var slope_base      = abs(slope.bbox_right - slope.bbox_left)
    var angle           = arctan(slope_height / slope_base)

    // Slope to the right
    if object_is_ancestor(slope.object_index, obj_slope_rx)
        if bbox_right < slope.bbox_right slope_spr_y = slope.bbox_bottom - (bbox_right + xVelSub - slope.bbox_left) * tan(angle) else slope_spr_y = slope.bbox_top } // Slope to the left else if object_is_ancestor(slope.object_index, obj_slope_lx) { if bbox_left > slope.bbox_left
            slope_spr_y = slope.bbox_top + (bbox_left + xVelSub - slope.bbox_left) * tan(angle)
            slope_spr_y = slope.bbox_top
    slope_spr_y = 0    // Not on slopes
And so in the draw event of the player I use the following:
// Slope Y Position
if (slope_spr_y != 0)
    var yspr = slope_spr_y
    var yspr = y + yVelSub

draw_sprite_ext(sprite_index, image_index, x + xVelSub, yspr, image_xscale, image_yscale, 0, c_white, image_alpha)


This system might not be perfect and I’m open to new solutions. Let me know if you have a better system to obtain smooth movements using low resolution assets.

A little update

Since I now have a full-time job, I removed my Patreon page and my silly “donations” form. I also ordered a brand new notebook; it’s ridiculously powerful so I can run GameMaker Studio 2 with no lag (and in Full HD resolution).

Lately I found myself willing to create content but the very same job that gave me financial freedom, is kind of keeping me from making progress on my own projects. I guess I should stop planning ahead and just go with the flow.

What’s next

Now that I have a full time job, I need to re-assess my priorities. Game development will always be a part of my life but in a lighter, brighter and smarter way. I’m focusing exclusively on my own projects while keeping an open approach for the future.

I have no immediate plans on releasing or developing commercial games. Right now I’m focusing on creating some content for this blog and for my Patreon channel. Maybe even my YouTube channel (but don’t hold your breath).

3 Platformer Engines

While developing Fuzeboy I learned a lot about platformer engines. I decided to share my knowledge with my Patrons so I’ll be creating three platformer engines, each one with a different level of complexity. Patrons will be able to download said engines and use them for any purpose, commercial or not, with or without crediting me; feel free to modify anything without my written consent. I basically give up any right I might have over them.

Basic Platformer Engine

This basic platformer engine will have all the characteristics of games such as the first Super Mario Bros. (8bit NES era). Basic platforming with no slopes, underwater physics, simple shooting mechanic, enemies with elementary AI, score points, basic health, basic powerups and maybe a couple of extra.

Intermediate Platformer Engine

While some characteristics will build upon the basic platformer, new problems will call for new approaches and a redesign of some game components. We’ll start using managers like the video manager, input manager and data manager. We’ll look at video scaling and we’ll add slopes and ladders. Also we introduce the 8-way shooting and the advanced animation system (the one I used in Fuzeboy). One way platforms, moving platforms and more.

Advanced Platformer Engine

This is a totally different engine. I’m thinking Super Metroid here. Powerups & inventory, room transitions, gamepad support and input customization, data saving and loading, complex world interactions, triggers, complex camera behavior, cutscenes, dialogues and much, much more.

GameMaker Studio 2 Courses

Just to reiterate that I’m not leaving game development altogether, I’m organizing GameMaker Studio 2 courses at my day job office. Right now we’re thinking about organizing classrooms for the locals but we might scale a bit and extend the offer to schools as well. This is something I’m making in real life so, no online courses for now (for those, look into Benjamin Anderson’s courses). So yeah, I’m also teaching GameMaker Studio 2.

The GameMaker Studio 2 Book

I was writing a book about making an Advanced Platformer Game in GameMaker Studio 2. Turns out making a book is way more complicated than making the game itself. For now I’m leaving this on the table but I won’t be actively working on it in the immediate future.

Kren – Deep Silence

Going back to my own projects and talking about long term plans, means going back to Kren. During the past months I developed a solid engine, written a sound storyline and found a group of people (all friends I know in person, in real life, here in Italy) interested in its development. We’re working weekends to draw concepts and storyboards but it won’t be until next January when I’ll be discussing and showing more substantial material. We take our time and we want to plan it well from start to finish, ironing out all the details.

That’s all for now

So that’s it. I’ll upload some new content soon.

Scaling up my game 4x without resizing a single sprite (GM:S 1.4)

So I was developing a low res game (480 x 270) in GameMaker: Studio 1.4. The moment comes when I need to test it on mobile. I create my APK, load it up on the phone and there it is… a horrible mess of graphic artifacts!

The camera movement was all jittery, the zoom effect made all the tiles look funny and overall it just felt wrong.

The problem was obviously the very low resolution of the game. The camera (the view), along with every other object in the game, can move only by whole “game pixels”. That means that if you divide the actual display resolution by the game resolution (480 horizontal pixels in my case) you get the minimum “screen pixels” that any object can be moved/re-drawn. No in-between values are possible.

This is actually hi-res. Just scaled up 4x (background still old-size) - 1 game pixel is now 1 view pixel. But sprites are 4x bigger so they look low-res (fake it).

On a 1920 pixels wide screen, that’s 4 “screen pixels” per “game pixel”. So the camera (along with every other objects) can move only by 4 screen pixels at once and no less. This means jittery movement.

Since I wanted the camera to be able to move at least 1/4th of a game pixel, I had to upscale the whole game by a factor of 4… I had to go Full HD to keep my low res game enjoyable.

That meant resizing 175 sprites, move their origins, check their collision masks, resize the tilesets and backgrounds, adjust the speeds, re-make the whole levels and probably fix other bugs… unless…

Unless I used this code in the room start event of my controller.

global.game_scale = 4

// Increase the room size
room_width  = room_width  * global.game_scale
room_height = room_height * global.game_scale

// Object resize
    x = x * global.game_scale
    y = y * global.game_scale
    image_xscale = image_xscale * global.game_scale
    image_yscale = image_yscale * global.game_scale

// Tile resize
var num = tile_get_count();
for (var i = 0; i < num; i++;)
    var tid = tile_get_id(i)
    var tx  = tile_get_x(tid)
    var txs = tile_get_xscale(tid)
    var ty  = tile_get_y(tid)
    var tys = tile_get_yscale(tid)

    tile_set_scale(tid, global.game_scale, global.game_scale)
    tile_set_position(tid, tx * global.game_scale, ty * global.game_scale)

I also increased the view size by 4 (and resized the application surface accordingly) so the objects in the game looked exactly like before (size-wise). Now everything is 4 times bigger.

I still have to resize any in-game created instance and modify the speeds of some of my objects… but at least I didn’t have to resize 175 sprites. Now the camera moves and zooms smoothly. Everything can move 1/4th of a game pixel without looking jittery.

Separation of Concerns in GameMaker Studio

I recently got into the (bad) habit of using just one single controller object for my games. It manages everything from input to video. The logic behind this was that the less objects GameMaker has to manage, the less resources it will use.

In principle that’s true. In reality, switching from 5-6 controllers down to 1 doesn’t make any difference at all in terms of performance. We’re not talking about hundreds of objects; we’re talking about 6. I mean… what was I thinking?

So I took a step back and returned to my old (good) habit of having multiple, distinct, autonomous and self-contained controllers. Each concerned only with doing his own thing.

These are my controllers now.

I’ll admit it: the Game controller is still somewhat generic; all the others define their own variables and run their own code independently. Data deals with game data like options and statistics. Video deals with app surface drawing, display resolution managing and view/camera stuff. Audio and Input are pretty self-explanatory too.

Log deals with the log console, but it will soon become Dev. A Development controller that enables development mode actions and tools like a debug console, a log viewer and so on. When a game is released, the Dev controller must be simply removed from the first init room.

The added benefit is that now I can export a single object into any other project, where and when I need it. That’s neat.

Touchpad three fingers tap as middle click and Drag and Drop on finger lift – no Delay – on Windows 10 (after creators update)

I rarely post about Windows tips and tricks but this one kind of saved my day, especially because drag and drop and middle click are vital features in the  GameMaker Studio workflow.

Three Fingers Tap as Middle Click

Let’s fix the Three Fingers Tap behavior. I want to disable Cortana and enable the middle click button.

  1. Open the Start menu and type regedit. Open it (and give it all the authorizations it needs to make changes to your computer).
  2. On the left panel navigate to this location
  3. In the right panel search for Tap_Three_Finger and double click it. Set its value to 2
  4. Eventually check that the Tap_Three_Finger_Enable is set to 1.

No Delay for Drop when Dragging (drop on finger lift)

  • Again in Computer\HKEY_CURRENT_USER\Software\Elantech\SmartPad
  • Search for the Drag_Radio key.
  • Set its value to 2 to immediately drop on finger lift.

Done. Now the three finger tap will be a middle click and the drag and drop will be instantaneous.

Fuzeboy – Status Update – [9 AUG 2017]

As some of you might know, Fuzeboy’s project scope changed considerably during its development. There’s been an overhaul of features, specifications, goals and deadlines.

A small mobile game…

Originally thought to be a quick mobile only game, we then shifted our vision a bit to make it playable on desktops as well; now we decided to abandon the mobile world altogether to focus exclusively on the Desktop platform.

This opened up a ton of possibilities as we’re not limited to touchscreen inputs anymore. The very essence of the game changed, as we made changes to game mechanics, enriching and expanding the world of Fuzeboy.

This is the tower with the locked doors… very mysterious…

Fuzeboy’s going to be a full fledged, complete platformer game for desktops (Win, Linux, Mac) but we’re not yet ready to show anything new to the world as I’m rewriting it from scratch in GameMaker Studio 2 while Darftey is reviewing (and adapting) all of the graphics.

We’re also starting a new project. Not because we suffer from shiny object syndrome (basically a disease of distraction) but because rewriting Fuzeboy from scratch, made it possible for us to reset our mental state.

Although far from a possible Fuzeboy-induced burnout, our mental state was then set for something new; different. That not only applied to Fuzeboy, but to both of us as a game development team. We took a step back and looked at our future as team Blocksword. And we saw things…

As we reviewed and re-started Fuzeboy, we reviewed our plans, projects and priorities as well. And we saw this…

Here’s a small teaser GIF

Due to the overwhelmingly positive feedback we received, we’re now thinking about making it our primary focus. We’re also considering funding as I didn’t plan to live off of my savings for this long without publishing a commercial title.

Two projects, two options

Should we decide to crowdfund the new game, we will have to define a clear project scope and commit exclusively to that for the time it will take to ship it. In that case the development of Fuzeboy will be put on hold (let’s say we will change it’s queue priority). As of now this is the most probable scenario.

Should we decide to keep going without funding (or fail at funding), we’ll suffer from a bit of a slowdown. I will have to seek a part-time job (or something) while working on both games at our discretion (we would have zero deadlines and relatively more freedom in the way we manage and evolve our own projects).

All of this might annoy someone; especially those who were waiting for Fuzeboy anytime soon this year. Especially if they were waiting for a mobile game. We know it and we don’t like when people get annoyed because of us; we will make up for it.

In conclusion

To sum it up: we’re working on the new Fuzeboy while defining the scope of this second project and defining the resources we need to allocate to each of these projects. Just know that we could completely shift our focus toward this new RPG game very soon (we’re evaluating feedback).

Sprites with different images dimensions in GameMaker Studio 2

When you try to import multiple images into a single sprite in GameMaker Studio 2, you could end up with unexpected results. Specifically, if the images have different sizes (width and height), the sprite size will be equal to that of the largest image, but all the other images will be imported stretched to fill the canvas (effectively ruining the sprite).

Continue reading Sprites with different images dimensions in GameMaker Studio 2

Advanced Animation Control in GameMaker Studio 2 – Method 1

Let’s say that you have a sprite with a complex animation (i.e. variable frame rate). As you can see from the following image, each frame will play at a specific time (I use a simple Photoshop script to export the frames, I’ll write an article about it later).

This is the folder’s content, exported from Photoshop. File naming scheme is important.

Continue reading Advanced Animation Control in GameMaker Studio 2 – Method 1