End of Support Announcement (Oct 2nd, 2023)

As I've been taking a step back from Game Dev over the course of the last year, I've finally decided it's time to cease formal updates on my assets. They will now be free to use, but will receive no further features, bug fixes, or any changes at all. Enjoy them for as long as they continue to work in GM, and thanks for all the support over the years.

TrueState is a robust finite state machine to help you organize and control even the most complex of objects.  From something as simple as a door that can be open and closed, to the most complex action platforming hero, anything is possible with TrueState!


  • Easy-ish to use
  • Control any number of events from a single script resource
  • Always know how long you've been in any one state
  • Run code when a state starts or ends
  • State history provides easy access to previous states
  • Setup attack combos and special abilities easier than ever
  • Plus all the benefits of using a Finite State Machine in the first place, like more organized code and easier debugging

How to use

Check out the documentation in the link below for how to get started with TrueState!


Wall tile art created by @GrogDev you are free to use in your own game!  
Character art created by Rvos - https://rvros.itch.io/

Rated 5.0 out of 5 stars
(8 total ratings)
AuthorPixelated Pope
Made withGameMaker
Tagsfinite-state-machine, GameMaker, scripts


Download NowName your own price

Click download now to get access to the following files:

TrueState 3.1.yyz 408 kB
use_truestate.gml 4 kB

Development log

View all posts


Log in with itch.io to leave a comment.

(2 edits)

Thanks for making it "free" after all of these years. It's completely worth a donation if you're willing and able. We appreciate your contributions to the GameMaker community.

This is still an excellent way to structure a FSM in 2023 (and beyond).

(1 edit)

I am not a programming expert, there is something i am struggling for. How to avoid code repetition? For example: I need to write the move code in every state that involves movement. Gravity is another issue, i am repeating all gravity stuffs all over the states. Any advice ?


Yeah, that is one of the downsides of the State Machine pattern. Because each state fully encapsulates everything that object is doing in any one step, that means anything that is shared is duplicated.

I often write functions like "move_and_collide" which would handle gravity and collision and all that. These "helper functions" are defined globally and available in any state on any object. Sometimes I'll allow those functions to accept arguments such as "in this state the gravity is .2, where as in this state the gravity is .3" or have them return results such as "I've hit the ground or a wall" so that the state can react accordingly.

Hey, using truestate_draw_current(truestate_id,x,y) what is truestate_id or how do I find it? The manual only lists the last two arguments.

Hmm.  That may be a typo. You shouldn't need to pass the ID (which is normally the enum you use to define or switch to a state) since it should be drawing the "current" state. Sorry about the confusion.

(2 edits)

Hello sir, I recently purchased truestate of gm market place and I cannot get the lock switch to work when trying to break out of queues. The line I ran is "truestate_switch(States.I,true)" but when i run it through debugger the truestate_switch_locked evaluates to false. Is the syntax im using wrong

(2 edits)


Hello again, I don't know if the really fixed the problem, but i went into the truestate_switch script and alter the order of the if statements (Moved the last if statement to the top) as well as commented out the first "exit". THis seemed to work so far but i dont know if it will cause problems down the line. When you get the chance can you tell me if you find whats wrong with my queue statement? Thank you

Hmm, yeah... to be perfectly honest, the queue system is by far the least "exercised" part of TrueState.  I never found a good personal use for it (and was planning on removing it from TrueState 3), and I most definitely did not test it in conjunction with the lock system.  

I'd say if you got it to work, I'd be surprised if there was any real impact on other systems if you haven't already noticed them.

(1 edit)

Yeah, nothing is broken so I think it’s fine. I find the queue system to be very useful. I’m using them to perform the attack combos for my bosses. I’ve created a library of enums, incorporating movement at attack types, and put them in an array. Now I just pick a random attack combo from that list and have boss run through the states to perform said combo. This makes creating new “dark soul type” boss combo very easy (By just make an enumeration of the attack order you want and put it in the array). I would highly suggest keeping it as I find it to be the most exciting feature in the package. 

I should also thank you for the package and your web articles they have help me with my AI and game organization a lot.


Awesome!  Yeah, it's really exciting to know that at least someone is using that feature.  I'll definitely include it in the next version, and make sure it doesn't have the same issue you found here.

Hello your pixelated holyness

I'd like to try out TS+. I see the project file for a TS+ on 2.3.1 example. Is there also a package file and manual planned?

Probably not a manual, no.  And Truestate itself is just a single script these days, so there's really no need for a separate package file.
The reason I probably won't be releasing a manual is TrueState 3 is on the horizon, and with TS3 I intend to remove the choice between TrueState and TrueState+.  As that will be a change for basic TrueState, I'll be updating the manual and hopefully putting together a video tutorial series.  
If you do check out TS+ and have any questions, feel free to hit me up on Discord and I'll answer any questions when I'm available.

Some packes I've created for myslef depend on TrueState. Wanted to move them to TS2+ but I guess I'll just wait for TS3 then. Thanks a lot for this great library :)

truestate_switch seems to not work in YCC builds, while it works in VM builds, after updating to 2022.2

I am not using TrueState PLUS


Interesting...  Not sure why that would happen, but I'll look into it.  Thanks for bringing it to my attention.

(1 edit) (+1)

Okay.  Check your begin step event.
...do you have a "return" in there?
If so, get rid of it.

Yeah, that's totally my bad.  I have no idea why that is there.

I found that "return" and removed it. Now works fine again! Thank you!

I recently started a new project and I also imported the true state parent obj, because I found it handy. So the 2022.2 update is irrelevant to this case and it was just an assumption...

Thanks again!


No problem!  Let me know if you find any other issues.

(1 edit) (+2)

Excellent product!!!

If I may make a small suggestion? It is safe and won't break anything.

The debug text of truestate_draw_current is tiny and not readable on bigger resolution (and even worse in mobile development). It would be handy an additional scale argument:

Thank you for your time!


Yeah, I could probably do something like that.  Good suggestion.

Hello Your Spriteness,

I came back to you after extensively using Truestate (not Plus) and I have some question regarding the system.

1/ Why is it that when using `truestate_create_state` the function will trigger `truestate_set_default` ? On top of that `truestate_set_default`will execute the srcipt but, as I'm in the Create Event, I don't want any state's script to be executed.

There's case where it doesn't work. For exemple :

//playerSpawner Manager object
inst = instance_create_layer(x,y,"layer", obj_Player)
inst.PlayerID = 1 //or whatever value
//Player Object - player_state_init function
camera = instance_create_layer(x,y,"layer", obj_Camera)
camera.viewport = PlayerID

GMS will tell me that PlayerID is not set when it will try to assign `PlayerID` to the Camera's `viewport` variable. It's because `player_state_init` is fired when `truestate_create_state` is called in the Create Event of my new created obj_Player.

But I want `player_state_init` to be fired only when I switch to the Init state.

2/Related to 1/, I think `truestate_set_default` should be split in to distinct function : 

  • truestate_set_default : where the systeme will rollback to if no state are found
  • truestate_set_start : which will be the starting state of the object.

The starting state is usually not the one you want to be the default. For exemple, I would want to launch an "intro" state, like my character walking in screen, but I don't want this state to be the default one during gameplay.

So is it me who get it wrong ? is this a bug or a "flaw" in the system and how can I work around that without doing the Alarm trick ?

Thank you :D

Good question!

Yes so having it this way solves some issues, but as you've discovered, can cause some others depending on what you are doing in your state new block.

It actually used to work the way you described, with the set default being a separate function.

There are a lot of ways to work around this, but the way you suggested would be totally okay.  You have all the scripts, if you feel it should work differently from the way it does, go ahead and change it!  Rip the set default out of the create script and split it out to its own function.  And you can prevent the setting of the default from running the state new if you'd like and see if that simplifies things for you (though you may find it causes more problems)

Wonderful. I'm buying, it will be very useful for me. How much license can I use in commercial products?


You are free to use it in any commercial project!  Only limitation is reselling the system to other developers as your own work, which I feel should go without saying :D

I bought this asset over at yoyo marketplace, the version there is still in 2.0.0 will we get an update there? do I need to buy the asset here on itch to get access to the update? is there a way to link my purchase to itch?

I bought this today and I missed a detail from the manual, so I contacted @Pixelated Pope via discord. He replied very fast, he was kind and helpful! As soon as he clarified a crucial detail to me I realized how powerful this tool is. 

Thank you @Pixelated Pope for this powerful tool!

It's good Pope. It's GOOD.


Hello, Your Spriteness.

Do you plan to write an alternative version for GMS 2.3 users to adress all the changes of the engine ?

That's the plan, but I don't know exactly when I'm going to get around to it.  Fortunately, the system still works really well in 2.3 as it is (I'm currently using it in a 2.3 project without any modifications)

The biggest thing I'm taking advantage of right now is that all of my state scripts for a single object are in a single script resource, which is super awesome.  So my resource tree doesn't get nearly as bloated as it would have before.  If I wasn't lazy, I could combine all of the truestate system scripts into a single script resource as well, but I've got them all in a folder that I never open, so it's not that big of a deal.

Good to hear.

I was afraid that some of them would become those unreadable "compatibility script" GMS generate when you import stuff being obsolete.



Just looking for an advice.

Is it better to: 

a. keep one state script by script ressource.
b. make state as function and group them in one script ressources by character

I have one script resource per character with a function for each state in said script resource.
There is also another script resource with shared common state functions that all state code can access.


Hey Pope, 

I just purchased the package and ran the demo. For the platformer, I noticed that you can move right but you can't move left. Also if you are against the wall you can't move at all... I haven't touched or manipulated any code so I thought I'd just pass this along. Cheers.

Oh, sorry for the late reply, I don't know how I missed this comment. 

I just downloaded the latest yyz and tried it out and both demos seem to be working fine.  If you are still experiencing issues, hit me up on discord and we'll take a look.

I am having this same issue. No manipulation either. This and the slope collisions don't work in the demo.

Are you on a mac?  This seems to be related to keyboard input on Macs for some reason, and as I don't have a mac, there is no way for me to debug it.  And slope collision was never a promised feature of TrueState.

Ah. Sorry about slope confusion. I just saw the red slope objects in the resources.

I am on a Mac. I also can't figure out what is going. 

read_controls looks solid, state_ap_player_stand and state_ap_player_run and ap_move_player as well.

The weird thing is it is only run left and standard jump left. But the character will turn and move left if the down arrow/jump dash is used.

(1 edit)

I love this state machine! I did find two issues once I deleted the Top Down scripts and objects on the platformer.

"ai_vars=[0,AiState.stand,1,no_direction];" had to changed to "ai_vars=[0,AI.idle,1,no_direction];"

"ai_var[0] = 0;" had to be changed to "ai_vars[0] = 0;" for the AI to load. The AI character also cant turn left.

When I enabled "draw_text(x,y,string(dpad_dir));" on the Draw event for the Player the correct numbers appear for the directions (180, 0, 270, etc), but after moving or jumping it sets to -1. If I press left and down before jumping the character turn left before jumping but the number displayed when standing is also -1. Is the number being displayed the face_direction? If so that might be the problem.

The character will also move left after jumping (but not face left) if the left and down button are both pressed.

So -1 is the value of "no_direction".  So any held direction should be between 0-360, and if there is no held direction, I use -1.  If there are issues related to hitting multiple keys on the keyboard, make sure it isn't a keyboard ghosting issue (which is extremely common).  Any time 3+ keys are hit at the same time, there's a good chance only 2 of them are actually registering.  

Big time follower, first time purchaser

I was going to fumble through making may spaceship dodge and shoot, but everywhere I looke, peeps talking about FSM and that you were the Pope in charge of such things. Looking forward to learning this and finding ways to make it work in other projects. Thanks, and also thanks for keeping the pricing low and assets great, it helps peeps like me that have pinched pennies in half.

Deleted 3 years ago

Hmm, that's unusual.  Are you using the standard state_switch() or are you trying to use the queue system?  To be honest, the queue system hasn't been super well tested (not many people use it) so there may be some bugs with it.  If you'd like to reach out to me on Discord, I'd be happy to help.

Ayy, I'm an idiot. I did not see there was a "draw_gui_end" truestate call that moved the stack forward.

System works great! Sorry for not cleaning this comment up :P

Additionally, and not to be a bother- is there a way to contact you for questions with using true state? I have some questions regarding changing states in response to colliding events and stuff

Absolutely!  You are always welcome to ask me questions on Discord (that's just the easiest for me).  I also recommend joining the GM discord server if you aren't already a member.  It's a great place to get help with just about anything GM related!


When it jumps and attacks it stays in the air?




Downloaded and implemented in no time. Extremely well organized and very effective state system! I will be using for all my upcoming projects. Thanks so much Pixelated Pope!