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.