top of page

Create Your First Project

Start adding your projects to your portfolio. Click on "Manage Projects" to get started

Delve

Overview

Delve is a top-down bullet-hell inspired by Enter the Gungeon. It was created during my first year and was my first exploration of the Unity engine.

Project type

Bullet Hell

Date

February

What I Did

I created a random dungeon generator based on Blackthordprod’s design, expanding it to allow rooms of multiple shapes and sizes.

I also implemented multiple weapons the player can pick from before starting a run: a pistol, a sniper (essentially the pistol but with a slower fire rate, less ammo capacity, and higher damage and projectile speed), and a shotgun. There is also a selection of passives for the player to choose from. The first halves reload time, the second doubles ammo capacity and the final one gives a 50% chance not to die when taking lethal damage. I also created a dodge roll that gives the player invincibility frames.

There are a few enemy types in the game: a basic enemy that shoots a single projectile, a burst enemy which fires a long burst of projectiles, and a shotgun enemy which fires an array of projectiles which spread out in a curve.

There are also sound and visual effects used throughout the project.

How I Did It

The random generator uses premade rooms with a spawn point at each opening, and a destroyer point at the centre of each “section” of a room (so a room that is two rooms long will have two destroyers). When the room is first spawned, these points check if they are colliding with any other spawn points or destroyers. If they’re colliding with a destroyer, they destroy themselves, and if they’re colliding with another spawn point, they disable the other point and immediately spawn a room. If they don’t collide with anything, a room is spawned after a short delay.

In the case of two destroyers colliding – this can happen if a larger room is spawned where there is only room for a standard one – the younger room will be destroyed, and the opening is filled with a wall. By destroying the younger room, the path through the rooms is preserved.

To decide which room prefab to spawn, each point stores where it needs an opening on the room it spawns. It then uses this to retrieve the appropriate list from the room handler (which stores lists of rooms with openings at the top, bottom, etc.). In the case of rooms with multiple openings, it will cycle through them until it finds an appropriate opening and then spawn the room using the point’s location.

Finally, after a set amount of time, the room handler will pick the last spawned room and create the exit. By adjusting the wait time, the maximum distance of the exit from the spawn room can be controlled.

The player’s weapons aim by rotating to face the mouse’s location. The parent script has serialized fields for the shooting cooldown, reload time, ammo, ammo max and sound effects. The shotgun has extra fields for the number of shots and the rotation between them. Each child prefab then has its sprite changed and shoot point adjusted to match.

The player’s passives are switched by stepping on spell circles in the hub world. When these circles detect an overlap, they switch the player’s current passive, which is stored as an integer. The reload time and ammo capacity passives just multiply the relevant value in the equipped gun on awake. For the 50/50 passive, when the player takes a hit that reduces their health to zero or less, it randomly generates either a zero or a one. If a one is generated, the damage from the hit is undone, and a sprite is spawned to show the passive took effect. If a zero is generated, the player dies as usual.

The dodge roll plays a roll animation, and briefly sets an invincible variable to true, which is checked at the beginning of the UpdateHP function.

All enemies use the same two states for their AI: Hold and MoveToPlayer. The Hold state simply stops the AI from moving around, and MoveToPlayer allows movement and sets the agent’s destination to the player’s position. At the same time, it runs an attack loop that fires projectiles every few seconds, with the cooldown determined by the enemy’s shootCooldown stat.

The basic enemy just shoots a single projectile for its attack loop. The burst enemy’s AttackLoop loops multiple times, firing projectiles. The number of loops per burst is dictated by a burstAmount variable, and the time between individual shots is determined by intershotCooldown. The shotgun enemy stores the shootPoint’s transform in a separate variable. It then loops five times, rotating the transform and firing a projectile each time. The amount it rotates each loop is determined by the rotationAmount variable.

What I Would Do Differently

The main thing I would do differently is making the generation more structured. I looked into how Enter the Gungeon generates its levels (BorisTheBrave wrote an interesting article on it). While the individual rooms are picked randomly, the overall layout is more structured, using graph data structures. This approach allowed the team to have much more control over the flow and length of their dungeons, and it makes it much easier to add specific rooms, such as shops or boss arenas.

The next change I would make would be implementing object pooling. A significant number of objects are being spawned and destroyed repeatedly (bullets and enemies), and implementing object pooling would save the time currently being spent on deallocating and reallocating memory.

The last significant change would be to encapsulate the enemy and player weapons into separate scripts rather than having them built into the larger objects. This would help with any potential bug fixing or expansion, and would have saved me repeating the basic shooting and shotgun code from the player to the enemy.

I also have some more minor changes I would make. First, using enums for storing the player’s passive and openings for rooms. It would make interacting with those systems much more intuitive. The second is using more VFX throughout the game, particularly with the shooting. Currently, bullets just appear and disappear, which spoils the immersion somewhat.

Contacts & Social Media
  • LinkedIn
  • Instagram
  • YouTube
  • TikTok
  • Vector-Email-Icon-Download-Transparent-PNG-Image-4244398915
bottom of page