loopier / animatron

Animatron for Godot 4.x <
MIT License
16 stars 1 forks source link

Use `/def`s in state machines #6

Open loopier opened 1 year ago

loopier commented 1 year ago

It's easy to create state machines with strings. If we use /def names as states in a state machine, it would make it easy to create state machines for commands -- we only had it for animations in ATv3. When changing states, we would call the new /def which would be the same as the new state name. There's a restriction, though: it would only accept commands with no arguments, so we'd need to create dedicated /defs.

For example, let's supose we have these /defs:

/def /dosomething ... blablalba
/def /dosomethingelse ... blablabla
/def /yetanotheraction ... blablabla

We could create a state machine with the /def names:

statemachine = {
  "/dosomething": ["/dosomethingelse"], // state 1
  "/dosomethingelse": ["/dosomething", "/dosomethingelse",  "/yetanotheraction"], // state 2
  "/yetanotheraction": ["/dosomethingelse", "/yetanotheraction"], // state 2
}

Then, on the /state/next call, we could update the state machine and call the corresponding `/def``:

// pseudo code
func next():
  currentState = statemachine[currentState].choose() // get a new random state based on the values in the array
  main.execute_command(currentState) // this would call a def, supposing there's such a method
totalgee commented 1 year ago

Okay, so this is just defining the state graph, there are no defined transition rules, you have to call next explicitly via OSC to make the next transition? (Just trying to clarify.)

loopier commented 1 year ago

I'm not sure what you mean by "transition rules". I tried to implement something similar to SuperCollider's Pfsm, where the current state executes, and the next is chosen from an array of possible states. This is what we had in ATv3 for animations (using animation names as states) and worked surprisingly well.

I guess the transition rule in this case is: choose any of the following. If we put any option more than once, it has higher probabilities to be the next one. Not the most elegant design, but it's simple and it works.

you have to call next explicitly via OSC to make the next transition?

In ATv3 it was called automatically when the animation was finished. And we could set any frame to be the last one. But this doesn't work for commands. The only way I could come up with, was calling next explicitly via OSC. It can be added at the end of any /def, or in a routine, or... I think we need to put it to work to see what we really need. In ATv3 I was happy with the animations state machines -- I think we should port it to ATv4 -- but I was lacking command state machines to create sequences of commands.

Any ideas on how this could be improved, or done?