Alien Invasion 2024

Alien Invasion 2024 is a remake of Alien Invasion from 2015 in Godot 4. The art assets have been reused from the original game, but the code was written from scratch in GDScript utilizing a component-based gameplay framework.

Improvements over the original game include

  • Particle effects for projectiles and alien death explosions
  • Screen shake on certain events to improve the game feel
  • Small improvements to the UI

I chose GDScript over C# as the programming language to have the ability to make this game playable in a web browser (since C# is not supported for exporting to the web in Godot 4.2).

The Game

Requirements

In order to run Alien Invasion 2024, you need the following system requirements:

  • CPU: Any x86-64 CPU
    Example: Intel Core 2 Duo E8200, AMD Athlon XE BE-2300
  • GPU: Integrated graphics with full Vulkan 1.0 support
    Example: Intel HD Graphics 5500 (Broadwell), AMD Radeon R5 Graphics (Kaveri)
  • RAM: 2 GB
  • Storage: 150 MB
  • Operating System: Windows 7 or higher

Screenshots

Insights

Source Code

The full source code is available on GitHub.

Spawning Projectiles in Godot

The approach of how to spawn nodes, like projectiles, into the game world is something I found a bit curious in Godot. Since you have to add the instantiated node to the node tree of the game level, it is often recommended to simply emit a signal in the node that wants to spawn something. Let’s say you want to spawn a projectile from the player ship when firing its weapon. Following this approach means you would have to create a signal, say weapon_fired, and listen to this signal in the level to do the spawning of the projectile for you.

I found this approach to be illogical, like putting the cart before the horse. The responsibility of spawning projectiles belongs to the player in my eyes, not the level the player is currently located in. There is also the inconvenience of having to remember listening to this signal in every level. What if you have a hundred levels? And then you would have to do this for every entity firing projectiles – like the aliens – in every level. Unless I am overlooking something here, I found this approach to be very cumbersome.

For these reasons, I chose to follow an approach similar to the Unreal Engine: I created a global node called Game that holds a reference to the world. This is always pointing to the current level (admittedly, there is only one level in Alien Invasion, so it wouldn’t matter, but I wanted a solution I could apply to other games with more levels.)

# Autoload: Game. No class_name required here as the autoload takes are of that.
extends Node

var world: World

The level is then setting the Game.world reference on it’s _init method to itself.

class_name World
extends Node2D


func _init() -> void:
	Game.world = self

With this done, I can then access Game.world from anywhere to spawn and add new nodes to the game world. In the case of the player, I am passing the world to the ProjectileSpawnerComponent which does exactly what its name implies.

class_name Player
extends CharacterBody2D


@onready var _projectile_spawner_component := $Components/ProjectileSpawnerComponent as ProjectileSpawnerComponent


func _ready() -> void:
	_projectile_spawner_component.world = Game.world

Lastly, in the ProjectileSpawnerComponent I can then easily access the world to add instantiated nodes to its tree:

class_name ProjectileSpawnerComponent
extends Node


## The stats that configure the projectile.
@export var _projectile_data: ProjectileData

## Reference to the world scene the game is played in.
var world: World


func spawn(position: Vector2) -> LaserProjectile:
	assert(_projectile_data, "Projectile Data not assigned")
	assert(world, "World not assigned")
	
	var projectile = _projectile_data.scene.instantiate() as LaserProjectile
	projectile.projectile_data = _projectile_data
	projectile.position = position
	projectile.collision_layer = _projectile_data.collision_layer
	projectile.collision_mask = _projectile_data.collision_mask
	world.add_child(projectile)

	return projectile

Concept Art

Check out the project page on the original game from 2015 for concept art.

Attributions

My Work

My contribution to the project was mainly the following:

  • complete reimplementation of the game logic in GDScript
  • creation of particle effects for the projectiles and alien deaths in Godot 4
  • recreation of the UI in Godot 4

The Team

I would like to express my sincerest gratitude to all people who contributed to the original project, upon which this work is based. These are, in no particular order:

My special thanks goes to Hansheinz Müller Philipps Sohn for providing the server infrastructure.