Oof, quite tired at the moment. Woke up today with the correllas, which this morning was at 2:30 am.
Sage advice from Kev Quirk. I feel like I’m struggling a little at work recently, like things are slipping. Like Kev I can’t multitask, and I know I’ve got to get better at doing a single thing at a time. But unlike Kev, I need to care more about making an effort.
Not sure I’ll ever get used to web forms that don’t have an explicit submit button.
Request to work from home tomorrow has been denied. That means I’ll have to deal with, what someone at work so elegantly put it, “rich people in go-karts driving round in circles.” 👎
I’d be curious to know why running Golang linter slows my system to a crawl.
John Gruber, on the casing of “Internet”:
The Internet is a lot like the Earth. It’s everywhere. It is our universe, in a sense, from the human-scale perspective. But it’s a unique and distinct thing, thus deserving to be treated as a proper noun. It’s almost disrespectful to lowercase it, and the Internet is one of the great achievements in the history of mankind.
It’s also grammatically wrong. As my Networks lecturer would say, “the Internet” — the thing hosting the Web that we use everyday — is distinct from “an internet” — a collection of interconnected networks. The Internet might be an example of an internet, probably the prime example, but there’s no law in computer science stating that there must only be one. Anyone is welcomed to make their own internet. No-one will because there are massive network effects associated with network protocols, not to mention the amount of money already invested in the TCP+IP stack. Why do you think it’s so hard getting people to move to IPv6?
That said, the style guide of this site has no hard requirements over the casing of “Internet”, mainly because it’s easier not to press the shift key. 😀
My reputation for a bottle opener.
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.

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:

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.
Can plane sleep even be classified as sleep?
Surely it does not meet the international standard for the definition of sleep
I wasn’t a believer until it happened to me once. It was a 10 hour flight traveling from Tokyo to Melbourne (so roughly in the same time zone). Granted I was in premium economy but I managed to sleep uninterrupted from dinner until breakfast, around 7-8 hours. I’ve never achieved that before or since, but I’m glad to know it was possible.
Plenty of people taking advantage of the warm weather and low water level at Pound Bend, Warrandyte today.

“Get out more” goal for March achieved. ✅
Joined a bushwalking club and went for a hike in Warandyte.
Rendezvousing with a group that published a Melway location with the address. Really miss when people did that. Miss just flipping through the Melways for no reason other than it’s cool looking at maps. Maybe I should buy a Melways.
The one good thing I get from hearing podcasters talk about Formula One is that they provide a good reminder for when the local race is on, so I can remember which dates I should stay the heck away from the city. 👎
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:
The platforms are built as a CharacterBody2D
with an Area2D
that will detect when a player enters the collision shape. When they do, a script will run which will have the platform “slipping” for a second, before the gravity is turned on and the platform falls under it’s own weight. The whole thing is bundled as a reusable scene which I could drag into the level I’m working on.

I got the basics of this working reasonably quickly, yet today, I had a devil of a time going beyond that. The issue was that I wanted the platform to respawn after it fell off the map, so that the player wouldn’t get soft-locked at at an area where the platform was needed to escape. After a false-start trying to reposition the platform at it’s starting point after it fell, I figured it was just easier to respawn the platform when the old one was removed. To do this I had to solve two problems:
- How do I get the platform starting point?
- How can I actually respawn the platform?
Getting The Starting Point
A Node2D
object has the property global_position, which returns the position of the object based on the world coordinates. However, it seems like this position is not correct when the _init function of the attached script is called. I suspect this is because this function is called before the platform is added to the scene tree, when the final world coordinates are known.
Fortunately, there exists the _ready
notification, which is invoked when the node is added to the scene tree. After some experimentation, I managed to confirm that global_position
properly was correct. So tracking the starting point is a simple as storing that value in a variable:
var init_global_position = null
func _ready():
init_global_position = global_position
Another option is to use the _enter_tree()
notification. From the documentation, it looks like either would probably work here, with the only difference being the order in which this notification is invoked on parents and children (_enter_tree
is called by the parent first, whereas _ready
is called by the children first).
Respawning The Platform
The next trick was finding out how to respawn the platform. The usual technique for doing so, based on the results of my web searching, is to load the platform scene, instantiate a new instance of it, and added it to the scene tree.
@onready var FallingPlatform = preload("res://scenes/falling_platform.tscn")
func respawn():
var dup = FallingPlatform.instantiate()
add_child(dup)
Many of the examples I’ve seen online added the new scene node as a child of the current node. This wouldn’t work for me as I wanted to free the current node at the same time, and doing so would free the newly instantiated child. The fix for this was easy enough: I just added the new node as a child of the current scene.
@onready var FallingPlatform = preload("res://scenes/falling_platform.tscn")
func respawn():
var dup = FallingPlatform.instantiate()
get_tree().current_scene.add_child(dup)
queue_free()
I still had to reposition the new node to the spawn point. Fortunately the global_position
property is also settable, so it was simply a matter of setting that property before adding it to the tree (this is so that it’s correct when the newly instantiated node receives the _ready
notification).
@onready var FallingPlatform = preload("res://scenes/falling_platform.tscn")
func respawn():
var dup = FallingPlatform.instantiate()
dup.global_position = init_global_position
get_tree().current_scene.add_child(dup)
queue_free()
This spawned the platform at the desired positioned, but there was a huge problem: when the player jumped on the newly spawn platform, it wouldn’t fall. The Area2D
connection was not invoking the script to turn on the gravity:
It took me a while to figured out what was going on, but I came to the conclusion that the packed scene was loading properly, but without the script attached. Turns out a Script is a resource separate from the scene, and can be loaded and attached to an object via the set_script method:
@onready var FallingPlatform = preload("res://scenes/falling_platform.tscn")
@onready var FallingPlatformScript = preload("res://scripts/falling_platform.gd")
func respawn():
var dup = FallingPlatform.instantiate()
dup.set_script(FallingPlatformScript)
dup.global_position = init_global_position
get_tree().current_scene.add_child(dup)
queue_free()
Finally, after figuring all this out, I was able to spawn a new falling platform, have it positioned at the starting position of the old platform, and react to the player standing on it.
The time it took to work this out is actually a little surprising. I was expecting others to run into the same problem I was facing, where they were trying to instantiate a scene only to have the scripts not do anything. Yet it took me 45 minutes of web searching through Stack Overflow and forum posts that didn’t solve my problem. It was only after a bit of experimentation and print-debugging on my own that I realised that I actually had to attached the script after instantiating the node.
To be fair, I will attribute some of this to not understanding the problem at first: I actually thought the Area2D
wasn’t actually being instantiated at all. Yet not one of the Stack Overflow answers or forum post floated the possibility that the script wasn’t being loaded alongside the scene. This does suggest to me that my approach may not be optimal. There does exist a “Local to Scene” switch in the script inspector that could help, although turning it on doesn’t seem to do much. But surely there must be some way to instantiate the script alongside the scene.
Anyway, that’s for later. For now, I’m happy that I’ve got something that works.
Ooh, you know you have a situation on your hands when you see three glass trucks in convoy.
I can’t see voice assistants ever getting better than very basic human understanding. I heard someone mention that they asked their cylinder to “brighten the lights in the room and make it warmer.” The assistant bumped up the heater, but if it was me, I would’ve adjusted the light temperature.
The next “touch grass” event, plus my “get out more” goal for March, has been booked for this upcoming long weekend.
It’s amusing to see a farewell card get passed around the office like a hot potato. A hot potato that everyone has to touch at least one, without letting the recipient know that such a potato even exists.