Gravity Ace
Gravity Ace is a daring deep-space action game coming soon to itch.io and Steam for Windows, Linux, and OSX

Devlog 3: Shield Design

Your ship in Gravity Ace can only take a single hit. One shot from an enemy or touching a wall causes instant destruction. Space is dangerous, weapons are powerful, and ships are fragile. To give players – especially new players – a fighting chance, your ship is equipped with a shield.

The shield takes the first hit... but not the second!

Node setup

The shield is fairly simple but was designed with a few interesting features. First, let me show you the node setup and then I’ll go through them one by one. Gravity Ace is being made with Godot Engine.

Shield node setup in Godot Engine

The root node shield is a RigidBody2D using the Character mode. Character mode works exactly the same as Rigid mode except that it doesn’t allow the body to rotate. That’s important so that the rechargeProgress UI component doesn’t rotate.

Within that is a collision which is a CollisionShape2D with a CircleShape shape. The joint node is a PinJoint2D. That’s how the shield attaches itself to the player ship.

The Sprite node is a standard Sprite2D with the shield texture. The AnimationPlayer holds three animations:

  • disabling the shield
  • recharginging and enabling the shield
  • disabling, recharging, and enabling the shield

rechargeProgress is a TextureProgress node with e clockwise Fill Mode. It shows the circular recharging progress UI. Finally, there are three AudioStreamPlayer2D nodes. The shield plays its own sound effects and comes with all of the sounds it needs.

One of the great things about this setup is that I can add this scene as a child of any RigidBody2D in the game pretty easily. That body will get a shield with all of the functionality, animation, and cool sound effects.

Any body that wants a shield just needs to be a RigidBody2D and it needs to emit signals revived and destroyed. When the shield node enters the game, it attaches itself to its parent via the joint node, a PinJoint2D. Then it connects the revived and destroyed signals on the parent to itself so that it can respond to the parent object being destroyed or revived.

The shield also automatically responds to fuel levels by checking if the parent object has a fuel_changed signal. If it does, it tracks the parent’s fuel level through fuel_used and fuel_added signals.

If the shield hits something, it disables the shield and starts the recharge sequence. If fuel is being tracked then it disables the shield when fuel runs out and recharges the shield when fuel is available. Here it is in action:

The shield recharge sequence

Gameplay design

The animation player controls the animation, progress UI, and also the collision. That last bit is important because it subtly balances the difficulty of the game in the player’s favor. The simplest way to do a shield would be to make the shield collide when it is visible and not collide when it is not visible. In fact that’s how I prototyped it. But where I ended up was more complex.

The shield starts to disable itself when it hits an object but it doesn’t happen instantly. It takes 600ms for the shield to disappear from view and a full second for the sound effect to play. And the shield remains fully active and collides for the first 500ms. That means that the shield can actually absorb multiple hits if they come in very rapidly. The shield only disables its collision when the animation is nearly finished.

Similarly, when enabling the shield, it goes through a recharge sequence and then the shield turns on. It takes 500ms for the shield to become fully visible but the shield will start absorbing collisions at the very beginning of that 500ms. That means that the shield is enabled and can absorb hits the instant the recharge sequence completes but before the player can actually see it.

Both of those combined add excitement by seemingly letting the player make narrow escapes or to barely avoid incoming fire. It also allows the player to take a couple of quick bounces off of walls in close quarters in a way that feels fair.

  • “I was about to get wrecked but my shield came back just in time!”
  • “Did you see me bounce off those walls just before my shield died!?”

Questions?

There are a few other small things. For example, the shield doesn’t disable when it hits certain small objects like asteroids or explosion debris. But these are the main features. I hope this helps you in creating your own games.

Please don’t hesitate to ask questions on Twitter, Itch.io, or Discord (links below)! I’m always happy to talk about games.

Published September 1, 2019

More devlogs...

Devlog 5: Engine sound breakddown

Devlog 4: Respawn System

Devlog 3: Shield Design

More...