#How to structure my spaceship entity? - Confused with composition...

1 messages · Page 1 of 1 (latest)

fiery void
#

Hi! I'm making a space game and I'm really confused on the architecture of my spaceship entity scene...

Right now it's a simple CharacterBody2D with sprite, collision and two components (screenshot attached). I'm starting to realize my current implementation isn't really good if i want to add new features to the ships, I also added a custom resource system to load stats into the ship object to instantiate different ships from the same scene. Also because my components aren't reusable in any way...

On top of that i'm going to redo the whole thing in RigidBody2D to use godots physic engine instead of my own maths.
Code isn't an issue i'll figure it out.

What do you suggest I do to structure the new ship scene?

My plans for the future include :

  • Individual sprites for thrusters, weapons and wings, to make damages or upgrades more dynamic on the ships.
  • Ship components that changes stats (mass, thrust => handling, damages, health, shields and so on...)
  • Possibly ship interiors (this is quite ambitious but i'm sure i'll get there someday)

I'd be happy to provide code, screenshots and details about anything.
Thanks a lot for reading my spaghetti :)

PS : feel free to ping me i won't be mad i promise

deft vortex
# fiery void Hi! I'm making a space game and I'm really confused on the architecture of my sp...
  1. I'd make all your ship components individual scenes. From there make sure they're completely module and don't have any direct dependencies to other components. If a component needs information from the outside world, use interfaces or duck typing to get that info.
    For example, lets say you want your thruster component to only function if engines are powered and you want the thrust power to be governed by the command station, but you don't want to directly reference those other components.
extends RigidBody2D
class_name Thruster

var thrust_strength = 100
var mediator

func thrust() -> void:
  if mediator.can_thrust() == false: return
  
var force = Vector2(thrust_strength * mediator.get_thrust_multiplier(), 0)
  apply_force(force)

Your Thruster doesn't care about the logic behind can_thrust or get_thrust_multipler or where it comes from. Your mediator handles the complex negotiation between components (such as checking engine power or command station pilot input) so you can develop those components independently from each other. This does of course result in a highly coupled mediator object, but that's okay because being highly coupled is it's job and can even be swapped out by other mediators if need be.

  1. I'd use objects for your stats. So instead of using a float for max speed you'd use a Stat object that contains a float. Access that float using get_value. Now you have a variable that you can attach StatComponents to making it easy to add and remove modifiers. It also means that you can completely change the logic behind get_value as you develop your game and it wont break any objects that reference that stat.

  2. No comment on ship interiors. You can probably just add it to the components later when you're ready.

fiery void
# deft vortex 1. I'd make all your ship components individual scenes. From there make sure the...

Thanks a lot for your answer, indeed the current flaws of my component is that they are directly dependent on others, i'm going to work towards fixing this.
And i also have to do some research on objects, i don't know what these are x)
My main issue is that i'm really lost and I don't know how to build the node structure for this.
Someone suggested to make every component an area2D with sprites and attach it to my RigidBody.

deft vortex
#

And an object is anything that's been instantiated from a class. So your ship is an object, the components are objects, etc.
So a stat would look like this:

extends Resource
class_name Stat

func get_value() -> float:
  return Any logic you want. Maybe Stat contains a linked list that adds up all the modifiers of a stat?
#

Or it just returns a float value it contains as a variable