Writing the Edicts - Setting the Scene


Hi again! Maurimo here, doing another little devlog to share some of the stuff we did for Ediction, in case it is useful or interesting to anyone who's reading! The previous one was really fun to make, and I'm always looking for some more fun stuff to share.

In this devlog, I want to talk really quick about the backgrounds of Ediction, the shaders made for them, and the particle system effect that plays in two little scenes. So, let's go!

The Backgrounds, Technically


In Ediction, all the backgrounds have a parallax effect on them, which makes the textures and colors shift around when you move your mouse. This is done by overlaying two pictures together with the difference blending mode, and adding a parallax effect to both layers, to create an offset effect when the mouse moves. The bottom layer is offset to the left, while the top layer is offset to the right. Then, we just zoom in the background via a transform applied to the final displayable, to avoid any cut-offs.


This is achieved by using the Ren'Py Blend Modes repository by CrossCouloir, which allows you to blend textures over displayables with a variety of blend modes. Using this repository, this is how we define our backgrounds + how we set the blend modes via a transform:

transform bg_blend(child=None, tex=None):
    cc_difference(At(child, parallax), At(Transform(tex, alpha=1.0), parallax_inv))
image bg_mountaintop = At("images/bg/mountaintop/base.png", bg_blend(tex="images/bg/mountaintop/over.png"))
transform bg:
    truecenter()
    zzoom True
    zpos -1000
    zoom 1.1
## In Ren'Py script:
show bg_mountaintop as bg at bg

And bam! You got yourself a blended background. While there are some backgrounds that are illustrated and don't use this effect, they all use a variation of this technique to make some good effects happen. A lot of our menu objects also use this technique, such as our textbox.

For actually creating/choosing the images, we selected various textures from sites like Pixabay, TextureLabs, and other royalty-free/CC0 image galleries. Then, we proceeded to just add on a lot of weird effects to them, the process is not really that clear so I can't provide a tutorial... so here's some general tips on how to make these images feel more unique:

  • Play with brightness/contrast
  •  Overlay paint textures on top of photos and play with blending modes, to add a painterly touch to your images
  •  Add grain/noise in various areas
  •  Distort images using the Liquify tool
  •  Play with colors via Selective Color, Hue/Saturation, etc.
  •  Draw on top of your images!

Also, make sure that you follow a similar process for all of them and keep art direction in mind, in case you're making many of them for the same work. As a final add-on, here's an unused background for the game that I made while I was experimenting with the method for them. These are both done using the same textures and composition, but have different blending modes, color settings, and have different things drawn on top of them.


This goes to show that you can evoke completely different things with the same images, just go ham on those effects and make them your own!

Particle System

There are two scenes in the game that create some particles in your screen. We wanted to make a falling leaf effect for a specific scene in the game, but uniform, boring particles didn't work for this. So, we found a solution to make a particle system that was customizable and still used the power of transform functions!


This is done via the SnowBlossom2 code by nyaatrap, and creating a transform function that sets some values. Here's the transform for the following particle, and the way it's defined:

init python:
    import random
    def rotating_leaf(trans, st, at):
        # If the leaf has just been created, set its parameters to a random value so every particle is different when it's spawned.
        # I made the alpha/blur values depend on the zoom, as I wanted bigger particles to be more visible and less blurry, and viceversa.
        if st == 0.0:
            trans.rotate = random.randint(-70, 70)
            trans.anchor = (0.5, 0.5)
            trans.zoom = random.uniform(0.3, 1.1)
            trans.alpha = lerp(0.2, 1.0, trans.zoom)
            trans.blur = lerp(10, 0, trans.zoom)
        else:
        # If we're continuously showing, then just make the leaf rotate a bit every frame.
            trans.rotate += 0.03
        return 0
        
transform rotating_leaf_t:
    subpixel True
    function rotating_leaf
image rotating_gold_leaf = At("images/gold_flake.png", rotating_leaf_t)
# Defining the actual SnowBlossom2 object:
image particles_leaves = Fixed(
    SnowBlossom2("rotating_gold_leaf", 16, xspeed=(10, 25), yspeed=(50, 65), start=30, fluttering=5))    

Then, you just do a simple show statement with them, and voila! You got some nice customizable particles!

Hand-Drawn Shader

In one of the scenes of the game, the UI completely changes to darkness until you get to see some magic stuff going on. In this scene, we use a shader that distorts a texture a bit in a saw-like pattern, to introduce some variations to the line every 5 frames or so. 

Here it is but on Howie's sprite, so you can really appreciate it.

Look! It's a cross-over! Howie is from WHODUNNIT?, a project we're working on currently!

It gives a bit of a hand-drawn vibe, and it was very useful in making some scenes feel alive! We didn't only use it for this, we also used it in Hermeto's silhouette when Ramla goes through the tunnels with him, in the light glares when Ramla first wakes up, and in many other instances to add some fun motion to the world. Here's the code, it's a bit messy and has no variables but it should be a nice base for you to work with. Maybe I'll make a repository for it... but we'll see. For now, here it is:

renpy.register_shader("hand_drawn", 
    variables="""
        uniform vec2 u_model_size;
        uniform float u_lod_bias;
        uniform float u_time;
        uniform vec4 u_random;
        uniform sampler2D tex0;
        attribute vec4 a_position;
        attribute vec2 a_tex_coord;
        varying vec2 v_uv;
        varying vec2 v_tex_coord;
    """, 
    fragment_functions="""
        vec3 hash(vec3 p)
            {
                p = vec3(dot(p, vec3(127.1, 311.7, 74.7)), dot(p, vec3(269.5,183.3,246.1)), dot(p, vec3(113.5, 271.9, 124.6)));
                p = fract(sin(p) * 43758.5453123);
                return p;
            }
        float rand(vec2 co)
            {
                return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
            }
        vec2 lerp(vec2 a, vec2 b, float t)
            {
                return vec2(((1.0-t) * a.x + t * b.x),((1.0-t) * a.y + t * b.y));
            }
    """,
    vertex_200="""
        v_tex_coord = a_tex_coord;
        v_uv = a_position.xy / u_model_size;
    """, fragment_200="""
        vec2 uvCopy = v_uv * 3.0;
        float randomSeed = rand(vec2(u_random.x, u_random.y));
        
        // distortSpeed will be 3 initially
        float distortSpeed = 1.0;
        // hand-drawn amount is 5 by default
        float distortAmount = 2.0;
        distortSpeed = (floor((floor(u_time * 3.0) + randomSeed) * distortSpeed) * 20.0 / distortSpeed);
        uvCopy.x = sin((uvCopy.x * distortAmount + distortSpeed) * 4.0);
        uvCopy.y = cos((uvCopy.y * distortAmount + distortSpeed) * 4.0);
        
        vec2 uv = lerp(v_uv, v_uv + uvCopy, 0.0005 * distortAmount);
        gl_FragColor = texture2D(tex0, uv, u_lod_bias);
    """)
transform handdrawn_distort(child=None):
    mesh True
    shader "hand_drawn"
    pause 0
    repeat

Thanks!

Hey, thanks for reading this devlog! These are very fun to make, and I'm happy to share anything about the game. If you're interested in knowing anything about the game or how we made it, feel free to reach out through the comments of this post!

Lastly, thank you so much for playing Ediction! We're almost at 1,000 downloads, which was unfathomable for us when we started making this project. It's been a wild ride seeing you play in livestreams, seeing people say "This body is not mine, but the body tea", and make all sorts of fun theories and comments about the game. We're very thankful, and can't wait to make more stuff in the future!

If you've played Ediction, please go ahead and leave a rating and comment if you enjoyed it! It helps us a ton. And if you haven't played...well, go ahead! You too can enjoy old men trying to restore the order of death. 

Go ahead and follow us on Bluesky for more news on Ediction, WHODUNNIT?, and other upcoming projects! Thanks!


Maurimo

Get Ediction

Leave a comment

Log in with itch.io to leave a comment.