• πŸ† Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. πŸ”—Click here to enter!
  • πŸ† Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! πŸ“… Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! πŸ”— Click here to enter!

[Success] Hybrid 12/24-player map | Backwards-compatible 1.24-1.28.5 & 1.31+

Status
Not open for further replies.
Level 19
Joined
Jan 3, 2022
Messages
320
There's one thing about Warcraft 3 maps that surprised me the most: the maps are entirely dynamic. Well, almost. Practically everything you think is saved permanently with WorldEdit, it is actually set up in war3map.j with code when the map loads. This means you can edit a whole lot about a map and its settings by editing war3map.j.
So I thought: can we have a backwards-compatible map file that opens in 1.26/1.27 with 12 players but with 24 players in Reforged?

I created a map in 1.26 WorldEdit and prepared spawn terrain for spawn locations of players 1-24 and touched nothing else. Saved the map and began to edit the war3map.j file:
  1. confg() function - where map preview and lobby screen is set up
    1. Change SetPlayers(number) and SetTeams(number)
    2. Add DefineStartLocation for players 13-24
    3. Add SetPlayerSlotAvailable for players 13-24
  2. InitAllyPriorities()function
    1. Add: (i = 0-based player ID)
      call SetStartLocPrioCount( i, 1 )
      call SetStartLocPrio( i, 0, i-1, MAP_LOC_PRIO_HIGH )
      call SetStartLocPrio( i, 1, i+1, MAP_LOC_PRIO_HIGH )
  3. InitCustomTeams() function
    1. SetPlayerTeam(playerID) for 13-24
  4. InitCustomPlayerSlots() function
    1. Again for players 13-24:
      call SetPlayerStartLocation( Player(i), i )
      call ForcePlayerStartLocation( Player(i), i )
      call SetPlayerColor( Player(i), ConvertPlayerColor(i) )
      call SetPlayerRacePreference( Player(i), RACE_PREF_HUMAN )
      call SetPlayerRaceSelectable( Player(i), true )
      call SetPlayerController( Player(i), MAP_CONTROL_COMPUTER )
  5. That's all folks! or not
The map now worked as before in 1.26 with 12 players and in Reforged... it still had 12 players?! WTF but I had done everything like WE would do! It turned out the game is very backwards-compatible and will initiate the game options differently for old maps :(
Blizzard.j from 1.26:
JASS:
// Game constants
constant integer   bj_MAX_PLAYERS           =  12
constant integer   bj_PLAYER_NEUTRAL_VICTIM =  13
constant integer   bj_PLAYER_NEUTRAL_EXTRA  =  14
constant integer   bj_MAX_PLAYER_SLOTS      =  16
Blizzard.j from 1.32:
JASS:
// Game constants
constant integer bj_MAX_PLAYERS           =  GetBJMaxPlayers()
constant integer bj_PLAYER_NEUTRAL_VICTIM =  GetBJPlayerNeutralVictim()
constant integer bj_PLAYER_NEUTRAL_EXTRA  =  GetBJPlayerNeutralExtra()
constant integer bj_MAX_PLAYER_SLOTS      =  GetBJMaxPlayerSlots()
You do see the problem, right? In 1.26 the numbers were constant-constant, I mean hardcoded constants that haven't changed since RoC. This is why obfuscators and their dog assumed that VICTIM/EXTRA player IDs were 13/14 and broke for Reforged maps. And many old maps had these values hardcoded too, so instead of bj_PLAYER_NEUTRAL_VICTIM a map maker would use 13 directly in code, optimization riii-ight? Blizzard devs could not have changed these numbers for old maps or these would have been broken.
Instead the Blizzard.j code for old and new maps in Reforged is the same, but the return values are different. When you play a Reforged map in Reforged, GetBJMaxPlayers() returns 24. If you load an old map in Reforged, GetBJMaxPlayers() returns 12 and so on.
-> It is not possible to dynamically change the player count from 12 to 24 in code. :goblin_cry:
Reforged initializes only 12 players when it detects an old map


Further work: Documentation​

If it's going to be required to edit the player and team settings manually in code, then these functions must be documented. You can find their usage in war3map.j when you open a map's MPQ with MPQEditor:
  1. DefineStartLocation
  2. SetPlayerSlotAvailable:
  3. SetStartLocPrioCount:
  4. SetStartLocPrio:
  5. SetPlayerStartLocation:
  6. ForcePlayerStartLocation:
  7. SetPlayerTeam:
  8. SetPlayers:
  9. SetTeams:
  10. SetPlayerColor:
  11. SetPlayerRacePreference:
  12. SetPlayerRaceSelectable:
  13. SetPlayerController:
If you want to contribute directly, start here.

UPDATE: IT WORKS!​

A single map file loads with:

  • 12 players in versions 1.24-1.28.5
  • 24 players in Reforged (I set it to support 1.31+, in reality it's possible since 1.29.0.8803)
Download in attachments
Note: the spawns at the bottom aren't aligned perfectly, but it doesn't need to be perfect. It just needs to work :peasant-victory:

Short description of what needs to be done​

I feel pretty angry at Blizzard over the Warsmash take down, so I won't upload the tools nor write a proper tutorial. A legally concise spit in the face, that's something they could be proud of. Maybe I will cool down over time or a donation will soothe my stance on them, their game, and the time spent specifically on this (PM).
  • The map must be created and edited in old WorldEditor.
  • See the spoiler above: "Code changes to war3map.j"
    • This means your players 13-24 cannot be modified in WE: no priorities, tech, pre-spawned units etc. Instead this is for maps with Jass code
  • war3map.w3i made for old versions:
    • placed in map's MPQ root (./war3map.w3i)
    • w3i_format=25
    • we_version=6059
    • any number of players in player array (seemingly ignored by game if >12, I didn't test impact on neutrals)
  • war3map.w3i made for Reforged versions:
    • placed in _Locales override folders FOR EACH locale:
      • β”œβ”€β”€ _Locales
        β”‚ β”œβ”€β”€ deDE.w3mod/
        β”‚ β”‚ └── war3map.w3i (LOADED FOR GERMAN PLAYERS)
        and so on:
        β”‚ β”œβ”€β”€ enUS.w3mod/
        β”‚ β”œβ”€β”€ esES.w3mod/
        β”‚ β”œβ”€β”€ esMX.w3mod/
        β”‚ β”œβ”€β”€ frFR.w3mod/
        β”‚ β”œβ”€β”€ itIT.w3mod/
        β”‚ β”œβ”€β”€ koKR.w3mod/
        β”‚ β”œβ”€β”€ plPL.w3mod/
        β”‚ β”œβ”€β”€ ptBR.w3mod/
        β”‚ β”œβ”€β”€ ruRU.w3mod/
        β”‚ β”œβ”€β”€ zhCN.w3mod (Chinese, Mainland)
        β”‚ └── zhTW.w3mod (Chinese, Taiwan)
        β”‚ β”‚ └──war3map.w3i (LOADED FOR zhTW PLAYERS)
      • Yes, it is currently replicated 12 times
      • Yes, if a new locale were to be released, the map would break in Reforged for them
    • w3i_format=28 (theoretically 1.29's w3i_format is sufficient, but there's no documentation)
      • The w3i must be in a correct format. I did not test yet if Reforged will take old w3i format but new we_version and work
    • we_version=6060 and above (my tool set to 6072 aka 1.31.0-1.31.1)
      • This is what changes game's behavior, initializes map with 24 players
    • Since this is Reforged's w3i version, it must have all players 1-24
  • Your Jass code must be compatible: dynamically detect if the map is played with 12/24 players
    • I didn't test GUI trigger -> code generation of old WE

Future plans​

What is done:
  • standalone w3i parser in Lua, supports multiple format versions (as described by Hodor: TFT=25, 1.31=28, 1.32=31)
  • based on above, a diff script that compares two maps' w3i data and shows differences
  • [DONE] Describe w3i format for 1.29 (first version with 24-player support) - publication WIP
TODO:
  • Research old WE GUI Trigger code generation with regards to 12/24p support
    • Does it use constants like "bj_MAX_PLAYERS"?
    • Is it fixable with custom WE Trigger definitions for code gen?
  • Write tutorials how to find and rewrite old hardcoded values in code
    • Like loops that go from 0-11 to iterate over all players
    • What constants must be used in their place
  • Automate war3map.j code changes needed to initialize players
    • make it user-friendly (dummy units?)
  • Check if Reforged relies on w3i player information at all, for initialization (or does it only use code in war3map.j?)
  • Minimap icon integration/custom map previews (war3map.mmp?) that loads correctly for 1.26/Reforged
  • Find if there's a better folder than _Locales/xxxx for Reforged overrides: so it doesn't break for new locales, and eliminates the need to replicate the file N times for each locale
  • Automate war3map.w3i creation
  • Better CLI tool to work with MPQs than MPQEditor (it doesn't print error messages or raise exit codes)
  • Automatic war3map.w3i injection into a ready map
  • Integrate with a build system
Feel free to work on any of these. At the moment I don't have time or motivation (read "spit in the face" above) outside of a single map I like.

Credits:​

 

Attachments

  • hybrid-12-24p-compat-works.zip
    84.8 KB · Views: 48
Last edited:
Level 19
Joined
Jan 3, 2022
Messages
320
Yee, if map is created before 1.29, It will always have 12 main players. An easy fix - open it in editor 1.29 or higher and resave.
The point is, I want a single map that works in old & new clients, but allows new clients to play with 24 players. The last promising thing is war3map.w3i and if there's a path that's loaded by Reforged but not Classic.
 
Level 18
Joined
Jan 1, 2018
Messages
728

Further work?​

war3map.w3i Map Info Β· stijnherfst/HiveWE Wiki this documentation suggests that map settings are not stored as part of the .w3x MPQ archive (like a header), but actually a .w3i file within the archive.
It used to be stored in both places (probably so you can easily retrieve this information without first having to extract war3map.w3i from the mpq archive), but then the feature was added that maps can be saved as folder (I think this was in 1.30), and since then the game reads this information from the .w3i file instead of the .w3m/.w3x file header, but only to display in the map list, when you go into the lobby the config function from the map script is used.

Yee, if map is created before 1.29, It will always have 12 main players. An easy fix - open it in editor 1.29 or higher and resave.
I haven't tested this but I assume it checks the world editor version in war3map.w3i to determine if 24 players are supported? In that case this value should be 6060 or higher: List of official patches for Warcraft 3
 
Level 19
Joined
Jan 3, 2022
Messages
320
@Drake53 thank you, you were right. I can't say this with utmost certainty, because an old Warcraft 3 bug invalidated some of my test results (the map didn't show up due to file name limit). Also the MPQ header looks totally empty for recent versions. There's nothing hidden there.

GOAL ACHIEVED​

The hybrid map that works. A single map file loads with:
  • 12 players in 1.26/1.27
  • 24 players in Reforged
For description read the end of the first post. Download is there too.
 
Last edited:
Status
Not open for further replies.
Top