DEATHWORLD SURVIVOR
Team I.G.D.
An in-game screenshot with all the weapon types in action.
-
DeathWorld Survivor is a roguelite-survivor game set on a planet where everything wants to kill you!
Enter the Deathworld, a hostile planet where everything is out to rip you apart. Thankfully, as a tough-as-nails Space Marine, you've come prepared. Your readiness and tenacity, however, can only carry you so far.
Just how long can you last?
-
GAME GENRE: 2D Roguelite Survival Action
ENGINE: Unity 2022.3.0f1
PLATFORM: PC (Itch.io)
TEAM SIZE: 6 Members
DURATION: 9 Weeks
ROLE(S): Combat Designer
-
Creation of two distinct types of enemy NPCs that spawn infinitely across random map coordinates
Definition of modular behavior patterns for enemies to attack based on their proximity to the player
Addition of logic to spawn weapon upgrades across random map coordinates based on the kill count
-
DeathWorld Survivor is on Itch.io as of April 30th, 2024!
PLAY IT HERE: https://jtshock.itch.io/deathworld-survivor
CODE SNIPPETS
This script controls the firing patterns of projectile-shooting hostile enemies. FireBehavior inherits from another script known as AttackBehavior, which is a script that runs the attack patterns of the enemy through a public virtual void method called RunAttackBehavior. This method takes an argument of GameObject parent, allowing it to inherit from the GameObject the script is parented to through FireBehavior’s override.
FireBehavior uses 6 different private variables, 5 of which are serialized fields that can be overwritten in Unity’s inspector. It gets reference to GameObject called bulletPrefab to shoot a projectile, a float called bulletSpeed to determine the velocity the bullet travels at, a float called damage to determine the bullet’s damage output, and a float called fireRate to determine the frequency at which the enemy fires bullets. A custom DamageType class called damageClass that determines what type of damage the projectile will deal is also referenced. This class is a scriptable object that can customize damage output based on a designated element. Bullet projectiles use a Physical damage type, the data of which is controlled by the Physical DamageType scriptable object.
In RunAttackBehavior, FireBehavior accesses the base RunAttackBehavior method in inherits from AttackBehavior and calls it with the parent GameObject argument passed into it. From there, timer increments by 1.0f after every 60 frames, or approximately a single second. If the timer becomes a value greater than 1 divided by fireRate, the enemy fires a bullet. For instance, if fireRate is set to 5.0f, the enemy shoots projectiles once after every fifth of a second.
In public void Fire(), a new Vector2 called targetDirection is created and set to the normalized value between the player’s current position and the enemy’s position. From there, a new GameObject called bullet is instantiated using the bulletPrefab assigned in the inspector. This prefab spawns at the enemy’s position with its default rotation. Following this, the bullet prefab is launched along the targetDirection Vector2 declared earlier, dealing the declared damage, using the declared damage type and traveling at the declared speed. Once launched, bullets are set to the Enemy layer to be registered as a hazard to the player.
This script defines a movement pattern used by hostile enemies that chase the player with the intent of dealing contact damage. Shamble inherits from another script called MovementBehavior, which is similar in structure to the aforementioned AttackBehavior script. However, instead of running attack patterns through a virtual void for inheriting scripts to override, the virtual function of MovementBehavior is called RunMovementBehavior and defines the way enemies advance throughout the level in relation to the player. Much like the RunAttackBehavior in the FireBehavior and AttackBehavior classes, RunMovementBehavior takes an argument of GameObject parent. This allows the script to inherit its parent GameObject and use that for the MovementBehavior argument.
The script has 2 private variables: a private Transform called target that dictates the end point the enemy should advance towards, and a float called moveSpeed that controls the velocity the parent should approach its target.
In RunMovementBehavior, the script gets reference to the PlayerController Singleton instance. If the player transform returns with a value other than null, a reference to the Rigidbody2D of the Shamble script’s parent is created and declared as body. Once body is found, a Vector2 called moveVector is calculated, which gets the difference between position of the PlayController script owner’s transform and the Shamble script’s parent’s transform position. As this difference is found, the position of body is incremented to travel along the normalized version of moveVector, multiplied by moveSpeed and Time.fixedDeltaTime. This means the enemy will travel at a set speed per physics update, making its way to the player’s coordinates.
SEE IT IN ACTION!
This is a video demonstration of Team I.G.D.’s DeathWorld Survivor. I am credited as the team’s Combat Designer!
Showcased in this clip is the basic gameplay loop, which includes encounters with three different enemy types that spawn at random map coordinates, weapon power-ups that spawn at random map coordinates depending on the player’s kill count, and enhanced periodic attacks based on the acquired weapon power-up.
DeathWorld Survivor contains three types of enemies. The first and most basic enemy type is the Orange Spider, which is programmed to run towards the player’s location to deal damage on contact. The second enemy type is the Orange Slime, which pursues the player similarly to the Orange Spider, but also fires its own damaging projectiles when the player enters their firing range. The last enemy type is the Magenta Slime. This enemy is unique in that it does not try to rush the player; instead, it strafes to a location distant from their immediate vicinity and fires bullets. Each of these enemy types spawn during random gameplay intervals and at random map coordinates.
In addition to containing three enemy types, the game contains three different types of weapons. The player’s starting weapon is the Rifle, which automatically fires a stream of bullets in the same direction the player is moving. If a player acquires a power-up during gameplay that spawns after a set quantity of enemies are killed, they will upgrade their Rifle to fire an additional Shotgun Spray. Once every second during the player’s firing pattern, a buckshot of five bullets will be launched in the same direction as the player’s movement. If a player survives long enough to acquire a third power-up type, they will augment their Rifle with the Flamethrower. For a period of two seconds after every four-second interval, a stream of huge fireballs will come roaring out of the Rifle within a cone-shaped trajectory range, roasting enemies to a crisp!
Upon death, the player’s highest kill count is saved. If the player breaks their record, the old count is overwritten, incentivizing further replays to get the highest score possible!
DeathWorld Survivor has been released to Itch.io as of April 30th, 2024.
To be brought to its webpage, click here!