Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
gdevelop5:tutorials:finite_state_machine [2018/09/13 10:09]
wendigo [Conclusion]
gdevelop5:tutorials:finite_state_machine [2021/11/22 23:06] (current)
Line 1: Line 1:
 ====== How to handle complex logic – The finite state machine (FSM) ====== ====== How to handle complex logic – The finite state machine (FSM) ======
  
-You probably followed some of the beginner tutorials and decided to create your own project based on the game mechanics you have learned. But as soon as you added more complex actions you quickly got lost in a jungle of nested conditions that lead to bugs which were hard to find. In the end you probably quit the project.+You probably followed some of the beginner tutorials and decided to create your own project based on the game mechanics you have learned. But as soon as you added more complex actions you quickly got lost in a jungle of nested conditions that lead to bugs which were hard to find. In the endyou probably quit the project.
  
 Most tutorials you find on the internet (independent from the game engine) just try to show you a way to achieve the goal of that specific tutorial with least distraction possible. Unfortunately, this usually results in code that doesn't care about extensibility. Most tutorials you find on the internet (independent from the game engine) just try to show you a way to achieve the goal of that specific tutorial with least distraction possible. Unfortunately, this usually results in code that doesn't care about extensibility.
Line 8: Line 8:
  
 ===== What is a state machine? ===== ===== What is a state machine? =====
-As already indicated a state machine divides an objects logic into a fixed set of manually defined states that operate independently from each other. Each State only contains the logic that is applicable to it. For example when the player is in “falling state” you neither have to check the buttons for left and right movement nor the jump button because there is no ground under your feet. To switch from one state to another you have to check if specific condition is met. So let's pretend we were in “falling” state. While in the air we won'be able to perform any actionsWe are just passively pulled downwards by gravity. In order to transit into another state, certain conditions have to be met. In case of our falling state we would have to check if the player is in collision with the ground. If so we change the state from “falling” to “idle”. In “idle” state we check if a movement button is pressed which in turn would lead us to the “walking” state in which you keep on walking until some other event happens. You get the picture?+state machine divides an object'logic into a fixed set of well-defined states, which operate independently from each other. Each State only contains the logic that is applicable to it. For examplewhen the player is in “fallingstateyou don'have to check the buttons for left and right movementnor the jump buttonbecause there is no ground under your feet. When specific conditions are met, the player state is switched to a different one. 
 + 
 +So imagine that the player is in “falling” state. While in the air, it should not be able to perform any actionIt is just passively pulled downwards by gravity. In order to transit into another state, certain conditions have to be met. In the case of a "fallingstate, this condition would be "in collision with the ground"When this happens, the game would then change the state from “falling” to “idle”. Now, in “idle” state, the game constantly checking if a movement button is pressedwhich in turn changes the player state from "idle" to “walking”. In the "walking" state, the player keeps moving until some other event happens (e.g. movement button is released). Do you get the picture?
  
 ===== Getting started ===== ===== Getting started =====
-So let's get started by downloading the assets from the “[[gdevelop5:tutorials:platform-game:start|]]” tutorial. Create a player as a “platformer object” and some platforms (“platform” behavior) to walk and jump on as described in the above-mentioned tutorial.+So let's get started by downloading the assets from the “[[gdevelop5:tutorials:platformer:start|]]” tutorial. Create a player as a “platformer object” and some platforms (“platform” behavior) to walk and jump on as described in the above-mentioned tutorial.
 {{ :gdevelop5:tutorials:screenshot_scenes.png?800 |}} {{ :gdevelop5:tutorials:screenshot_scenes.png?800 |}}
 Open the properties of the player object and create the animations “idle”, "walking","jumping" and "falling". Then create a string variable on the player object and call it “direction” with the value “right”. Open the properties of the player object and create the animations “idle”, "walking","jumping" and "falling". Then create a string variable on the player object and call it “direction” with the value “right”.
 {{ :gdevelop5:tutorials:player_animations.png?600 |}} {{ :gdevelop5:tutorials:player_animations.png?600 |}}
-Switch to the event editor (“main” scene) and create these external events “playerstateinit”, “playerstatefalling”, “playerstateidle”, “playerstatewalking”, “playerstatejumping”. In the events of your main scene create a new event group from the drop down menu on the right-hand side. Name it “Player logic”. Now add a "At the beginning of the scene" condition. Add a sub event to the condition and link in the external event sheet “playerstateinit” via the “add”/”other” button. Do the same for all the other player states.+Switch to the event editor (“main” scene) and create these external events “playerstateinit”, “playerstatefalling”, “playerstateidle”, “playerstatewalking”, “playerstatejumping”. In the events of your main scene create a new event group from the drop-down menu on the right-hand side. Name it “Player logic”. Now add a "At the beginning of the scene" condition. Add a sub-event to the condition and link in the external event sheet “playerstateinit” via the “add”/”other” button. Do the same for all the other player states.
  
-<note tip>Instead of an animation we could also have chosen a dedicated "state" variable to control the players state. This would have given you a little more flexibility but the animation approach has the benefit that it allows you to bundle the logic with the corresponding animation which saves you some space in the event sheet and makes the logic look a little cleaner. Furthermore, you have access to the frames of the current animation/state and can trigger some logic at a certain frame inside the animation.</note>+<note tip>Instead of the animationwe could have created here a dedicated [[http://wiki.compilgames.net/doku.php/gdevelop5/all-features/variables#declare_variables_using_the_editors|Scene Variable]] "state" to control the player state. This is more advanced but allows for better flexibility. However, the approach presented here has the benefit of bundling the logic with the corresponding animation, allowing for clarity and simplicity in the event sheet. Furthermore, you have access to the frames of the current animation/state and can trigger some logic at a certain frame inside the animation.</note>
  
 {{ :gdevelop5:tutorials:main_events_state-linking.png?600 |}} {{ :gdevelop5:tutorials:main_events_state-linking.png?600 |}}
 ===== Debugging information ===== ===== Debugging information =====
-In order to determine in which state the player currently is we will add a text object and call it “debug_state”. Add it to the main scene and create the following logic at the end of main scenes logic list in order to display the current player state right above it'head for debugging purposesSo whenever something doesn't function the way we want we will always know in which state we have to look for the error.+In order to know in which state the player currently is during gameplay, create a text object and call it “debug_state”. Add it to the main scene and create the actions as below (with an empty condition), in order to display the current player state right above its head. Whenever something doesn't function the way it should, we will know which state we have to investigate to find the error.
  
 {{ :gdevelop5:tutorials:main_events_debug.png?600 |}} {{ :gdevelop5:tutorials:main_events_debug.png?600 |}}