Issue with "real" attribute
SpriteLeaf
Member Posts: 4
I have a game in which cannonballs are firing at a castle wall and you need to tap on them to blow them up and protect the castle. Simple enough, right? Have a look at my set of rules for the spawn cannonball actor. I used a test actor with display text to ensure that the "Spawn Speed" real attribute was subtracting properly every 5 seconds, which it was. However, the second timer in the ruleset, which is supposed to spawn the cannon balls every amount of seconds specified by the Spawn Speed real attribute, doesn't change. It always spawns it at the default speed which is set to 1 second. Why isn't it changing to spawning every 0.8 seconds, 0.6 seconds, etc, like it should?
Comments
Yes, this is "one of those things" ... if you update a global attribute that is used within an every timer like you have there then the actor that is on the scene already will not use the updated global value.
You can solve it by destroying and respawning the actor that use that timer (when it's spawned after you have updated your global value that the timer use, then it will work)
Which is why I built this: http://forums.gamesalad.com/discussion/comment/464547/#Comment_464547.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
@tatiang nice one
Thanks!
Would you consider this a bug with a workaround, or is this just how the software works?
@JayCrafton I would not call it a bug. I think it's the intended behavior even though to you and me it seems to not make sense. So yes, it's a workaround of sorts.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
I'd say it was simply the way the software works, in fact to me the idea of using 'every' with a changing value makes no sense logically (or even in English).
I think of it like this, a shop claims to open every Saturday . . . so you visit on Saturday only to find the shop is shut, when you phone up the owner he says "yes, we are open every Saturday during the first week, then every Thursday the next week, then every Monday for the next week (etc)"
Which, of course doesn't make much sense, and to me 'every [changing value]' makes just as little sense logically as 'every' means all instances of a set, but the requirement in something like every (random) seconds is to only use the generated value once rather than every time.
GameSalad does what it says it does, it uses the value it finds in the expression field every time. Hope that makes sense.
In this case I disagree with you. We are not telling GS to do something just "every" time but "every x" time and "x" can change based on other conditions.
Let's modify your example with the shop. A shop opens every Saturday during January-July but is then closed every other Saturday for a Month because the store owner is overworked and needs some vacation Now the opening times would realistically be formulated in a more suitable way but my point being is that the "every" condition in fact changes
An example from a potential situation in a game:
change attribute game.SpawnTimer to 1
timer every SpawnTimer seconds spawn actor BadassEnemy
When score is 10 then change attribute SpawnTimer to 0.8
when score is 20 then change attribute SpawnTimer to 0.5
when score is 30 then change attribute SpawnTimer to 0.2
One way to workaround the issue is to destroy and respawn the actor that use the every-timer, that solution is ugly but it works. Even using a constrained attribute as a value for the every-timer does not help, only the first set value is being used in the timer. It would be better if the GS timer respected the fact that the attribute has been changed.
'x' can change, but 'every' can't !
'Every' means all the units in a set, the logic is saying I want 'all' ('every') cycle to do x, in that context it makes little sense that 'x' is then variable as this negates the whole idea of 'every', and as we see this is empirically this the case, in situations when the timer is set up like this.
In the same way we could say Change Attribute X to Y (where Y is a changing variable), the behaviour will only take the state of Y at the time the behaviour is triggered and copy it to X, it won't continually track Y, the same is true of the timer, the logic (and to me the language) is setting up a process that reads the value at the time it's triggered and then uses that value for every cycle of the timer.
It just doesn't make much sense to me (in language) to have a series of changing values (increasing, decreasing, random or otherwise) that only happen once prefixed with 'every' . . . so in a situation where a random number generator throws out 7, 3, 5, 11, 9, 3, 3, 2, 6 . . . you would seem to be saying every 7 seconds do X, then every 3 seconds do X, then every 5 seconds do X, then every 11 seconds do X . . . etc, yet nothing is done every 7 seconds (or 3 or 5 or 11 . . . ), these processes happen just once.
But, very simply, what you've described is not every Saturday, it's just a variation on my random shop opening days, where every is used to point to all the members of a set (Saturdays), itself a variation on 'every random seconds', the first condition is being contradicted by the second, it seems to be a category error, to me at least.
That's how I normally do it, it doesn't seem too ugly to me, this would be the Spawner Actor:
Change game.X to random value/changing value (etc)
Timer After X seconds
Spawn the thing you want spawning
Destroy
Spawn Spawner Actor.
It wouldn't make sense to me logically . . . . but would be useful !
Yeah, so we have solved it in the same way then
There are lot's of things in the world that makes no sense but that is part of what make things interesting
Absolutely!
Yeah, basically, although I don't use 'every' for a set of changing values, I use 'after', which seems to make more sense to me. If the value is going to change it seems wrong (to me!) to choose a method that is set up to repeat a value ('every').
This is an instance where using selftime is a better option for ajusting on the fly.
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
Not sure that I understand you correctly, given the example below, how would you solve it then?
We have a global value that changes how often enemies spawn within a certain score range
initial value of game.SpawnTimer=1
timer every SpawnTimer seconds spawn actor BadassEnemy
When score is above or equal to 10 then change attribute SpawnTimer to 0.8
when score is above or equal to 20 then change attribute SpawnTimer to 0.5
when score is above or equal to 30 then change attribute SpawnTimer to 0.2
(only one timer is needed but must destroy and respawn for the GS timer to recognize the changed value of SpawnTimer)
And I will strike down upon thee with great greenpeace and furious broccoli those who attempt to poison and destroy my brothers.
Change game.SpawnTimer to new value (based on your particular rules)
Timer
--After SpawnTimer seconds
----Spawn the thing you want spawning
----Destroy
----Spawn Spawner Actor.
ok I see but if the GS timer would have recognized that we had changed the attribute that is in use for the timer then there would be no need for destroy and respawn in this situation.
A timer resets the every x whenever the rule it's in changes condition. Why the need to destroy them, even if you want to avoid using self.Time?
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
Because if you change x after the timer is in action and then want the timer to use your updated x value then it will not do so
Yes it will.
Using self.Time as @tatiang and @The_Gamesalad_Guru suggested is more accurate, though, than either what I show there or destroying the actor.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
Why the resistance to using self.time? It's the most precise and efficient method in this application. (Scratching my head)
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
Agree completely. It gives more flexibility, faster response, and more precision.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
Nobody has said otherwise so you can stop scratching your heads now
Neither Socks or me has any problems with this, we were just debating how the GS timer works / should work.
That's great and all but I'm sure this poor user is confused by now...lol
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
And I'm afraid I'm with @Socks. The timer does what you tell it to, until you tell it to stop. At that point you can tell it to do something else (as per my image).
I'd argue if you're destroying and re=spawning actors, though, that's a problem. One easily avoided in at least two different ways!
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
maybe looking like this by now
Agreed, but that's not how 'every' works !
Yep ! I've no issue with self.time, I use it all the time
All he wanted was to fire some cannonballs at a castle but he got a broccoli Samuel L Jackson and a journey into the dark side of GameSalad's timer behaviour.