Staredit Network > Forums > SC1 UMS Mapmaking Assistance > Topic: [SOLVED] Efficient create spawn trigger
[SOLVED] Efficient create spawn trigger
This topic is locked. You can no longer write replies here.
Sep 5 2011, 4:31 am
By: dolosus  

Sep 5 2011, 4:31 am dolosus Post #1



I'm making a game and for part of it whenever a player creates a building it spawns a certain units every 30 seconds. For example a player creates a spawning pool it makes 2 zerglings at the end of 30 seconds. So when a play makes two spawning pools it should make 4 zerglings. Now i can do this but i have to make 2 triggers, and that really becomes a problem when i want to allow a player to make 20 spawning pools because then i have to make 20 triggers. And 20 plus trigger for all the basic units, times 2 for both forces is a whole lot more then i want to make. Does anyone know a easier way for me to do this?



None.

Sep 5 2011, 4:39 am Lanthanide Post #2



Binary arithmetic.

You need to progressively count how many spawning pools the player has. Have triggers like this:
Current player commands at least 16 spawning pools & [other spawn conditions]
-> Give 16 spawning pools to Player 10
-> Create 32 zerglings for current player at 'spawn location'
-> Move location 'blah' to map revealer owned by current player at 'anywhere'

Current player commands at least 8 spawning pools & [other spawn conditions]
-> Give 8 spawning pools to Player 10
-> Create 16 zerglings for current player at 'spawn location'
-> Move location 'blah' to map revealer owned by current player at 'anywhere'

Current player commands at least 4 spawning pools & [other spawn conditions]
...

Current player commands at least 2 spawning pools & [other spawn conditions]
...

Current player commands at least 1 spawning pools & [other spawn conditions]
...

[other spawn conditions]
-> Give all spawning pools owned by Player 10 to Current Player


Now say the player has 11 spawning pools. The triggers for 8, 2 and 1 will run, spawning you a total of 22 zerglings. If the player owned 19 spawning pools then they'll get 32 + 4 + 2 = 38 zerglings.

The triggers here will spawn a maximum of 62 zerglings: (16 + 8 + 4 + 2 +1) * 2 = 62. Add another trigger for "commands 32 spawning pools" and you can spawn up to 126: (32 + 16 + 8 + 4 + 2 + 1) *2.

Note that the "move location 'blah' to map revealer owned by current player at 'anywhere'" is an action that achieves nothing, but this is REQUIRED for the triggers presented here to work. The reason is because Starcraft only updates unit ownership on unit kill/remove and location move actions, but does *not* update as a result of give actions. If you don't include this location movement, then if the player owned exactly 8 spawning pools, the first trigger will fire, and so will the 2nd one that checks for 4 spawning pools because it hasn't registered that you gave all 8 spawning pools to P10. It'll keep checking all the remaining triggers and you'll end up spawning 62 zerglings instead of the 16 you expected.

You can use any dummy location here, you could probably even use "move location 'anywhere' to map revealer owned by current player at 'anywhere'". Personally I just have a dummy location that I use for generic tasks for this.

This is the spawning system that I use in DS Night Fixed. So it *does* work.

Post has been edited 1 time(s), last time on Sep 5 2011, 6:27 am by Lanthanide.



None.

Sep 5 2011, 4:49 am dolosus Post #3



Ok so i'm having some trouble with this still
here are my triggers

player one commands at least 16 spawning pools, countdown timer is exactly 0 game seconds

give 16 spawning pools owned by player 1 at 'player 1 base' to player 10, create 32 zerglings at team' 1 spawn point' to current player, center location labeled 'location blah' on map revealer owned by current player at anywhere, preserve trigger

and also the ones lower then it in descending order and are the same except for 8 spawning pool 16 zerglings, 4 spawning pools ect...

the countdown timer is also working so i know its not that, but im unsure what else it could be

Post has been edited 1 time(s), last time on Sep 5 2011, 5:46 am by dolosus.



None.

Sep 5 2011, 6:20 am Azrael Post #4



You may be resetting the countdown timer before the trigger runs. It'll be hard to tell exactly what the problem is without the map.




Sep 5 2011, 6:26 am Lanthanide Post #5



You haven't said what trouble you're actually having, so it's difficult to suggest much.

I am assuming you're using hyper triggers.

My guess however is that you're getting more zerglings spawning than you expect. The thing to note is that the countdown timer stays on any 1 time for approx 8 trigger cycles when running hyper triggers. So you need this:

1. Spawn zerglings by giving pools to P10, as described above.
2. Give P10 pools back to P1.
3. Set countdown time to 30.

This means that visually the countdown timer will go from 1 second straight back up to 30, without the players see it sitting on 0:00. Note that if you have multiple human players in the game and you want them all to spawn, then you need to have the countdown timer set back to 30 for the last player in the game. In DS Night, player 8 is a CPU and always present in the game, so I just give all of these 'cleanup' type triggers to them to execute after all the players have spawned their units.



None.

Sep 5 2011, 9:35 pm Vrael Post #6



If you want all this spawned instantly (within 1 trigger cycle) by the way, you'll need at least 1 trigger per spawn. If instant spawning isnt a problem, then nevermind. This is assuming the units are being spawned at the spawning pools or something, if they're all being spawned in 1 place then the binary suggestion lanthanide made works fine.

Edit:
See lanthanide's post immediately below this one. His method reduces the amount of triggers that I claimed were necessary, as long as all the spawn buildings are of the same type.

Post has been edited 1 time(s), last time on Sep 6 2011, 1:42 am by Vrael.



None.

Sep 6 2011, 1:03 am Lanthanide Post #7



Not sure I follow your comment, Vrael.

If you want to spawn the zerglings immediately next to the spawning pools, you can still do this using binary arithmetic in a single spawning cycle.

If you have 8 spawning pools, instead of spawning the 16 zerglings in 1 set location, just do this:
-> Move location 'pool' on Spawning Pool owned by Current Player at Current Player Base
-> Give 1 spawning pool at 'pool' owned by Current Player to Player 10
-> Create 2 zerglings at 'pool' for Current Player
-> [repeat 7 more times]

Then do the same for 4, 2, 1 pools. Doing this will simply run into the 64 trigger action limit much more quickly than if you spawn the zerglings in a set location that doesn't move. But otherwise there's no issues with it. In fact you have to use triggers like this to handle add-on buildings, because you cannot give add-ons between players, you must give the base building and the add-on follows the new owner of the base building.



None.

Sep 6 2011, 1:47 am ubermctastic Post #8



when you run out of action slots you just copy the trigger with the highest number of actions enough times that the possibility of overflow is negligable.



None.

Sep 6 2011, 2:42 am Heinermann Post #9

SDE, BWAPI owner, hacker.

Quote from Lanthanide
Note that the "move location 'blah' to map revealer owned by current player at 'anywhere'" is an action that achieves nothing, but this is REQUIRED for the triggers presented here to work. The reason is because Starcraft only updates unit ownership on unit kill/remove and location move actions, but does *not* update as a result of give actions. If you don't include this location movement, then if the player owned exactly 8 spawning pools, the first trigger will fire, and so will the 2nd one that checks for 4 spawning pools because it hasn't registered that you gave all 8 spawning pools to P10. It'll keep checking all the remaining triggers and you'll end up spawning 62 zerglings instead of the 16 you expected.

I just had to verify this and... The ownership of the unit itself is correctly given immediately (including score, counts, supply, etc). However there is a unit count "copy", which makes this behaviour intentional.

There is a variable involved. It is first set to 0 as the trigger cycle begins. If this value is different than the value assigned by certain conditions then the count is updated.
  • Command, Command the Most, Command the Least, leaderboard sorting ---- Value is set to 1.
  • Bring, Command the Most At, Command the Least At, leaderboard sorting ---- Value is set to 2. Reset if location is different than previous call.
  • Move Location, Remove Unit, Remove Unit At, Kill Unit, Kill Unit At, Move Unit ---- Value is reset to 0.

The most efficient of these actions will probably be Move Unit.

Unrelated note: Using conditions and actions involving locations that are larger than 256x160 will perform faster than with smaller locations.

Post has been edited 1 time(s), last time on Sep 6 2011, 2:53 am by Heinermann.




Sep 6 2011, 3:06 am Lanthanide Post #10



That's useful Heinermann, thanks.

So you think Move Unit is more efficient than Move Location? Do you have to actually move an existing unit to a valid location? Can I, for example, move a terran marine that doesn't exist in a location that is outside of the map boundaries to another location outside the map boundaries to force this variable to be updated? Or must it be an existing real unit in a valid location?



None.

Sep 6 2011, 4:08 am Heinermann Post #11

SDE, BWAPI owner, hacker.

Yes a unit does not need to exist. You could use Cantina or something. Just make sure there are no units inside the location, otherwise they will be considered and then cycled through the unit type filter.
It will search for the unit inside the location bounds and take no action if it isn't found.

This is different from Move Location, which will search for the unit inside the location bounds and then still perform an action if it was not found.




Sep 6 2011, 3:29 pm NudeRaider Post #12

We can't explain the universe, just describe it; and we don't know whether our theories are true, we just know they're not wrong. >Harald Lesch

Without going into details of your specific error in the spawning triggers it might help to take a look at Desert Strike (it's not protected) which has a similar way of spawning units that you plan in your map. The main difference is that players take turns, which means there's always only 1 player per team (2 total) spawning which makes the spawning conditions a little more difficult, but if you take that out you've got a ready to go solution.

Here's a concept summary:
- * Countdown timer is at most 0____ ==>____ set switch 'Spawning'
- Switch 'Spawning' is set and Current Player owns at least 1 pool____ ==>____ give 1 pool for Current Player to P9 and create 2 lings
- Switch 'Spawning' is set and Current Player owns at most 0 pool____ ==>____ give all pool for P9 to Current Player and clear switch 'Spawning' and set CD timer to 30

So far the basic idea. This system is called cycling. You check buildings 1 by 1 and give them away to a temporary player so you know which buildings you already checked. When all buildings are checked you reset the spawning.

Now this system has several issues which have to be solved: (hopefully one of those covers your problem)
  • To make it work for more than 1 player you need a computer player that initiates the spawning (* 1st trigger) and 1 switch per player or even better, a single Death Counter. Otherwise the first player who is finished spawning would end it for everyone.

  • The spawning takes more than 1 trigger cycle because you only give 1 building per cycle. That's why Lanth suggested the binary method which spawns them all in the same trigger loop.
    So it's for you to decide if you're okay with a spawning method that can take a split second or up to several seconds for the units to be all created or if you want to make several similar triggers per unit in the fashion Lanth described.

  • Creating many units in the same location or creating units where there's already a lot of buildings can lead to unplaceable errors. Avoid these by creating the units at a separate location on the map where you make sure that there's enough space for all the units. And then move them to their destination.
    Keep in mind, however, that moving to crowded locations over and over creates lag if you do it every trigger loop, so
    a) move only every 1-2 seconds (8-16 trigger loops) and
    b) flush your destination location regularly by ordering the units somewhere.
    Setting up such an environment efficiently can prove a challenge, but for that too, you can check Desert Strike to get ideas how to implement it in your map.

Note: I've also added an early version of Desert Strike as attachment which hasn't as many triggers, so it might be easier to understand. The spawn triggers are at the end of the trigger list for the respective forces.

Attachments:
Sand Castle light v0,6.scx
Hits: 5 Size: 41.55kb

Post has been edited 1 time(s), last time on Sep 6 2011, 3:34 pm by NudeRaider.




Sep 7 2011, 8:19 pm theleo_ua Post #13



Quote from Lanthanide
Note that the "move location 'blah' to map revealer owned by current player at 'anywhere'" is an action that achieves nothing, but this is REQUIRED for the triggers presented here to work. The reason is because Starcraft only updates unit ownership on unit kill/remove and location move actions, but does *not* update as a result of give actions. If you don't include this location movement, then if the player owned exactly 8 spawning pools, the first trigger will fire, and so will the 2nd one that checks for 4 spawning pools because it hasn't registered that you gave all 8 spawning pools to P10. It'll keep checking all the remaining triggers and you'll end up spawning 62 zerglings instead of the 16 you expected.

You can use any dummy location here, you could probably even use "move location 'anywhere' to map revealer owned by current player at 'anywhere'". Personally I just have a dummy location that I use for generic tasks for this.

This is the spawning system that I use in DS Night Fixed. So it *does* work.

This is really strange, because I dont use "move location 'blah'" at my Castle Fight map, and all works fine.

I use "player bring at least 4" and "player bring at least 1 and at most 3" triggers. Maybe I dont have errors because of "bring" instead of "commands"?

I attached my map, so if you want - you can check and say to me, why this is work in my map.

Attachments:
CASTLE_FIGHT_7.31.SCX
Hits: 1 Size: 99.04kb

Post has been edited 1 time(s), last time on Sep 7 2011, 8:37 pm by theleo_ua.



None.

Sep 7 2011, 9:38 pm Lanthanide Post #14



The exact same problem happens with straight 'bring' conditions, as outlined by Heinermann above.

What does work is alternating bring and command conditions:
Bring 8 spawning pools
Command 4 spawning pools
Bring 2 spawning pools
Command 1 spawning pool

Again why this works can be divined from Heinerman's post. The DS Night Final that I based Fixed on used this method to spawn units. I replaced it with Command due to lower processing overhead with that condition compared to Bring.

I'm at work so I can't download your map and check what you've done.



None.

Sep 7 2011, 10:13 pm theleo_ua Post #15



Quote from Lanthanide
The exact same problem happens with straight 'bring' conditions, as outlined by Heinermann above.

What does work is alternating bring and command conditions:
Bring 8 spawning pools
Command 4 spawning pools
Bring 2 spawning pools
Command 1 spawning pool

BTW - I started map making in 2000 (without any tutorials, except blizzard help in staredit.exe and learning blizzard ums maps), and noticed, that "command" condition dont work (especially when I started to create "crazy cpu" map). I cannot say, was it my error or bug in staredit.exe, but from that day I used only "bring" condition, and didnt used "command", till today.

Maybe it was some special map structure of the "crazy cpu", which made "command" triggers not working, but I still dont know, what was the exact reason.

Quote from Lanthanide
I'm at work so I can't download your map and check what you've done.

You can check it when you will be at home and have time, but it really interesting, is it my error in testing the map or some interesting triggers, which solving this issue. I tested on zealots now (created 1, 4, 8 and 9 gateways) and it worked correct.

P.S. Please change player 8 to computer, if you want to play this map via singleplayer

Post has been edited 2 time(s), last time on Sep 7 2011, 10:18 pm by theleo_ua.



None.

Sep 8 2011, 7:33 am Lanthanide Post #16



Right, looking at your triggers it's pretty clear what's going on.

You simply have "at least 4 of X building" will spawn 4 units, and "at least 1, at most 3 of X building" will spawn 1 unit.

In the case where P10 owns 9 gateways, they will spawn 4 zealots only. If you removed the "at most 3 gateway" check, then they would spawn 5 zealots. Basically you don't run into this problem because if P10 has 4 gateways and they're given to Current Player, P10 will still register as having 4 gateways for the next trigger check which says "at most 3", and since they have 4 the "at most 3" condition won't be met and the trigger not run.

Thinking about this some more, I see the fundamental difference here. Your triggers will operate over multiple trigger cycles, whereas my triggers will complete in a single trigger cycle (up to the limit of the buildings accounted for by the triggers). For example, if someone has 15 gateways with your triggers, it will take 6 trigger cycles to spawn all the zealots:
15 -4 = 11: spawn 4 zealots
11 -4 = 7: spawn 4 zealots
7 -4 = 3: spawn 4 zealots
3 -1 = 2: spawn 1 zealot (this does not happen in the above cycle, because P10 will still register has owning 7 gateways)
2 -1 = 1: spawn 1 zealot
1 -1 = 0: spawn 1 zealot

Whereas my triggers will do this all in a single cycle:
15 - 8 = 7: spawn 8 zealots, 7 - 4 = 3: spawn 4 zealots, 3 - 2 = 1: spawn 2 zealots, 1 - 1 = 0: spawn 1 zealot.

Post has been edited 3 time(s), last time on Sep 8 2011, 9:46 pm by Lanthanide.



None.

Sep 10 2011, 8:09 am Lanthanide Post #17



Quote from Heinermann
Unrelated note: Using conditions and actions involving locations that are larger than 256x160 will perform faster than with smaller locations.
Is that locations that are 256x160 and larger, or just ones that are larger than 256x160?

Do the actual dimensions themselves matter - is SC more efficient dealing with locations that are multiples of 32 (eg size of a tile) or will odd numbers like 657 be processed just as efficiently?



None.

Sep 16 2011, 1:43 am Heinermann Post #18

SDE, BWAPI owner, hacker.

It may not be 256x160, it will just perform better if the location's height is equal or larger than the maximum height of all unit types, same goes for the width.
So if Floor Hatch has the largest width then that will be the max width. If another unit type has the largest height, that will be used for height.

This is also dependant on mods.

The reason is due to the nature of the "unit finder" (unit ordering) algorithm Starcraft uses to iterate units at a location. If a unit is larger than the location, there's a chance it could be skipped, so if the location is smaller than the largest unit height/width then it turns to a fallback which is quite slow compared to the original algorithm (it is cumulative).

Large location: Iterate the finder indexes, flag unit IDs in the location, then run the callback on each flagged unit ID.
Small Location: Iterate the finder indexes, grab the unit pointer, compare the unit's X/Y position with left/top/right/bottom bounds to make sure it is inside the location, flag the IDs that were found, then run the callback on each flagged unit ID.




Sep 16 2011, 2:10 am Lanthanide Post #19



So inverse locations would always qualify as "small location" from this algorithm's perspective, right?

Also looked up unit sizes, I think 256x160 is the maximum; 256 from floor hatch and 160 from dark swarm.

What happens if the location has all of the terrain heights turned off, eg air up/mid/low and ground up/mid/low are all disabled, does the unit check algorithm quit early because no possible units can exist inside it?

Post has been edited 1 time(s), last time on Sep 16 2011, 2:17 am by Lanthanide.



None.

Sep 17 2011, 7:21 pm Heinermann Post #20

SDE, BWAPI owner, hacker.

No. It will still grab every possible unit (including those that don't match the unit type) and then do the comparison in the callback.




Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[11:21 am]
UEDCommander -- That worker hardcode shit is annoying
[11:15 am]
UEDCommander -- I would like to point out that "successfully modded" and "done everything i want" are two big differences
[05:46 am]
O)FaRTy1billion[MM] -- 🥝
[04:47 am]
Pr0nogo -- kiwi
[04:46 am]
A_of-s_t -- I think Corbo made it a mango at one point
[04:46 am]
jjf28 -- what was it.. like... a peach originally?
[04:46 am]
A_of-s_t -- lol :aofst: forgot about that one
[04:45 am]
jjf28 -- :aofst:
[04:44 am]
A_of-s_t -- Sweet, thanks :)
[04:42 am]
Pr0nogo -- only a select few are done in scr due to its constraints
Please log in to shout.


Members Online: polanin431026, Roy, IlyaSnopchenko, jun3hong