A ton of spawner issues and questions

edited November 2011 in Help request
Hello iarwain! With javierely1 posting, all 3 members of our team are present on this forum, which is awesome. Anyway, I have some questions about the spawner.

First off, in the code, my team has created spawners that spawn enemies; "enemy waves" to be precise. Those enemies all have spawners - "bullets" - that are bound to them. Both have wave sizes. But enemy waves are not bound to an object, and thus does not fire off automatically (which is what we want).

Now, that timer we asked about is simply supposed to call a function (StartEnemyWave). This function creates a new spawner from config every time it's called. It uses the same configuration section for enemy waves that move the same way. Since the spawner has a wave size, I assumed that it would fire off its wave on creation. But it didn't.

So we tried enabling it. Nothing happened.

So we tried using the spawn command, passing it the spawner's wave size. It only spawned one enemy per wave, because the wave size is 1.

How do we get this spawner that is being instanced in code to behave as if it was started automatically? (the bullet spawner, which is being created automatically, has a wave size of 1, a delay of 0.4, and a TotalObject size 10. It shoots 10 bullets. The enemy waves have the same stuff, but if we use orxSpawner_Enable, nothing happens, and if we use orxSpawner_Spawn, we get one enemy in stead of TotalObject (currently 3) enemies.)

Also, there seems to be slight synchronization issues with the spawners. If we have two set to go off at the same time, they seem to be one frame off (one bullet that should be on the same y coordinate as another is off by a pixel or two). Is there a way to get them to actually process at the same time? Could it just be that the first one is encurring some loading time? If that's the case, how can we preload the graphics to prevent that from happening?

Finally, I have one other question. Is it possible to fine-grain spawner control? Like, could we have one spawner fire bullets in three specified directions at the same time? Can one spawner fire bullets in a circular pattern around itself? How much coding time and game performance difference would there be if we didn't use spawners, and created all of the objects ourselves?

That was a lot to ask in one post, and a lot of information to take in. If you need more clarification , let me know.

Comments

  • edited November 2011
    sonicbhoc wrote:
    Hello iarwain! With javierely1 posting, all 3 members of our team are present on this forum, which is awesome. Anyway, I have some questions about the spawner.

    Hi, nice to have you all around here!
    First off, in the code, my team has created spawners that spawn enemies; "enemy waves" to be precise. Those enemies all have spawners - "bullets" - that are bound to them. Both have wave sizes. But enemy waves are not bound to an object, and thus does not fire off automatically (which is what we want).

    Now, that timer we asked about is simply supposed to call a function (StartEnemyWave). This function creates a new spawner from config every time it's called. It uses the same configuration section for enemy waves that move the same way. Since the spawner has a wave size, I assumed that it would fire off its wave on creation. But it didn't.

    Wave control only works for spawners that are linked to an object. What you have to do is, instead of creating the spawner directly, simply create an object that only contains your spawner.[/quote]

    So we tried enabling it. Nothing happened.

    So we tried using the spawn command, passing it the spawner's wave size. It only spawned one enemy per wave, because the wave size is 1.[/quote]

    Yes, the Spawn function is what is internally called when managing a spawner bound to an object.
    How do we get this spawner that is being instanced in code to behave as if it was started automatically? (the bullet spawner, which is being created automatically, has a wave size of 1, a delay of 0.4, and a TotalObject size 10. It shoots 10 bullets. The enemy waves have the same stuff, but if we use orxSpawner_Enable, nothing happens, and if we use orxSpawner_Spawn, we get one enemy in stead of TotalObject (currently 3) enemies.)

    As I said, simply create an object that contains your spawner. Something like:
    In config:
    
    [MySpawner]
    ...
    
    [MySpawnerHolder]
    Spawner = MySpawner
    
    In code:
    
    orxObject_CreateFromConfig("MySpawnerHolder");
    
    Also, there seems to be slight synchronization issues with the spawners. If we have two set to go off at the same time, they seem to be one frame off (one bullet that should be on the same y coordinate as another is off by a pixel or two). Is there a way to get them to actually process at the same time? Could it just be that the first one is encurring some loading time? If that's the case, how can we preload the graphics to prevent that from happening?

    Mmh, interesting. On which platform have you tried? There's no asynchronous loading except on Android. So, as long as your spawners have the same creation time and all share the same wave values, you should have everything perfectly synced.
    However, if you want to prevent possible hitches when textures are loaded for the first time, you can easily pre-load them.

    For that you simply need to call orxTexture_CreateFromFile("NameOfYourTexture"). When you don't want to hold it in memory anymore, call orxTexture_Delete() on it. If the texture is still used by other objects, it'll stay in memory as long as there's no object using it anymore and will be unloaded after the last reference has been removed.
    Finally, I have one other question. Is it possible to fine-grain spawner control? Like, could we have one spawner fire bullets in three specified directions at the same time? Can one spawner fire bullets in a circular pattern around itself? How much coding time and game performance difference would there be if we didn't use spawners, and created all of the objects ourselves?

    That was a lot to ask in one post, and a lot of information to take in. If you need more clarification , let me know.

    For simple patterns, like a spiral of bullets around the shooter, simply set an angular velocity on the object holding your spawner. If you want more complex things that cannot be emulated for a simple motion/FX motion, you have to listen to the spawner events. There are events to let you know a wave has started/finished or for every object spawner within a wave. From the event listener you have access to both the spawner and spawned object and can then apply whichever modifier you need.

    In the example of firing in 3 directions at the same time, I see two easy way of doing this:
    - Either you listen to the wave start event, init your angle, and on every spawn event you update your bullet trajectory + increment your angle.
    - or you can use the object hierarchy: the spawner spawns an empty object that has 3 children (ie. the bullets) with already preset relative angles. That empty object has a very short life time and will then be deleted soon while the bullets continue on their own. You can also cascade hierarchies of object with spawner to spawn multiple types of bullets in different patterns. You can easily do complex combinations to achieve your goal without having to write any modifying code or listen to the events.

    So basically, depending on your own preference, you can update your spawned objects in code by listening to events or by creating hierarchies of preset objects/spawners. The second one doesn't require any code unless you want to do some tracking or linking the spawned objects to any class of your own.
  • edited November 2011
    iarwain wrote:
    Wave control only works for spawners that are linked to an object. What you have to do is, instead of creating the spawner directly, simply create an object that only contains your spawner.
    So that's the secret. I knew it! Time to relay the good news to the team.
    iarwain wrote:
    Mmh, interesting. On which platform have you tried?
    Windows 7, MSVS2010.
    iarwain wrote:
    There's no asynchronous loading except on Android. So, as long as your spawners have the same creation time and all share the same wave values, you should have everything perfectly synced.
    However, if you want to prevent possible hitches when textures are loaded for the first time, you can easily pre-load them.
    Thanks. I was wondering that.
    iarwain wrote:
    If you want more complex things that cannot be emulated for a simple motion/FX motion, you have to listen to the spawner events. There are events to let you know a wave has started/finished or for every object spawner within a wave. From the event listener you have access to both the spawner and spawned object and can then apply whichever modifier you need.

    In the example of firing in 3 directions at the same time, I see two easy way of doing this:
    - Either you listen to the wave start event, init your angle, and on every spawn event you update your bullet trajectory + increment your angle.
    That sounds easy enough.
    iarwain wrote:
    - or you can use the object hierarchy: the spawner spawns an empty object that has 3 children (ie. the bullets) with already preset relative angles. That empty object has a very short life time and will then be deleted soon while the bullets continue on their own. You can also cascade hierarchies of object with spawner to spawn multiple types of bullets in different patterns. You can easily do complex combinations to achieve your goal without having to write any modifying code or listen to the events.
    I never thought of doing it that way. It seems a little bit odd to do it that way, though.

    Thanks for you help!
  • edited November 2011
    The synchronization problem we encountered happened when we used AddTimer to add 2 events that we want to happen at the same time. I don't have any problem adding to a list of things that need to happen upon a single timer event (instead of adding mutliple timers for the same point in time), which is probably more efficient in the long run. What do you suggest?

    As for the spawner, I'm seriously considering coding my own solution, which would give us a higher degree of flexibility in our bullet patterns. By letting us directly convert a quadratic formula to a table of coordinates over time, We can transform (scale, translate, rotate) the path's values read from the table relative to their spawn point or even change any property of the bullet at will (graphic with body, bullet size, etc...). Given the freedom this custom solution would provide wihout any performance loss from what I can see, what are your thoughts regarding usage of the built-in spawner versus my custom solution?
  • edited November 2011
    Yoder wrote:
    The synchronization problem we encountered happened when we used AddTimer to add 2 events that we want to happen at the same time. I don't have any problem adding to a list of things that need to happen upon a single timer event (instead of adding mutliple timers for the same point in time), which is probably more efficient in the long run. What do you suggest?

    Well it's hard for me to advise you on this as I don't know what architecture you chose.
    I know that if I were to make a scrolling shmup, I'd define some kind of sequencer and would create the spawner(s) when hitting the corresponding sequence. I don't think I'd need to use AddTimer() at all in order to do so.
    As for the spawner, I'm seriously considering coding my own solution, which would give us a higher degree of flexibility in our bullet patterns. By letting us directly convert a quadratic formula to a table of coordinates over time, We can transform (scale, translate, rotate) the path's values read from the table relative to their spawn point or even change any property of the bullet at will (graphic with body, bullet size, etc...). Given the freedom this custom solution would provide wihout any performance loss from what I can see, what are your thoughts regarding usage of the built-in spawner versus my custom solution?

    Sure, though they are not incompatible. Spawners are there to spawn objects but you can still have your own class to control the projectiles themselves. A simple example in Mushroom Stew is that all projectiles are spawned via spawners but they have their own control code (ie. their own C++ class) to differentiate them (bullets, fire balls, lightning balls, homing missiles, ...).

    As for changing properties at will, isn't already what you can do with the config system?

    Anyway, you should go with whichever solution you feel is the easiest for you to deploy. I know how I'll write a shmup using spawners and FXs but that doesn't mean it's the solution the most adapted to everyone's need.
  • edited November 2011
    If I understand the way in which you are using the word "sequencer," I believe I am using the clock as a sequencer. I am curious as to how would you make a sequencer without relying upon some sort of timer/clock system.



    I understand that we could use a hybrid approach, but I still find the creation of multiple bullets simultaneously to be cumbersome no matter the approach (multiple spawners, event listening, container object). However, I think the solution to contain the enemy wave spawners in objects is sufficient for our needs.

    In mentioning the config system, do you refer to the ability to load another *.ini file to overwrite certain properties' values?

    I'll be coding and testing my solution during college winter vacation. I won't come to a definitive conclusion until I have tried out the various means.
  • edited November 2011
    Yoder wrote:
    If I understand the way in which you are using the word "sequencer," I believe I am using the clock as a sequencer. I am curious as to how would you make a sequencer without relying upon some sort of timer/clock system.

    That's basically what it is. All you need is a list of event + time stamps and the current time. Everytime your time cursor triggers new event, you create the corresponding objects.
    I understand that we could use a hybrid approach, but I still find the creation of multiple bullets simultaneously to be cumbersome no matter the approach (multiple spawners, event listening, container object). However, I think the solution to contain the enemy wave spawners in objects is sufficient for our needs.

    The goal is for you to feel happy and comfortable with your code. I was simply explaining how *I* would do it. And that solution is adapted to me but sounds probably tedious or inadapted to others. When I can I try to write as little code as possible and have everything data driven, ie. everything defined in config in this case.
    In mentioning the config system, do you refer to the ability to load another *.ini file to overwrite certain properties' values?
    Not directly, though that's a valid point. I wanted to express the fact you can define all the properties (scale, rotation, ...) in config, whether it's hand edited or modified at runtime from code.
    I'll be coding and testing my solution during college winter vacation. I won't come to a definitive conclusion until I have tried out the various means.

    Looking forward to seeing what you come up with.
  • edited November 2011
    Okay, so we were thinking the same thing.

    I understand that that was your approach; I was merely explaining my reasoning. :)

    We will be using the config system to make the changes to the bullets at runtime. I wasn't aware that "config system" could refer to that aspect of orx as well.

    Thanks for the encouragement!
Sign In or Register to comment.