Hello! My name is Sergey Kachan, and I’m a client developer on the War Robots project. War Robots has been around for many years, and during this time the game has accumulated a huge variety of content: robots, weapons, drones, titans, pilots, and so on. And for all of this to work, we need to store a large amount of different types of information. This information is stored in “balances.” Today I’m going to talk about how balances are structured in our project, what’s happened to them over the past 11 years, and how we’ve dealt with it. Balances in the Project Like any other project, War Robots can be divided into two parts: meta and core gameplay. Meta gameplay (metagaming) is any activity that goes beyond the core game loop but still affects the gameplay. This includes purchasing and upgrading game content, participating in social or event activities. Core gameplay (core gameplay loop) is the main repeating cycle of actions that the player performs in the game to achieve their goals. In our case, it’s robot battles on specific maps. Each part of the project needs its own balance, so we also split balances into two categories — meta and core. War Robots also has so-called Skirmish modes, which require their own separate balances. A Skirmish mode is a modification of existing modes or maps with different characteristics or rules. Skirmish modes are often event-based, available to players during various holidays, mainly for fun. For example, players might be able to kill each other with a single shot or move around in zero gravity. So in total, we have 4 balances: 2 for the default mode and 2 for the Skirmish mode. \ \ Over 11 years, War Robots has accumulated a ton of awesome content: 95 robots 21 titans 175 different weapons 40 drones 16 motherships a huge number of skins, remodels, modules, pilots, turrets, ultimate versions of content, and maps And as you can imagine, to make all of this work we need to store information about behavior, stats, availability, prices, and much, much more. As a result, our balances have grown to an indecent size: | \ | Default mode | Skirmish mode | |----|----|----| | Meta balance | 9.2 MB | 9.2 MB | | Core balance | 13.1 MB | 13.1 MB | After some quick calculations, we found that a player would need to download 44.6 MB. That’s quite a lot! We really didn’t want to force players to download such large amounts of data every time a balance changed. And distributing that much data via CDN isn’t exactly cheap either. Just to remind you: War Robots has reached 300 million registered users. In 2024, our monthly active audience was 4.7 million people, and 690 thousand players logged in every day. Now imagine the amount of data. A lot, right? We thought so too. So, we decided to do everything we could to cut down the size of our balances! Hunting Down the Problem The first step was to analyze the balances and try to figure out: “What’s taking up so much space?” Manually going through everything was the last thing we wanted to do — it would’ve taken ages. So, we wrote a set of tools that collected and aggregated all the information we needed about the balances. The tool would take a balance file as input and, using reflection, iterate through all the structures, gathering data on what types of information we stored and how much space each one occupied. The results were discouraging: Meta Balance | \ | % in balance | Usage count | |----|----|----| | String | 28.478 % | 164 553 | | Int32 | 27.917 % | 161 312 | | Boolean | 6.329 % | 36 568 | | Double | 5.845 % | 33 772 | | Int64 | 4.682 % | 27 054 | | Custom structures | 26.749 % | — | \ Core Balance | \ | % in balance | Usage count | |----|----|----| | String | 34.259 % | 232 229 | | Double | 23.370 % | 158 418 | | Int32 | 20.955 % | 142 050 | | Boolean | 5.306 % | 34 323 | | Custom structures | 16.11 % | — | \ After analyzing the situation, we realized that strings were taking up far too much space, and something had to be done about it. So, we built another tool. This one scanned the balance file and generated a map of all the strings along with the number of times each one was duplicated. The results weren’t encouraging either. Some strings were repeated tens of thousands of times! We had found the problem. Now the question was: how do we fix it? Optimizing the Balances For obvious reasons, we couldn’t just get rid of strings altogether. Strings are used for things like localization keys and various IDs. But what we could do was eliminate the duplication of strings. The idea was as simple as it gets: Create a list of unique strings for each balance (essentially, a dedicated storage). Send this list along with the data. \ public class BalanceMessage {   public BalanceMessageData Data;   public StringStorage Storage;   public string Version; } \ StringStorage is essentially a wrapper around a list of strings. When we build the string storage, each balance structure remembers the index of the string it needs. Later, when retrieving data, we just pass the index and quickly get the value. \ public class StringStorage {    public List<string> Values;    public string GetValue(StringIdx id) => Values[id]; } \ Instead of passing the strings themselves inside the balance structures, we began passing the index of where the string is stored in the string storage. Before: \ public class SomeBalanceMessage {   public string Id;   public string Name;   public int Amount; } \ After: \ public class SomeBalanceMessageV2 {   public StringIdx Id;   public StringIdx Name;   public int Amount; } \ StringIdx is basically just a wrapper around an int. This way, we completely eliminated direct string transfers inside the balance structures. \ public readonly struct StringIdx : IEquatable<StringIdx> {   private readonly int _id;   internal StringIdx(int value) {_id = value; }   public static implicit operator int(StringIdx value) => value._id;  public bool Equals(StringIdx other) => _id == other._id; } \ This approach reduced the number of strings by tens of times. \ | \ | String usage count | String usage count | |----|----|----| | | Before | After | | Meta balance | 164 553 | 10 082 | | Core balance | 232 229 | 14 228 | Not bad, right? But that was just the beginning — we didn’t stop there. Reworking the Data Protocol For transmitting and processing balance structures, we had been using MessagePack. MessagePack is a binary data serialization format designed as a more compact and faster alternative to JSON. It’s meant for efficient data exchange between applications or services, allowing a significant reduction in data size — especially useful where performance and bandwidth matter. Initially, MessagePack came in a JSON-like format, where the data used string keys. That’s certainly convenient, but also quite space-consuming. So we decided to sacrifice some flexibility and switch to a binary byte array. Before: \ public class SomeBalanceMessage {   [Key("id")]   public string Id;      [Key("name")]   public string Name;      [Key("amount")]   public int Amount; } \ After: \ public class SomeBalanceMessageV2 {   [Key(0)]   public StringIdx Id;      [Key(1)]   public StringIdx Name;      [Key(2)]   public int Amount; } \ We also removed all empty collections — instead of sending them, we now transmit null values. This reduced both the overall data size and the time required for serialization and deserialization. Testing the Changes A golden rule of good development (and one that will save you a lot of nerves) is to always implement new features in a way that lets you quickly roll them back if something goes wrong. For that reason, we add all new features behind “toggles.” To make this work, we had to support two versions of balances at the same time: the old one and the optimized one. During development, we needed to make sure that all data was transferred correctly. Old and new balances — regardless of format or structure — had to produce the exact same values. And remember, the optimized balances had changed their structure drastically, but that wasn’t supposed to affect anything except their size. To achieve this, we wrote a large number of unit tests for each balance. At first, we compared all fields “head-on” — checking every single one explicitly. This worked, but it was time-consuming, and even the smallest change in the balances would break the tests, forcing us to rewrite them constantly. This slowed us down and was quite distracting. Eventually, we had enough of that and came up with a more convenient testing approach for comparing balances. Reflection came to the rescue again. We took two versions of the balance structures, e.g. SomeBalanceMessage and SomeBalanceMessageV2, and iterated over them — comparing field counts, names, and values. If anything didn’t match, we tracked down the problem. This solution saved us a huge amount of time later on. Optimization Results Thanks to these optimizations, we managed to reduce both the size of the files transmitted over the network and the time it takes to deserialize them on the client. We also decreased the amount of memory required on the client side after balance deserialization. File Size | \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta balance | 9.2 MB | 1.28 MB | - 86 % | | Core balance | 13.1 MB | 2.22 MB | - 83 % | Deserialization Time | \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta balance | 967 ms | 199 ms | - 79 % | | Core balance | 1165 ms | 265 ms | - 77 % | Data in Memory | \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta + Core | ~ 45.3 MB | ~ 33.5 MB | - 26 % | Conclusions The results of the optimization fully satisfied us. The balance files were reduced by more than 80%. Traffic went down, and the players were happy. To sum it up: be careful with the data you transmit, and don’t send anything unnecessary. Strings are best stored in unique storages to avoid creating duplicates. And if your custom data (prices, stats, etc.) also contains a lot of repetition, try packing those into unique storages as well. This will save you many megabytes — and a lot of money on maintaining CDN serversHello! My name is Sergey Kachan, and I’m a client developer on the War Robots project. War Robots has been around for many years, and during this time the game has accumulated a huge variety of content: robots, weapons, drones, titans, pilots, and so on. And for all of this to work, we need to store a large amount of different types of information. This information is stored in “balances.” Today I’m going to talk about how balances are structured in our project, what’s happened to them over the past 11 years, and how we’ve dealt with it. Balances in the Project Like any other project, War Robots can be divided into two parts: meta and core gameplay. Meta gameplay (metagaming) is any activity that goes beyond the core game loop but still affects the gameplay. This includes purchasing and upgrading game content, participating in social or event activities. Core gameplay (core gameplay loop) is the main repeating cycle of actions that the player performs in the game to achieve their goals. In our case, it’s robot battles on specific maps. Each part of the project needs its own balance, so we also split balances into two categories — meta and core. War Robots also has so-called Skirmish modes, which require their own separate balances. A Skirmish mode is a modification of existing modes or maps with different characteristics or rules. Skirmish modes are often event-based, available to players during various holidays, mainly for fun. For example, players might be able to kill each other with a single shot or move around in zero gravity. So in total, we have 4 balances: 2 for the default mode and 2 for the Skirmish mode. \ \ Over 11 years, War Robots has accumulated a ton of awesome content: 95 robots 21 titans 175 different weapons 40 drones 16 motherships a huge number of skins, remodels, modules, pilots, turrets, ultimate versions of content, and maps And as you can imagine, to make all of this work we need to store information about behavior, stats, availability, prices, and much, much more. As a result, our balances have grown to an indecent size: | \ | Default mode | Skirmish mode | |----|----|----| | Meta balance | 9.2 MB | 9.2 MB | | Core balance | 13.1 MB | 13.1 MB | After some quick calculations, we found that a player would need to download 44.6 MB. That’s quite a lot! We really didn’t want to force players to download such large amounts of data every time a balance changed. And distributing that much data via CDN isn’t exactly cheap either. Just to remind you: War Robots has reached 300 million registered users. In 2024, our monthly active audience was 4.7 million people, and 690 thousand players logged in every day. Now imagine the amount of data. A lot, right? We thought so too. So, we decided to do everything we could to cut down the size of our balances! Hunting Down the Problem The first step was to analyze the balances and try to figure out: “What’s taking up so much space?” Manually going through everything was the last thing we wanted to do — it would’ve taken ages. So, we wrote a set of tools that collected and aggregated all the information we needed about the balances. The tool would take a balance file as input and, using reflection, iterate through all the structures, gathering data on what types of information we stored and how much space each one occupied. The results were discouraging: Meta Balance | \ | % in balance | Usage count | |----|----|----| | String | 28.478 % | 164 553 | | Int32 | 27.917 % | 161 312 | | Boolean | 6.329 % | 36 568 | | Double | 5.845 % | 33 772 | | Int64 | 4.682 % | 27 054 | | Custom structures | 26.749 % | — | \ Core Balance | \ | % in balance | Usage count | |----|----|----| | String | 34.259 % | 232 229 | | Double | 23.370 % | 158 418 | | Int32 | 20.955 % | 142 050 | | Boolean | 5.306 % | 34 323 | | Custom structures | 16.11 % | — | \ After analyzing the situation, we realized that strings were taking up far too much space, and something had to be done about it. So, we built another tool. This one scanned the balance file and generated a map of all the strings along with the number of times each one was duplicated. The results weren’t encouraging either. Some strings were repeated tens of thousands of times! We had found the problem. Now the question was: how do we fix it? Optimizing the Balances For obvious reasons, we couldn’t just get rid of strings altogether. Strings are used for things like localization keys and various IDs. But what we could do was eliminate the duplication of strings. The idea was as simple as it gets: Create a list of unique strings for each balance (essentially, a dedicated storage). Send this list along with the data. \ public class BalanceMessage {   public BalanceMessageData Data;   public StringStorage Storage;   public string Version; } \ StringStorage is essentially a wrapper around a list of strings. When we build the string storage, each balance structure remembers the index of the string it needs. Later, when retrieving data, we just pass the index and quickly get the value. \ public class StringStorage {    public List<string> Values;    public string GetValue(StringIdx id) => Values[id]; } \ Instead of passing the strings themselves inside the balance structures, we began passing the index of where the string is stored in the string storage. Before: \ public class SomeBalanceMessage {   public string Id;   public string Name;   public int Amount; } \ After: \ public class SomeBalanceMessageV2 {   public StringIdx Id;   public StringIdx Name;   public int Amount; } \ StringIdx is basically just a wrapper around an int. This way, we completely eliminated direct string transfers inside the balance structures. \ public readonly struct StringIdx : IEquatable<StringIdx> {   private readonly int _id;   internal StringIdx(int value) {_id = value; }   public static implicit operator int(StringIdx value) => value._id;  public bool Equals(StringIdx other) => _id == other._id; } \ This approach reduced the number of strings by tens of times. \ | \ | String usage count | String usage count | |----|----|----| | | Before | After | | Meta balance | 164 553 | 10 082 | | Core balance | 232 229 | 14 228 | Not bad, right? But that was just the beginning — we didn’t stop there. Reworking the Data Protocol For transmitting and processing balance structures, we had been using MessagePack. MessagePack is a binary data serialization format designed as a more compact and faster alternative to JSON. It’s meant for efficient data exchange between applications or services, allowing a significant reduction in data size — especially useful where performance and bandwidth matter. Initially, MessagePack came in a JSON-like format, where the data used string keys. That’s certainly convenient, but also quite space-consuming. So we decided to sacrifice some flexibility and switch to a binary byte array. Before: \ public class SomeBalanceMessage {   [Key("id")]   public string Id;      [Key("name")]   public string Name;      [Key("amount")]   public int Amount; } \ After: \ public class SomeBalanceMessageV2 {   [Key(0)]   public StringIdx Id;      [Key(1)]   public StringIdx Name;      [Key(2)]   public int Amount; } \ We also removed all empty collections — instead of sending them, we now transmit null values. This reduced both the overall data size and the time required for serialization and deserialization. Testing the Changes A golden rule of good development (and one that will save you a lot of nerves) is to always implement new features in a way that lets you quickly roll them back if something goes wrong. For that reason, we add all new features behind “toggles.” To make this work, we had to support two versions of balances at the same time: the old one and the optimized one. During development, we needed to make sure that all data was transferred correctly. Old and new balances — regardless of format or structure — had to produce the exact same values. And remember, the optimized balances had changed their structure drastically, but that wasn’t supposed to affect anything except their size. To achieve this, we wrote a large number of unit tests for each balance. At first, we compared all fields “head-on” — checking every single one explicitly. This worked, but it was time-consuming, and even the smallest change in the balances would break the tests, forcing us to rewrite them constantly. This slowed us down and was quite distracting. Eventually, we had enough of that and came up with a more convenient testing approach for comparing balances. Reflection came to the rescue again. We took two versions of the balance structures, e.g. SomeBalanceMessage and SomeBalanceMessageV2, and iterated over them — comparing field counts, names, and values. If anything didn’t match, we tracked down the problem. This solution saved us a huge amount of time later on. Optimization Results Thanks to these optimizations, we managed to reduce both the size of the files transmitted over the network and the time it takes to deserialize them on the client. We also decreased the amount of memory required on the client side after balance deserialization. File Size | \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta balance | 9.2 MB | 1.28 MB | - 86 % | | Core balance | 13.1 MB | 2.22 MB | - 83 % | Deserialization Time | \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta balance | 967 ms | 199 ms | - 79 % | | Core balance | 1165 ms | 265 ms | - 77 % | Data in Memory | \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta + Core | ~ 45.3 MB | ~ 33.5 MB | - 26 % | Conclusions The results of the optimization fully satisfied us. The balance files were reduced by more than 80%. Traffic went down, and the players were happy. To sum it up: be careful with the data you transmit, and don’t send anything unnecessary. Strings are best stored in unique storages to avoid creating duplicates. And if your custom data (prices, stats, etc.) also contains a lot of repetition, try packing those into unique storages as well. This will save you many megabytes — and a lot of money on maintaining CDN servers

Optimizing the Ever-Growing Balance in an 11-Year-Old Game

Hello! My name is Sergey Kachan, and I’m a client developer on the War Robots project.

War Robots has been around for many years, and during this time the game has accumulated a huge variety of content: robots, weapons, drones, titans, pilots, and so on. And for all of this to work, we need to store a large amount of different types of information. This information is stored in “balances.”

Today I’m going to talk about how balances are structured in our project, what’s happened to them over the past 11 years, and how we’ve dealt with it.

Balances in the Project

Like any other project, War Robots can be divided into two parts: meta and core gameplay.

Meta gameplay (metagaming) is any activity that goes beyond the core game loop but still affects the gameplay. This includes purchasing and upgrading game content, participating in social or event activities.

Core gameplay (core gameplay loop) is the main repeating cycle of actions that the player performs in the game to achieve their goals. In our case, it’s robot battles on specific maps.

Each part of the project needs its own balance, so we also split balances into two categories — meta and core.

War Robots also has so-called Skirmish modes, which require their own separate balances.

A Skirmish mode is a modification of existing modes or maps with different characteristics or rules. Skirmish modes are often event-based, available to players during various holidays, mainly for fun. For example, players might be able to kill each other with a single shot or move around in zero gravity.

So in total, we have 4 balances: 2 for the default mode and 2 for the Skirmish mode.

\

\ Over 11 years, War Robots has accumulated a ton of awesome content:

  • 95 robots
  • 21 titans
  • 175 different weapons
  • 40 drones
  • 16 motherships
  • a huge number of skins, remodels, modules, pilots, turrets, ultimate versions of content, and maps

And as you can imagine, to make all of this work we need to store information about behavior, stats, availability, prices, and much, much more.

As a result, our balances have grown to an indecent size:

| \ | Default mode | Skirmish mode | |----|----|----| | Meta balance | 9.2 MB | 9.2 MB | | Core balance | 13.1 MB | 13.1 MB |

After some quick calculations, we found that a player would need to download 44.6 MB. That’s quite a lot!

We really didn’t want to force players to download such large amounts of data every time a balance changed. And distributing that much data via CDN isn’t exactly cheap either.

Just to remind you: War Robots has reached 300 million registered users. In 2024, our monthly active audience was 4.7 million people, and 690 thousand players logged in every day.

Now imagine the amount of data. A lot, right? We thought so too. So, we decided to do everything we could to cut down the size of our balances!

Hunting Down the Problem

The first step was to analyze the balances and try to figure out: “What’s taking up so much space?”

Manually going through everything was the last thing we wanted to do — it would’ve taken ages. So, we wrote a set of tools that collected and aggregated all the information we needed about the balances.

The tool would take a balance file as input and, using reflection, iterate through all the structures, gathering data on what types of information we stored and how much space each one occupied.

The results were discouraging:

Meta Balance

| \ | % in balance | Usage count | |----|----|----| | String | 28.478 % | 164 553 | | Int32 | 27.917 % | 161 312 | | Boolean | 6.329 % | 36 568 | | Double | 5.845 % | 33 772 | | Int64 | 4.682 % | 27 054 | | Custom structures | 26.749 % | — |

\

Core Balance

| \ | % in balance | Usage count | |----|----|----| | String | 34.259 % | 232 229 | | Double | 23.370 % | 158 418 | | Int32 | 20.955 % | 142 050 | | Boolean | 5.306 % | 34 323 | | Custom structures | 16.11 % | — |

\ After analyzing the situation, we realized that strings were taking up far too much space, and something had to be done about it.

So, we built another tool. This one scanned the balance file and generated a map of all the strings along with the number of times each one was duplicated.

The results weren’t encouraging either. Some strings were repeated tens of thousands of times!

We had found the problem. Now the question was: how do we fix it?

Optimizing the Balances

For obvious reasons, we couldn’t just get rid of strings altogether. Strings are used for things like localization keys and various IDs. But what we could do was eliminate the duplication of strings.

The idea was as simple as it gets:

  • Create a list of unique strings for each balance (essentially, a dedicated storage).
  • Send this list along with the data.

\

public class BalanceMessage {   public BalanceMessageData Data;   public StringStorage Storage;   public string Version; } 

\ StringStorage is essentially a wrapper around a list of strings. When we build the string storage, each balance structure remembers the index of the string it needs. Later, when retrieving data, we just pass the index and quickly get the value.

\

public class StringStorage { &nbsp;&nbsp;&nbsp;public List<string> Values; &nbsp;&nbsp;&nbsp;public string GetValue(StringIdx id) => Values[id]; } 

\ Instead of passing the strings themselves inside the balance structures, we began passing the index of where the string is stored in the string storage.

Before:

\

public class SomeBalanceMessage { &nbsp;&nbsp;public string Id; &nbsp;&nbsp;public string Name; &nbsp;&nbsp;public int Amount; } 

\ After:

\

public class SomeBalanceMessageV2 { &nbsp;&nbsp;public StringIdx Id; &nbsp;&nbsp;public StringIdx Name; &nbsp;&nbsp;public int Amount; } 

\ StringIdx is basically just a wrapper around an int. This way, we completely eliminated direct string transfers inside the balance structures.

\

public readonly struct StringIdx : IEquatable<StringIdx> { &nbsp;&nbsp;private readonly int _id; &nbsp;&nbsp;internal StringIdx(int value) {_id = value; } &nbsp;&nbsp;public static implicit operator int(StringIdx value) => value._id; &nbsp;public bool Equals(StringIdx other) => _id == other._id; } 

\ This approach reduced the number of strings by tens of times.

\

| \ | String usage count | String usage count | |----|----|----| | | Before | After | | Meta balance | 164 553 | 10 082 | | Core balance | 232 229 | 14 228 |

Not bad, right?

But that was just the beginning — we didn’t stop there.

Reworking the Data Protocol

For transmitting and processing balance structures, we had been using MessagePack.

MessagePack is a binary data serialization format designed as a more compact and faster alternative to JSON. It’s meant for efficient data exchange between applications or services, allowing a significant reduction in data size — especially useful where performance and bandwidth matter.

Initially, MessagePack came in a JSON-like format, where the data used string keys. That’s certainly convenient, but also quite space-consuming. So we decided to sacrifice some flexibility and switch to a binary byte array.

Before:

\

public class SomeBalanceMessage { &nbsp;&nbsp;[Key("id")] &nbsp;&nbsp;public string Id; &nbsp;&nbsp; &nbsp;&nbsp;[Key("name")] &nbsp;&nbsp;public string Name; &nbsp;&nbsp; &nbsp;&nbsp;[Key("amount")] &nbsp;&nbsp;public int Amount; } 

\ After:

\

public class SomeBalanceMessageV2 { &nbsp;&nbsp;[Key(0)] &nbsp;&nbsp;public StringIdx Id; &nbsp;&nbsp; &nbsp;&nbsp;[Key(1)] &nbsp;&nbsp;public StringIdx Name; &nbsp;&nbsp; &nbsp;&nbsp;[Key(2)] &nbsp;&nbsp;public int Amount; } 

\ We also removed all empty collections — instead of sending them, we now transmit null values. This reduced both the overall data size and the time required for serialization and deserialization.

Testing the Changes

A golden rule of good development (and one that will save you a lot of nerves) is to always implement new features in a way that lets you quickly roll them back if something goes wrong. For that reason, we add all new features behind “toggles.” To make this work, we had to support two versions of balances at the same time: the old one and the optimized one.

During development, we needed to make sure that all data was transferred correctly. Old and new balances — regardless of format or structure — had to produce the exact same values. And remember, the optimized balances had changed their structure drastically, but that wasn’t supposed to affect anything except their size.

To achieve this, we wrote a large number of unit tests for each balance.

At first, we compared all fields “head-on” — checking every single one explicitly. This worked, but it was time-consuming, and even the smallest change in the balances would break the tests, forcing us to rewrite them constantly. This slowed us down and was quite distracting.

Eventually, we had enough of that and came up with a more convenient testing approach for comparing balances.

Reflection came to the rescue again. We took two versions of the balance structures, e.g. SomeBalanceMessage and SomeBalanceMessageV2, and iterated over them — comparing field counts, names, and values. If anything didn’t match, we tracked down the problem. This solution saved us a huge amount of time later on.

Optimization Results

Thanks to these optimizations, we managed to reduce both the size of the files transmitted over the network and the time it takes to deserialize them on the client. We also decreased the amount of memory required on the client side after balance deserialization.

File Size

| \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta balance | 9.2 MB | 1.28 MB | - 86 % | | Core balance | 13.1 MB | 2.22 MB | - 83 % |

Deserialization Time

| \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta balance | 967 ms | 199 ms | - 79 % | | Core balance | 1165 ms | 265 ms | - 77 % |

Data in Memory

| \ | Old balances | Optimized balances | Profit | |----|----|----|----| | Meta + Core | ~ 45.3 MB | ~ 33.5 MB | - 26 % |

Conclusions

The results of the optimization fully satisfied us. The balance files were reduced by more than 80%. Traffic went down, and the players were happy.

To sum it up: be careful with the data you transmit, and don’t send anything unnecessary.

Strings are best stored in unique storages to avoid creating duplicates. And if your custom data (prices, stats, etc.) also contains a lot of repetition, try packing those into unique storages as well. This will save you many megabytes — and a lot of money on maintaining CDN servers.

Market Opportunity
SQUID MEME Logo
SQUID MEME Price(GAME)
$33.158
$33.158$33.158
-0.01%
USD
SQUID MEME (GAME) Live Price Chart
Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact service@support.mexc.com for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

Holywater Raises Additional $22 Million To Expand AI Vertical Video Platform

Holywater Raises Additional $22 Million To Expand AI Vertical Video Platform

The post Holywater Raises Additional $22 Million To Expand AI Vertical Video Platform appeared on BitcoinEthereumNews.com. Holywater is positioning itself as “the
Share
BitcoinEthereumNews2026/01/17 01:18
OpenVPP accused of falsely advertising cooperation with the US government; SEC commissioner clarifies no involvement

OpenVPP accused of falsely advertising cooperation with the US government; SEC commissioner clarifies no involvement

PANews reported on September 17th that on-chain sleuth ZachXBT tweeted that OpenVPP ( $OVPP ) announced this week that it was collaborating with the US government to advance energy tokenization. SEC Commissioner Hester Peirce subsequently responded, stating that the company does not collaborate with or endorse any private crypto projects. The OpenVPP team subsequently hid the response. Several crypto influencers have participated in promoting the project, and the accounts involved have been questioned as typical influencer accounts.
Share
PANews2025/09/17 23:58
Best Crypto to Buy as Saylor & Crypto Execs Meet in US Treasury Council

Best Crypto to Buy as Saylor & Crypto Execs Meet in US Treasury Council

The post Best Crypto to Buy as Saylor & Crypto Execs Meet in US Treasury Council appeared on BitcoinEthereumNews.com. Michael Saylor and a group of crypto executives met in Washington, D.C. yesterday to push for the Strategic Bitcoin Reserve Bill (the BITCOIN Act), which would see the U.S. acquire up to 1M $BTC over five years. With Bitcoin being positioned yet again as a cornerstone of national monetary policy, many investors are turning their eyes to projects that lean into this narrative – altcoins, meme coins, and presales that could ride on the same wave. Read on for three of the best crypto projects that seem especially well‐suited to benefit from this macro shift:  Bitcoin Hyper, Best Wallet Token, and Remittix. These projects stand out for having a strong use case and high adoption potential, especially given the push for a U.S. Bitcoin reserve.   Why the Bitcoin Reserve Bill Matters for Crypto Markets The strategic Bitcoin Reserve Bill could mark a turning point for the U.S. approach to digital assets. The proposal would see America build a long-term Bitcoin reserve by acquiring up to one million $BTC over five years. To make this happen, lawmakers are exploring creative funding methods such as revaluing old gold certificates. The plan also leans on confiscated Bitcoin already held by the government, worth an estimated $15–20B. This isn’t just a headline for policy wonks. It signals that Bitcoin is moving from the margins into the core of financial strategy. Industry figures like Michael Saylor, Senator Cynthia Lummis, and Marathon Digital’s Fred Thiel are all backing the bill. They see Bitcoin not just as an investment, but as a hedge against systemic risks. For the wider crypto market, this opens the door for projects tied to Bitcoin and the infrastructure that supports it. 1. Bitcoin Hyper ($HYPER) – Turning Bitcoin Into More Than Just Digital Gold The U.S. may soon treat Bitcoin as…
Share
BitcoinEthereumNews2025/09/18 00:27