Making a Game - Causing Environmental Damage - EP 21


Video Tutorial

Aims of this Tutorial

  • Create a simple arena in Blender and export for Godot.
  • Make the players take damage for leaving the arena.
  • Make the players take damage for overcharging their weapon.

Creating Arena Visuals

Simply pop into blender and create a sphere. There are two choices of sphere, both with their own merits. You can go for the UV sphere which will have rectangular faces but they will get very deformed near the poles. This would be ideal if you could not look at the poles. For my game, I went with the icosphere which uses triangles and is isometric.

Now, we want to create a laser mesh effect from this sphere. In order to do that, we can simply add a wireframe modifier and slightly bump up the thickness. Once you are satisfied with the geometry, export it as gltf 2.0 making sure that you select apply modifiers.

When you import it into Godot by placing it in your project folder, you then need to open that scene in Godot and give it a material. Then turn on emission, give it a nice colour and ramp up that intensity to create a laser mesh. You can then place this in your scene.

Causing External Damage

This calculation will happen solely on the server, since it is the server that has the final say on who lives and who dies. We just need to incorporate a new function in the main physics loop to take damage from other sources. We also need to make a slight amendment to the take damage function:

func take_damage(damage : float, time : float) -> void:
	health -= damage
	if health < 0 and is_alive:

Taking damage from exiting the arena

This is simple, since we know the radius of the arena and it is positioned at the origin, we just need to measure the length of the position vector against the radius (or, equivalently, comparing the length squared with the radius squared to reduce computation time). So we just add this function to the main loop:

func calculate_other_damage(delta : float, time : float):
	if (translation.length_squared() > 100):
		take_damage(OOB_DAMAGE * delta, time)

Taking damage from overcharging

This is a little more involved because it requires us to keep track of the players energy. Since energy is capped at 100, we need to remove energy when firing and add energy when not. We can therefore make the following amendments to the player script:

# fire()

energy -= delta * BASE_ENERGY_USAGE

# physics_process()

if current_weapons_element.firing and is_alive:
	fire(delta, plan_time)
elif energy < 100:
	energy += BASE_ENERGY_REGEN * delta

We can then use this energy value to deal damage based on it's value and so the take other damage function becomes:

func calculate_other_damage(delta : float, time : float):
	if (translation.length_squared() > 100):
		take_damage(OOB_DAMAGE * delta, time)
	if energy < 0:
		take_damage(-energy * BASE_OVERCHARGE_DAMAGE * delta, time)

This deals damage based on the players energy deficit, therefore not penalising slight over-usage nearly as much a rampant laser firing. Finally, the constants that I used in these snippets are:

const BASE_ENERGY_USAGE : float = 75.0
const BASE_ENERGY_REGEN : float = 150.0
const BASE_OVERCHARGE_DAMAGE : float = 5.0
const OOB_DAMAGE : float = 100.0

That concludes this episode. There will not be episodes for the next two weeks, but after that we should be getting right back into the swing of things!