[CRITICAL/BLOCKER] Minimap not working on macOS

Problems with mini-map (doesn’t matter Regorged Graphics or Classics HD) - it is simply black and its litterally impossible to play because navigation just horrible in that case (you simply don’t see where your base/enemy base, in which part of map you are) - this bug is literally CRITICAL (nearly Blocker to be honest, because without minimap you cannot do nothing because you won’t even notice that enemy came to your camp while you’re creeping, won’t be able to reach campaign’s quest targets, well, you can but will waste lots of time on this)

What I tried so far:

  1. Reinstalling the game completely (didn’t help)
  2. Reinstalling THE WHOLE MACOS SYSTEM WITH NVRAM AND SMC RESETING (didn’t help)
  3. Tried testing the game on Bootcamp Windows 10 (works under Windows which means its not a hardware issue, but rebooting and dealing with Bootcamp itself another “quest” you’d like to avoid especially when you need to deal with GPU drivers for AMD Radeon videocard, as official ones wasn’t updated since 2021 and you have to install community drivers to make you machine perform at least somehow good enough)
  4. Tried multiple versions of macOS - doesn’t matter whether its Ventura, Sonoma or latest one Sequiora (I tested latest stable releases of Ventura and Sonoma - no chance. Tried latest 15.1.1 - also same thing)

My config:
macos 15.1.1 (latest, tried 14.7.1 and 13.7.1 as well, no lucj)
Macbook Pro 16 2019
Intel Core i9
32 GB RAM
AMD Radeon Pro 5500m 8 GB

Just FYI - I’m NOT ALONE WITH THIS ISSUE, ITS MAC-ONLY:

https://www.reddit.com/r/warcraft3/comments/1gujar3/minimap_bug_since_20_patch/

P.S.: You can see screenshot of that issue in a reddit thread I’ve attached.

3 Likes

I have having the same problem. M1 mac air.

1 Like

without looking at the in-house code for minimap, one idea that comes to mind for me is that maybe for Mac the devs could change to use less efficient code that is easy to write. So basically, I think the ideal way to do the minimap is probably to have it re-use the same GPU buffer that is applied to terrain shading for fog of war. But that requires understanding of buffers, which is a more advanced programing concept.

On my GitHub where I have a warcraft 3 emulator that I have been rewriting so that I can play the game in case the official version is messed up by some catastrophe, and in that project we’re just doing clean room engineering making a thing that looks similar without access to the original. Within the scope of that software, I was totally putting off the fog of war on the minimap system - and just always revealing the entire map - because I had not written the software properly to access the terrain GPU buffer from the minimap code.

Then, one of the GitHub contributor had a good idea to do a “for loop” on the CPU that draws a bunch of black squares over the minimap at a fine grain resolution so that they cover up the areas of the map that are behind fog. Conceptually this should cause a big dip in performance, but it turns out that modern computers are written for rendering “web” code which is usually terrible anyway, and it doesn’t even matter, and I’ve been able to use this minimap system and get the experience I wanted and forget about the performance that it was spinning on CPU. When I played on Raspberry Pi 5 on the ARM chip, the game performance was bad enough that it didn’t really work, but if you’re playing on a modern Apple Mac device I seriously doubt it would be an issue if Mac has done their job well similar to Windows to make it render anything even if the software is poorly written in terms of optimization.

In case this helps you guys, I will include the subroutine from my github contributor below. At the time they contributed their first draft of this code to the repo the project was MIT licensed. Since then, the code changed very slightly and also the project changed to AGPL license because one of the dependencies was GPL and someone told me that means I have to be GPL, and I didn’t want to have to worry about it. But since Microsoft cannot use this code in its exact form and would have to refactor language to C++ anyway, they wouldn’t be using the original code anyway and I figure no one cares.

So if it’s easy to just add a branch on Mac to just do an idiot “for loop” and draw black rectangles over the base minimap texture on the CPU like this, you guys could probably do that in the short term until you get someone who wants to bother to do more:

// function for MeleeUIMinimap::render(...)
	public void render(final CSimulation game, final SpriteBatch batch, final Iterable<RenderUnit> units,
			final PathingGrid pathingGrid, final CPlayerFogOfWar fogOfWar, final CPlayer player) {
		if (!this.visible) {
			return;
		}
		batch.draw(this.minimapTexture, this.minimap.x, this.minimap.y, this.minimap.width, this.minimap.height);
		final Color og = batch.getColor();

		final int minX = pathingGrid.getFogOfWarIndexX(this.playableMapArea.getX());
		final int minY = pathingGrid.getFogOfWarIndexY(this.playableMapArea.getY());
		final int maxX = pathingGrid.getFogOfWarIndexX(this.playableMapArea.getX() + this.playableMapArea.getWidth());
		final int maxY = pathingGrid.getFogOfWarIndexY(this.playableMapArea.getY() + this.playableMapArea.getHeight());
		final float mapXMod = this.minimapFilledArea.width / (maxX - minX);
		final float mapYMod = this.minimapFilledArea.height / (maxY - minY);

		for (int y = 0; y < (maxY - minY); y++) {
			for (int x = 0; x < (maxX - minX); x++) {
				final CFogState state = fogOfWar.getFogState(game, x + minX, y + minY);
				if (CFogState.FOGGED.equals(state)) {
					batch.setColor(0f, 0f, 0f, 0.5f);
					batch.draw(this.teamColors[0], this.minimapFilledArea.x + (x * mapXMod),
							this.minimapFilledArea.y + (y * mapYMod), mapXMod, mapYMod);
				}
				else if (CFogState.MASKED.equals(state)) {
					batch.setColor(0f, 0f, 0f, 1f);
					batch.draw(this.teamColors[0], this.minimapFilledArea.x + (x * mapXMod),
							this.minimapFilledArea.y + (y * mapYMod), mapXMod, mapYMod);
				}
			}
		}

		this.heroAlpha += HERO_STEP * this.polarity;
		if ((this.heroAlpha <= 0.5) || (this.heroAlpha >= 0.95)) {
			this.polarity *= -1;
		}

		for (final RenderUnit unit : units) {
			final CUnit simUnit = unit.getSimulationUnit();
			int dimensions = 4;
			if (!simUnit.isHidden() && !simUnit.isDead() && simUnit.isVisible(game, player.getId())) {
				batch.setColor(1, 1, 1, 1);
				final Texture minimapIcon;
				if (simUnit.getGoldMineData() != null) {
					minimapIcon = this.specialIcons[0];
					dimensions = 21;
				}
				else if (simUnit.getOverlayedGoldMineData() != null) {
					final CAbilityOverlayedMine overlayedGoldMineData = simUnit.getOverlayedGoldMineData();
					if (overlayedGoldMineData instanceof CAbilityEntangledMine) {
						minimapIcon = this.specialIcons[3];
					}
					else {
						minimapIcon = this.specialIcons[4];
					}
					dimensions = 21;
				}
				else if (simUnit.getUnitType().isNeutralBuildingShowMinimapIcon()) {
					minimapIcon = this.specialIcons[1];
					dimensions = 21;
				}
				else if (simUnit.isHero()) {
					if (player.hasAlliance(simUnit.getPlayerIndex(), CAllianceType.PASSIVE)) {
						batch.setColor(1f, 1f, 1f, this.heroAlpha);
					}
					else {
//						Color pc = new Color(game.getPlayer(simUnit.getPlayerIndex()).getColor());
						batch.setColor(1f, 0.2f, 0.2f, this.heroAlpha);
					}
					minimapIcon = this.specialIcons[2];
					dimensions = 28;
				}
				else {
					if (simUnit.isBuilding()) {
						dimensions = 10;
					}
					minimapIcon = this.teamColors[unit.getSimulationUnit().getPlayerIndex()];
				}
				final int offset = dimensions / 2;
				batch.draw(minimapIcon,
						(this.minimapFilledArea.x + (((unit.location[0] - this.playableMapArea.getX())
								/ (this.playableMapArea.getWidth())) * this.minimapFilledArea.width)) - offset,
						(this.minimapFilledArea.y + (((unit.location[1] - this.playableMapArea.getY())
								/ (this.playableMapArea.getHeight())) * this.minimapFilledArea.height)) - offset,
						dimensions, dimensions);
				batch.setColor(1, 1, 1, 1);
			}
		}
	}

As a note, this subroutine is not written to respect the “masked areas are partially visible” setting from war3map.w3i parser, and instead always drawing solid black for the mask. Might be a slight adaption you could do for that if dumping it in on Mac.

I know it’s a long shot and you’ll probably just have to wait until some C++ guy can figure out invalidation of GPU buffer pointers on Metal or some other silly thing, but I figured I would mention how absolutely stupid code like this can work for parroting the original experience in some instances without inputting the actual same level of technical skill required for building the original 2003 game - precisely because modern hardware is often way overkill for simulating this game.

1 Like

Still have this issue in February 2025. Almost half of the year passed. That slackers do nothing! Check Viva La Dirt League’s sketches on YouTube. Their sketches about “imaginary” ArcticStorm company is 100% spot on about Blizzard and definitely true.

1 Like

Mac user is blocked since the crash last October, followed by the mini map issue, I 'm now using Parallels Desktop and have lost all hope in this company.
Maybe I should hope they won’t crash Windows version again.

I have the same issue. A workaround that kind of worked for me in campaigns is to ping the map anywhere. The minimap will then light up for a few seconds on my MAC. Of course this is not viable for PvP play, so please fix this bug!