So I've been making two enemies for my game and they've worked fine by themselves, but when I tried to run the game with two of them in my level, it freezes for around a half second whenever either of them change states. There's a few things that I think could be causing it but I'm not completely sure if any of them are the real issue. It could be caused by both enemies using the same state, but the game freezes when they're in different states too. It could also be that they're both trying to use the state machine at the same time, but I tried offsetting their timing and still had the issue. I'm pretty stumped, does anyone else know why this is happening? Here's a screenshot of how my state machine works.

    Camp
    @exports are shared between instances of the same scene, unless you set it in editor, but you can't change it in game.

    you are doing push_warning()
    why? just use print.
    and before doing this s**t I would set current_state to a static cast and do the same with everything else in the scene and test if things exist.

    current_state doesn't have a type. you are testing if current_state:. what do you think this will return? because not godot nor me would know.

    you don't need to test if state is State if you just set a parameter type:
    func change_state(state : State):

    anyways it feels like the problem is with the State class and not here.

    I changed everything you said in the state machine and made it much smaller, but this is all that's in my state class's script:

    Could the issue be that all the enemy states that extend state use super() for their ready, enter_state, and exit_state functions?
    EDIT: I was wrong, they do not use super(). However, this is leaving me super confused. I've also found out that the freezing doesn't happen when I have 2 of the same enemy. It only happens with 2 different enemies. Also, if I'm correct, if current_state: returns true if current_state has a value and false if it doesn't.

      Camp Don't use node based "state machines". It's clunky and a total overkill for a simple system like player/enemy controller.

      Put everything into one script and use flags and ifs. There, I said it 🙂 That's the easiest way to learn the basics of state management. Only when you're familiar with that and your system becomes too complex for handling via flags, then you can start thinking about more elaborate state management, employing dedicated state classes etc...

      Imho this type of non-hierarchical state machine often presented in beginner tutorials is confusing, bug prone and generally useless in real life. It's too unwieldy for simple several-state system, yet not flexible enough to manage complex state.

      • Camp replied to this.

        xyz I see what you're saying, but the main reason I'm using a state machine is to keep my code manageable and understandable, and to be able to reuse states. My player character was originally one big script but I decided it was becoming too large and unwieldy and remade it as a state machine. If there's a better way to have short/understandable code while keeping my code in one script I'll do that instead, but right now I'm using a state machine for those reasons.

        • xyz replied to this.

          Camp the main reason I'm using a state machine is to keep my code manageable and understandable

          Apparently you achieved the opposite of that; not being able to manage a bug due to not understanding the code 😃

          Camp Post a minimal reproduction project. Hard to debug from screenshots.

          • Camp replied to this.

            Camp have you stopped using exports?
            if these states are part of the statemachine, they would have to be children of the state machine and you can obtain them using a get_node()/$.

            and we still don't have enough information because you posted what appears to be the BASE class of a number of other classes that do who knows what. there's still a billion unknown variables.

            now, an idea: WHEN is change_state executed? all you've shown us the ready function, but claim that this problem happens WHEN changing state, meaning state is changed somewhere else.
            meaning you are running this thing multiple times per frame on some other script and that could be the problem. my guess.

            xyz I tried cutting everything I could from the project but the file was too big because of the massive size of the assets. The artist I'm working with uses blender and makes spritesheets from 2d frames of the animations they make and they say they can't make them smaller. When removing things, I did find out that the freezing only happens when the scene starts off with a pickup for some reason, so it only happens when there's two or more different enemies and any number of pickups. I have no idea why. Here's the script for the pickup:

            • xyz replied to this.

              Camp Well you can remove the assets completely, they're not relevant for the state machine functionality.

              • Camp replied to this.

                xyz I was trying to do this and then found out that if I delete the AnimatedSprite2D of the pickup or delete the sprites of the enemies, the freezing goes away. Maybe the issue is from animation instead of enemies changing state, but that doesn't explain why it only happens when there's two different enemies and a pickup, unless the issue is that the file sizes are too big and the engine chugs trying to animate them, but I don't think I'm even at the scale where that's possible yet, especially with only two enemies.

                • xyz replied to this.

                  Camp Well only remove the resources (images, textures etc...), not the nodes themselves.

                  If I delete the SpriteFrames resource from the pickup and keep the textures of both enemies, the game still freezes. If I delete the texture of one enemy and the SpriteFrames of the pickup or delete both enemies' textures and keep the SpriteFrames, it doesn't. I also tried deleting the player's texture and that also fixed the freezing.

                  • xyz replied to this.

                    Camp It doesn't matter what does what. If you want to get it looked at and the project is too big, first try to delete the .godot, if still too big delete all scenes except the relevant one, if still too big resize all the images to 1/16th of their size, or smaller. The point is to reduce the size of the project for posting.

                    • Camp replied to this.

                      xyz What I'm trying to say is that when I make the project smaller the bug stops. If I did resize the project, there would be no bug. This is why I think the freezing could be coming from the animations, not the state machine.

                      • xyz replied to this.

                        Camp Well then remove things one by one and the last thing you removed before it started working is likely the cause.

                        • Camp replied to this.

                          xyz I did that and I found that removing different things would make the bug stop. I'm thinking it has to do with the number of textures being loaded / the size of them?

                          • xyz replied to this.

                            Camp Use the profiler and debugger monitors to surveil what's happening with system resources at runtime.

                            • Camp replied to this.

                              xyz The process time seems to be what's causing the freezes, but what does that mean? I've never used the profiler before so I don't know what I should change.

                              • xyz replied to this.

                                Camp If you suspect the memory is getting eaten up then you need to look at monitors tab in the debugger. If you've never used profiler/monitors, then read about it in the docs. Those are essential tools.

                                • Camp replied to this.