Key-up conditions not correctly detected in Any rule
thebitmaster
PRO Posts: 75
If I create one Any Rule with several conditions, each of which is the detection of a Key Up event, the rule no longer fires after I add the second event. This would be correct for the All Rule, but not for the Any. If I create four separate rules for each separate key-up event, it works fine. They *should* be equivalent. Anyone know why they might not be?
I'm seeing this with 0.9.88 beta.
I'm seeing this with 0.9.88 beta.
Comments
computer constantly √s user input … it has done what you asked for with the first/second/third/fourth condition of the Any Rule …
your second condition was true …
Key state was up … condition was valid … performed that action … now waiting for another event to re-access those conditions.
(i.e. Key is Down … waiting for Key to be Up : then √ the conditions again)
alas, computers only do as directed, when directed; and don't repeat a direction unless told to do so by the program or user input.
MH
The project I submitted has all the details, but it's not visible here.
Here's the simple case that works
Any Rule
- if key UP is released
then stop moving
This version works. However, if I have all four arrow keys in the decision list for the Any Rule, it *never* fires no matter how often any of those keys is released:
Any Rule
- if key UP is released
- if key DOWN is released
- if key RIGHT is released
- if key LEFT is released
then stop moving
The actor never stops moving.
If I make four completely separate rules like the first one above, then it works, but it shouldn't be necessary. The Any Rule with all four conditions should detect *any* of those conditions *whenever* it occurs, and fire.
think these rules should be part of the rules that initiate the event (movement)
On your moving Actor:
===
Group: Y axis
Rule:
when key Up is down
changeAttribute [exp] self. Motion.linear velocity.Y To: 200 (the positive # for your speed)
Otherwise:
changeAttribute [exp] self. Motion.linear velocity.Y To: 0
Rule: for Down key is virtually the same except the speed is - (negative)
===
Group: X axis
Rule:
when key Right is down
changeAttribute [exp] self. Motion.linear velocity.X To: 200 (the positive # for your speed)
Otherwise:
changeAttribute [exp] self. Motion.linear velocity.X To: 0
Rule: for Left key is virtually the same except the speed is - (negative)
===
it takes less time in to create these Rules in GS than for me to type them in this comment
try to think of how the computers reads your directions …
MH
However, the fact that the simpler case in my second post above *does* work indicates that GS *does* detect both the transition from Up (understood to be the default) to Down, *and* from Down to Up, because that isolated rule that does nothing but detect the Key Up event fires correctly when there is only one condition to the rule. Add a second condition for another key, however, and with no other changes, the rule never fires again. It's the *why* of that truth that I'm trying to understand, and so far I haven't been able to glean an explanation from your otherwise helpful replies. It has something to do with the actually fairly complicated way that rule evaluation collides with keyboard input that isn't obvious from the docs. I *do* recall reading something, possibly in the update report of a new release, saying that with complex decision structures, if one value changes and the rule fires once, the other conditions might not be re-evaluated until the first value changes back again. Although it appears that the rule *never* fires in my case, it might be something similar going on here.
Thanks for sticking with me on this one!
we tend to consider computers as thinking machines… when they are processing machines … think CPU!
Computers are logical; literal; linear … all input is processed with the values of Boolean algebra …
which you do understand adequately to program! 'Any' conditions structures are processed in linear flow (condition1; then condition2; then condition3; …)
if condition1 is false (0; gate closed), the computer will process condition2.
if a condition is true (1)… the gate is open and the computer will cease processing the conditions and move on to processing the actions/events you call for.
re: "firing of rules" …
my thoughts are: in your AnyRule, the computer does not process a default condition unless the state of the key has changed from the default.
this functionality is not just in GS, but in all programming. (well, except in dynamic-programming, which none of us want to think about!)
MH
It's also worth noting that there is a very simple reproducible case for this in the hands of tech support that saves a lot of this tedious "trying to describe in written language the nit-piggly details of a specific situation in GS".
The issue is here related to the time-bound nature of GameSalad, and the real question is *when* is a previously evaluated Rule evaluated again? I *was* mistaken earlier when I said that the rule with the four conditions wasn't firing it all. As you stated, it *was* firing, by default, as soon as the program started to run. I verified this by changing the initial velocity of the actor to a non-zero value, and, sure enough, as soon as the game starts, the actor stops moving, meaning that rule fired one time.
The real question here is "why is an identical rule with only one condition continuously re-evaluated when the same rule type of rule with multiple conditions isn't?"
I have both actors on the screen at the same time. In the case of the one coded with all the key-up events in separate rules, the actor stops moving the instant one lets up on the keys. The same would be true, I'm guessing, of an actor using the method you suggested. It's also important to note that these rules are *not* inside a timer of any kind, I am counting on the GS engine to re-evaluate them as the events are received. This is the assumption that is breaking down in the case of the multiple-condition Any Rule in question. The actor that uses that Rule only stops once, as soon as the program is started, and never stops again, meaning that the rule is never evaluated again. So I decided to try putting that decision into a timer, and that "fixed" the problem. Putting it inside a timer evidently forces re-evaluation on every iteration, and the actor stops when I let go of the keys.
A better way to narrow this discussion is to create an even simpler, completely unambiguous reproducible case without the need for an accompanying project, which is what I'm doing now.
For Example:
"Any Rule
- if key UP is released
- if key DOWN is released
- if key RIGHT is released
- if key LEFT is released
then stop moving"
The only way this would work is for all the buttons to be down at all times then one is released. Once one is released the conditions are valid and the rule will not trigger again until all conditions become invalid again. I would recommend (and sorry if Motherhoose already covered this) Coding it like this.
When Up is Down
-Move Up
--Otherwise
---When Down is Down
----Move Down
-----Otherwise
------When Right is Down
-------Move Right
--------Otherwise
---------When Left is Down
----------Move Left
-----------OtherWise
------------Stop Movement
This will only allow one movement at a time and the way otherwises work it stops reading the rules below once a condition becomes valid. Then once invalid it goes back to checking for all of them.
Thanks for helping!
So what you're saying is that the Any rule will not fire again until *all* of the rules are false again? I seemed to recall reading something like that, maybe in the release notes, and it's exactly what I was looking for. It seems like something GS support should have been able to tell me almost immediately. I'll look at the situation again in light of this info and see if that is, in fact the source of the problem.