Score check bug?
So this is a strange one... Maybe there's a simple answer but I can't seem to wrap my head around it.
Attached is a demo file that has two actors with simple rules. Pressing the 1 or 2 key adds 50 points for each key press to game.score. Pressing the 3 or 4 key does the same. The only difference is that the rules for 1 & 2 are in a separate actor whereas the rules for 3 & 4 are in the same actor as the rule that checks to see if the score has changed.
The problem/bug is that if you press the 3 & 4 keys together, the score increases by 100 points and both attributes are updated each time to be equal to each other. But, if you press the 1 & 2 keys together, the score increases by 100 and very quickly the attributes become unequal. The score checking rule then stops firing.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Comments
If you put the key 1/2 in the 3/4 actor theres no issue works perfect. but putting 3/4 in 1/2 still same issue, humm.
So seems the issue is the self.score # game.score it's not keeping up if you put that rule in a timer every 0.01 seconds it works, it's almost like theres a break between the two actors a frame miss or something,humm.
So putting that rule in a made timer also works, So I guess for what ever reason the rule that checks the self score against game score can't keep up or it's keeping up to well which cause a match and it stops working,if that makes sense.
@BBEnk thanks for your attempts at figuring this out. I should add that it's a bug that @Socks discovered... he and I were trying to resolve it but I thought more minds might help.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Did you try rearranging their order in the layers? Put the checker first in the code order and layer order.
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
instead of:
if self.score =/= game.score
'change attribute' self.score check to game.score
try
if self.score =/= game.score
'constrain attribute' self.score check to game.score
hey presto! You can now button mash 1,2,3,4 till the cows come home without error
Great observation! Constrain is always better for stuff like this.
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
Cheers for the input BBEnk, yes a timer will make it work, but the goal is actually to avoid using a timer or constrain or anything more taxing that a simple one shot change attribute behaviour (in fact this whole thing is essentially a replacement for a bunch of constrain behaviours)
Layer order doesn't seem to be the issue, but it was one the things tried and didn't seem to make a difference.
Yes, constrain will work (as will a timer or a delay of some kind), but unfortunately the whole aim here is to get rid of ten constrain behaviours which are making the project sluggish - replacing them with Change attributes instead (like in tatiang's project above) does the trick, it changes the game speed from 50-55fps back up to full speed at 60fps.
But . . . after a while it stops working.
For context, I am using a custom font with ten digits (1,000,000,000) and in the traditional (passed down through the generations of GameSalad elders ) method each individual numeral is constrained to the game's score, that's ten actors with constrain firing away full time - I wanted to replace the constrain behaviours with change attributes which are a lot less taxing as they only fire once when you tell them to.
. . . . . . . . . . . . . . . .
Although we didn't work out why the rule is behaving as it does a solution was found that avoids going back to using all those system draining Constrain behaviours. Instead of using this . . . .
if self.ScoreCheck is not equal to Game.Scrore . . .
then change self.ScoreCheck to Game.Scrore
. . . this solved the issue . . .
if self.ScoreCheck is not equal to Game.Scrore . . .
then change self.X to true . . . . otherwise change self.X to false
if self.X is true . . . then change self.ScoreCheck to Game.Scrore
Thanks to everyone for their input.
Looks like it's not so much a bug as one of those rare cases where order of execution actually matters. If you force the update of the self attribute to wait until after everything is finished in that cycle the problem vanishes.
This is also probably why your use of a boolean works - it forces the update of the self attribute to take place one "step" later.
I actually found a similar problem working on a similar alternative method for displaying a score, and this is how I fixed it.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
@Armelline said:
Yep, that's what I found too, a timer (or any sort of delay) sorted the problem out, so it probably is an order of execution thing like you say.
@Armelline said:
The traditional method seems very inefficient given that in a game, even a busy game, your score spends more time idle than it does increasing, even when your score jumps up every half a second the fact that it only take a fraction of a second to do so still means it's spending most of its time idle with a constrain whirling away in the background busy doing nothing most of the time except eating up processor power . . . and when you have a large digit score like 000,000 or even 000,000,000 it starts to impact on performance.
Did you try a loop instead of a rule?
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
I agree completely, and the only alternative I came up with involved the use of those 0 second timers. Since all they do is slightly delay the execution of the logic, rather than adding more conditions to evaluate, I think they're a better solution than using booleans, and a far far better solution than using any kind of every timer, or constrains.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
I'm going to download the file and try my hand at it. This seems a fun puzzle.
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
Until we get guaranteed order of execution across multiple actors, I'll be very very impressed if anyone comes up with a better fix for it I wish you luck!
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
Loop behavior works and it is at 60fps. @Armelline
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
But why use a loop that is firing constantly when there are far more processor efficient ways to do it? Once you've got 10 of those running on top of a full game, it'll be making a difference. Dropping constraints and replacing them with loops is entirely pointless.
Both the 0s timer delay and the boolean attribute solve the problem too with far less overhead.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
The loop will stop when satisfied so what happens is if there is a hiccup it will loop again making up for the minor blips and stop. If you see the code the only thing in the loop is the old score vs new. I would argue that it is less as you need no timer or Boolean and no rule just a loop behavior. I didn't see we were addressing the constrains for custom score. @Armelline
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
Remember a loop will stop if the conditions set for it are met. It only loops until they are not.
Plus in tests I did with @POM a while back we discover if you split loops into multiple actors the loop is way faster and less processor intensive. These tests were done doing large table searches a much more demanding application.
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
It will really depend on how GameSalad have implemented their loop behaviour, but I'd be extremely surprised if it was more efficient than the boolean or the 0s timer. Remember that a 0s timer isn't actually a timer - it's just delaying the execution of the logic contained within by the minimum time GS can manage. You might well be right though. Would be very interested to hear someone familiar with the low-level workings of GameSalad weigh in on this.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
As I reiterated, a loop will stop that is why it has conditions like a rule they work in a similar way in that regard but when the scan happens and the condition is not me it will loop until it is. This could happen in .06 of a second .09, .12 et... Most likely is it .06 on the second cycle. I'll have to do a search for the threads on the loop behavior someone did some tests and posted the results.
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
Here is one thread. http://forums.gamesalad.com/discussion/68317/loop-behavior-vs-constrain-behavior
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
I think ultimately it's swings and roundabouts. All three methods are presumably going to complete in the same number of code cycles.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
The zero timer will complete twice in a code cycle according to that thread. Not sure if that's good or bad. I could go either way with that. But you must admit, I did slim the code...lol
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
added a simple self.check Boolean to rule and having a second condition seems to keep it together.