I am using a FSM for the player entity and it is working fine. Currently the entity has one state and only one (e.g. paralyzed). The entity's state process() method is called every turn.
It is necessary however, that each entity can have more than one state simultaneously (e.g. paralyzed and blinded). Each state affects the entity attributes e.g. paralyzed reduces the walking range to 10% and blindness reduces it to 50%. Vision range is not affected by paralyzed state, but by blindness (set to 0).
Now it is important in which order the states are processed. I either end up with a wrong walking range or a wrong vision range. I could do checks in every state's process() whether the entity has any other states and alter the code accordingly, but this gets very messy the more states I add.
Currently I think it's a better choice to attach only one state to the entity, but to create more states, some of them a combination of two states (e.g. a blindedAndParalyzed). This way I'll and up with a lot more states than I currently calculated with, because ever state has to be combined with other states. I'm wondering if that is the best solution?
A state is a Singleton with an enter, process and exit method. Process is called each turn.
Currently process() for paralyzed looks like this:
public void process(){
walkRange = 10% * walkRangeBase;
visionRange = visionRangeBase;
}
and process() for blinded looks like this
public void process(){
walkRange = 50% * walkRangeBase;
visionRange = 0;
}
At the moment the result is always fine becvause only the process() method of only one state is executed. If I switch to multiple states both get executed and the result is either walkRange = 50% and visionRange = 0 or walkRange = 10%. THe desired result would be a walkRange of 10% and a visionRange of 0, because the walkRange should be limited to the smallest one.
I could do something like that:
public void process(){
if(state != paralyzed)
walkRange = 50% * walkRangeBase;
visionRange = 0;
}
But i have around 20 different states, so I have to create a lot of if cases. Choosing the smallest value for e.g. walkRange doesn't work either because there are some states with positive effect on walkRange.
So I am wondering if it is better to avoid a state machine with more than one concurrent state and live with a bigger amount of states (about 50), or if there si another solution to this problem.
walkRange
was already set towalkRangeBase
, then paralyzed could dowalkRange = 50% * walkRange
and blindedwalkRange = 10% * walkRange
. The result would be the same independently of the order of operations. When the effect wears off you could calleffect.wearOff()
which would do the opposite manipulations. \$\endgroup\$