Visitor #5 - General Tuning

Tagged: visitor gamedev

Visitor┬║ is a game I'm building in Godot. This post covers a batch of fine-tuning I did regarding animating sprites with the Tween node and fixing scene changing on android.

Fixing performance issues on device

First, I had to fix the aspect ratio, which was borked. This meant changing scaling in Godot's project preferences (Project Settings > Display > Window > Stretch > Mode) from ignore to expand.

Then, I had to lower the number of stars that were generating - I was probably generating between 100-300, if I remember correctly, which was causing the device to slow down a fair bit. After reducing the count to between 10-30 per starfield, things are moving much faster. I like how it looks more too.

The compass idea I had originally thought of did not work. I realized that a) the design was too cryptic, b) it took up a fair bit of space on screen and c) it made navigating pretty intuitive.

I fixed all of the above by switching to a simpler nav point, kept at the top of the screen. When a player taps on the screen it lights up to indicate that their character on screen is moving through space.

I also had to update how rotation of the nav point happened, which ended up being less code than I thought:

func _input(event):
	if event is InputEventScreenDrag and Global.get_player_can_move():
		var drag_val = clamp(event.relative.x, -10, 10 )
		compass_texture.rect_rotation += ( drag_val )

Before, I was clamping values quite a bit and it was quite difficult to rotate the compass. This feels much smoother and more intuitive.

Adding a beacon effect to the light nodes

I was pleased with this one - I got to do some basic animating and it was satisfying to see some motion in the game. One part of the game's mechanics is to "collect light" - however, these inert light sprites were just spawning and sitting in space without any indication differentiating them from the stars (or the player). By adding a duplicate sprite of the light underneath the original, and using the $Tween node, I was able to build a basic animation of a beacon.

This wasn't difficult (nor revolutionary) but it made quite a difference. One thing I learned that was tricky, was that the AnimationPlayer node would have worked great for this, but because the nodes of light are spawned at random locations, I was unable link the AnimationPlayer changes to where the nodes were spawning. In the end, the code for tweening animations looked like this:

func _animate_light():
	tween_node.interpolate_property(pulse_sprite, "scale",
			pulse_sprite_tween_scale_vals[0], pulse_sprite_tween_scale_vals[1], 2,
			Tween.EASE_OUT, Tween.EASE_IN)

	tween_node.interpolate_property(pulse_sprite, "modulate",
			pulse_sprite.modulate, Color(1, 1, 1, 0), 2,
			Tween.EASE_OUT, Tween.EASE_IN)

	# -- HACK --
	# this is a noop tween so that we can have a "pause" before the animation resets.
	tween_node.interpolate_property(pulse_sprite, "position",
			pulse_sprite.position, pulse_sprite.position, 3,
			Tween.EASE_OUT, Tween.EASE_IN)
	# --

func _on_Tween_tween_all_completed():
	pulse_sprite.modulate.a = 1
	pulse_sprite.scale = pulse_sprite_tween_scale_vals[0]

Scene changing issues on Android

This bug was discouraging me for a while. I followed some of the docs on changing scenes in Godot. It worked well on the render window, but was not working on Android. After googling I found several reports of people saying that android has case-sensitivity to loading resources. All the issues reported were due to file names having a space in them - but none of mine did. Eventually I found that one of my assets has a space in it, so I fixed that. I think that might have fixed it, but if I remember correctly, I might have had change the scenes to all lowercase too. At this point I don't remember, but at least I know that Android is more particular than Mac.

const scenes_map = {
	Scenes.Title: "res://src/title.tscn",
	Scenes.Game: "res://src/game.tscn",

Adding Titles

I used what I learned from the tweening of the light nodes to add some motion to my titles. Now, when a player starts the game we are met with a title describing a part of the game. After, I was able to wire up the player code so that when it reaches a certain size it will trigger the next "epoch" of the game.

What's next

Next, I would like to fix a frustrating bug where the game opens, the sky renders all of the starfields, but all the stars themselves are not visible. It's a frustrating one because the bug seems non-deterministic - it happens, albeit rarely, when I start the game (both in godot and on the android.)

Other than that, I'll make some stylistic changes next, I think, as well as start planning out the NPC interaction and dialogue (the other main mechanic of the game).