Lofty Editor Dreams

While I realize the majority of dev time is being spent squashing the bugs plaguing Azeroth or balancing NE, I can’t stop thinking about what could come in the future. These are a couple of hopes I have for possible updates to the editor, though I know the chances are slim.

A model editor is my first request. While there are fan alternatives out there, from what I have seen they require ripping the game files from your PC and entering them into an external program. I feel a model editor IN the world editor would be a much better alternative, as all of the WC3 assets are there, without need to mess with the local files. This would allow for things as simple as copying a hero glow to a unit who is not normally a hero to making completely new models. More Blizzard models in the editor are always appreciated, but making a tool like this would allow creators to make almost anything, while staying in the editor and NOT messing with the games files.

Similarly, I have seen a post on here that shows 6 selectable races, utilizing the local game files. While that is great for them I am sure plenty of players would love a similar option but are too afraid or too incompetent to do what that poster did (I am both)! Custom races are currently stuck on a single map, and require several triggers to allow someone to choose that race. A race editor would allow for a race to be used on any (melee) map and to start right into the game without triggers, allowing even novice editors to create something unique. Many of the tools to create a custom race are present, of course, there are just a few additions that could make the race editor indispensable.
• “Starting Units” would be a fast way to choose what units begin with the Tier 1 Hall (1 Ghoul, 3 Acolytes).
• “1 to 1 AI” where you compare custom units to standard ones so the regular AI can at least play the race to a small degree. Of course, it may miss the finer points/specific strategies of that race, but will actually know how to make units, tier up, and creep instead of sitting there with 5 Peons. This is definitely a stand-in for a custom AI, but would be fantastic for someone new to the editor.
• “Elevated Status” being able to choose the race pre-game instead of in-game via a pop-up. The race drop down has “Custom” below Random, which opens a second drop down with the custom races. A toggle could also be made (in the same place as “Lock Teams” and the fog settings) turning custom races on or off before a game. Custom races would only be available offline, LAN, or in Custom Games, and the races available are those on the hosts computer.

Lastly, a feature that I will call “Batching” is something that would be tremendously helpful for classifying units/objects. For example, when you make a custom hero, the game doesn’t recognize it as a hero until you add it’s name to the list in “Gameplay constants.” When you have a ton of custom heroes, you have to classify each of them one by one in order for them to work correctly (only being able to have 3, for instance). If you could select multiple at once in a batch, this process would take a single click. Another example would be adding items to a shop; click on each item you want to add, then confirm, instead of opening a menu one by one, reopening for each new item. Hero spells, buildings that train several different units, basically anything that uses that pop-up menu with the unit icons would benefit from batching units together, even if only a few are batched each time. It may seem like a small QoL to ask for, but it would be intuitive and efficient nonetheless.

I realize these are long-shots but just wanted to get it out there. Any thoughts, ideas or criticism is welcome. (I will try to respond when I check back, I am not on these forums much but want to join the discourse).

Hi. As the author of the Retera Model Studio fan model editor and also the 6-race Reforged propaganda video that was posted on here a while back, I can tell you that Blizzard is not going to do either of these two projects that I did anytime soon. I mean, that would be great if they did, but it is most likely not going to happen.

In the old 2002 game client, the rule of “There are only 4 races” was hardcoded in the game in many locations. You can’t break it and you can’t escape, you would have needed to have obtained the source code and it would have taken a long time. Even in the 2002 game, there is a fifth race option called Demon that is dysfunctional and only working in certain locations within the game binary.
When you choose a race in the pre-game lobby, the computer records a numeric value from 0-4 (five possible options, because it includes “Random”) and this value is sent to all of the other players in the game.
Each of those other players’ computers receive the number and most likely sanitize it to make sure it is between 0-4 before assigning it to the pre-game lobby’s storage.
For some reason that I don’t fully understand, this numeric value is then converted into a set of five bitflags (probably stored in an 8-bit numeric data type) that we can see represented by constants in the in-game script file, “Scripts\common.j”. In this file, there are two constructs created to represent player race, apparently made in a hurry so that the RACE_PREF concept would replace the RACE concept because it would include a binary value for Random, and this value is 32. The bit flags are laid out as on/off switches in a binary value, which you can imagine as looking roughly like this:
0 0 0 0 0 1 0 0
Above, we encode the numeric value 8 in binary, this being the Night Elf setting in “Scripts\common.j”. Edit: And actually, the more I looked into this, the more that I see I was not entirely correct. The point of this system is for the lobby configuration, and only after the lobby is done do we convert the value to a simple number from 0-3 (so RACE_PREF is this special encoded value and RACE is the simple number). It all makes sense if we think about the meaning of “Night Elf & Selectable”. This is a state that the lobby can hold which means the player’s race is Night Elf, but that player is allowed to change his or her dropdown option. Contrary to the above example, this would encode as:
0 1 0 0 0 1 0 0

Even if we treat it as a simple unsigned value, the 8-bit numeric data type that was most likely used in this case can only store up to 255. In other words, it can be thought of as 8 possible on/off switches.

Each of these switches are given explicit meaning in “Scripts\common.j”.

constant racepreference     RACE_PREF_HUMAN                     = ConvertRacePref(1)
constant racepreference     RACE_PREF_ORC                       = ConvertRacePref(2)
constant racepreference     RACE_PREF_NIGHTELF                  = ConvertRacePref(4)
constant racepreference     RACE_PREF_UNDEAD                    = ConvertRacePref(8)
constant racepreference     RACE_PREF_DEMON                     = ConvertRacePref(16)
constant racepreference     RACE_PREF_RANDOM                    = ConvertRacePref(32)
constant racepreference     RACE_PREF_USER_SELECTABLE           = ConvertRacePref(64)

Going from left to right, assuming the binary number having most significant to least significant digit order, this would mean that the toggles mean:
Unknown, User Selectable Switch, Random Switch, Demon Switch, Undead Switch, Night Elf Switch, Orc Switch, Human Switch.

As soon as you introduce more options you have to rewrite the networking code, because what you’re saying would require more binary switches that could be enabled and this would mean a larger data type.

So let’s assume for a moment it was the year 2006 and you were working on Warcraft III’s second expansion, which never happened because of World of Warcraft and the existence of vastly more profitable financial opportunities for the company. Maybe in this expansion you want to offer more races like this, so you decide you will do this thing and add more binary bitflags to allow more possible race options.
Firstly, once you have rewritten the networking logic to use a larger (most likely we would increase to 16-bit) data type, we then have to change the constants in “Scripts\common.j”. Suppose this gives us the following:

constant racepreference     RACE_PREF_HUMAN                     = ConvertRacePref(1)
constant racepreference     RACE_PREF_ORC                       = ConvertRacePref(2)
constant racepreference     RACE_PREF_NIGHTELF                  = ConvertRacePref(4)
constant racepreference     RACE_PREF_UNDEAD                    = ConvertRacePref(8)
constant racepreference     RACE_PREF_DEMON                     = ConvertRacePref(16)
constant racepreference     RACE_PREF_RANDOM                    = ConvertRacePref(32)
constant racepreference     RACE_PREF_USER_SELECTABLE           = ConvertRacePref(64)
constant racepreference     RACE_PREF_CUSTOM_RACE_1             = ConvertRacePref(128)
constant racepreference     RACE_PREF_CUSTOM_RACE_2             = ConvertRacePref(256)
constant racepreference     RACE_PREF_CUSTOM_RACE_3             = ConvertRacePref(512)
constant racepreference     RACE_PREF_CUSTOM_RACE_4             = ConvertRacePref(1024)
constant racepreference     RACE_PREF_CUSTOM_RACE_5             = ConvertRacePref(2048)
constant racepreference     RACE_PREF_CUSTOM_RACE_6             = ConvertRacePref(4096)
constant racepreference     RACE_PREF_CUSTOM_RACE_7             = ConvertRacePref(8192)
constant racepreference     RACE_PREF_CUSTOM_RACE_8             = ConvertRacePref(16384)
constant racepreference     RACE_PREF_CUSTOM_RACE_9             = ConvertRacePref(32768)

…and maybe this would give us the option of 9 additional user-selectable races. However, when we first implement this addition, most likely the developer would order it differently to suit himself and leave “RANDOM” and “USER_SELECTABLE” at the end of the list, for consistency. This would change them to be the bitflags corresponding to the binary integer representation of 16384 and 32768, but “protected” custom maps would have most likely hardcoded their binary integer values to make stuff as complicated and “optimized” as possible so it does not do lookups, and if that’s true then those custom maps might all break because they wanted to make the Race option be user-selectable out of game, but now instead they assign the option to the unselectable binary 64 value which would maybe fall on RACE_PREF_CUSTOM_RACE_2 in that theoretical case.

And this is before we talk about launching the actual map. Once the game begins the race preference is used to determine the race, and querying the race from userland JASS2 scripts then results in spawning of the units. At the same time, the game UI themes are skinned differently based on race as an index into the list of possible options stored in the file “UI\war3skins.txt” which retroactively changes all FDF UI templates that are set to have the “DecorateFileNames” flag, which really as a setting only exists to mean that the texture files loaded by that UI component should swap dynamically based on the “UI\war3skins.txt” file’s name to texture mapping used for file name resolutions.

And that’s pretty much how the game launches. But there’s another problem. Once you have this upgraded engine that now supported 9 extra dropdown options, we have fundamentally altered what every map accepts. Now, at the start of any melee game, a player could spoof to the server for a melee tournament or ladder game that they were playing as RACE_PREF_CUSTOM_RACE_9 and break the game. Perhaps they would start with no units, or with a little herd of 10 sheep, or something else unexpected. (There is actually code built into the 2002 game to spawn a herd of 10 sheep in this case.)
So, we have already broken several “optimzed” custom maps with our proposed change, and created a gaping hole through which players could cheat or exploit melee games, and we have only just started.

I doubt any programmer hired on to work on Reforged could have put this information into a set of coherent sentences when they took the job, because to understand this flow of the game’s architecture is not a part of the training of a skilled software developer. I only know this because I have looked for the way to do what you are asking for the past decade but never been quite satisfied.

So, recall that I was discussing this is what you would have encountered in 2006 when you desired to make a new expansion for the Warcraft III game. Now, fast-forward to today. The fundamental systems that I just described, in all their elegant simplicity, have been replaced by vastly more complex systems in Reforged. In the Reforged game, the developers were all tired and worried about the future of the project, but they all knew they loved the game. So, when it came time to make the Reforged menu screen, they used a web-page technology to create the game’s menu because manipulating a web page is a well known task that you can find and pay a human being to do. However, knowing all that domain-specific, proprietary verbiage that I described above is not something you can find and employ a technician of any kind for. There are not Warcraft III technicians. So, you have to have someone waste their time re-learning it all.

When you look at what the web-page developer wrote who was creating the Reforged menu screen, this human was an avid consumer of “modern gaming culture” and of the Twitch website. Rather than secret code pathways that spawn a herd of sheep in the case of failure, there are hidden systems tests in the code that spawn a set of default players with Fortnite streamer names like Dr.Disrespect and Ninja. As a consumer of games, this fellow knew that Warcraft III was a game of 4 races, and so rather than one fundamental dropdown enumeration the system now encodes the possible races in many new locations. When I search for the race names in the HTML and JavaScript code, the names of the four races appear as hardcoded variables over and over again. In some cases this is for processing the communication with the server, and in one specific case it is for the list of text that populates the dropdown. Then, on top of this new complex web-page menu, the old game is still running and the web-page menu at some point queries the old game for its old locale files: maybe we need to display “Elfo de la Noche”, which might be the translation for “Night Elf” in Spanish, rather than the text “Night Elf”. And, once again, the web page passes one of four race-specific values to be matched against the old system’s config files.

Now, somewhere prior to the announcement of Reforged (2017-2018) I sent to a contact of mine that may have reached Blizzard a very long PDF asking them for something very similar to what you have asked for. Obviously there are a lot of us who want to think this would be a fun feature to have the game actually support custom races!

The gist of the feedback that I received was that implementing my request for a third format – similar to maps and campaigns – to have a mod format that included a simple config file with a list of additional races to show on the dropdown was not feasible. Instead, they suggested that what they could do was to make Custom Campaigns playable in multiplayer where it would unlock the races from those campaigns for the multiplayer Custom Game for which the campaign was loaded. I do not have any data to support my theory other than just a personal hunch, but if I had to guess… developers giving up halfway through this code change might possibly be why Reforged is not able to support Custom Campaigns even in single player.

The moral of the story is that Warcraft III is a game of four races. Five shall thou not count, neither count thou three, except to then proceed to four. Six is right out.

#$%@#$%@#$^@#^

I have wanted this for a long time.

The following Reforged mod never existed. I mean, it was never played. I didn’t follow through. I developed the technology and then didn’t think to publish it. The rule of four, that there are only four races, is still true. Watch the video carefully. For the fifth and sixth menu options, the Blizzard server cannot process these options and so they are sent to the server by encoding the value as Handicap instead. So, in the HTML and JavaScript code, I simply said, “if a player chooses Race 5, send to the server that they chose Race 1 with Handicap 90% instead”. This way, any modded client who receives “Race 1, Handicap 90%” from the server knows to treat this data as “Race 5” instead. Likewise, “Race 2, Handicap 90%” is treated as “Race 6” and we just keep counting from there.

2 Likes