I’m working on a 2D platformer with a modular ability/moveset for the player character, and I was thinking about implementing a storage system for this using resources. This would involve data from damage to timing (all fairly simple), but I also wanted to store frame data as well. I currently have it stored as two arrays of Shape2D and Vector2 for the shape and position respectively, but it feels extraordinarily clunky this way.
Is there a better way to approach this? Or any resources y’all would recommend? I have been struggling to figure out the best way to approach the issue in the first place. Thanks!
Unless I’m missing a far easier way of doing it, there’s a couple ways of doing my current idea:
Go through the 2-3 line steps for shape creation for each shape individually
Create a separate resource for shape handling (which only abstracts a small amount of the factory process away)
And both then require additional assembly once loaded to be attached to a CollisionShape2D and Area2D after that. I know I can make a framework to handle that whole assembly line, but it feels like a lot of work for very little, and possibly removing all the performance benefits using resources allows. Just seems so messy, but also I could be wrong about it, hence why I ask.
Store as little data as possible that’s sufficient to recover the state. Don’t worry abut “assembly line” performance. Unless the profiler shows it is an actual bottleneck.
Could you take a step back and describe the actual use case, like how the game works, as opposed to the technical details? I have a couple of potential ides for you, but it’s unclear to me what exactly you’re trying to accomplish.
You also might check out my DevLogs for Katamari Mech Spacey which I’m currently creating. (Scroll down to the bottom of the page for the devlog entries.) I created a modular ship system where the engines handle forward movement, inertial dampeners handle slowing down, attitude thrusters handle turning, etc. It might be that what I just did would help you. If not, I have suggestions on a modular state machine that might be what you need.
Of course –the game is a metroidvania style 2D platformer with the player being offered a variety of skills and weapons throughout the journey. They’re able to swap between different attacks and upgrades at any point.
The goal is to make a system that handles the animation and numerical data that handles any skill/weapon he player is using without hard coding anything that doesn’t need to be.
Also! After reading through your ship design devlog, that gave me a further idea of instead of trying to save just the data for an attack, have a resource defining each weapon or power, and that contains all the necessary data for it. That said, it still runs into the same issue with hitbox storage as before, but it’s a step I think!
Yeah, I’m going to recommend you take a look at my StateMachine class and try it out. It is fully documented with installation and usage instructions in the Readme. You may come up with your own version, but I’m recommending mine because I designed it for the use case you are describing, and my engine parts are based on the idea if not the code.
Most state machines are push models. When you need to change states, either the machine, or a state, tells another state to start - pushing it to start. My model is a pull model. Each State monitors conditions it cares about and asks for control when those conditions are met. It pulls focus onto itself only when it is ready. The StateMachine decides whether it can allow that through checking a can_tansition property on the current state, and then for the state requesting transition. If either is false (the reason doesn’t matter) the StateMachine just passes on the request. It doesn’t queue it.
The benefit of this machine is that if I want to add something to it, like a new power, the power automatically just works when added to the tree. It knows everything it needs to know to function and is completely autonomous. If you remove it from the tree, it stops working. So you can simulate powers, and when switching them, just move the States out of the StateMachine node connected to the player.
There is a list of character-specific states in my Character3D AddOn. The base CharacterState identifies the player (or enemy/NPC) it is attached to. Anything that is common between the two, like Idle is a CharacterState. Anything that is specific to the Player is a PlayerState, EnemyEnemyState, etc. This allows me to categorize states and find them easily in the tree. It also tells me when I modify a state, whom it is going to affect.
From an OOP point of view, I consider my StateMachine model to be part of the object it is operating on, rather than the “Manager” of it. This means that I am enforcing encapsulation at a macro and micro level. for another example of how I use my StateMachine, check out the one attached to Main in my Game Template.
The usage of a pulling State Machine is really smart – I’ll definitely be taking a look. After working on the issue a bit more I think I’m just going to redo my entire architecture, as it’s not super conducive to modularity at the moment. Thank you for all the help!