-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add timeout conditions #41
base: master
Are you sure you want to change the base?
Conversation
I'll look into the error. I was getting it earlier, but I thought that I had fixed it. Sorry about that! I don't understand your comments about Equally, it also has no associated comparator, because the only comparators that make sense in context are So the reason I didn't make it a |
Ah, I see. It only works in my test case because I have a parameter changing every update. Give me a few days to think about this. My inclination is to put timeout conditions in an array, then have a separate method to check state timeouts. May I ask why conditions are currently stored as a dictionary, keyed on the parameter? |
The data structure of state machine was designed this way for the sake of intuitive, based on the relationship between data: var state_machine = state_machine_player.state_machine
var state = state_machine.states[state_name] # keyed by state name
var transition = state_machine.transitions[from][to] # keyed by state name transition from/to
var condition = transition.conditions[condition_name] # keyed by condition name The conditions are actually keyed by Condition.name. I guess the impression that conditions are keyed by parameter is mainly because of ValueCondition where parameter is used as the name of condition. In fact, gd-YAFSM has no concept of "parameter", a parameter is nothing but a identifier for the value passed to the state machine. |
Hi, sorry for the delay. I've thought about this a little now, and I think the timeout transition might be the wrong approach. The Instead of timeout transitions, what if there was a mechanism where parameters could automatically pull their values from variables on other nodes. For example, what if a parameter named set_param("$Character:walk", $Character.walk) Or more generally: if param_name.begins_with("$"):
var node_path = param_name.trim_prefix("$")
match get_node_and_resource(node_path):
[_, _, null]:
pass # node with no variable index
[var node, null, var index]:
set_param(param_name, node.get_indexed(index))
[_, var resource, var index]:
set_param(param_name, resource.get_indexed(index)) This way a timeout transition could be written as a float condition named |
The idea sounds really cool, but I don't think it fits well as an alternative solution to timeout condition, I thinks it's more related to expression condition #31 The original idea of adding a timeout is really simple yet powerful, for example in the case of gd-YAFSM demo, developer can replace I think we both somehow over-engineer the solution, I just realized we can just add a "delay" property to Transition.gd
tool
extends Resource
signal condition_added(condition)
signal condition_removed(condition)
export(String) var from # Name of state transiting from
export(String) var to # Name of state transiting to
export(Dictionary) var conditions setget ,get_conditions # Conditions to transit successfuly, keyed by Condition.name
export(int) var priority = 0 # Higher the number, higher the priority
export(float) var delay = 0
... |
A delay property is an interesting idea, but how do you envision transitions working if the user only needs a timeout, and doesn't need the associated condition check? |
Okay, but what happens if I want a transition with just a delay, and no associated parameter comparison? For example, what if I want a "dash" state to always transition back to "idle" after 0.1 seconds? |
Just use a transition without any conditions and set delay to 0.1s |
Oh, I see! I had it in my head that a transition required at least one condition, but that was a dumb assumption for me to make :) Adding a delay to the transition seems like a good idea. It would certainly solve my problem, and I can also see how it would be useful when combined with other conditions (like |
Just wondering what is the status of this PR? Thanks! |
This closes #40, though there are some rough edges in the implementation.
First, timeout conditions don't have an associated parameter, so the name of the condition will just be the randomly assigned default.
Second, I added in a clause in
TransitionLine
to handle the label for timeout conditions, but it might be better to refactor this to make use of thedisplay_string
method on theCondition
objects instead. As far as I can see, the label formatting inTransitionLine
mimics the output fromdisplay_string
, except for triggers.Finally, I use a
_time_in_state
float to record the time that the state machine has spent in the current state, incrementing it at each update. I think this is reasonable compared to just taking a timestamp, as it gives a consistant time per update.