Indie Game Dev

Weirdtris (re)released

It’s been a while wasn’t it? The long delay since Galaxus’s release (which was almost a month) was caused by my attempts at figuring out how to actually tackle the FLA-based projects. Specifically how to get a legal and free version of Adobe Flash Professional. Long story short I didn’t figure it out, Weirdtris was built using a demo version of Adobe Animate CC 2017. I have 6 more days to get all other projects of this type done, and if I don’t? ¯\_ಠ_ಠ_/¯

Let’s get down to business – Weirdtris is a tetrisque match-3 action-puzzler with shiny art that came from Alex’s... Mouse I guess? Check out its page here.

Post-processing shaders in Monogame

While working on Trans Neuronica I realized I don’t want to work on some things relating to the gameplay right now, so I figured “Hey Maurycy, it’s time to do all the cool shader effects you want to have in the final game.” I don’t really want to do that either, but I already wasted some time on research, so why not finish it and talk it over?

Two important things first:

  1. This is not a typical tutorial that takes you step-by-step explaining in-depth everything I do. I’m going to dump a lot of knowledge without much explanation but I think overall the steps are pretty simple.
  2. I use RetrocadeRenderBatch which is my own extension to SpriteBatch so the functions may not map 1:1. And there is some other code that you should understand how it works but won’t be able to find it in MonoGame.


Shaders are tiny functions/programs you upload to your GPU so it can do magic on things you render. Vertex shaders are concerned about the geometry, fragment/pixel shaders are concerned with manipulating the actual pixels before they are rendered.

Post-processing shaders are basically pixel shaders which take your whole, rendered scene as the input and manipulate it in some way, for example to add CRT simulation or add ripple.

Let’s start

So! I have my own C# framework built on top of MonoGame and MonoGame Extended called Retromono (I’ll talk about it some other day). I have RetrocadeGame class extending Mono’s Game which wraps around a couple of custom components of mine (like States and UI and Input Managers) and it also wraps around all of the rendering in the game.
What I did first was to inject a new PostProcessor class which has one method called directly before all Draws and another directly after:

Yes, there is a slight inconsistency with the naming there. I’ll refactor it later.

What it does, basically is call Game.GraphicsDevice.SetRenderTarget(RenderTarget); before anything draws and Game.GraphicsDevice.SetRenderTarget(null); after everything draws. Then it puts RenderTarget on the screen. Here is my PostProcessor class which I extend for the specific game/project/use:

public abstract class BasePostProcessor {
    protected readonly RenderTarget2D RenderTarget;
    protected readonly RetrocadeGame Game;

    protected BasePostProcessor(RetrocadeGame game, int width, int height) {
        Game = game;
        RenderTarget = new RenderTarget2D(game.GraphicsDevice, width, height);

    public virtual void BeforeDraw(RetrocadeRenderBatch batch) {

    public void AfterRender(RetrocadeRenderBatch batch) {

    protected virtual void AfterDraw(RetrocadeRenderBatch batch) {

    protected virtual void DrawSelf(RetrocadeRenderBatch batch) {
        batch.Draw(RenderTarget, Vector2.Zero, RenderTarget.Bounds);

Applying cool shaders

The above code is basically all that I need to get the post-processing working with a single exception – I don’t have the shader yet. I don’t have it physically and I don’t have it loaded and used, so technically that’s three exceptions.

Without further ado, here is the shader we’ll use:

#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0 // This was ps_4_0_level_9_1, do that for DirectX

Texture2D SpriteTexture;

sampler2D SpriteTextureSampler = sampler_state
    Texture = <SpriteTexture>;

struct VertexShaderOutput
    float4 Position : SV_POSITION;
    float4 Color : COLOR0;
    float2 TextureCoordinates : TEXCOORD0;

// I don't understand the stuff before here
float4 MainPS(VertexShaderOutput input) : COLOR
	// Applying our cool effect. What it does is: when drawing pixel X:Y, instead of taking the 
	// pixel from texture position X:Y, take it from (X+Y*0.2:Y) to create a slanted effected
	float2 tex2; // I am using a temp var because I don't know if we can/should modify input.TC
	tex2[0] = input.TextureCoordinates[0] - input.TextureCoordinates[1] * 0.2f;
	tex2[1] = input.TextureCoordinates[1];
    return tex2D(SpriteTextureSampler,tex2) * input.Color;
// Here comes the rest of the things I don't understand
technique SpriteDrawing
    pass P0
        PixelShader = compile PS_SHADERMODEL MainPS();

Before I tell you how to get this into your project, here is a gif showing it in action so that you don’t get too bored after that wall of textcode:

When I press Ctrl the shader is used.

Fancy! Save the shader above as shader.fx somewhere in your assets directory and open MonoGame’s Pipeline Tool. Create a new project if you haven’t already, drop your shader, make sure your project build platform is DesktopGL (if you’re making your project for other platform you might need to change the shader somehow but I don’t know how ¯\_(ツ)_/¯). Then load it and feed it to draw.Begin():

Code for importing the shader: Effect PostProcessShader = content.Load("shaders/shader");

Code for using the shader: batch.Begin(effect:PostProcessShader);

And voila!


  1. Wrap all your rendering in GraphicsDevice.SetRenderTarget(RenderTarget); and GraphicsDevice.SetRenderTarget(null); and I mean all of  it.
  2. Create the actual shader file
  3. Import it with MonoGame Pipeline Tool (alternatively use 2MGFX util to convert it to necessary format)
  4. Load it with content.Load<Effect>("shaders/shader");
  5. When rendering your RenderTarget, add the loaded effect in begin: batch.Begin(Gfx.PostProcessShader);

Galaxus source code & assets + Comments

A quick update to tell you that Galaxus‘s source code has been released.

You can get it on GitHub. You can get the art assets on our own Open Source section. Or on Open Game Art. I am throwing it all around, everywhere, wherever I can and want. It’s pretty fun to give back even though it’s probably not used by too many people~!

Oh and also, you can now comment on – one more way for me to spend time doing boring maintenance work rather than productive, creative stuff.

Gamedev updates: Neuronic editors

So I randomly stumbled upon this post on Jeff Atwood’s blog: Quantity Always Trumps Quality. I’ll spare you my thoughts about how I think it’s a very good advice but, unlike many of the commenters, you shouldn’t take it literally – I think Jeff didn’t mean it literally. I’d like to live in a world where I can make quantity of posts, say every week, and learn quality that way! If I didn’t know myself that well I’d make a promise here and now. But I promise – no promises!

Damn fine cup of advice (Twin Peaks)

“Cooper, you remind me today of a small Mexican chihuahua.”

Let me tell you the progress I made over the last week on my projects. And by progress I mean… An actual prgress!

Read More