Hey, I'm a bit late on this topic, but I agree with the general consensus: we don't necessarily want EUDs, but we want many of the things they allowed us to do. Going off of the prioritized and requested features from
, there are quite a few things that are in high demand.
UnitsBy far the most requested feature is to be able to read properties on specific units. Now, with EUDs we were limited to referencing units by their index ID (i.e., the pointer to the unit struct in the unit array), which had pros (such as easily being able to keep track of that unit's state) and cons (such as obtaining the ID in the first place, or locating the unit's position on the map for the purposes of interacting with that area). While not ideal, it would be relatively low effort to allow us to reference units by index ID for the purposes of checking things like:
- Get/Set/Add/Subtract Current/Max HP
- Get/Set/Add/Subtract Current/Max Energy
- Get/Set/Add/Subtract Current/Max Shields
- Get/Set/Add/Subtract Current Kill Count
- Get/Set/Add/Subtract Unit Movement (Flingy) Speed
- Get Current Facing Direction
- Get Current Order (stop, move, attack, etc.)
- Get Current X/Y Coordinates
These, among other properties, were all accessible with EUDs as long as you knew the index ID. Going beyond this, the X/Y coordinates of the unit can be useful, but it would be useful to extend this to check if a
specific unit is within the bounds of a location (in the existing system, we can only be as specific as the
type and
player owner of a unit, so two Terran Marines owned by Player 1 are indistinguishable from each other).
While having these options available to us is great, working with the index ID is not exactly ideal. What would be ideal is the solution found in the likes of Warcraft III's trigger editor (and also StarCraft 2's trigger editor): variables. Being able to create and assign variables for units would solve the complexity of the index ID issue. Assignment could be as simple as "Set <variable> to <unit type> owned by <player> at <location>", and, like many other triggers that exist today, just take the first matching unit if available.
However, adding variables is likely a significant overhaul of SC's current trigger system, so I understand the likelihood of this is slim. A less ideal but practical solution is better than the ideal, impractical one. Perhaps a happy medium would be to resolve the unit target the way SC does with its other conditions and actions like "Set Doodad State": specify a location, unit type, and player owner, and take the first matching unit.
One last remark on this section: while it never performed correctly with EUDs, more unit order options, like telling units to use an ability such as Burrow, would be a very beneficial addition, if it would be easy to implement.
Upgrades and TechnologiesCurrently there are no ways to check the upgrades or technologies a player has, nor can we change these via triggers. EUDs made this possible, and it was really as simple as looking at the corresponding location in memory and reading the value. However, since EUDs worked by reading 4 bytes at a time, and upgrades/technologies are stored in single bytes, there were challenges getting precise values for every 3 out of 4 entries. I see no reason why this would be challenging to add as native conditions/actions, and it will open up more possibilities than what we had prior.
Player InformationWe're missing a small handful of things regarding players. With EUDs, we were able to do things such as:
- Get/Set/Add/Subtract Used/Max Terran Supply
- Get/Set/Add/Subtract Used/Max Zerg Supply
- Get/Set/Add/Subtract Used/Max Protoss Supply
- Get Current Unit Selection
- Get Player Name
Particularly knowing which units a player has selected created a whole assortment of new mapping techniques. This again relied on unit index IDs, in addition to needing to check which "slot id" (position out of 12 possible selected units) the unit was put under, but despite this specificity, many cool things came out of this option being available. Having a native implementation in some form would be fantastic.
MiscellaneousSince EUDs are just reading from a wide range of memory, it's hard to list out everything that was available to us. Picking out a few key items:
- Get/Set/Add/Subtract Current Game Speed
- Get/Set Current Game Latency*
- Set Current Gamma*
- Get Key Press Detection*
- Get Display Text Detection*
Many games are built under the expectation of running under a specific game speed (usually Fastest), and wouldn't operate correctly under other speeds (because Wait actions run in real time). Being able to check for game speed, or even adjust it, would open up several avenues of creativity in mapmaking.
I've marked most of these with asterisks for a specific reason: these values aren't separated out for individual players, but are based on local client values. With EUDs, this means we had to be very careful about not using these as conditions on triggers that affect the game state, or else it would cause a discrepancy that would disconnect/drop players that didn't have matching game states from each other (though as actions they are without such consequence). It stands to reason, then, that if these were to be included as native trigger conditions, there would need to be some netcode rework, which is not nearly as trivial as some other mentioned items in this write-up.
Game Latency was mostly useful as a condition: hackers, or even just people with Cheat Engine open, could locally adjust their latency to gain an unfair reaction-time advantage over their opponents. Using EUDs, we could detect this discrepancy and remove the exploiter from the game via desynchronizing their game state, which causes them to drop from the other players. Like game speed, it would be a nice option as a trigger action to be able to change the game's latency setting.
I recently saw a game that used EUDs to change the game's brightness in the middle of the game to simulate day-night cycles: when night comes around, the brightness levels automatically turn down, and come sunrise, brightness turns back up. This type of simple mechanic could be used for other atmospheric situations (dark caves, power outages, etc.), and again, while it would be an issue to use as a trigger condition, it would be harmless to include as a trigger action.
Being able to detect what keys on the keyboard a player presses is possibly one of the most beloved trigger conditions made available by EUDs, but unfortunately, it does not play nicely in multiplayer, since the values are going to vary per client. While this type of trigger functionality was available on Warcraft III, it came with a small performance penalty: like SC, Warcraft III operated with a latency system that delays taking action immediately to give time to broadcast a player's actions to others, but this didn't apply to trigger events, so key presses would try to send out immediately and halt the game until all players were ready to fire the trigger, which could cause stuttering with players on slower connections. It's unfortunate that key press detection is a nontrivial implementation when it has many very cool applications.
Finally, Display Text is the most complicated thing to detect with EUDs, but nevertheless, many proof-of-concepts have come out of it. One famous example is the ability to detect a very popular hacking program, after which the game could cause them to disconnect from the other players. But other examples can be found as well, such as having a text command that does something in-game. This again can be compared to Warcraft III's excellent text detection system (used in many famous maps, including DotA), though what we could do with EUDs was ridiculously nuanced and limited, and ultimately it's not practical in its current form to try and read game/chat text.
ArithmeticFinally, what EUDs were most powerful at was the option to let us add and subtract values to things we could normally only set. Particularly regarding units, upgrades, and technologies, being able to say, add 5 health to a unit was as simple as it is to add 5 minerals to a player. I'm sure someone could compile a larger list, but personally, the things I think are most important:
- "Modify Unit Energy" - Set/Add/Subtract raw value (instead of just set percentage)
- "Modify Unit Hit Points" - Set/Add/Subtract raw value (instead of just set percentage)
- "Modify Unit Resource Amount" - Add/Subtract options
- "Modify Unit Shield Points" - Set/Add/Subtract raw value (instead of just set percentage)
- New "Set Kills" action with Set/Add/Subtract (corresponding to "Kills" condition)
- New "Move Location by Pixels" action
- New "Move Screen Position by Pixels" action
Moving a unit by pixels would be a nice-to-have, but if I remember correctly, it didn't work to just set the unit's coordinates with EUDs, and ultimately, the same effect can be achieved by moving a location on top of the unit, moving the location by pixels, and then moving the unit onto the location.
This doesn't pertain to EUDs specifically, but having multiplication, division, and modulus would simplify a lot of the calculations mapmakers have to do today and open up a lot more practical solutions to problems we commonly face.