Force of Nature 2 Dev. Blog


Entry 50 - New Map

To begin, let me briefly summarize the previous post. The builder had minimal interaction with others during the game, so the following changes were made to address this issue:

  • The map was redesigned to include a shared forest for both teams, where builders can gather resources.
  • A new leveling system for builders was introduced, encouraging them to visit the forest more frequently.
  • The attack mechanics of the gnomes were adjusted so that they could be the same easily destroyed by both champions and builders.
  • Builders now have adaptive running speeds: they run quickly when no enemies are nearby and switch to normal speed when enemies are present.

Now, let's move on to testing. We will examine the gameplay from the builder’s perspective. I apologize in advance for the video quality. We recorded these sessions for internal use – they were very helpful in analyzing the outcomes of matches. During gameplay, attention is often focused on one thing, and many issues go unnoticed. Watching the recordings, especially those of someone else's game, allows us to see the overall picture and quickly identify areas for improvement. As a result, after each game, we had several videos from the perspective of each player. To facilitate faster sharing and easier storage, we decided to record in lower quality to keep file sizes small.

 

 

I'd like to highlight some interesting moments from the game and comment on them. I'll refer to the timestamps using the YouTube timer.

 

The first notable moment occurs at 2:56. Here, the builder goes to collect iron, which is a crucial resource used in many recipes. We intentionally placed it on the map in such a way that the path to it is blocked by bushes from the base side and open from the lane side. Therefore, the builder has to choose between spending time and energy to clear a path through the bushes to the iron ore or taking the lane route, which carries the risk of being spotted by an enemy champion. In this scenario, the builder risks getting trapped with no way out. At 8:23, the builder goes for iron again using the already cleared path. However, you can notice that he decided to mine the ore closer to the enemy base rather than the one near his own base. This was because the current situation on the lane made it unlikely for him to be spotted by an enemy champion. Since iron is quite limited on the map and may become scarce towards the end of the game, the builder seized the opportunity to steal the enemy's ore.

 

At 13:44, we see the builder actively placing archer gnomes. He strategically places them among trees to prevent enemy melee minions from reaching them. Another gnome is placed at the enemy's iron ore (at 15:14), highlighting one of the most strategically important locations.

 

The next crucial stage is the extraction of obsidian. Our builder chose a method where the tower guarding the obsidian is distracted by a minion. First, the builder constructed an orc lair because orcs have a troll, the toughest minion, making it perfect for tanking. At 15:38, we see the builder send the troll to attack the tower, while he stands ready to collect as much obsidian as possible. He barely manages to break one stone, yielding three resources, which is just enough to build a shaman lair – the strongest minions.

 

At 22:24, we see the builder placing a gnome to monitor the enemy's obsidian. This was a very successful move, as two minutes later, at 23:05, he spotted the enemy builder heading to collect obsidian. Our builder immediately took advantage of the situation and went to interfere with the enemy’s resource gathering. However, upon arrival, he found that the enemy's defensive tower had already been destroyed, allowing him to freely collect obsidian. The enemy builder had opted for the strategy of upgrading to skeleton archers and using one to destroy the tower. As I mentioned in a previous post, this strategy might seem easier at first glance, but it is actually riskier. As a result, our builder managed to collect some obsidian without much effort but decided not to linger because the enemy champion was not visible on the map, posing a potential threat. As soon as the builder finished breaking the stone, he immediately returned to his base. Meanwhile, an allied champion headed towards him to be ready to defend if necessary.

 

Starting around the 25-minute mark, the builder sets a goal to mine all the iron on the map. Although he doesn’t have a shortage of iron, this strategy can deprive the enemy of a valuable resource. Strategically placed gnomes help spot the enemy champion in time when they attempt to ambush our hero in the forest. Ultimately, the goal of mining all the iron is achieved, leaving the enemy team limited in a resource crucial for upgrading many minions. Later, our builder applies the same strategy to copper.

 

At 30:35, the builder begins controlling a lightning mage minion to defend a tower from enemy attack. As I mentioned earlier, mages are the strongest minions. Additionally, each mage has a unique spell that the builder can activate with a button press. The lightning mage has an attack that targets all enemies within a large radius. The cold mage can slow down all nearby enemies, while the fire mage can launch a fireball that flies in a straight line, hitting and igniting a single target for a period of time.

 

At 32:20, using a gnome, the enemy builder was discovered mining the remaining copper near our base. The champion immediately went to gang up on them. They weren't able to kill the enemy, but at the very least, it forced them to retreat to base for health regeneration and disrupted their resource gathering. At 42:21, we see the reverse situation where the builder, controlling a mage minion, attempted to finish off a champion who had very little health left. They also couldn't secure the kill, but it was a tense moment for everyone involved!

 

In the final minutes of the game, the builder had nothing left to build or upgrade – it was all done. From this point onward, their focus shifted solely to assisting the champion by controlling minions. At 48:30, this assistance proved sufficient to eliminate an opponent. This marked the beginning of the most intense battles, but from the builder's perspective, there was no more material for analysis. One notable tactic occurred at 1:01:00 when the builder decided to barricade the portal with chests from which minions emerged, delaying waves at the base. After accumulating several waves in confinement, they destroyed the chests, unleashing a mega-wave! This unconventional move surprised all other players. Unfortunately, the mega-wave didn't yield much benefit as a mage champion utilized napalm to swiftly dispatch the entire wave with a single spell.

 

Next, we decided to end the game in a draw as it had already lasted over an hour. As a bonus, I'll upload the same game but from the perspective of the champion.

 

 

Let's summarize the gameplay at this point. Have we corrected previous mistakes? Absolutely! The builder now feels like a full member of the team and interacts much more actively with all other players, making the game much more engaging not only for them but also for the champions. Are there still issues in this gameplay? Certainly, and they are quite significant! I'll discuss them in detail in the next post.

2 Comments

Entry 49 - Interaction Between Builder and Other Players

For start, let's clarify some terminology: we'll refer to the combat heroes who stand on the lane and fight each other as champions, while the heroes who focus on gathering resources and building will be called builders.

 

Let's take a closer look at the main gameplay issues using the video from the previous post as an example. At first glance, everything seems quite decent. We see a rather intense and dynamic duel between two champions (an archer and a mage) throughout the game. Meanwhile, the background decorations for this duel, namely the minions and towers, become increasingly interesting, vibrant, and colorful. It looks great; however, the problem is that from the champion's perspective, the game remains a duel from start to finish. There is absolutely no sense of teamwork with the builder.

 

From the builder's perspective, things are even worse. Although the player is actively engaged in various tasks, and the effectiveness of their actions does impact the game's outcome, they barely feel the presence of other players on their own team, let alone notice the enemy team. For the builder, the game becomes less of a team battle and more of a competition against the opposing builder: who can earn more gold, hire stronger minions, and fortify towers faster. The one who contributes the most to their team wins.

 

This happens because the builder doesn't interact with anyone in the game. Let's delve into this further. What types of interactions could they theoretically have? Perhaps the following:

  • builder to allied champion
  • builder to enemy champion
  • builder to builder
  • builder to minions and towers
  • builder to location.

 

Interaction: Builder – Location, Minions, Towers

First, let's examine the simpler connections. Regarding the "Builder – Location" interaction, there are no issues. The builder runs around the location, gathers resources, and interacts with neutral towers. The connection between the character and the location is strong and persists throughout the game. Now, let's look at the builder's interaction with allied minions and towers. Here, everything is also in order, as this was initially designed to be their primary area of responsibility. The interaction between the builder and enemy minions/towers is more complicated – it is practically nonexistent. The builder cannot personally attack them due to their low damage. To enable the builder to attack minions and towers personally, without turning them into a powerful fighter and rendering champions useless, we decided to give the builder the ability to craft a new weapon – a sling. The sling has a long attack animation, and the stone it launches travels very slowly. As a result, hitting a moving target with it is nearly impossible. However, its damage is quite substantial, making the sling an effective weapon against stationary objects such as enemy towers.

 

Interaction: Builder – Allied Champion

This is the primary interaction that ensures a sense of team play, and it currently has major issues. The champion has little to offer the builder. Even for gathering obsidian, it was much easier for the builder to enlist the help of a minion rather than distract the champion from the lane, as this could risk losing their own tower. The builder couldn't help the champion either. One might say the builder helps the champion by sending stronger minions to the lane, but in reality, this is more of an influence than direct assistance. Strong minions do help the lane overall, but they aren't flexible enough to adapt to specific situations. Imagine the situation where the opponent has developed faster, and their side has stronger minions than ours. In such a scenario, our champion would face a tough challenge because besides battling the enemy champion, they would also have to deal with the remnants of minions left after each wave. This critical situation prompts our champion to ask the builder for help. But what can the builder do? They cannot send support in the form of strong minions because they are lagging behind in development, and these minions simply do not exist yet. Essentially, all the champion can ask of the builder is to play better!

 

A more realistic approach seemed to be the builder's assistance through setting up gnome totems. For example, in a critical situation, the builder could come to the lane and place a bunch of archer gnomes who would shoot down enemy minions. Yes, it would require some of the builder's time and resources, but it could effectively help in specific situations. However, a problem arose here as well – the archer gnomes proved to be the most useful, but they were very difficult to balance. If we give them high damage and a lot of health, these gnome totems would become too imbalanced against the enemy builder – just a few of them strategically placed in key points of the enemy forest could make gathering resources practically impossible. On the other hand, with low damage and few health points, these gnome totems became ineffective on the lane – they could be destroyed by a champion in just one or two hits. To try to influence this situation, we decided to change the damage system for gnomes. Each gnome had 3 lives, and any attack against them, regardless of the amount of damage it dealt, would take away one life. This way, a gnome would be destroyed after three attacks, regardless of whether it was attacked by a minion, builder, or champion.

 

Interaction: Builder – Enemy Champion

It was assumed that champions, when they had some free time, could roam into the forest and try to kill the enemy builder. However, even this did not work out.

 

The first reason was that it was extremely difficult for the champion and the builder to meet in the forest. It turned out that the builder spent most of the time at the base – constructing dens, processing resources, and researching upgrades for minions. From the beginning of the game, the builder already had a strategy in place for early-game development, so he knew well which resources and how much of them he would need. To avoid wasting time on frequent visits to the forest, the builder would gather all the necessary resources in one trip and spend the rest of the time at the base. To encourage him to go to the forest more often, we significantly limited the size of his inventory, and the initial pickaxe collected resources very slowly. To allow for personal growth, the builder could craft a stronger pickaxe and a more capacious bag for himself. Fortunately, all the necessary mechanics for this were already available in FoN.

 

But there was a second reason why it was ineffective for the champion to attempt to chase down the builder – they had significantly different running speeds. Even if the champion encountered the builder in the forest, the builder could easily escape. Gathering resources required the builder to constantly cover large distances, so his running speed was much higher than that of the champion, who spent most of his time on the lane. To address this issue, we adjusted the builder's running speed to match the champion's, but we added a passive ability that needed to be upgraded through the skill window – Speed Boost. This skill provided a significant speed boost if no enemies were nearby the builder for the last few seconds. This meant that the builder could still run quickly through the forest to gather resources, but encountering an enemy champion (or even a minion) would instantly deactivate his speed boost ability, giving the champion a chance to catch up.

 

Since we started adding skills that needed to be leveled up for the builder, we also decided to introduce an ability that significantly sped up the resource gathering process for a few seconds. The ability to control minions was also made into a skill – the builder couldn't control minions right from the start; he needed to first upgrade the corresponding skill.

 

Interaction: Builder – Builder

Builders from opposing teams also did not intersect with each other. The reason was simple – they each had their own forest for gathering resources. Initially, we designed the location based on the standard MOBA genre map (like in DOTA and League of Legends), reducing the number of lanes from three to one. In MOBAs, each team has its own jungle, and there are heroes who level up not on the lane, but in the jungle – they are called junglers. They are somewhat similar to our builders. The idea of having two separate forests worked perfectly in DOTA and LoL because junglers had a specific role within the team – they leveled up in the jungle and provided assistance on lanes where needed, using the element of surprise. This is how they interacted with other players, and meeting the enemy jungler in the jungle was unnecessary. In our game, however, this division of forests resulted in the builder remaining isolated. Having separate forests made it less effective to influence another builder's strategy through gnomes – placing a gnome in the enemy's forest required spending a significant amount of time just to enter it.

 

As a result, the map was completely redesigned so that there was only one forest on it, shared by two builders.

 

 

 

That's all for now. In the next post, I'll detail how effective all our gameplay changes turned out to be.

0 Comments

Entry 48 - Evolution of Builder

At this stage, we had established a solid foundation for the MOBA+Builder concept. It was possible to play matches with a builder and a hero on one team against another team with a builder and a hero. Based on our impressions, we iteratively improved the game. To facilitate this, my testers and I would gather at a cozy café, order three large pizzas (thanks to a permanent deal – order two pizzas and get the third one for free), and discuss the matches we had played the previous day. We shared our emotions, talked about what we liked and what we didn't, and voiced our ideas and suggestions. We discussed these proposals, refined them, and compiled a list of fixes and new features we wanted to try in the next test. Once all the adjustments were made, we played several more matches and gathered at the café again. The whole process repeated itself.

 

Minimap

The first thing we changed was the minimap in the corner of the screen. In Force of Nature, the minimap was attached to the main hero, as only the events happening directly around him mattered. In a team game, important events occur in multiple locations simultaneously, so it's crucial to be able to quickly assess the situation. To address this, we had already implemented a free camera that was not tied to the main hero and could move freely across the entire map. However, this was still not enough – it was still quite easy to miss the beginning of an important battle on the main lane, as the builder was focused on a specific task rather than endlessly scanning the area for interesting events.

 

Therefore, the minimap was redesigned to display the entire location. This allowed players to understand what was happening at a glance. Besides being fixed and showing the whole area, the minimap also needed to integrate with the fog of war. Since fog of war wasn't initially present in Force of Nature, it wasn't shown on the minimap. In Force of Nature, there was no fog of war but rather a display of explored territory. This logic wasn't suitable for a MOBA, as players need to know the topology of the map from the beginning. Only the actions of opponents should be hidden, which is why the fog of war exists. Changing the minimap's logic might seem insignificant, but once it was adjusted, playing as the builder became significantly easier!

 

Gnome Totems

As another way for the builder to invest resources, we decided to give him the ability to place totems at various locations on the map. To avoid creating special models for them, we used existing gnome decoration models from Force of Nature. We had the Observer Gnome, Shooter Gnome, Defender Gnome, and Berserker Gnome:

 

 

The Observer Gnome simply revealed the map around him at a considerable distance. The Shooter Gnome attacked any targets within his line of sight. The Defender Gnome provided an aura to all nearby allies (including minions and heroes) that reduced incoming damage. The Berserker Gnome provided an aura that increased attack speed.

 

Rat Minions

New minion races were also added, which became available upon constructing special dens – rats and mages. To remind you, in order to summon particularly strong minion units for the next wave, you first need to build a den for that race. Dens are built using resources that the hero gathers in the forest or crafts himself. However, even after constructing a den, its units are not provided for free. For each summoning of a unit, it was necessary to pay with gold. Gold was obtained by killing any enemy minion. The initial minions, goblins, were completely free of charge. If the builder did not have enough gold to summon the next wave consisting of strong units, a wave of goblins was automatically sent instead. As an alternative to goblins, the rat race was added – these units were stronger than goblins and were also provided free of charge.

 

Here is how the rat den looks:

And here are the rats available for summoning. Like for all other races, there's a tank, melee, and ranged unit:

 

As you can see, for the ranged unit, we chose the porcupine from the second location of FoN. It shoots three quills simultaneously – one quill flies straight towards the target, while the other two veer slightly to the sides. This feature makes them quite interesting units because with proper positioning, they can collectively deal significantly more damage to the enemy team.

 

Mage Minions

Another den added to the game was the Mage den. Unlike other races, these units were not divided into tank/melee/ranged categories. All three mages had ranged attacks and differed in their elemental magic – fire mage, frost mage, and lightning mage. For their appearance, I used models of mages from the last location of FoN, but modified the appearance of their staffs to more vividly represent their respective elements.

 

 

Magic minions were the most powerful, but their den was not easy to build - it required obsidian. In each forest, there was only one obsidian deposit, guarded by a tower - similar to the towers on the lane, but belonging to neither team and firing indiscriminately at everyone. These towers inflicted less damage than those on the lane, but it was still significant enough to prevent peaceful obsidian mining. Destroying the tower was also difficult, as the builder was extremely weak in combat.

 

Despite this, there were three different strategies to obtain obsidian:

  1. Distract the Tower: This was the simplest method. The builder could mine obsidian while the tower was attacking someone else. A hero ally could also be used as a tank. However, using a minion was more effective because the builder could command it to attack the tower. The best strategy was to develop quickly to the rats, snatch a tank rat from the wave of minions, and send it to attack the tower. Meanwhile, the builder would be prepared, ready to start collecting obsidian as soon as the tower began attacking the minion.
  2. Destroy the Tower: Despite the tower being quite strong, it could still be destroyed. Again, the hero's assistance could be used, but using a minion proved more effective once more. The skeleton archer minion had a greater attack radius than the obsidian-defending tower, allowing it to be sent to attack the tower. Once the skeleton archer completely destroyed it, the builder could then safely begin harvesting the resources. However, the skeleton required quite a bit of time to single-handedly destroy the tower, and the builder could only control one minion at a time, unable to multitask. Therefore, this method took longer. Additionally, it allowed the enemy builder to potentially utilize the third method of obtaining obsidian.
  3. Steal Obsidian from the Enemy: Using the observer gnome, it was possible to catch the moment when the enemy builder went to mine obsidian and take advantage of the situation – either by disrupting their efforts or using their distraction to gather obsidian oneself. If the enemy builder was busy destroying a tower, it provided a window to freely gather their resources.

Testing

All these new features seemed intriguing to us, but it was equally important to evaluate how the presence of a builder affects the gameplay of a regular hero holding the lane. Here, I will provide an example of an archer hero standing against a mage hero on the lane, while the builders on both teams are busy with their tasks.

 

 

Don't pay attention to the bugs and lags. Various issues frequently appeared during testing, but they were promptly fixed as soon as they were noticed. In the video, at the 15-minute and 18-second mark, you can see the allied builder sending a shielded rat to distract the tower while he mines obsidian. Unfortunately, this attempt was unsuccessful. Destroying an obsidian stone yields more resources than mining it, and the stone had very little health left. The builder thought he could destroy it in time, but this turned out to be a fatal mistake. Additionally, the builder lost all his resources in the process. At the end of the 20th minute, the builder made another attempt, this time successfully. Around the 6:45 mark, you can see the archer heading into the enemy forest in an attempt to gank the enemy builder, but this attempt also failed. Naturally, there were still many issues in the current gameplay, which I will discuss next time.

0 Comments

Entry 47 - Implementation of Builder

Playing as a builder is what will set my game apart from other MOBA games. Initially, the plan was for the builder to manage the processes that usually happen automatically in this genre. This means that minions and towers would fall under their control.

 

As with other heroes, selecting the builder was done through skill acquisition. However, unlike the others, the builder had no additional learnable abilities; instead, progress was made by investing various resources. All resources had to be gathered in the forest. For simplicity, I decided to eliminate resources that required crafting. Thus, only directly obtainable resources were used – such as sticks, logs, bamboo, palm leaves, stone, copper, iron, and obsidian. Gold was also a resource, but it wasn't gathered in the forest; instead, it was earned by killing enemy minions and heroes. Like other heroes, the builder had access to a shop where he could buy artifacts. His appearance was customized through invisible clothing slots, which, in addition to their aesthetic function, provided the builder with an extra 16 inventory slots.

 

Since the builder needs to move around the map a lot, his running speed was significantly higher than that of combat heroes. However, in direct combat, he doesn't pose a serious threat.

 

Towers

To influence the towers, I decided to limit the builder’s ability to upgrade the existing towers placed along the road from the start of the game. Eventually, I planned to add the ability to construct new towers and enable towers to use their own spells. However, at the outset, the starting tower could only be upgraded to one of three second-level tower variants: Lightning Tower, Machine Gun Tower, and Plasma Tower.

 

 

All three advanced towers have increased attack range, more health, and deal more damage compared to the original tower. Textures from Force of Nature were used for the appearance of these towers, but new models were created. The models were kept relatively simple and temporary since game elements were frequently added and removed. The Machine Gun Tower has a high rate of fire but low damage. Its attacks deal purely physical damage. The Lightning Tower fires more slowly but with greater power, dealing damage that is half physical and half magical. Additionally, the Lightning Tower has slightly more health than the other two. The Plasma Tower deals magical damage. It has the slowest attack speed, but its damage is the highest. I wouldn't say the towers are radically different from each other, but this was the initial setup. To upgrade the starting tower to an enhanced version, the builder needed to approach the tower with all the required resources and rebuild it. During this process, the tower would remain inactive for a few seconds.

 

Minions

From the start of the game, portals on both sides generate a wave of 5 goblins every 30 seconds. First come 2 defender goblins, then one melee goblin, and finally 2 archers. At any time, the builder can open a special minion management window and set a new wave configuration.

 

The builder can use gathered resources to construct dens for new minions, allowing players to hire mercenaries from other races using gold. Dens were made available for spiders, orcs, skeletons, and lizards. Despite goblins being available from the start of the game, players also had the option to construct a goblin den. In these dens, players could research upgrades for minions that increased various characteristics specific to each race. Like the towers, the models for these dens were assembled using existing textures. Here they are, in the following order: Goblin Den, Orc Den, Spider Den, Skeleton Den, Lizard Den:

 

 

Like goblins, each of the other races also had a defender minion, melee minion, and ranged minion. All units were taken from Force of Nature. Initially, defenders and melee units did not differ significantly from each other – they were both melee units with slightly different parameters. Some had higher attack speed, others more damage, some more health, and others armor. Different races also had different types of damage (physical, magical, poison) and varying defenses against these attacks (normal armor, magic resistance, poison resistance). There were more significant differences among ranged units. For lizards, their ranged unit was the kappa, which spewed a poisonous cloud that dealt area damage and poisoned enemies for a period of time. For skeletons, their ranged unit was the skeleton bomber, which also dealt area damage with bombs. Spiders had a ranged attack from the spider with webbing, whose attacks created webs that slowed down the attack and movement speed of enemies. Essentially, these features were directly adapted from Force of Nature since they were already developed.

 

 

In addition to constructing dens and upgrading minions, there was another way the builder could influence mobs. It was decided that the builder could "possess" any mob at any time and control it directly. This required some adjustments to the network code, as in Force of Nature each client connected to the server calculates their own hero and controls it. Calculating the physics of movement, hero actions, spell cooldowns, health, and the effects of various auras and spells – all of these computations are handled on the client's computer. I've already mentioned this in this post. However, the server (host player who started the game and invited friends) handles the calculation of all monsters. To allow builder-clients to control minions, a Star-based interaction system had to be implemented (this system was mentioned here).

 

Once everything was ready, we began testing the game from the builder's perspective. From that point on, we started recording all our matches to be able to analyze them later and identify any gameplay issues. So, from now on, I'll be documenting my posts with full gameplay videos.

 

0 Comments

Entry 46 - Implementation of MOBA. Part 2

Implementing Heroes

To prevent heroes from interacting with resources, their inventory size was reduced to zero. To allow for gold collection, gold coins were introduced. From the game's perspective, these coins are treated as ammo and automatically occupy the ammo slot. The primary weapon, even if it is something like a bow, does not consume this ammo. The character's clothing slots were hidden and replaced with six slots for amulets. All purchasable artifacts designed to enhance heroes are considered amulets. Even items like "Boots of Mega Speed" are treated as amulets in the game. I repurposed the crafting table to serve as the item shop. This table allows artifacts to be crafted instantly using a single resource: gold coins. The crafting table is automatically created at each base at the start of the game. I had to rework the logic of the crafting table so that after crafting an item (which, according to the new logic, means purchasing the item), it automatically moves to an available amulet slot on the character.

 

 

Different heroes should have different sets of skills. I implemented hero selection through a standard skills window from Force of Nature 2. I didn't have to change a single line of code for this. During the development of FoN, I had already implemented the ability to choose one skill from multiple options. I anticipated that at some point, players might face a decision on which development path to pursue. Once one option is selected, the remaining options automatically become unavailable for the rest of the game. Ultimately, this mechanic didn't make it into the final game, but it proved to be very useful in this case. Different heroes are implemented as skills in the development tree, linked by a choice – only one of these skills can be learned, effectively constituting the hero selection. Additionally, from the start of the game, the player is given an extra Skill Point, which they must spend on choosing a hero. The skills of each hero are designed as regular skills in the development tree, dependent on the main hero skill, and therefore available only to a specific hero. Yes, it may not look very elegant, but remember, this is just a prototype. When a hero's skills are learned, these skills are automatically placed into the hotkey slots for spells – there is no need to drag them there with the mouse, as was required in FoN.

 

 

When the main hero skill is learned (in essence, when the hero is chosen), this skill not only unlocks the other skills of that hero but also automatically equips the hero with pre-prepared clothing and weapons. The clothing is used to differentiate between heroes. Since the clothing and weapon slots are hidden from the inventory, they cannot be changed later, thereby fixing the hero's appearance for the entire game. As you know, in FoN, there is a wide variety of clothing to create many different looks. I simply added some color to certain parts of this clothing, giving some elements a bright red or green color to make it immediately clear which team the hero is from.

 

It was decided that for the prototype, three different heroes would be sufficient: a warrior-swordsman, an archer, and a mage.

 

Warrior

Among the trio, the warrior is the only melee hero. His key strengths are speed and durability. His skills include:

  • Critical Strike: The next attack deals increased damage.
  • Dash: A somersault towards the cursor. During the somersault, the hero is not affected by collision detection with other units, so this skill can be used to escape from surrounding enemies.
  • Sprint: Temporarily increases movement speed. Since this is a melee hero, he needs skills that can quickly close the distance to the target for an attack and also quickly retreat to a safe distance.
  • Block: The warrior gains a lot of armor and magic resistance for a short time, making him nearly impervious to enemy attacks. Additionally, during this time, the hero receives significant health regeneration.

 

Archer

The archer has the longest attack range with both his weapon and abilities. He is quite weak up close, but his skills allow him to harass enemies from a distance:

  • Berserk: Temporarily increases attack speed.
  • Fan of Arrows: The archer releases a fan of arrows that not only deal damage but also slow the target for a short time.
  • Precision: Temporarily increases attack range. This skill allows the archer to stay even further from the enemy, continuing to deal irritating damage. At higher skill levels, the archer can even attack towers while remaining out of their range.
  • Fire Arrow: The archer fires a flaming arrow that flies slowly but passes through any obstacles and enemies, dealing significant damage.

 

Mage

The mage has low base damage, but his main strength lies in his skills, with which he can deal a huge amount of damage:

  • Meteor: The mage marks a point where a meteor strikes after a short interval, dealing area damage.
  • Electric Discharge: Fires a lightning bolt in the specified direction, hitting only the closest target in its path.
  • Flash: Stuns all enemies around the mage.
  • Napalm: Throws a fireball that ignites the area for a short time, damaging all enemies in that area.

 

Testing

Testing showed that the heroes turned out quite successful. Each one's playstyle was significantly different, yet they were balanced well in terms of strength. Some of the heroes' skills were nearly identical copies from games like DOTA and League of Legends, but at this stage, it wasn't a concern, as the goal was to quickly build the MOBA foundation based on the experience of other games. Additionally, many skills were copied from Force of Nature 2, saving development time. In addition to hero skills, I relied on League of Legends and DOTA for many other balance aspects:

  • Hero, minion, and tower health ratios and damage
  • Attack timings
  • Cooldown times and energy costs for spells
  • Tower damage and range
  • Experience and leveling up speed
  • Unit movement speed
  • Artifact prices
  • Hero strength growth speed as they level up

I also had to tweak the AI of the monsters so that they, like towers, would switch to attacking a hero if the hero behaves aggressively and attacks another hero. In addition, homing arrows were implemented, which cannot be dodged and ignore all obstacles except the target they were fired at. These arrows are fired by heroes (archer and mage) and towers.

 

In the end, we (me and other testers) quickly managed to achieve the same emotions from the game as from League of Legends (which was the main reference). The hero felt good to control, farming in the lane was dynamic and intense. The price of mistakes was not too high to discourage players from taking risks and trying new things, but also not too low to maintain concentration throughout the game. We quickly started devising different battle tactics, and then counter-tactics against those tactics. Overall, the gameplay was exciting, and there was a sense that I was doing everything right.

 

I understand that at this stage, the game was simply another DOTA clone, and its value as a game itself was not great. However, it was an excellent foundation for further experiments with the builder.

0 Comments

Entry 45 - Implementation of MOBA. Part 1

In the comments to the previous post I was told about a problem with asymmetrical gameplay  some players prefer to play only one role and don't want to play other roles, so sometimes it can be difficult to complete a team with a full complement. This is a very serious problem, and later I realized it. But I want to tell about the evolution of my gameplay in order, including all the mistakes I made. I can't say that I didn't see this problem at all, I just had what I thought was a simple solution  when a player queues up to play, he can specify whether he wants to be a hero or a builder (or no matter who). The matchmaking algorithm takes this into account when compiling teams. If suddenly there are so many people in the queue who want to play exclusively for the builder that it is impossible to put them into teams (remember, only one builder is needed for a team), the game offers such players to play 1-on-1 duels without heroes. Similarly if there are too many heroes, only in this case they can even be grouped into teams, just without a builder.

 

Another important point. Since I anticipated finding the right gameplay through trial and error, I didn't initially consider the current outcome as a finished game. I defined this stage as working on a game prototype. The goal was to ensure that the resulting gameplay would indeed be engaging. And only after finding such gameplay would I start creating the actual game. The prototype was made directly within Force of Nature 2. For this, I created a separate version of the game on Steam, which features a PvP game mode. I didn't focus much on the user-friendliness of this mode, as I planned to develop a separate game for the final version. This new game would only include the essential code from FoN. I intended to create entirely new character models and environments to give the game a distinct visual appearance. However, for now, it was just a separate mode in Force of Nature 2. Incidentally, the code architecture in FoN proved to be quite effective, allowing for easy and rapid addition of various new mechanics that were not originally planned.

 

Now, let's move on to the implementation of the MOBA + Building idea.

Here's the general plan:

  1. Implement the MOBA in its pure form.
  2. During testing, balance it to a state where it is enjoyable to play. (At this stage, I am simply replicating the successful experiences of other games.)
  3. Add the builder hero.
  4. Balance the builder so that his contribution to the team is proportionate to that of regular heroes, making the game even more engaging.

 To implement the MOBA itself, quite a lot needed to be done: 

  1. Redesign the map. Place the foundations for bases and towers, and create a road between the bases.
  2. Add a portal that periodically generates mobs.
  3. Implement mob movement  they should follow the road and attack any enemy they encounter. If they stray from the road, they should return to it and continue their path.
  4. Add towers.
  5. Implement heroes. Heroes in MOBA differ somewhat in leveling up from what is present in FoN.
    • There should be an option to choose one hero from several at the start of the game.
    • The hero should not be able to gather resources, build, or work at the base.
    • The hero should have unique spells/abilities available from the beginning, which can be leveled up.
    • Upon death, the hero should enter a respawn timer and then reappear at the base.
  6. Configure several different heroes.

 

Map Redesign

I decided to limit myself to just one road (lane) between the bases  for the prototype, this was sufficient. Additionally, initially I had only three testers besides myself, so we usually played 1v1 or 2v2. This lane divides the entire map into two halves, giving each team its own forest for resource gathering.

 

 

As you can see, besides metal and stones, there is also obsidian in each forest on the map. However, it is guarded by a neutral tower that automatically shoots at anyone it sees. This makes gathering obsidian dangerous  you either have to destroy the tower or use someone as a distraction to draw fire while the builder gathers obsidian.

 

Towers

Towers line the road and shoot at any enemies that come into their line of sight. Their behavior is fairly simple: if they don't have a priority target, they scan the area around them every 0.1 seconds for enemies, select one as their priority target, and start attacking. If they already have a priority target, they will continue attacking it until the target leaves the tower's attack range. As in other MOBAs, if the tower is attacking a minion but a hero enters its attack range, the tower will continue targeting the minion and not the hero. However, if a hero starts attacking another hero, the tower will immediately switch its priority target to the attacking hero. The models for the tower were hastily assembled from fragments of existing FoN constructions.

 

 

 

Portal and Mobs

For spawning mobs, I used a ready-made portal model from the tropical world. Implementing the logic to spawn several specific mobs every 30 seconds was not difficult at all. Implementing mob behavior also didn't take much time. The entire lane is divided into several checkpoints. Every second, the mob determines the nearest checkpoint. If it's close enough, it determines the next checkpoint along the path and moves towards it. If the nearest checkpoint is far away, it means the mob has deviated from the path, so it moves towards that checkpoint to return to the lane as quickly as possible. The mob periodically scans for enemies around it, and as soon as it detects them, it begins to attack.

 

I used monster models initially created for Force of Nature 2 but ultimately not included in it as models for the mobs (yes, I have about a dozen of those).

 

 

I'll stop here for now and continue next time.

0 Comments

Entry 44 - MOBA + Building

Let's briefly summarize the main problem at hand: managing a complex entity like a "settlement" requires a significant flow of information, which is difficult to achieve in practice among players who are unfamiliar with each other.

 

To reduce this flow, we should resort to a time-honored practice: the division of responsibilities. Each player takes charge of one specific aspect of the overall team effort, fulfilling their role. To avoid conflicts, one person should handle resource management, while the others focus on their own character and the tasks assigned to them. In essence, one person on the team is essentially playing an RTS (Real-Time Strategy), managing all resource-related tasks, while the others play an RPG (Role-Playing Game), focusing on operational tasks. The most successful example of team-based combat among RPG heroes is the MOBA genre, which is why I decided to redesign my current gameplay as a blend of MOBA + Building.

 

I believe most players are familiar with the MOBA (Multiplayer Online Battle Arena) genre, but I'll briefly describe it just in case. In this genre, all players are divided into two teams. Each team has its own base where players can strengthen themselves and recover. Between the bases lies the battlefield where the main gameplay takes place. Each player controls their own hero. The goal is to destroy the opponent's base. Besides the heroes, the base itself actively contributes to achieving this goal. For defense, it uses towers that are present from the beginning and automatically shoot at any enemies within range. For offense, the base generates mobs that automatically march out to attack anything hostile. There are several predetermined paths (lanes) between the bases, along which the mobs travel and towers are placed.

 

 

In a MOBA, the base plays a significant role but operates automatically. Therefore, it makes sense to assign one player the role of managing the base. This player, whom I call the builder, should be the only one in each team with this role. The builder gathers resources, constructs and upgrades defensive towers, enhances mobs (and possibly controls them), and produces useful items for the heroes. Meanwhile, the heroes engage in battles, gain experience, level up, and enhance their abilities. Heroes also have different roles – some focus more on offense, some on defense, some on magic, and others on support. The only resource available to heroes is gold, which they earn in battles and can use to purchase upgrades. To avoid resource conflicts, each hero has their own individual wallet.

 

The gameplay for the builder and the heroes differs significantly. The builder focuses on resource collection and management, as well as overseeing the overall flow of the battle, while remaining relatively safe. The heroes engage in local skirmishes, concentrating on combat tactics. These roles are asymmetrical – is this good or bad? Initially, I saw only positives in this:

  • Such asymmetry will distinguish the game from other MOBA titles, which are numerous and often very similar to each other.
  • By blending genres, the game may attract a larger audience.
  • The game features gameplay familiar to a large number of MOBA genre fans, making it accessible to them with a low entry barrier.

Imagining how the matches will unfold, another example of a custom map came to mind, this time from another cult classic game, Half-Life – the map was called Natural Selection. In this mod, a very similar idea with asymmetrical roles is implemented – one player on the team focuses on base development, while the rest engage in combat. The battles, however, didn't take place in an RPG genre but rather in a first-person shooter genre. This mod was so popular that it even got a sequel in the form of a standalone game, Natural Selection 2. Interestingly, the asymmetry in this game was even more pronounced – not only did different players within one team engage in gameplay from different genres, but the teams themselves also differed significantly from each other.

 

 

Well, there's a new idea, new references for other games. This idea does not have the shortcomings that the previous idea had. We can move on!

4 Comments

Entry 43 - Communication

So, there is a ready idea. This idea was tested as a map for Warcraft 3. This map was interesting to play. Why then after testing it was decided to completely abandon such an idea?

 

Straight to the point - the main problem is that the game requires too much communication within the team. As I wrote earlier, the genre of this game is essentially real-time strategy. In strategies, our entire base is like one complex "character" that we develop and control. Each building or unit is just a part of one unified whole. And there should be no competition for resources between these parts. When we are going to invest resources in the development of the base, we evaluate the current strengths and weaknesses of this "character". Since resources are limited, we have to choose and consciously sacrifice some aspects in favor of others. The correctness of these choices largely determines the outcome of the battle.

 

In ordinary strategy games, all these choices take place in the mind of one person who tries to implement some clever idea and thus defeat the opponent. Meanwhile, the situation dynamically changes, and you have to constantly adapt to the circumstances. Let's say you planned a daring raid into the enemy's rear - sail to his base in boats and strike from behind. From the direction where he least expects it. With this strike, you plan to defeat the enemy completely, so you invest all the wood in building boats. But suddenly the opponent starts attacking you, trying to destroy the palisade that protects your base. Wood is also needed to repair the palisade, and now you are faced with a choice.

 

 

Perhaps the enemy's attack is not that dangerous, and you should not deviate from your plan to strike the enemy from behind. Or maybe this attack needs to be repelled first, and only then you can return to the boats. There's a lot of information rushing through your head.

 

But what if there are several players on the team? Who will make decisions and form the main strategy? What if you got the right amount of wood and were about to build a boat, but suddenly you discover that another player on your team has already used that wood to craft a cart because he didn't understand your plan? In regular strategy games, there are modes where you fight in teams, but each player controls their own separate base and collects their own resources, so there's no such problem - everyone implements their own plan.

 

But what about the Island Troll Tribe map? In it, players manage ONE base and SHARE resources, but at the same time it was interesting to play this map. So, the thing is that all the times we played this map, the whole team consisted of one group of friends. We were all in one audio chat, so we had the opportunity to quickly coordinate our actions. There was a lot of communication - every decision in the game required discussions. From choosing the location for the base to the tactics of conducting individual battles with opponents. Such cooperative work really gives a lot of positive emotions. The trouble is that not every player has a team of friends who are always ready to play. So players simply queue up and the game automatically forms teams from that queue. You can also enter as a group of players into the queue, if your friends currently are free and also want to play with you. As a result, in practice a team often consists of several separate groups of friends, or even single players. And every next match the composition of the team can change. Not all players are ready to communicate out loud with random strangers - some simply do not have such an opportunity (there is no microphone or headphones, or someone else is in the room), and there is often a language barrier. As a result, communication between separate groups of players within a team is reduced to brief messages in chat. But it won't be enough for my game. So, as I wrote at the beginning, the main problem is that the game requires too much communication within the team. Next time I'll talk about how I changed the core gameplay to deal with this problem.

0 Comments

Entry 42 - First Version of PvP Mode

In the next few posts I want to talk about how the gameplay of the new game evolved, what problems I encountered, how I solved them, and why several times I had to make difficult decisions and start development from the very beginning.

 

Simpsons Warcraft 3 Custom Maps already did it!

 

From the very beginning of the development, I had a pretty good idea of the gameplay I wanted, because I had already played a similar game. I'm talking about the map for Warcraft 3, which was called Island Troll Tribes. In short, here is the idea of this map. Two teams start in different corners of the island. In each game, all players initially have the first level and a completely empty inventory. First of all, they begin to collect basic resources, such as logs, stones, and choose a place where to set up a base. Then they begin to hunt, chop trees, mine more complex resources, construct buildings that allow them to cook food and produce weapons and other power-ups. By performing certain actions players earn experience and gain levels (in a game that lasts 20-30 minutes players can earn a dozen levels and become much stronger at the end of the game than they were at the beginning). The team needs to become as strong as possible and destroy the opponents' base. In fact, it is a strategy game, except that not a single player manages the entire settlement, but several players. And each player controls one unit.

 

(an example taken from open access)

 

Overall the description is very similar to survival games where you build your base. Therefore, this is exactly how I imagined a team battle mode that I could implement on the basis of FoN2. All the necessary mechanics have already been implemented, many resources, buildings, weapons, clothing, food are already available, the network code that allows multiple players to play the same game is also ready. Then what's left to do?

  1. Divide the players into 2 teams. Players must be able to attack players from the other team. Players should also be able to attack the other team's buildings and not be able to use them. Research conducted on the science tables should not be revealed to the enemy team.
  2. Rework the camera. When several people are playing, a lot of things can happen at the same time. To make it easier to control what is happening, the camera should not always be attached to the hero and the player should be able to look around the base and the surrounding area.
  3. Implement fog of war. If you implement a free camera, you also need to make sure that teams can hide their actions from each other.
  4. Prepare the map. The location where the events take place should be compact enough so that the teams can interact with each other. At the same time, the map should contain all the resources necessary for crafting and building.
  5. Rebalance crafting and building. Each match should take 20-30 minutes. During this time, players should have time to develop their settlement from scratch. For this purpose, many crafting chains and recipes should be significantly simplified, and the time intervals for production and resource mining should be reduced by an order of magnitude. Some mechanics should probably be abandoned altogether (such as taming animals and growing crops).

Although the list looks quite impressive, it took me about a month to implement it. The technical part (the first three points) was the easiest and was completed in just a couple of weeks. The whole map at that time consisted of one small island, similar to the first location from FoN2. However, this island also contained small patches of a tropical biome with ferns and bamboos. All available metal was limited to copper. Growing crops, taming animals, changing day and night, temperature and weather changes were completely removed. The pick and axe were combined into a single weapon. Experience was given for destroying rocks and trees.

 

Next, the testing began. Unfortunately, at that time I had not yet recorded full battles, so I only have small fragments that show the free camera and the fog of war.

 

Almost immediately it became clear that this kind of gameplay has a lot of drawbacks, and if you want to make a really interesting game, you will have to change a lot of things. I'll tell you about this next time.

0 Comments

Entry 41 - Back to Blogging

More than two years have passed since my previous post. The events that are taking place in the world right now have affected me directly, but I will not speak out on this topic in detail, because not every freedom of speech is possible today. However, I really hope that good will eventually triumph over evil. Good luck to all and a peaceful sky above your heads!

 

Even though I stopped blogging, game development didn't stop for me. As you can see, the multiplayer for Force of Nature 2 has been successfully released. After that, I had a choice in which direction to develop further. The first, rather obvious direction is the third part of the game. I have a huge amount of ideas for it (also thanks to all those who wrote to me by email and on Discord). In addition to the development of the third part, there was also an idea to implement a team battle with the construction of a base based on FoN2. In each match, two tribes start at different ends of the island, build their settlements and try to defeat each other. The idea was to release this as a separate free to play game and monetize it through in-game purchases, which will not affect the gameplay in any way and will be purely cosmetic. Since I already have a working network code for FoN2, have the opportunity to build a base, fight, level up a character, it seemed to me that implementing such a network battle would not be so difficult. I just need to come up with interesting match rules, and assemble the game from ready-made bricks. The rapid development of such a mode could give me additional funds to better implement all the ideas of the third part of the Force of Nature. Therefore, it was decided to focus specifically on developing a network battle based on the FoN2 code and resources.

 

Yes, you probably guessed that things didn't go according to plan. The challenge was to come up with an interesting gameplay that would allow matches to be played again and again without loss of interest, even for the losing team. I think many might laugh at my words. Is it really that hard to come up with interesting gameplay? After all, almost everyone has a picture of a super game in their head that would be very interesting to play. I had such a picture in my head too. In addition, this picture was even supported by real positive gaming experience. But as this picture came to life, I was faced with a cruel reality and realized that most interesting ideas in practice are broken by many pitfalls.

 

In future posts, I will describe in more detail about the entire path I have overcome. For now, I'll just summarize that after many iterations, I've arrived at a completely unexpected gameplay that has almost nothing to do with the original idea. Moreover, the game I'm currently working on has nothing in common with FoN2 - neither in terms of lore and setting, nor in terms of reusing code, models or animations. This is a completely new game. In three words it can be described as “MOBA without gravity”.

 

Now I have a finished prototype that is really fun to play. However, for full implementation, I still have a lot of work to do - setting up databases of player accounts, configuring servers, working on network code security, protection against cheating, implementing a large number of heroes and their abilities, balancing parameters and much more. For this I have to reassemble the team, because most of the people who worked on FoN2 have already left for other projects. At the moment me and a couple of other people are working on a trailer to get on Kickstarter and raise more funds for further development. I will tell you more details in the following posts. I have quite a lot of stuff that I would like to share, so I will try to post once a week.

6 Comments

Entry 40 - Multiplayer. Synchronization of Base

In this post, I'll talk about the most difficult task I had to implement: synchronization of the base. This synchronization included building/moving constructions, crafting items with bare hands and on tables, growing and gathering plants, feeding and controlling animals, and interactions with ghosts.

 

The difficulty here was in a wide variety of closely intertwined mechanics. Synchronization of all these processes had to be done very carefully so as not to break anything. There were significant changes of code and - in order to make sure everything works correctly - I gradually uploaded these changes to Steam (I combined such changes of the mechanic with small updates and with new decorations). Because these changes can potentially break the game, I always try to update in the morning and regularly check the mail/Discord/forum in Steam during the day to see if there are bug reports. On several occasions, there were some bugs indeed, but they were quickly detected and fixed.

 

Constructions

As I wrote earlier, for multiplayer I had to make virtual images of all locations in order to be able to synchronize environmental objects between players if the players are in different locations. But I didn't have to do this for buildings, because such a scheme has already been implemented for them. Even in singleplayer, ghosts can work with some constructions while the player is traveling around the world, so I needed these buildings to be in memory all the time.

 

 

Therefore, data on everything built by the player (i.e. position, state, items inside, etc.) is constantly stored in the computer's memory within virtual copies of all constructions. This data storage architecture turned out to be very useful when implementing multiplayer. Because the image of each building is already in memory (even if the location itself with this construction is not loaded now), and each construction has an unique ID, this greatly facilitates synchronization; everything works exactly the same way as with the objects of the environment (bushes, stones, and items on the ground). The only difference is that, instead of virtual worlds made specifically for synchronizing environmental objects, I use virtual worlds made for ghosts. Therefore, the opening/closing of windows and doors, changing the mannequin's poses, and the inscriptions on signs and portals were all implemented quite quickly.

 

Chests and other storage units caused far more trouble. I had to significantly refine the system of resolving collisions between players' actions to avoid, for example, such situations: several players simultaneously click on an apple in the chest and it goes into everyone's inventory. Now, this system can also resolve conflicts of territories. For example, if two players want to build a construct on the same piece of land at the same time.

 

Crafting and building

All crafting takes place on the server computer. Clients process only their own manual crafting. Everything that happens on the tables, building of new constructions, growth of plants on seedbeds, etc. is processed by the server. I had to completely redo the way of measuring time intervals for crafting. In singleplayer, when we teleport between worlds, the whole game is paused; time stops and all crafting freezes. In multiplayer, this behavior is unacceptable because if the server player teleports to another world and is currently loading another location, other players should still see that crafting on the table continues. There was also a lot of work with resolution of conflicts. Conflict resolution was especially difficult when using tables with built-in storages and when planting on seedbeds with the use of fertilizers that lie in a fertilizer storage. The difficulty here is that one player can start crafting from items that are on the table and, at this moment, another player can take some resources from this table into their own inventory. Additionally, if one player plants flora with fertilizers then the other player takes these fertilizers from the storage. These tasks are not very difficult, but I had to think a lot on taking these possible scenarios into account.

 

 

These two videos demonstrate the synchronization of using constructions, crafting, and building:

 

Feeding animals and controlling ghosts

Synchronization of feeding animals was even more difficult, especially automatic feeding when the animal itself eats from the trough. In addition to resolving all possible conflicts with the animal itself and the trough's inventory, I had to take into account the ability of the animal to reach the trough. Troughs are designed in such a way that if animals don't have direct access to them, they will not be able to take food from there. And again, this becomes a problem if the server player is in another location. In singleplayer this was not a problem; the availability of the trough could not change while the player was in another location. Therefore, when the player changed the location, each animal simply remembered the list of troughs to which it has access. In multiplayer, availability can change. While the server is fighting monsters somewhere in the swamps, the client can open some gates and make the trough available. All such moments require additional synchronization.

 

Ghosts had the apotheosis of various mechanics interweaving; their synchronization was the most difficult moment in the whole game. Ghosts are characters, so their animations and position need to be synchronized. They also participate in crafting, they can be controlled, you can talk to them, they have their own settings (priority of work), they can interact with the story and progress, have scenario items in the pouch, etc. Ghosts are the only characters in the game, besides the main character, who can move around locations. Individually, these tasks would not be difficult, but here they all occur in one character. Therefore, when synchronizing each individual ability of the ghost, I had to keep all of their other abilities in mind so that everything worked smoothly. All of this took about two weeks and a lot of my nerves.

 

 

Now, the good news. The list of tasks I gave earlier has already been fully implemented. The last thing added to it was the synchronization of monsters, bosses, scenario events, and the magic sphere. There is still one point I forgot to include in the list initially: synchronization of the minimap. In addition, I'm going to record a new trailer that demonstrates multiplayer capabilities. The game will need to be thoroughly tested and perhaps its balance will be slightly changed for several players.

6 Comments

Entry 39 - Multiplayer. Effects and Locations

In the last post, I left out one kind of interaction with the environment - damaging objects! I decided to describe it in this post instead because attacks revolve heavily around audio and video effects.

 

Synchronization of audio and video effects

Let's start with the attacks. The concept of an "attack" in the game is quite complex. Each attack has a lot of parameters - preferred target (what we click on), host of the attack, damage (physical / magical / poison), weapon material, effects (poisoning, slowing, burning, pushing, stunning, etc.). If it's an arrow, then we have to factor in its appearance and flight path; same with a boomerang or fireball. All of these effects do not have a save/load code, because they are not saved when you exit the game. Instead of creating code for writing/reading all possible effects (there are lots of them), I use a simple and logical step - I send only a link to the weapon as an inventory item. 

 

I've already implemented the sending of inventory items. The attacks of each monster are also already implemented through weapon items (i.e. each monster does not just store the damage it deals, but a link to a full-fledged item which is the same as the sword or spear that our main hero uses). The only exceptions to separate weapons include swamp water, a volcano's vent in the bowels of the mountains, and cannons that guard the pirate boss. For multiplayer, I had to rewrite their code a bit and create a "weapon" for each of them to fix it.

 

 

To synchronize the flight of an arrow, stone, needle, dart, fireball, etc., I don't transmit the position of these items for every frame. I calculate the parameters of the equation of the parabola along which these items will fly, and transmit only these parameters. Other players, having received them, can easily launch the ammunition along the same trajectory. However, the other players’ client doesn't try to determine the collision of the item with anything. It simply moves the arrow along the parabola until it receives a signal from the first player that the movement should be stopped and the item itself removed. The boomerang is synchronized in a similar way, but the trajectory there, of course, is more complex and the number of parameters is greater.

 

Synchronizing sounds, sparks, explosions, and other one-time effects is the easiest. You just need to tell other players at which point to play certain effects. To be able to transmit a link to the effect, I made a script that automatically scans all game files, gives each file a unique number and places these numbers into the dictionary, which allows it to quickly identify each file by its code.

 

Synchronization of effects and sounds was one of the most pleasant tasks - there were no difficult moments, and the result was very noticeable! We can already see how other players are running around the map, interacting with the environment, cutting down trees, shooting arrows, using magic, etc. At this stage, I posted the second demo video. You have already seen it, but I will duplicate it here:

 

Jumping between locations

The world in the game is divided into several locations. Moving players around these locations is not a problem. Going to another location, the player simply sends a signal to the server, the server redirects it to the other clients, after which they hide the corresponding character. The difficulty lies in the fact that locations are randomly generated when entering for the first time. If one of the clients goes to a location where no one has ever been before, that location must be created. This is what happens in a single-player game. 

 

So what's the problem? In programming, it’s called RAM fragmentation. When the program works, it often allocates some pieces of memory, then releases, then allocates again, and so on. Then, over time, RAM becomes like a colander - small pieces of allocated and currently used memory are distributed throughout all available space. When we need to allocate memory for a new and very large chunk, the system understands that this chunk cannot be taken and the program crashes with the error "not enough memory." Although, there would be enough free memory in total for this piece.

This problem exists only in 32-bit operating systems. For 64-bit systems, the address space is so large that we will not be able to fill it with garbage. In the first part of the game, I encountered this problem because - in the early stages of development - I did not think about memory fragmentation. To generate a world, you need to allocate several fairly large chunks of RAM for the geometry of the level, its textures, grass, etc. If a player played for a long time in a ready-made game, then exited the menu and tried to start a new game, there is a high probability that the game would crash. To avoid this, I had to do a trick that - when trying to start a new game - the game asks the player to restart the application. As a result, RAM for the application was renewed and the game had a large chunk of memory without garbage. 

 

In the second part of the game (as I mentioned above), each location is generated when you first enter it, so I needed to protect myself from the fragmentation problem. To do this, when I start the game I immediately allocate several large memory buffers for future map generation and then use these buffers, if necessary. To prevent these pieces of memory from being idle during the main game, the game uses them to store some information about the currently loaded level - height map, textures, and grass. Subsequently, it turned out that there was no sense in supporting 32-bit systems anyway and, as there is no problem for 64-bit systems, this approach turned out to be unnecessary. 

 

In the online game, it became a significant problem. If the client goes to a new location, then the server needs to generate this location, meaning it needs to free up memory buffers for this. But it uses them for the location that was currently loaded. Therefore, I had to significantly redo the memory management.

 

That's it, see you in the next post!

4 Comments

Entry 38 - Multiplayer. Environmental Interaction

In the past, I’ve described the process of launching the game in Co-op mode and improving the synchronization of players' positioning and animations. Read on to learn more. 

 

Interaction with the environment

 

I decided to synchronize environmental objects (i.e. trees, bushes, items lying on the ground, plants that can be gathered, and so on). In general, the synchronization of these objects occurs according to the same scheme:

  1. Firstly, we define the entire set of events that can occur with the object. For example, for an item on the ground, this is picking it up and dropping out, for a tree - dealing damage to it and cutting it down, for a plant - gathering it.
  2. For each event, it's necessary to create a data packet which includes the indication of the object and the operation on it.
  3. Send this packet to all other players.
  4. When receiving a packet, resolve an object, an operation, and perform this operation with the object.

For example, since the map is initially synchronized for all players, players A and B both see an apple lying on the ground in the same place. Player A gets closer to that apple and wants to pick it up (clicks on its label or presses LCtrl).

What happens next? An apple is added to player A's inventory and information is sent to the server (this was already mentioned in the previous post). However, the apple must be removed from the ground so that no one else can pick it up. Therefore, player A forms a data packet, places the apple in it, and writes the operation "update quantity" (equal to zero). Player B, having received this packet, will understand that the apple just needs to be removed, and will do it. Everything is quite simple, but this scheme does have its difficulties.

 

Regarding simplicity, there are not many objects in the environment and include a tree (in the game a bush is also considered a tree), a stone, a plant, an item, and a decoration (which includes barrels, boxes, fences in the first location, and so on). There are not many actions that can be done with these simple objects.

 

The second item listed above has one difficulty - you need to be able to point other players to a certain object (a particular tree or a specific bush of wheat). The need to point to specific objects will be useful later in synchronizing other game elements like effects, attacks, and animals. This means that we require a universal mechanism and so, each object or other element in the game must have a unique ID. 

 

During the initial map loading, the server assigns these identifiers to all objects and - when the client connects and requests a map save - the server sends these IDs along with other data. Clients should also be able to assign IDs to new objects and the events they generate themselves. At the same time, IDs must not be duplicated, otherwise there will be confusion. To generate unique, unrepeatable identifiers, there is a ready-made, simple, and secure solution - GUID (Globally Unique Identifier)

https://en.wikipedia.org/wiki/Universally_unique_identifier

 

With just one line of code I can generate such identifiers, but their size is 16 bytes. Since the links to the objects will have to be sent constantly, I decided to go a more complicated route by using unsigned integers of 8 bytes as identifiers. Session number is always stored in the first 4 bytes, and the ID itself is stored in the remaining 4 bytes. Every time someone connects to the game, the server gives them a session number which will increase by one each time. Even if the same client connects to the game, exits, and connects again, they will receive a different session number. 4 bytes for identifiers within one session is enough even if you generate events and items 100 times every second continuously for a year.

 

In order to send a data packet to other clients (point three of the list), each such packet is sent to the server where it is copied and sent to all other clients. I wrote about the ways of sending packets in my previous post. Afterwards, one of the Factorio developers wrote to me. If you’re reading this, hey! And hello to all other developers who have been brought to my blog!

So, he told me that the network communication schemes I wrote about are called Star (when all messages pass through the servers) and Mesh (when each client sends messages directly to other clients). Based on experience, he also advised me to use the Star model instead of Mesh. Additionally, he told me about some of the subtleties of the Internet and the specifics of sending messages via Steam API. Thank you very much, kind man! Now, what was I talking about? Oh yes! The Star scheme is used to send the package to all clients for environment packets.

 

There are no difficulties in receiving the packet, resolving the object by ID, determining the operation, and performing this operation. However, there is another significant point, which (I think) is a big problem for almost all online games: What happens if two players simultaneously click on an apple to pick it up?

If you leave everything as it is, the apple will slide into the inventory of both players, leading to a simultaneous message sent to the server that the apple should be hidden. The apple will be removed, but a total of 2 apples will be added to the players' collective inventory. To resolve such conflicts, we have to make an object locking system. Before picking up an apple, each player sends a request to the server to allow the operation with the object. The server sends a positive response, while noting that the apple is currently in use. If someone else asks the server for permission to do something with this apple, the server will deny them. After the player (the one who had received initial permission to work with the apple) picks it up, they immediately send a message to the server that the work with the apple is finished.

 

After all this was implemented, players could already see the interactions of other players with the environment. At this stage, I posted the first video demonstrating these capabilities. I will post it again since it corresponds well to what I’ve described. Keep in mind that it is an old video which you may have already seen.

 

Now let's check the task list:

  • Lobby - Done!
  • Starting the game and setting up the connection - Done!
  • Auxiliary tools - Done!
  • Synchronization of heroes - Done!
  • Interaction with the environment - Done!
  • Synchronization of audio and video effects - Done!
  • Jumping between worlds - Done!
  • Synchronization of constructions - Done!
  • Synchronization of crafting and building - Done!
  • Synchronization of monsters - Half done
  • Synchronization of quests and scenario events - Not ready
  • Testing and balancing - Not ready

Since I first wrote this list, I realized that there are 2 more tasks that should be implemented - synchronization of the minimap and the weather. However, these are not very large tasks and, in total, will take no more than a week. All together, it should take about a month of work. However, for greater reliability, I’m estimating it will take around 2 months. In total, the expected release date of the multiplayer at the moment is mid-March.

2 Comments

Entry 37 - Multiplayer. Main tasks. Part 2

Multiplayer implementation is somewhat similar to the work of a surgeon. I have 2 computers running the game. I need to synchronize each event that occurs on any of them - form a package for it and send it to the other computer, so that this event is displayed there as well. As a result, it's like I'm stitching 2 games together, painstakingly connecting each event. 

 

Save and load functions play an important role while syncing. I can save the game on the server, and save it not to a file, but to an array of bytes. Then I can send this array to another computer, and load the game from it, as if it was a save file. In such a simple way, I quickly achieved that after starting the game on two computers we see the same world. Even if player on the server managed to cut down a couple of trees before the client connected to it, the client will see that trees have already been cut down, because when connected, the server will send to it a save of the world's current state. However, after both players have loaded the same world, nothing connects them anymore - everyone plays his own game. That's why it's necessary to synchronize all game events further.

 

Synchronization of heroes

The first thing I synchronized was main heroes of all players themselves. By this I mean not only their position and movements, but also their customization, inventory, weapons in their hands, and so on.

When saving the game, the server began to save all characters' settings, sending them to the rest of the players along with the world files. Also, the server assigns a unique ID to each connected player, by which the players then distinguish each other. Hurray! As a result, all connected players can be seen after the game start. But for now they just stand still and do nothing.

 

2 Methods of client-server communication

First you need to decide which way to send packages. There are 2 ways: 1) each client sends data packets to everyone else directly and 2) each client sends it's state to server, and then server forwards it to other clients. When there are only two players, there is no difference - in both variants each client simply sends a package with it's condition to the second one. However, when there are lots of players, the situation begins to change. Suppose we have 10 players. In the first method everyone has to send a packet to the others, i. e. 9 packets. Totally, to synchronize the state of all characters on all computers, we need to send 90 packets. In the second method, each of 9 clients will send 1 packet to the server, and the server will send 1 packet with the state of all players to each client, i. e. a total of 18 packets (5 times less than in the first method). But also the delivery time of a package from one client to another is doubled. For the first part of the game I chose the second method as more versatile. However, for the second part I reevaluated both of these methods and came to the conclusion that the first one is better. The maximum number of players is 4, and in this case 12 packages will be sent against 6. However, we'll need to send many other packages - with the states of monsters, buildings, environments, special effects, and so on. So 6 extra packages won't make much difference. In addition, these extra packages completely fall on the clients, not on the server, which in this case is the bottleneck of the system. But the delay in the game will be halved.

 

By the way, I managed to significantly optimize characters' state packages themselves compared to the first part of the game. If in the first part the full state of the character sent over the network took 166 bytes, now it takes only 26 bytes, i. e. 6 times less. Which is very useful, because in the future I still have to synchronize monsters, which in the second part we have several times more.

 

The method of communication of each with each is implemented only to synchronize characters' position and animation, where the minimum delay is most important. For most other packages, a centralized scheme was chosen, when all packages pass through the server. This allows to ensure that the order of packages processing is the same on all clients (in which order packets arrive at the server, in the same order it redirects them to clients, and in the same order clients process them). If clients send packets to each other, then their order may be violated. And this can create problems.

 

Motion smoothing

Just sending a character's position regularly will not be enough. Packets arrive from one computer to another with different delays, even if both are in the same room. As a result, movements of the remote characters are intermittent, discontinuous, not smooth. To get rid of this, I need to smooth out the received data. In the second part I significantly improved the algorithm from the first part - it not only smooths characters' position, but also foresees their movement in advance, based on previous data. As a result, I can get smooth and natural movements even when sending only 10 packets per second (in the first part 30 packets were sent per second).

 

Synchronization of settings

In addition to the characters' position I had to tinker a little more with the synchronization of their animations. The task is not very difficult - you just need to track the change in your animation and send a new animation to the rest of the players. However, the difficulty was to figure out how to get such control over the animations in Unity. 

 

After synchronizing heroes I implemented the change of weapons, equipment, inventory, hot slots and all client settings (such as the position of interface windows on the screen, the selected preferred ingredients in recipes where there is a choice, the skill tree, the state of hot slots and much more). There were quite a lot of tasks and they took a decent amount of time, but it doesn't make sense to describe them in detail - they were all implemented according to the same scheme:

  1. we monitor changes in something, save these changes to the stream, send it to the server
  2. the server stores this state (so that in further game sessions with the same player to send him all his settings)
  3. the server redirects to other clients only the part of data that directly affect character's appearance

 

Ugh! A lot of text. I'll try to describe other tasks in less detail. In the meantime, let's check our ToDo list - since the previous post, the "Synchronization of crafting and building" item has moved to ready tasks:

1 Comments

Entry 36 - Multiplayer. Main tasks. Part 1

In the previous post, I wrote a list of the main tasks that have already been done and that still have to be completed. Now I will go through them in more detail.

 

Lobby

This is where you start a multiplayer game and wait for other players. In general, lobby in the second part is structurally the same as in the first part. Of course, interface design has been changed for the new style. But there is one significant difference. In the first part, you could only run a multiplayer game for an already created world. Therefore, to start playing with a friend, you first had to create a world in a singleplayer mode, exit it and reconnect to it with a friend. At the same time, the friend did not have the opportunity to customize his character specifically for this game. Now you can choose the option to play a new game with a friend, and the friend will be able to set the appearance of his character. This part of the work turned out to be the easiest, since all the code for the lobby is a separate small structure, not connected in any way with the network code of the main game. It was not difficult to think through its architecture at all.

 

Game launching

After the game is selected and all players are ready, you need to start loading the world. But first you need to create and run the core of the network code - the server for the player who created the game and the client for the rest of the players. I decided not to make a big difference between the server and the client, since I wanted the roles to be changed and clients could sometimes take on some of the server's tasks. This is necessary in order to loosen the strict affection between players to make easier for them travelling the worlds independently of each other. Therefore, the game does not have a server as such. There is only a client, although for the player who created the game, this client still performs slightly more functions than others - it controls game saving, generates new locations, resolves access conflicts and monitors data streams to be consistent. Despite the fact that there is no server as such, I will still use this word for the player who created the game.

 

When the client is running and configured, the world starts loading. And there is also one important difference from the first part of the game. Previously, clients received all the necessary information about the world over the network from the server every time. Now the client receives the world files only on the first launch. It saves them to itself and in subsequent connections it requests from the server only the changes that have occurred to the world. This allows to reduce the amount of transmitted data several times and significantly speed up the loading of the game.

 

Auxiliary tools

Initially, I started designing network code so that it would run in a separate thread in parallel with main game. This would avoid delays in the data messages exchange at the moments when the computer is very busy, for example, by loading resources when changing locations. However, I quickly realized this approach would be difficult to implement, since Unity doesn't allow working with resources in parallel threads. You can bypass these limitations, but the complexity of the code will increase significantly. Therefore, I decided to try launching the client in the main thread of the game and break those moments in the download, when the game is freezing, into smaller parts. A rather painstaking work was done, but in the end I managed to make sure that during loading the game does not freeze for more than 0.1 seconds, which is quite an acceptable delay for multiplayer.

 

In addition to this problem, there were a number of auxiliary tasks needed to be implemented before starting to make the main network code: packets grouping, delayed dispatch, allocating areas for generating unique IDs between clients, organizing different data streams for auxiliary and main packages. This is a very large number of small tasks, but their design and implementation took a very long time. Perhaps also because these tasks are purely technical and difficult to visualize in your imagination. There were times when I didn't write a single line of code for several days, but just walked from corner to corner or laid on the couch, forming in my head a picture of how the interaction of game objects should be built. But finally this stage was successfully passed and it was possible to move on.

 

That's all for now.

The item "Synchronization of buildings" from the list of tasks (from the previous post) has moved to the finished tasks. This includes the instant addition, removal and relocation of buildings, as well as their use (except for time-consuming processes, as these tasks relate to the item "Synchronization of crafting and building").

2 Comments