I have always wanted to make a game similar to Ogame, TribalWars, or Hattrick; for whatever reason, the idea has always fascinated me, even though I've never really had the time to invest in these types of games since most are long-term games, especially Hattrick, where it can take years to achieve your goals.
A few weeks ago, I considered creating one, and after a while programming I realized that the first thing I needed to do was design it.
Of course, this is just what I’ve learned, and it may not be 100% correct, or there might be things you’d change. But as a starting point and as an exploration, I find it very interesting.
Index
1 - What is a browser game?
A browser game, as the name suggests, is a type of game that we access through the browser and is about being a manager or administrator of an environment or system. These games are based on resource management, whether it’s owning a team, where you can expand the stadium, hire players, staff, etc. (Hattrick), or the boss/owner of a planet where you must manage resources, attacks, etc. (Ogame).
The main appeal is that you compete against other people to see who is the best (PVP), focusing on a long-term strategy. In Hattrick, for example, as a football manager, it might take you several years (or even more) to climb a couple of divisions.
Basically, you could say it’s like playing Excel. *This is a meme for all Football Manager fans.
Nowadays, unless you do it to learn, creating these kinds of games is like suicide because the mobile gaming market has completely taken over. In the end, your competition is Clash of Clans and similar games, with their abusive techniques that make them feel more like slot machines than games—but that’s another topic.
1.1 - Real-time browser game
When I was a teenager, browser games became somewhat popular; in fact, there was one that really stood out. I’m not talking about Habbo, which I never played, so I don’t know if it even worked in the browser.
What I mean is El Bruto—just like Hattrick or Ogame, El Bruto was played in the browser, but its main difference was that the PVP was real-time. Today, we’d do this with Websockets, or SignalR if you work with .NET.
So, if you want something in real-time, as you can see, it’s not complicated to add.
2 - Game design
2.1 - Choosing the game style
Initially, what I had in mind was a pirate game, where you have ships with crews going out to sea to fight. I was thinking of making a world full of islands—basically like One Piece.
However, this comes with several difficulties to consider. What do you do with the ships? I’d like it to be realistic, meaning you can’t attack with 100 ships and have all of them land—that’s not how it works. Each island should have a percentage of land where you can land, and from there continue.
If you notice, just this first game design idea already complicates the implementation, because these are small but important details that consume all your time.
So at this point, I shelved the pirate idea and decided to go with something simpler: foot soldier battles. Here, I could do the same, pick my favorite series and base the design on it, but my idea was to make a sketch of the idea, have something tangible, and I picked what you’re probably all thinking. Age of Empires—soldiers, archers, knights, and once the prototype is complete, siege weapons and cars that shoot 👀.
The idea is to capture that in a game that isn’t real-time and runs in the browser.
If you do some research, you’ll see this already exists and is called TribalWars (launched in 2003, although there’s a second version), so, well, we won’t release it into production, but it will be great for learning and brainstorming for a while.
Once you have the theme, it doesn’t matter whether it’s the Middle Ages (TribalWars), an ancient Greece simulation (Ikariam), or an alternative Star Wars version (Ogame)—they’re all more or less the same. You have your city/planet and attack others, the cost of attacking, both in resources and time, is based on the distance to that place. At this point, you’re probably visualizing your own scenarios, and now comes the global mechanics.
2.2 - Resources and progression
One of the most important, or the most important, aspects of any game is to keep people interested in it—I don’t want to say hooked because that requires abusive techniques I don’t agree with, but at least interested in staying connected.
And for that, you need very good progression. You don’t want to reach max level in a day, but you also don’t want it to be completely impossible. It has to be gradual.
This is where resources come in, as it’s the simplest way to regulate progression.
All these types of games have a resource system, whether they’re basic resources for building structures, or coins/tokens tied to real money.
In this section, we’ll talk about basic resources.
In short, you need resources both to create troops and upgrade buildings.
For example, let’s say the resources are food, wood, iron, and stone. Each of these materials comes from a different building.
For example, wood from a sawmill, stone from a quarry, iron from a mine, and food from the farm.
If we wanted to make it realistic, we should be able to set limits on how much iron can be mined from a mine, how many trees are in the forest, or a minimum and maximum number of farms, but extreme realism is not only hard to achieve technically—it can drive away more casual users, and hardcore players don’t care much either. So, the recommended approach is to have a building that produces X resources per hour, with requirements to level it up so it can produce more per hour.
Time is another factor—the first levels are very fast, to give users a sense of progression, while the last ones are much slower, to show that it’s a tough task and you really have to think before upgrading.
The same applies to troops; they have both a basic resource cost and a time cost.
2.3 - Monetization in browser games
For better or worse, we have to monetize our application because servers aren’t cheap. These kinds of games give you administrative advantages when you pay for premium—they’re not pay to win.
This means that, when you pay, buildings don’t finish faster, troops don’t train faster, cost less, become stronger, or give you extra resources.
NOTE: Ogame does this 🤦
So, why would anyone pay?
Remember how we said in the previous section that progression is slow? What happens if a building takes 10 hours to complete and that means it’s done at 3 a.m.? Well, to start another, you’d either lose valuable hours while sleeping or, by paying premium, you get a feature to queue building upgrades automatically.
The same goes for nighttime—you can schedule attacks to happen at night without having to be present. These are administrative advantages; they don’t speed up progression and aren’t unfair to other players.
How much you want to offer in the premium model is up to you, but it has to be just enough so users pay, and free users don’t feel it’s impossible to play without paying.
In the specific case of Hattrick, a football manager simulator, there are 4 types of premium subscriptions (https://www.netmentor.es/entrada/suscripciones-stripe), and in the two most expensive ones you can manage another team. (In fact, that’s the only difference between gold and platinum).
NOTE: Hattrick is programmed in .NET, at least the interface is ASP.NET Framework (https://www.netmentor.es/entrada/explicacion-versiones-dotnet-).
2.4 - Game engine
The game engine is not like a "normal" game—I’m not talking about Unity, Godot, or making your own engine, since the engine of this type of game is really your server running the whole infrastructure.
What I’m referring to is the combat engine in TribalWars or in our combat game, the match engine in Hattrick.
It’s very important to have an engine that’s as “realistic” and neutral as possible, so it’s fair for everyone.
Otherwise, your game might not be balanced, just like the first generation of Pokémon with psychic types that had no counter and everyone used Mewtwo—by the way, mine was the best with Psychic, Recover, Ice Beam, and Thunder.
The best thing to do is run many simulations until you verify there isn’t a composition that breaks game balance.
2.4.1 - The game's graphics engine
While it’s most important to balance the troops, the graphics are also important. In our case, it doesn’t take much—just having a village as a map and buildings that visually change as they level up is enough. If you want to keep it graphical, go ahead, but if you want to play entirely on a spreadsheet simulator, displaying information is more than enough (Ogame does, or did, exactly this).
3 - Implementing the game engine
For our case, the main focus is combat, and while I’m not reinventing the wheel here, I’ve given it a lot of thought, and I have a version I might put on GitHub someday.
When we talk about battles, we mean several things—battalions and combat are the most basic. So, how do we approach fighting?
We could do something similar to the Risk game: if you attack with 10 and the opponent defends with 12, we roll dice until one side runs out of troops.
Implementing this is easiest; we would probably want to implement something like one point per soldier, 0.8 for archers, 1.3 for knights, or something along those lines, and repeat.
But I’m a big fan of RTS (Age of Empires-type games) and turn-based games, so here’s what I thought—and I’ll show my mental process here.
First, I imagined a 1 vs 1 fight, as it’s the simplest form.
In my case, a soldier and an archer.
Obviously, the archer can attack from a distance and the soldier can’t, so you can’t just put them in front of each other—it doesn’t work like that in reality.
What came to mind was to have a map where the troops are separated by 10 units. These units refer to distance, speed, or range; for example, I gave the archer 7 range.
This means that for the archer to hit the soldier, someone has to move.
And to let troops move, we need to know how often, throughout the match, they can move. Here’s where I added the turn system. Each battle has a random number of turns between 8 and 12—why those numbers? I don’t know, but it’s the first version, so 8–12 is just as valid as 14–25.
Another key element in turn-based games is that a user does all their moves (whether with one unit or all) in a row without enemy intervention. For me, that’s not fair—I think both sides should move, and after moving they attack, which is how I do it: turns are simultaneous.
In our case, we reach the first step of the turn, where they’re 10 units apart.
Since the soldier can only attack things 1 unit away, he has to move, and the same for the archer—since he can’t quite shoot yet, he has to move.
That means both will move, which is VERY important. Why? Because if the soldier moved 3 and the archer stayed, they’d be 7 units apart. BUT if the archer also moves, they become 5 units apart, which is important because the soldier will close in quicker. I hope I’m explaining myself.
And of course, the same happens when attacking: if two troops attack, they do it at once, and deaths are resolved at the end of the turn.
Note: For now, troops attack once per turn.
This would be the position at the end of turn one:
Note: I checked the code: the archer moves 3 and the soldier moves 2.
Of course, the archer has a small chance to miss, and the soldier’s damage takes into account the arrow's damage and whether they have armor, etc.
On the next turn, the soldier will move but the archer will not, so he’ll only attack. And so on, until either one dies or the turns end.
3.1 - Implementing battalions
Of course, nobody attacks or defends with just one troop—it’s better to have battalions. For now, let's keep just one type of unit in our battalions; the fight could go something like this:
This is a basic example but helps illustrate several problems we’ll face.
The first is battlefield size: a 10-unit gap isn’t enough. We need a battlefield width, ideally not the same for every village, and each village flank should be different too—so as the attacker, you’ll need to scout them to know where to strike.
Something we notice is not all archers can reach the same spots with 7 range. For example, the archer in the upper right, after one turn, can attack these positions:
Meaning to reach enemies at the bottom, he’ll have to move on the board.
One possible solution is to treat all troops as one group and work with that—it’s a possible solution but... honestly, it’s kind of meh.
We’d have to investigate if investing in individual or group interactions is worth the effort for implementation.
Let’s continue, because in our battalions we don’t have just soldiers and archers; we also have knights or spearmen, who are ideal against cavalry. If we’re following the movie 300, spearmen have a range of 2 units.
At this point, it’s clear we need a much larger battle map—maybe a 30-unit gap or more depending on how high you want the unit limit. And much more tall, too.
You’ll find many more details regarding movement—for example, preventing two troops from occupying the same square or passing over another troop, which requires a pathfinding algorithm to implement.
3.2 - Implementing formations
Having units spread out on the map allows for formations; the one in the previous image could be considered a line formation, but you could also call it the default.
But what if you want to press harder on the flanks and less in the center? Maybe you know the defender uses a particular formation and want to break it by targeting those points.
Or if you know they only defend with artillery, spacing your troops out is crucial so the artillery doesn’t hit multiple units. Yes, this is common in Age of Empires—I’ve played it a lot.
To me, formation is fundamental in strategy games and essential for a good engine.
Of course, the downside is you’d have to choose the formation before entering battle—which isn’t a big problem as long as we limit the number of possible troops.
With formation come orders—you might want only one flank to attack while another stays back to strike after soldiers have moved forward.
All these little variables make programming an engine for these games truly challenging—and super entertaining.
4 - Architecture of a browser game
Finally, let’s talk about the architecture behind a browser game. You could put everything in a monolith, so when attacks happen, you just run a background job that updates the game state. For an MVP, this is what you should do.
But what’s the fun in doing this post and suggesting a monolith is enough—let’s make a distributed architecture as the ideal case.
Clearly, the FrontEnd is very basic—normal views, whether or not you use SPA, in the end, you just have to show simple information on the screen, maybe use polling when a timer finishes, either for sending an attack or resource completion, simply refreshing that section.
The part that can get a bit complicated is the BackEnd.
For example, what happens when you click to upgrade a building? The interface will show a timer for how long it takes to upgrade, but what about the backend?
First, you’d lock the database so nothing else could update.
But you must also ensure that, when the timer reaches zero, you level up the building and unlock the interface.
To do this, you need a distributed job scheduler; alternatively, you can have a background task system that triggers events when an action should happen.
For example, let’s go back: when a user clicks to level up a building, we’ll generate an event (Pub/Sub), which will be picked up by the system we use as our scheduler.
When the time comes, the scheduler will trigger another event with the information to level up the building, which will be processed by a consumer that accesses the database:
The same goes for attacks—we generate an event saying when we’ll attack, because while troops are attacking, we must lock the number of available troops in the city to prevent them from attacking others.
So, once they arrive, the scheduler generates an event, and the consumer takes care of calculating the battle, the report, and "returns" the resulting troops, which have to be updated upon returning to base—requiring another system and scheduler.
All this event interaction happens in milliseconds, and we do it this way for multiple reasons. First, it ensures events happen and, if they don’t because a system is down, we can always retry everything exactly as it was at that moment.
Separation of responsibilities is also very important, as is scalability. Early in the game’s life, more buildings will level up than attacks will happen; later, there will be more attacks compared to building upgrades.
Note: We’ve skipped use cases like canceling a building upgrade or canceling an attack, but I think it’s clear from what I’ve shown.
If you have doubts about distributed systems, don’t forget we have the best course in Spanish on the subject here on this website, and it’s completely free.
Link to the Distributed Systems course (free)
Finally, I want to mention something that just occurred to me: knowing what I know, I could always have the API open (auth required) so anyone can create their own FrontEnd if they want. Don’t like how I made the website? No problem, you can build your own ;)
If you like the content, don’t forget to leave a message below and maybe we can do a series creating such a game!
If there is any problem you can add a comment bellow or contact me in the website's contact form