Hello, apologies for anyone crazy enough to try and help me. I’m going through this video and recreating a FSM system, and one thing I just can’t wrap my head around.
@08:05
At this time, the dude sets up a constructor for whenever he initiates a new class
public State(Batttlesystem system)
{
_system = system;
}
All well and good. But when he goes to create a class he uses intellisense to auto fill this in for each class and doesn’t discuss it at all @ 09:25
Each class requires something like
public BeginState(Batttlesystem system) : base(system)
{
}
With nothing in the brackets. What is going on here? What is that :base thing and why does it care about (system)? According to C# doco it’s trying to
“Specify which base-class constructor should be called when creating instances of the derived class”
That sounds like word salad to my brain. I can’t read it.
It would at least kind of make sense to me if the code was
public BeginState(Batttlesystem system) : base(system)
{
_system = system;
}
I just don’t understand it at all, if we have already declared the constructor in the base, why does each class get pissy if we don’t write this in again each time?
Is there a simpler, less abstract why to write or understand this? Please respond to me as if you were responding to a drunken, sleep deprived 7 year old.
I know it works, but not sure why, and not sure why it’s a problem if I don’t add it. I really hate this guy’s videos, but they are so useful.
In C#, you can’t inherit Constructors. So in order to satisfy the compiler, we create a new Constructor for the BeginState class. But since we just want to call the same code that State calls, we just call the base constructor. Normally, the base keyword allows us to call methods that are overridden, so you would expect to be able to do something like this.
public BeginState(Battlesystem system)
{
base(system); // <== bad, can't do, compiler will complain
}
But you cannot call a constructor method like a normal method, as constructors are for creating new objects. To remedy that, C# has that thing above which allows us to call the base constructor’s code.
public BeginState(Battlesystem system)
{
_system = system; // the code pulled from the base class
}
If you called
public BeginState(Batttlesystem system) : base(system)
{
_system = system;
}
It would essentially be this
public BeginState(Battlesystem system)
{
_system = system; // this is from the base class
_system = system; // this is from your actual line of code, is a repeat
}
Yes there is. This needless silly abstraction of an ULTRA simple programming problem drives me nuts. I actually keep a specific warning paste handy for this.
FSM finite state machines:
I suggest never using the term “state machine.” Instead, just think:
I have to keep track of some THING(s)
That THING might change due to reasons
Depending on that THING, my code might act differently
That’s it. That’s all it is. Really!! The classic example is a door:
track if it is open or closed
if it is open, you could close it
if it is closed, you could open it
if it is open you could walk through it
if it is closed you could bump into it
Wanna make it more complex? Put a latch on one side of the door.
This is my position on finite state machines (FSMs) and coding with them:
Thank you so much, this was the simple hidden thing I was trying to understand and could not find documentation on. Would have been looking in the wrong place.
Thanks KD, there is a fair bit for me to chew on there, I’ll take some time to process.
I managed to get a turn based battle system working using enums a la Brackeys using Update() and conditionals. It worked, but was very clunky and not scalable which led me down FSM rabbit holes.
I was trialling a more complex battle system with about 15 states (or turns) per round. Using these class based States, I figure I can just pop this in the main CombatSystem script Update() method:
Update()
{ currentClass.Update() }
In order to call whatever State specific Update functions every frame.
It seems cleaner so far. I’m almost 50% confident the refactor will in no way backfire or introduce more problems…