Intro
As many of you are aware, there are some very useful EUDs that you can't use in multiplayer without causing a desync. Lethal and I found a way around this a few months ago but never bothered to share our knowledge officially on the SEN forums.
How It Works:
In order to understand how this works, you first must understand why local EUDs cause desyncs. Each client connected together in a Starcraft game simulates what should be happening in the game, based on Starcraft's "physics" (mechanics) and the inputs of every other player. When these simulations don't match up it results in a desync and the computers disconnect. Local EUDs (like detecting keyboard presses and screen position) themselves don't cause desyncs, but rather the differences they make (desyncing actions).
If you have a trigger like this:
CONDITIONS:
- Keystroke "L" is pressed (EUD shorthand)
- Create 1 Zergling at Location 1 for Player 1
It creates a zergling for the player that presses "L" and not for the others, causing a desync. Technically if every player pressed "L" at the exact same time, the zergling would be created and there would be no desync. Local actions also don't cause desyncs (display text, center view, etc), meaning you can have pressing the key "K" display the message "You pressed K!" just fine without desyncs.
Unlike most units, when the action "Kill X Zerg Egg for Player Y" occurs it sends a cancel order for the egg rather than going through the normal kill script. Like most of the mechanics we abuse, this is because of a bit of laziness on Blizzards part, as it keeps them from having to do some messy clean up with the Zerg Egg states. Consequently, when a Zerg Egg 'dies' (via trigger actions) for a client, instead of causing a desync, the other clients accept the death as a cancel order input and update themselves by killing the Zerg Egg in their runtimes as well- SO LONG AS THE ZERG EGG BELONGED TO THE PLAYER THAT HAD THE ZERG EGG DIE FOR THEIR CLIENT (this part is important, otherwise it'll cause a desync like always).
Now, we can abuse this by using Zerg Egg deaths as indicators of local EUD events. Example:
TRIGGER 1:
CONDITIONS:
- Keystroke "L" is pressed (EUD shorthand)
- Kill 1 Zerg Egg for Player X at CurrentEggLocation
- Preserve Trigger
TRIGGER 2:
CONDITIONS:
- Player X Brings At most 0 Zerg Egg at CurrentEggLocation
- Display Text ("HEY EVERYONE, PLAYER X PRESSED THE L KEY")
- Move 1 Zerg Egg from EggStorageLocation to CurrentEggLocation
- Any other actions you want, like casting a spell
- Preserve Trigger
To restate, the other clients accept the Zerg Egg Kill command as a cancel input, rather than a disparity thats cause for desync. This in turn sates the condition for trigger 2, and everyone sees the message "HEY EVERYONE, PLAYER X PRESSED THE L KEY" displayed to their screen.
There are a few problems though. For one, Zerg Eggs can't be detected by the Bring condition, so you have to detect its absence in more round about ways (I just used bring in the example for ease of comprehension) like continually moving a Reaver (arbitrary ground unit) where the egg is and if the Reaver finally exists where the egg should've been, then move the Reaver away and activate the Actions you wanted.
Secondly, if any player presses "L" the Zerg Egg will be killed for Player X, and if you were paying attention, if any player other than Player X kills Player X's Zerg Egg locally, it will cause a desync. This can be remedied in a couple ways- either each Player has a different local EUD triggers (IE P1 presses L and P2 pressed K) or you have another local EUD condition to delineate between the players so that its impossible for them to activate other's EUD events. In my test maps, I used the EUD condition for, in essence, "Is Player 1", "Is Player 2" to delineate, as seen in the following example:
Example
In the following example vespene gas acts as a health potion counter. If player 1 or 2 press Q, it subtracts a vespene gas and they are healed. No desyncs occur, despite using local EUDs.
Example Triggers
PROS:
- Any Local EUD can be used as a condition in Multiplayer maps without causing a desync
- Like all maps that use EUDs, patches may ruin map
- Every player needs their own storage of preplaced Zerg Eggs, which can really add up
- You can only used the local EUD event as many times as you have stored eggs
- Each type of local EUD needs a separate "CurrentEggLocation"
- If you want to pass something like screen position (which has a range of values, not just ON/OFF), you'll have to have multiple Egg pools to kill from to act as a binary sequence
I'll get my test map in a presentable state real quick and attach it.
Post has been edited 1 time(s), last time on Apr 2 2012, 8:46 am by Kaias.
None.