MHServerEmu Progress Report: March 2025
It’s a bird! It’s a plane! It’s an MHServerEmu Progress Report!
0.6.0 and Beyond
We have been doing quarterly stable releases for a whole year now, and this month we released version 0.5.0. As soon as it was out, we began working on the next one, 0.6.0, which is now available via nightly builds.
There are two major features planned for 0.6.0: the implementation of the long awaited power customization via talents, and a fundamental overhaul of our server architecture that is going to allow us to bring some of the “MMOness” back into the game. After doing an informal poll on our Discord server, we decided to prioritize additional work on powers, as it was what the majority of people wanted to see.
We will share more details on the architecture overhaul in future reports, but the short version of it is that the current architecture was designed as temporary scaffolding to allow us to work on the gameplay side of things as soon as possible. The vast majority of gameplay code is going to remain the same, but everything around it, such as game instance management, chat functionality, and other social-oriented features, will be undergoing major changes. It is not going to make much of a difference for people playing on locally hosted servers, but it will be crucial for public servers that intend to replicate the game’s original, more social, experience.
Talents
Although many players seem to associate talents with the Biggest Update Ever (BUE), it is actually a much older system. First introduced as specialization powers in version 1.35, this system has been in Marvel Heroes since the release of Doctor Doom as a playable hero on the game’s second anniversary in 2015. We happen to have a highly experimental server implementation for this exact version of the game, which we can use to show what the UI for this feature looked like back then:
The underlying code that runs this system remained mostly the same, and in some cases talents are still referred to as specialization powers (e.g. SpecializationPowerPrototype
). While it is good for pre-BUE support later down the line, it also meant more work needed to be done on the backend of the power system now.
This is a good opportunity to talk about the power progression system and what was the actual extent of changes brought by BUE. You may have noticed that it was possible to use travel and ultimate powers from level 1, even though they are supposed to unlock at higher levels. Team-ups were also using powers that were supposed to be locked for them. The reason for this is that we did not have a proper implementation of the power progression system and simply assigned all powers to avatars and team-ups. The only thing preventing you from using everything from level 1 was client-side validation, and team-ups did not have this “problem”.
There was a reason why we did not work on power progression until we had to do it. Even though BUE seemingly got rid of power ranks, the entire backend is still very much rank-driven and does all the necessary calculations, taking into account various modifiers to power ranks, only to arrive at rank 0 or 1 for everything but ultimate powers. What BUE actually did was set the starting rank of all powers to 1, remove point assignment and rank-modifying affixes from gear, and rescale everything accordingly. For us implementing power progression was a not insignificant amount of work, most of which is going to be pretty much invisible until we support pre-BUE versions of the game. However, since talents are just specialization powers with a new coat of paint, they relied on this underlying system, so it needed to be done.
As a result of implementing power progression, travel and ultimate powers now become usable when they are supposed to, and team-ups unlock powers gradually as they level up. However, this is not the full extent of these changes: it is now also possible to upgrade your ultimate power’s rank using character tokens, and team-up procs that can activate when the team-up is away are now properly assigned to avatars.
Another vital piece of the talent puzzle is mapped powers. This is not a new system either: it was introduced at least as far back as September 2014 when Rogue was released as a playable hero in version 1.26, and it is the foundation of her power stealing mechanic. Mapping a power means replacing it with another one, while also keeping the original power’s rank. The system itself is not very complicated, but it required doing an overhaul of our ability key mapping implementation, which was more in-depth. Ability key mapping is what the game calls action bars, and each “ability” can be either a power or an item. This system was built with various other features in mind, including having multiple switchable bars (unused in BUE), power specs, and tranform mode powers that replace all of your buttons. All of them had to be accounted for.
Speaking of transform mode powers, there are only two of them in version 1.52 (Rocket Raccoon’s Mechfall and Rogue’s Final Form), and both of them now work thanks to these backend improvements.
There is also one thing I would like to note regarding ability key mappings in version 1.52, because we have received numerous bug reports about this. When you level up, the client automatically slots powers into free slots, even if they were not unlocked by reaching that specific level. This means powers will always be reslotted into their designated slots on level up, as long as these slots are not occupied by other powers. Although this is arguably not intuitive behavior, it is done by the client on its own, so to avoid desyncs we have to do the same server-side.
With power progression and mapped powers implemented, talents were pretty much ready to go. The rest of the functionality, like changing how a power behaves, is done using the same proc and condition based “scripting” system we discussed in previous reports, so it pretty much just worked all of a sudden. Now the power system is almost feature complete, with only a few minor things still missing, like shared health pools used by one of the boss encounters in the Muspelheim raid. We will take care of these smaller features at some point before 1.0, but for now we will be moving on to other, higher priority features.
Prestige
Talents ended up being implemented faster than expected, which gave me some time to work on minor features that were originally scheduled for 0.7.0: Hero Synergies and Prestige. Synergies are not very interesting to talk about, since they are simply stat bonuses, but with Prestige there are some curious aspects to discuss.
Prestiging a hero is more involved than just resetting their level. You also need to:
-
Validate the prestige consumable item interaction.
-
Do a full respec, including unassigning mapped powers and talents.
-
Check restrictions of all equipped items and unequip them, handling potentially running out of space in the general inventory.
-
Reset the progress of missions that save their state per avatar.
-
Grant prestige loot (more on that later).
-
Recalculate the number of avatars at the new prestige level to update achievements.
-
Do a teleport to the starting region.
As you can see, there are many different systems interacting to make this single thing happen. Because all of this occurs at the same time, there were some timing-related issues to solve, particularly related to modifying the inventory at the same time as teleporting, which triggers a save.
While many people remember one of the main Prestige rewards being additional copies of the starting costume, this was actually changed in BUE. Here is how Asros, one of the developers working at Gazillion at the time, explained why this change was made on the game’s official forums:
[…]
Costumes and costume revenue is a very important part of our business. We understand that there are many free to play players out there who will be disappointed in this decision. We feel very strongly that going forward, purely cosmetic things like costumes, for the most part(achievements/log in gifts as exceptions), should be cash shop items. Sometimes we have to make unpopular decisions for the betterment of the long term health of the game and the company. The reason for the free defaults was to make prestiging easier for players who had high level costume cores attached. Now with the changes to catalyst system, that is no longer a necessity.
[…]
Gazillion ended up replacing the starting costume with the bonus item find (BIF) loot table (Loot/Tables/BonusItemFind/BonusItemFindTable.prototype
), which is the table also used by S.H.I.E.L.D. Supply Drops. The bad news is that it did not end up being good for the “long term health of the game”. The good news is we do not have financial obligations, so I have added a new setting called GrantStartingCostumeForPrestige
that returns the original reward. Once crafting is working, this will be very useful for all of your costume blending needs.
Now that we have Prestige working, there have been some requests from the community to be able to continue leveling up past Prestige level 6 (Cosmic), which is the cap in version 1.52. Gazillion was actually working on extending the Prestige system with something called the Omega Prestige:
Omega Prestige was available in the console versions of the game for some heroes, and the code for it exists in PC test center builds of version 1.53. None of it is available in 1.52, but we have come up with an alternative.
Ultimate Prestige (named by popular vote on our Discord server) is going to be a custom system that will allow you to reset your Prestige level back to 0 (White). We even came up with a way to display your Prestige reset count in the client’s UI:
Ultimate Prestige will be effectively uncapped, allowing you to level up your favorite hero over and over for as long as you desire. This system is going to be completely optional: server owners will be able to completely disable it in server settings, and we also plan to make the Prestige reset count hideable, in case you do not want everybody around you to know just how much fun you are having with your Squirrel Girl.
Prototype Patcher
AlexBond is back again to talk about his latest endeavor - patching the game’s data files server-side.
Hello everyone, this is AlexBond.
After the recent large power update we discovered more bugs that existed in the original game, which we usually call Gazillion issues. One example of such issue is related to Emma Frost’s controlled minions. As it turns out, when Gazillion reworked mobs as part of their story overhaul, they forgot to flag the new mob alliances as hostile for controlled entities, which means entities controlled by Emma, Vision, Magik, and Rogue are not going to attack enemies belonging to these alliances. These enemies are encountered in the first chapter of the story, so it is not as noticable as it could have been.

New alliances:

To fix issues such as these I came up with an idea to implement a system called Prototype Patch Manager, which can be used to change prototype data when it is being loaded on the server. This allows us to fix numerous bugs without having to rely on hardcoded fixes.
All patches are stored in JSON files in the following subdirectory: Data\Game\Patches
.
For example, the patch to fix the issue with Emma Frost looks like this:
{
"Enabled": true,
"Prototype": "Entity/Alliances/Overrides/Controlled.prototype",
"Path": "HostileTo[]",
"Description": "Add [GangBiker, GangShocker, GangHellbane, GangElectro, EnemyToEveryone] to Controlled Keywords",
"ValueType": "PrototypeId[]",
"Value": [ 3046566727234031236, 11722709847486435174, 1849637429396115378, 3414168095237017445, 4627307232939675976 ]
}
-
Prototype
is the file path of the prototype we want to modify. -
Path
is the internal path inside the prototype that points to the required value or array (arrays are specified using[]
). -
ValueType
is the type of the value we are going to change. For prototype references this is going to bePrototypeId
, but for embedded prototype instances you need to usePrototypeDataRef
. -
Value
is a general purpose field that can contain various types, like numerical values, strings, or JSON objects.
Thanks to these patches, we can fix bugs that existed in the original game, bring back events that require loot table modifications, and much more.

We can also add back entities that were removed from the game by repurposing unused markers. For instance, these patches add Cloak and Dagger to the Avengers Tower:
{
"Enabled": true,
"Prototype": "Resource/Cells/DistrictCells/Avengers_Tower/AvengersTowerNPE_HUB.cell",
"Path": "MarkerSet.Markers[27].EntityGuid",
"Description": "Add Dagger",
"ValueType": "PrototypeGuid",
"Value": 6158563480682235387
},
{
"Enabled": true,
"Prototype": "Resource/Cells/DistrictCells/Avengers_Tower/AvengersTowerNPE_HUB.cell",
"Path": "MarkerSet.Markers[27].Position",
"Description": "Change Dagger position",
"ValueType": "Vector3",
"Value": [ -694.76, 2003.63, 160.97 ]
},
{
"Enabled": true,
"Prototype": "Resource/Cells/DistrictCells/Avengers_Tower/AvengersTowerNPE_HUB.cell",
"Path": "MarkerSet.Markers[28].EntityGuid",
"Description": "Add Cloak",
"ValueType": "PrototypeGuid",
"Value": 13282508175937904349
}
Meet the new guests!

In addition to modifying the values of existing fields, there is also a more complex system that can be used to add new embedded prototypes. For example, we can create a loot table that would drop Carnival Beads by repurposing the unused TestItemsLootTable
:
{
"Enabled": true,
"Prototype": "Loot/Tables/Test/TestItemsLootTable.prototype",
"Path": "Choices[0].Choices[]",
"Description": "Add [MGBeads, MGBeads2] as LootDropItemPrototype",
"ValueType": "Prototype[]",
"Value": [
{
"ParentDataRef": 1071992662862269383,
"Item": 7800473051294539167,
"Weight": 50
},
{
"ParentDataRef": 1071992662862269383,
"Item": 10014849647161122257,
"Weight": 20
}
]
}
To add a new Prototype
you need to specify its ParentDataRef
, usually it is a *.defaults
prototype:

ParentDataRef
is followed by fields inside this class (Item
, Weight
) that we override from defaults. In order for the TestItemsLootTable
to work and bosses to drop what we want, we need to add this table’s id (14120665269944980064
) to the global SpecialEventsTable
:
{
"Enabled": true,
"Prototype": "Loot/Tables/Mob/Bosses/SpecialEventsTable.prototype",
"Path": "Choices[]",
"Description": "Add TestItemsLootTable for CarnivalEvent",
"ValueType": "PrototypeDataRef",
"Value": 14120665269944980064
}
Now we can defeat Black Cat and get our Carnival Beads:

I have made patches for multiple such events, Mardi Gras is just an example for people who want to try doing it themselves.
It is also possible to modify missions like this in a limited fashion, including bringing some of them back. When making changes to mission prototypes, here is what is important to keep in mind:
-
The client is going to complain and not refresh objectives if the mission was disabled. However, the mission will work and you will be able to get rewards.
-
You cannot modify elements related to visibility and interaction. They have to be in sync between the client and the server.
-
If data is used only by the server, it is safe to modify.
Hopefuly somebody will use these tools to bring back something that was disabled (intentionally or by mistake).
And with that it is time to say goodbye for now. Good luck leveling up NoLifer Ultimate Prestige!
This is it for this progress report. See you all next time!