I was curious if you guys could help me trouble-shoot this anomalous behavior I've been getting. I've only ever made one SC2 map, so I'm kind of a noob. What I did was take the standard melee game and modify it so that nukes were more realistic (like infinite range, ghost not required, much more powerful, etc.)
My trouble has arisen with the logic that calculates nuclear fallout for specific map coordinates. To implement nuclear fallout, there is a 400X400 array of Reals called radiationMap that represents nuclear fallout. The array indices represent the map coordinates with a +72 offset (to avoid array out-of-bounds). Whenever any player explodes a nuke, the floating point values (errmm... I mean "Reals") at the appropriate indices within radiationMap are updated. Basically, if I want to add radiation to map coordinate (x,y), I do:
HERE'S THE PROBLEM: It works great playing by myself. However, I frequently play this map with a RL friend of mine who has a somewhat slow computer in multiplayer. He'll lag pretty bad when there are six active elite and insane AIs. I've never played it with anyone else. When I play with my friend, the radiationMap values do not update properly. He'll drop a nuke and sometimes the radiationMap values won't change at all at the impact point. I swear, I've even seen the radiationMap values go DOWN. I think, but I'm not certain, that radiationMap sometimes malfunctions after I drop a nuke, too.
What's going on?! How is this possible? I've searched through my logic repeatedly, I cannot find the flaw, and it works FINE when I'm by myself. radiationMap is always properly updated. It's only once I take it to multiplayer that I see the problem.
If I truly don't have any errors in my logic, then it must be my assumptions (or, unlikely, a bug in the trigger system itself). I am assuming that global variables are only running in one spot (host? battlenet? Who handles trigger execution logic?) and that triggers are not multi-threaded (i.e., an infinite loop will freeze the game; the game allows as many CPU cycles to finish trigger loops as those loops require, it does not save pause long loops and resume them later). Anyway, perhaps each player runs triggers and has global variables stored, and that my friend's global variables can interfere with MY global variables?!
Try this, run the map by yourself online. If it does not work, then the array is too large. There some kind of memory limit when running maps over b.net.
Thanks! I did not consider that possibility. That is partly because I do believe that I DID try it over battlenet by myself, and it worked, BUT, I MIGHT be confusing that with playing by myself in the "test map" function.... I've done both. Also, it's not that the trigger logic doesn't WORK, it's that the trigger logic doesn't work reliably. Sometimes the fall-out in a location doesn't increase enough after a nuke lands, sometimes it doesn't increase at all. That kind of thing. So, it can be hard to tell if it's really working or not.
Does this memory limit apply as a TOTAL limit or is it a limit on a per-variable basis? And what is it a limit on? triggers only? Or could I reduce something else to free up room for triggers?
I'd just be surprised if a 400x400 array caused a problem. I would think that 160000 floating point numbers is absolutely nothing compared to the rest of the data traffic that is going on.
Perhaps I'm updating the array too quickly? It gets updated every time a nuke lands. It takes something like 300 to 1000 nuclear launches to win a map (assuming you go all-nuclear), and there can be like five nukes landing within the same second. I'm already adjusting the logic to update the arrays only once every 4 game-seconds. (In the new method, nuke impacts get temporarily stored in another array, and when a timer expires, this nuke impacts array gets read and that updates the radiation map).
Perhaps I should adjust my trigger logic to just work with a 256x256 array instead. It wouldn't be so hard if I was trying to program this in an actual programming language; trying to make complicated conditional statements and loops in the trigger editor is a real PITA (AND they are really hard to read, as well).
Is there any way at all to open some kind of debug message window DURING MULTIPLAYER and see if the map is generating errors? Another thing that makes this hard is the lack of any debugger (that I know of).
Anyway, I really hope you're wrong, because I've been working on an update to the logic that implements a fall-out map for each player so that the "Radiation sickness" debuff & DoT can award kills to the players who actually caused the fall-out that gave the enemy unit radiation sickness. Right now, enemy units that die from radiation sickness don't count towards your kill total. (OH YEA, I have so much fun dropping a couple "salted" thermonukes on zerg bases and watching them slowly wither and die from radiation sickness. Let's just say that this map is most definitely NOT intended to be even remotely fair, that's the best part about it :D. Because, let's be honest: IRL, Terrans would win every single battle because Zerg can't grow nukes and Protoss are too environmentally conscious to use them.)
Forget about limits - there are no limits on anything that would be exclusive to online games. 400x400 array of scalar type like fixed (aka real) is nothing. Whether you actually need this array to achieve what you need is another thing, but let's not focus on this.
I am assuming that global variables are only running in one spot (host? battlenet? Who handles trigger execution logic?
It seems like you just don't get how SC2 works. It's based on so called deterministic synchrous game engine.. I'd recommend you to read this [1] to get better understanding.
To answer your question in short - everyone.. that is every client/player connected to the game. Not the battlenet server though. When your friend drops a nuke, he has to process the action on the same terms as you do (over the wire there are transmitted only inputs/commands from each client). Thus both of you use the same global variables to get the same result. Perhaps this is what you've missed, when implementing triggers (I didn't try to analyze them).
and that triggers are not multi-threaded (i.e., an infinite loop will freeze the game; the game allows as many CPU cycles to finish trigger loops as those loops require, it does not save pause long loops and resume them later).
There is multi-threading.. but no the one you'd expect - threads cannot run in parallel. And executions happen in cycles. I'll just link the wiki again, because it explains it better than I would be able to:
In case of SC2 context switch can be initiated by Wait function. When supplied with 0.0 it guarantees the thread will be resumed in next game frame. And yes, there's a limit of actions VM can perform during one frame. I don't recall exact limit, but you can indeed freeze the game for few secs, before timeout occurs.
Another thing that makes this hard is the lack of any debugger (that I know of).
There's one.. kinda obscure, but does the job. In testmode you can open it by typing "TrigDebug". Also it requires game to be in windowed mode. If you want to have it at start of the game then head over to editor preferences -> test document.
Is there any way at all to open some kind of debug message window DURING MULTIPLAYER and see if the map is generating errors?
You can setup TriggerDebugMessage to save to log file. Log file will be written anytime you play the game or watch the replay.
But, you can also relaunch SC2 with "-development" flag, that will enable test mode for replays. Including access to debugger. If you launch SC2 from Battle.net client, then in its options there's somewhere a field to type additional cli params. For testing purposes that would be "-development -windowed -trigdebug".
When testing offline it's also good too add additional dummy players, that have the control shared to you. And simulate what would happen in actual online game.
Well, I had a map that had a huge array. I had to reduce total number of variables for the triggers to work over b.net. But if your triggers are still running (you sure your triggers didn't freeze in the middle of running?) then its not the 400x400 array.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
Hello all,
I was curious if you guys could help me trouble-shoot this anomalous behavior I've been getting. I've only ever made one SC2 map, so I'm kind of a noob. What I did was take the standard melee game and modify it so that nukes were more realistic (like infinite range, ghost not required, much more powerful, etc.)
My trouble has arisen with the logic that calculates nuclear fallout for specific map coordinates. To implement nuclear fallout, there is a 400X400 array of Reals called radiationMap that represents nuclear fallout. The array indices represent the map coordinates with a +72 offset (to avoid array out-of-bounds). Whenever any player explodes a nuke, the floating point values (errmm... I mean "Reals") at the appropriate indices within radiationMap are updated. Basically, if I want to add radiation to map coordinate (x,y), I do:
radiationMap[x][y] = radiationMap[x][y] + <additional fallout>
where <additional fallout> is a calculated value or a flat value depending on how close coordinates (x,y) are to the nuclear blast.
See the screenshots below (sorry, for some reason, I cannot put them into my post).
https://imgur.com/Lp41uSr
https://imgur.com/OutmwWV
HERE'S THE PROBLEM: It works great playing by myself. However, I frequently play this map with a RL friend of mine who has a somewhat slow computer in multiplayer. He'll lag pretty bad when there are six active elite and insane AIs. I've never played it with anyone else. When I play with my friend, the radiationMap values do not update properly. He'll drop a nuke and sometimes the radiationMap values won't change at all at the impact point. I swear, I've even seen the radiationMap values go DOWN. I think, but I'm not certain, that radiationMap sometimes malfunctions after I drop a nuke, too.
What's going on?! How is this possible? I've searched through my logic repeatedly, I cannot find the flaw, and it works FINE when I'm by myself. radiationMap is always properly updated. It's only once I take it to multiplayer that I see the problem.
If I truly don't have any errors in my logic, then it must be my assumptions (or, unlikely, a bug in the trigger system itself). I am assuming that global variables are only running in one spot (host? battlenet? Who handles trigger execution logic?) and that triggers are not multi-threaded (i.e., an infinite loop will freeze the game; the game allows as many CPU cycles to finish trigger loops as those loops require, it does not save pause long loops and resume them later). Anyway, perhaps each player runs triggers and has global variables stored, and that my friend's global variables can interfere with MY global variables?!
Any help at all would be much appreciated.
An array of 400x400 might be too large.
Try this, run the map by yourself online. If it does not work, then the array is too large. There some kind of memory limit when running maps over b.net.
Thanks! I did not consider that possibility. That is partly because I do believe that I DID try it over battlenet by myself, and it worked, BUT, I MIGHT be confusing that with playing by myself in the "test map" function.... I've done both. Also, it's not that the trigger logic doesn't WORK, it's that the trigger logic doesn't work reliably. Sometimes the fall-out in a location doesn't increase enough after a nuke lands, sometimes it doesn't increase at all. That kind of thing. So, it can be hard to tell if it's really working or not.
Does this memory limit apply as a TOTAL limit or is it a limit on a per-variable basis? And what is it a limit on? triggers only? Or could I reduce something else to free up room for triggers?
I'd just be surprised if a 400x400 array caused a problem. I would think that 160000 floating point numbers is absolutely nothing compared to the rest of the data traffic that is going on.
Perhaps I'm updating the array too quickly? It gets updated every time a nuke lands. It takes something like 300 to 1000 nuclear launches to win a map (assuming you go all-nuclear), and there can be like five nukes landing within the same second. I'm already adjusting the logic to update the arrays only once every 4 game-seconds. (In the new method, nuke impacts get temporarily stored in another array, and when a timer expires, this nuke impacts array gets read and that updates the radiation map).
Perhaps I should adjust my trigger logic to just work with a 256x256 array instead. It wouldn't be so hard if I was trying to program this in an actual programming language; trying to make complicated conditional statements and loops in the trigger editor is a real PITA (AND they are really hard to read, as well).
Is there any way at all to open some kind of debug message window DURING MULTIPLAYER and see if the map is generating errors? Another thing that makes this hard is the lack of any debugger (that I know of).
Anyway, I really hope you're wrong, because I've been working on an update to the logic that implements a fall-out map for each player so that the "Radiation sickness" debuff & DoT can award kills to the players who actually caused the fall-out that gave the enemy unit radiation sickness. Right now, enemy units that die from radiation sickness don't count towards your kill total. (OH YEA, I have so much fun dropping a couple "salted" thermonukes on zerg bases and watching them slowly wither and die from radiation sickness. Let's just say that this map is most definitely NOT intended to be even remotely fair, that's the best part about it :D. Because, let's be honest: IRL, Terrans would win every single battle because Zerg can't grow nukes and Protoss are too environmentally conscious to use them.)
Forget about limits - there are no limits on anything that would be exclusive to online games. 400x400 array of scalar type like fixed (aka real) is nothing. Whether you actually need this array to achieve what you need is another thing, but let's not focus on this.
It seems like you just don't get how SC2 works. It's based on so called deterministic synchrous game engine.. I'd recommend you to read this [1] to get better understanding.
To answer your question in short - everyone.. that is every client/player connected to the game. Not the battlenet server though. When your friend drops a nuke, he has to process the action on the same terms as you do (over the wire there are transmitted only inputs/commands from each client). Thus both of you use the same global variables to get the same result.
Perhaps this is what you've missed, when implementing triggers (I didn't try to analyze them).
[1] https://blog.forrestthewoods.com/synchronous-rts-engines-and-a-tale-of-desyncs-9d8c3e48b2be
There is multi-threading.. but no the one you'd expect - threads cannot run in parallel. And executions happen in cycles. I'll just link the wiki again, because it explains it better than I would be able to:
https://en.wikipedia.org/wiki/Cooperative_multitasking
In case of SC2 context switch can be initiated by Wait function. When supplied with 0.0 it guarantees the thread will be resumed in next game frame.
And yes, there's a limit of actions VM can perform during one frame. I don't recall exact limit, but you can indeed freeze the game for few secs, before timeout occurs.
There's one.. kinda obscure, but does the job. In testmode you can open it by typing "TrigDebug". Also it requires game to be in windowed mode. If you want to have it at start of the game then head over to editor preferences -> test document.
You can setup TriggerDebugMessage to save to log file. Log file will be written anytime you play the game or watch the replay.
But, you can also relaunch SC2 with "-development" flag, that will enable test mode for replays. Including access to debugger.
If you launch SC2 from Battle.net client, then in its options there's somewhere a field to type additional cli params. For testing purposes that would be "-development -windowed -trigdebug".
When testing offline it's also good too add additional dummy players, that have the control shared to you. And simulate what would happen in actual online game.
Previously known as: SomeoneTookMyNameTT
Well, I had a map that had a huge array. I had to reduce total number of variables for the triggers to work over b.net. But if your triggers are still running (you sure your triggers didn't freeze in the middle of running?) then its not the 400x400 array.