Issue with "real" attribute

SpriteLeafSpriteLeaf Member Posts: 4
edited July 2015 in Tech Support

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

  • JSprojectJSproject Member Posts: 730

    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)

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • JSprojectJSproject Member Posts: 730

    @tatiang nice one :)

  • SpriteLeafSpriteLeaf Member Posts: 4

    Would you consider this a bug with a workaround, or is this just how the software works?

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949

    @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

  • SocksSocks London, UK.Member Posts: 12,822
    edited July 2015

    @JayCrafton said:
    Would you consider this a bug with a workaround, or is this just how the software works?

    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.

  • JSprojectJSproject Member Posts: 730

    @Socks said:
    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.

  • SocksSocks London, UK.Member Posts: 12,822
    edited July 2015

    @JSproject said:
    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.

    'x' can change, but 'every' can't ! :smile:

    '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.

    @JSproject said:
    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 :)

    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.

    @JSproject said:
    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.

    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.

    @JSproject said:
    It would be better if the GS timer respected the fact that the attribute has been changed.

    It wouldn't make sense to me logically . . . . but would be useful ! :smile:

  • JSprojectJSproject Member Posts: 730
    edited July 2015

    @Socks said:
    That's how I normally do it...

    Yeah, so we have solved it in the same way then :)

    It wouldn't make sense to me logically . . . .

    There are lot's of things in the world that makes no sense but that is part of what make things interesting

    but would be useful !

    Absolutely!

  • SocksSocks London, UK.Member Posts: 12,822

    @JSproject said:
    Yeah, so we have solved it in the same way then :)

    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').

    @JSproject said:
    There are lot's of things in the world that makes no sense but that is part of what make things interesting

  • The_Gamesalad_GuruThe_Gamesalad_Guru Member Posts: 9,922

    This is an instance where using selftime is a better option for ajusting on the fly.

  • JSprojectJSproject Member Posts: 730

    @Socks said:
    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').

    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. :)

  • SocksSocks London, UK.Member Posts: 12,822
    edited July 2015

    @JSproject said:
    . . . given the example below, how would you solve it . . .

    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.

  • JSprojectJSproject Member Posts: 730

    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.

  • ArmellineArmelline Member, PRO Posts: 5,327

    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?

  • JSprojectJSproject Member Posts: 730

    @Armelline said:
    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?

    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

  • ArmellineArmelline Member, PRO Posts: 5,327

    @JSproject said:
    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.

  • The_Gamesalad_GuruThe_Gamesalad_Guru Member Posts: 9,922
    edited July 2015

    Why the resistance to using self.time? It's the most precise and efficient method in this application. (Scratching my head)

  • ArmellineArmelline Member, PRO Posts: 5,327

    @The_Gamesalad_Guru said:
    Why the resistance to using self.time? It's the most precise and efficient method in this application. (Scratching my head)

    Agree completely. It gives more flexibility, faster response, and more precision.

  • JSprojectJSproject Member Posts: 730

    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.

  • The_Gamesalad_GuruThe_Gamesalad_Guru Member Posts: 9,922

    @JSproject said:
    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

  • ArmellineArmelline Member, PRO Posts: 5,327

    @JSproject said:
    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.

    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!

  • JSprojectJSproject Member Posts: 730

    @The_Gamesalad_Guru said:
    That's great and all but I'm sure this poor user is confused by now...lol

    maybe looking like this by now

  • SocksSocks London, UK.Member Posts: 12,822
    edited July 2015

    @JSproject said:
    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.

    Agreed, but that's not how 'every' works ! :smiley: :wink:

  • SocksSocks London, UK.Member Posts: 12,822

    @JSproject said:
    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.

    Yep ! I've no issue with self.time, I use it all the time :smile:

  • SocksSocks London, UK.Member Posts: 12,822

    @The_Gamesalad_Guru said:
    That's great and all but I'm sure this poor user is confused by now...lol

    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.

Sign In or Register to comment.