 This video was brought to you by my patrons. Thank you so much for your support Hello there in the previous week I've been working on a combat system for kitchen tails my latest game if you're not following kitchen tails I highly recommend you to do so you can follow it on github to get the latest update Get some pull requests and comment on the code and get the source code as well I put the link the description and you can also follow me on each IO so you can get updates on the game I've been posting some dev logs and other stuff like that there So I've been working on this special move system where you can combine some keys and then you have a special action So if you press like down and right and punch you will cast like a Haduki know something like that or fireball And in this video, I want to show you how I broke down this problem So how I broke down the system into smaller problems that we could easily so and how did I Approach that system and how did I solve that problem? So let's get started So we are going to try to achieve this so I'm pressing down right and Z which is the punch Action and we are trying to cast this fireball without that. I can press down and nothing happens I can press right and left and the character basically moves and I can press punch and basically it will just Create this hitbox, but if I combine these three actions, I can cast this fireball. So let's get started So let's start with the building blocks of this system, which is this special moves class This is a resource So it's basically a data container and what this will store is a dictionary with a movement list So we'll define keys that will represent the movement name So let's say we have a fireball So we'll define the fireball followed by a pool string array that will define the actions that build up this special action so we can insert in this pool string array down right and Punch and as such this this pool string array will build up this special action So let me show you how this works. I have here a basic special actions and Here you can see that I have a dictionary with five keys Dash attack left dash attack right fireball left fireball right and fireball up and they are all Pool string arrays if I open one of these you can see that it has a size of three So we can define how many simple actions will build up this special action and after that We can define strings that will tell which are the actions that will build up this special action So down left and attack the values of this pool string array must be reflected into the project Project settings input map. So you can see that I have here left right up down the fan attack dash jump, etc We'll see later that this system even works with Multiplayer actions. So if we have something like this left one and left two or left three four, etc The system will filter these indexing characters and try to maintain only what is the actual action So that we can design what builds up an action knowing that independent of the player the action will still be cast So this is the main building block of the system This is how we will define the actions that will be cast later on Then let me open this platform combat actor here We have a node that represents an action buffer and if I open this Action buffer will see that it has a timer and you see why now The action buffer has a clear time So what this will do is that it will store these actions into an array and after some time if nothing happens If this array isn't solved by the next class It will clear it up and basically it will be an empty array after some time And also this action buffer has some a pool string array with the valid input actions So that for instance, we don't consider a UI input inside this input action So it will create a chain of actions and we can state which are the actions through this Pool string array will define which are the valid actions that will enter this action chain This is how we will define which are the actions that will actually enter inside this action chain So if I open this action buffer here, we have this unsolved action chain Which is an empty array by default We have these variables here with the solver timer Which is this time and the clear time which is the time within the array will be kept And after this time it will be cleared and we also have this pool string array with the valid input actions That will define through the inspector. We also have the signals that will tell other classes Which is the current action chain So we insert actions inside the action chain inside this unsolved action chain And every time that we insert a new action it will update the classes that are observing this signal And it will try to tell them which is the current action chain So the current unsolved action chain So if we open here, we can see that here I have unhandled input With just a method called to the stack input event Passing this event to another method which I can control better So basically I filter some undesired events So if it's not an action type, we don't want to treat it If it is an event equal, I don't want that inside the chain as well And if the event is not present, so it's basically a release I don't want this as well inside the action chain Basically what this does is that it will try to figure out Based on this event which is the action that it represents So we will get this through this other method that I created here So we get the event action passing the event through this method And basically what this will do is that it will go to the input map And get the list of actions And then it will for each action try to see if this event represents One of the events that is inside this action Since here in the project, project settings, we can define a list of events that represents this action So for instance we have the keyboard left that represents the left The left action but we also have a joystick that represents this action We can have other buttons so we can have the A button representing left And also the left arrow represents the left action What this will do is that it will receive this event And try to figure out which action has this event inside of it And then it will return this action name, so it will return a string And we will store this action name inside this action variable here And if we have something, you can see that by default it's empty So if it doesn't find any action that represents this input It will not store it, so it will return an empty string And if we have an empty string, it will not enter Inside the stacked input method logic So it will skip this branching here And basically what this does is that it will append this action inside the unsolved action chain Creating this chain of actions And it will emit the signal telling all the classes that are observing the signal That the unsolved action chain was updated And it will start the timer So each time we add a new event to this unsolved action chain It will restart the timer And as such, if no valid actions were inserted inside this array It will clear it after this clear time that we defined here And to do that, we will call this cleared unsolved actions method here That basically resets this action chain So it will clear this array and resize it to zero And basically is what this does And it will emit the signal to tell all the other classes That maybe were trying to solve an unsolved action chain That they can stop and they don't have to try to solve anymore Because there's no action chain further So with that action buffer storing these unsolved actions into an action chain And communicating to classes that are interested in solving this action chain What is the current unsolved action chain? I created an action chain solver So you can see that the action chain buffer Is connecting its signal that the action chain changed To this action chain solver resolved action chain method This action chain solver is what will use the resource that we created earlier So it's what will actually get this resource The special moves resource And by using this resource It will try to search for combinations So for values, the values of the keys that we have here So it will get these values here So down left attack And try to see if they are present inside this current unsolved action chain So this is basically what this does I did that approach because now with that being resources So with the list of special actions being resources If I want to I can create a list of characters So let's say I have four different characters of your game And each one has a list of special actions That are these resources that we designed And each one can have different combinations of actions With different special actions And these actions solver will receive this resource And it will try to search for these keys and for these values And then it will try to resolve the action chain So if I open that You can see that this is basically the description of the class It checks for the presence of a special move Combination in an action chain And the way that it do that Is by first it will render this special movement list as a string So that it will override the pull string array with string values So it will transform this pull string array into a string itself So it will get the values of the keys And then it will override the value of the key With a string that represents this pull string array Basically I render the pull string array as a string So that we can use this and use some methods that string class provides to us And after that we have the resolve action chain So we get an action chain basically through this action buffer It will pass this action chain through this class And we will transform this action chain into a string as well But we will treat this string first And we do that by getting that action chain treated through this method here We will receive an action chain And basically what we will do is that we will take rid of some characters That we don't want inside of these values of this string Of this pull string right? Of this array here Because currently this is an array And what we will do is that we will go to the indexes of So the values of this array And we will try to transform what is an integer into an integer So if we have something like left underscore three Inside this action chain array We will remove this three And try to break down the name of this action Into just the action itself Not the indexes So we are trying to remove this indexing characters here And you can see that we are taking rid of this number So if there is an integer it will take rid of that It will take rid of the underscore It will also take rid of the dash character as well And after that it will override the value of this index Into the pull string array And it will override it with this new treated value And after that we will transform this treated action chain Into a string as well So we have two strings to compare here Into the resolve action chain method So we have now a string that is the movement list Which was before a pull string And we will now have a string that also is the action chain So we can have for the presence of one inside the other I couldn't think of another way to get that approach To solve this problem So this is the approach that I went for And now it will take this list of special moves So the special movement, special actions And it will get the value So the combination of actions that represents these special actions And then it will try to search if this special move So if this combination is inside of the current action chain So it will get the action chain and try to see If any of these combinations fits inside of it In any way, in any order So it will basically remove the brackets Because we transformed a pull string into a string And it keeps the brackets But now we are removing these brackets From these special moves I think that I could throw this even on this render method here Basically I think that I could do that And if it finds, if it figure out any combination of special Any combination of simple movements That fits this current action chain It will then emit a signal telling other classes That the action chain was solved And that the special action is the action That we are currently in inside this movement list So basically what this will do Let me open this action chain So over here Basically what this will do is that If it figure out combinations of these That are inside the action chain It will communicate to other classes That this is the special action that shall be cast So basically if this combination fits the current action chain It will communicate to other classes Dash attack right It will tell, oh the special action that is present Inside this action chain is the dash attack left And basically that's how the class Solves this unsolved action chain And while this is what basically closes the system So we have a resource that we can Configurate for as many characters as we want We have an action buffer that will store actions That are relevant for casting a special action And storing them into an array And communicate to other classes What is this current array And then we have an action solver That will take this array And it will try to match a combination of actions Inside this action chain And basically what we have here And this is completely up to you Is create a class that will take this data That the action chain solver creates So it will communicate What's the name of the special action That was just found inside this action chain And basically I created a class That will receive this data So we can see here That the special action executed method That passes the special action name It is communicated to this special action cast class So if I open that We have this method here That will get this name And then it will execute something In my case it will go to this left fireball If it receives the name of fireball left And it will tell it to spawn a fireball It will go to the fireball right If it gets the fireball right name Of the special action And it will tell it to spawn And basically that's how I use this data Of this system into my game So that's how I implemented This special movement system into my game And I think that you can easily integrate That approach into your game as well So I will put the link in the description For the project into github But really follow the project there Because you are losing amazing stuff like that You can of course start the project And turn on the notifications by clicking on watch On the github repository, okay If you like this kind of content Don't forget to leave a thumbs up And if you are not subscribed to my channel yet What are you doing with your life? I'm posting amazing stuff like that Amazing game development stuff like this Follow me to get more of this content So that's it Thank you so much for watching Keep developing and until the next time