Before I start in ernest, Magelusion’s source is now available on Github for anyone who would like to take a deep dive into what I’m doing. With that said…
I have to be honest… I do feel there are times I get rediculously caught up in trivial things… or, at least trivial as far as the “game” of the video game is going to be. I watch other game jammers who post videos on YouTube and they tend to do the smart thing of getting their core mechanics down before going forth and making everything pertty (intensionally mispelled). Me? I really enjoy playing with the stuff that’s supposed to “dazzel”.
Fire… for instance.
Playing with Fire
I’m making a game set in a dungeon and my pixel are style is 2-bit, so to add some visual diveristy, I decide to add fire (and, well, a lighting system… but so far that’s only in service to fire). So I draw a sprite for it? Nope! I go strait for a shader! I ended up basing my fire shader heavily on the one used by Bramwell Williams in his great little YouTube tutorial
I do a few modifications of my own. The one in the video is doing a fire shader that has no limitations. My little LOWREZJAM game has a 64x64 pixel limit, so I force the shader to obey the pixel limits that can be defined by some uniform variables.
As I did with my last post, I will share my little fire shader…
shader_type canvas_item;
uniform bool uv_to_texture_size = false;
uniform bool force_texture_size = false;
uniform vec2 alt_texture_size = vec2(16.0, 16.0);
uniform sampler2D noise;
vec2 adjTextureSize(ivec2 size){
if (force_texture_size)
return alt_texture_size;
return vec2(float(size.x), float(size.y));
}
void fragment(){
vec2 nuv = UV;
vec2 tsize = adjTextureSize(textureSize(TEXTURE, 0));
if (uv_to_texture_size)
nuv = vec2(floor(tsize * UV) / tsize);
vec4 base = texture(TEXTURE, nuv);
vec4 n = texture(noise, vec2(nuv.x, nuv.y + (TIME*0.75)));
base.r += 0.4f - distance(vec2(0.5, nuv.y), nuv);
base.r = (base.r * 0.3f) + (n.r * 0.4f);
float a = base.r;
if (a < 0.4f){a = 0.0f;}
COLOR = vec4(float(base.r > 0.4), float(base.r > 0.5), float(base.r > 0.6), float(a > 0.25));
}
This shader, when done, did show me one thing I wasn’t paying attention to, though…
I tend to gravitate of lower rez games. Not sure what it is, but I’m comfortable in working on games that, in my mind at least, have a resolution no larger than 640x480. That may be due to my lack of artistic skills, but still, I generally work at “small” resolutions. That said, when working with game engines, I don’t normally pay attention to how the engine is doing the resolution scaling (making the viewport scale to the actual window size). For Godot I usually scale with the “2D” scale mode, as that always looked nice to me… However, after my initial work with the fire shader, I noticed that, for a game that supposed to be 64x64, the fire I was getting was rediculously detailed. It was this observation that made me force the shader to “pixelize”. But that wasn’t the end of it…
Initially, after I “Pixelized” the shader, I figured I was done, but, something in the back of my mind niggled at me. Then I added a little “glow” to the fire… just a simple Light2D that grows and shrinks randomly. As I watched the effect, I noticed the pixels of the light map were moving “out of alignment” with the pixels of the background… which means the engine was treating the elements as just scaled-up assets, but effectively at whatever resolution the window was at… meaning my game was not, technically running at 64x64 even if my art was.
After some experimentation, I noticed that if I set the resolution scaling from “2D” to “Viewport”, then everything lined up pixel perfect. Wonderful! Everything is back on track!
BLOOD, Sweat, and Tears… mostly the former
To be fair, I don’t generally do one thing, then the other… for better or worse… but may flip flop between some things. Not sure why I felt the need to bring that up, but there it is regardless. On to Blood!
I’ve always liked the effect of “pixel” blood in many indie games, and using another great tutorial I came across on youtube (I do this a lot), I ended up with a very nice blood effect. You can see it in one of the screen shots below.
For this effect, I a tutorial by Mitch Makes Things. Contrary to the title of this section, there was virtually no sweat or tears in doing the blood as I use the setup from the tutorial almost exactly.
The only issue I’m really having is, the “blood” particles seem to keep shooting out predominantly on the left. I’ve checked the randomness of their vectors and they seems like they should be going in completely random directions, but, like I said, mostly to the left.
I suspect is has something to do with the games extreemly small resolution, and the fact the particles are spawning ON the player character. In the tutorial, the guy moves his player character as the blood spawns, so, it may have to do with my player character not actually moving at the time of the particles spawning. It doesn’t look horrible as is, but, when/if I get more time, I’ll see about looking deeper into the issue.
Platforming
This one also sort-of came from a tutorial. This one from Game Endeavor to be specific (and, I also wanted to share it because I’ve watched other tutorials from this channel and found them VERY informative). That said, the only thing I took from this tutorial was the existance of the GDScript function set_collision_mask_bit()
Basically, I setup a one way collider on the platform. Set that collider to act on bit 1 of the collision layer, then, in the player, when I jump down, I disable the mask for the bit 1 collision mask! Simple as all hell. In the tutorial, he’s doing a lot more… and, if the game was more complex, I may have needed to worry about that complexity, but as it stands now, I can easily jump on and off those platforms through some strategic toggling of that collision mask bit!
In conclusion
I think things are coming along rather nicely! I do hope to get the basic mechanics of the game going tomorrow. I want my wizard able to shoot fire and water out of his wand… and allow those two particles to form “steam” if they meet. I hope I’m not biting more than I can chew, but, there’s only one way to find out!
And with that… I leave you some screen shots!