Posts in "Devlog"

Here’s the coding projects I’ve been working on in my spare time.

The results of my first play-test are in. And overall, they were pretty positive: movement was good, hit-boxes were fair, and it was described as “quite fun,” which was better than I was hoping for.

One thing I’ll need to look out for is telegraphing secrets. The number of secrets is indicated at the end of the level, and based on the play-tester’s feedback, they seemed to have spent a lot of time running against walls trying to find them. There is one secret in the level 1-1 that I thought was telegraphed well, and I can confirm that the player found them all. But I will concede the others required the player to make a leap of faith, and fall into an area that the player will usually want to avoid, which is pretty unfair. So I’ll need to fix that.

A bit more on the Godot game this morning, this time working on background tiles artwork. Made some grey masonry tiles for the end castle sequences. Also tried some background rocks for underground areas. I’m pretty rubbish at anything organic, but they didn’t turn out too bad.

Auto-generated description: Two rectangular pixel art frames with stone textures, one in brown and the other in gray, are displayed with matching filled versions inside them.
Right side has the background tiles surrounded with their complementary foreground tiles on the left.

Added a few final things to my Godot game, such as a really boring title and end-title screen, before preparing a release for play testers (or play tester, I’ve got exactly one lined up). I think we’re ready.

Auto-generated description: A game welcome screen introduces Princess Real-estate, instructing players to collect coins and avoid hazards to reach a castle.

A bit more on Godot this evening, mainly working on pausing the game, and the end-of-level sequence. Have got something pretty close to what I was looking for: a very Mario-esc sequence where the player enters a castle, it start auto-walking the character, and the level stats show up and “spin” for a bit. Not too bad, although I may need to adjust the timing and camera a little to keep the stats from being unreadable.

A bit more Godot work this evening. I wanted to add a foreground layer of tiles that obscured in the player. This is for making false walls to hide secrets around the level. It took me a while to work out how to turn off collision of this foreground layer: there wasn’t really any way to do so within the designer.

Fortunately, this Github comment showing how to do so using a script worked like a charm:

extends TileMap

const foreground_layer = 1

func _use_tile_data_runtime_update(layer: int, coords: Vector2i) -> bool:
	return layer == foreground_layer
	
func _tile_data_runtime_update(layer: int, coords: Vector2i, tile_data: TileData) -> void:
	tile_data.set_collision_polygons_count(0, 0)

Only limitation seems to be that it will disable collision for the whole layer, but that’s perfectly fine with me.

Spent more time on my Godot platformer yesterday, mainly rebuilding the first level from scratch. The previous version was rush and was just not fun (it didn’t look good either, but I didn’t dress it up yet). This new one is much nicer, and allowed me to use a few new mechanics I’ve built.

I still need to build out the level ending sequence. I’ve got less than the basics at the moment: a drawbridge descends and that’s pretty much it. I need to add the conditions for when the bridge descends (specifically, a minimum number of coins), stopping the player movement for a brief scripted sequence, then transition to the next level. I think I know how I want to do this, it’s just a matter of implementing it. Once level 1 is dressed up and working, I think that’ll be the next thing I do.

I’m enjoying working on this project so far, although part of me is a little afraid that I’m spending time on something that just isn’t good, like there’s some sunk cost with the time I’m spending on this that’s better put to use on something else. Of course, when I give in to these feelings, I usually just spend the time watching TV. So which activity is the real waste of time? Is producing something that may be crap (or worse, just boring) better than not producing anything at all?

Anyway, not should how this became a feeling post. This game might be rubbish, but I still enjoy working on it: Godot is actually quite fun to use. Surely that is reason enough to continue.

Was looking at how I could add hazards to my Godot project, such as spikes. My first idea was to find a way to detect collisions with tiles in a TileMap in Godot. But there was no real obvious way to do so, suggesting to me that this was not the way I should be going about this. Many suggested simply using an Area2D node to detect when a play touches a hazard.

I was hesitant to copy and paste the scene node I had which handled the collision signal and kill the player — the so-called “kill zone” scene —but today I learnt that it’s possible to add multiple CollisionShape2D nodes to an Area2D node. This meant I needed only a single “kill zone” scene node, and just draw out the kill zones over the spikes as children. The TileMap simply provides the graphics.

Auto-generated description: A game development interface displaying level design with a grid layout, tiles, and collision shapes is shown.

This discovery may seem a little trivial, but I’d prefer to duplicate as few nodes as a can, just so I’ve got less to touch when I want to change something.

Tried opening my Godot project this morning and was greeted with the following error:

Auto-generated description: A computer screen displays a development environment with an error message pop-up about an invalid or missing scene file.
scene/resources/resource_format_text.cpp:284 - res://scenes/falling_platform.tscn:14 - Parse Error: 
Failed loading resource: res://scenes/falling_platform.tscn. Make sure resources have been imported by opening the project in the editor at least once.
Failed to instantiate scene state of "res://scenes/falling_platform.tscn", node count is 0. Make sure the PackedScene resource is valid.
Failed to load scene dependency: "res://scenes/falling_platform.tscn". Make sure the required scene is valid.

Traced it back to the technique I was using to respawn the falling platform. Looks like Godot didn’t like the two preloads I included:

# file: scripts/falling_platform.gd

@onready var FallingPlatform = preload("res://scenes/falling_platform.tscn")
@onready var FallingPlatformScript = preload("res://scripts/falling_platform.gd")

This resulted in a parse error and Godot thinking the level scene was corrupted. In retrospect, this kinda makes sense. What I doing was technically a circular dependency, where the scene and script was trying to preload itself. I was hoping Godot was smart enough to recognise this, but I guess not.

So I had to change the respawn code. I modified it to make use the duplicate method. Here’s the revised version:

func respawn():	
    var dup = self.duplicate()
    dup.global_position = init_global_position	

    # Duplicate also copies the velocity so zero it out here
    dup.velocity = Vector2(0, 0)
    get_tree().current_scene.add_child(dup)

After some limited testing, this seems to work. One good thing about this approach is that it looks like duplicate copies the script, so I no longer need to do anything special here.

So I guess the lesson here is don’t try to preload the script within itself.

Adventures In Godot: Respawning A Falling Platform

My taste of going through a Godot tutorial last week has got me wanting more, so I’ve set about building a game with it. Thanks to my limited art skills, I’m using the same asset pack that was used in the video, although I am planning to add a bit of my own here and there. But it’s the new mechanics I enjoy working on, such as adding falling platforms. If you’ve played any platformer, you know what these look like: platforms that are suspended in air, until the player lands on them, at which point gravity takes a hold and they start falling, usually into a pit killing the player in the process:

Prototyped a game I had in mind, sort of a 2D Sokoban-like thing, where you control a robot with a retractable pushing arm that is to push gems to a “receiver” tile. Not entirely sure if it’s fun enough to actually build.

Used PixiJS to build it. Not a bad framework.