en uk

How games (or any pet projects) should never be developed

This story is about wasting time and life. It is about Attraction Wars.

Attraction Wars is an online browser game I developed in my free from job time.

I am surrounded with "success stories". But very few new projects (or startups if you want) succeed. According to the different sources, it is less than 10%, I more believe sources which say that it is even less than 1%.

Of course, it dramatically depends on which stage startup was accounted for this statistics... But this story is not about it. I just feel that I should write "story of NOT success", just to dilute all that success stories with other fairy tale.

Honestly I think that history of Attraction Wars development is an example of how games (or any pet projects) should never be developed.

However it teached me a lot, including technologies and outlook, so I hope this experience will be useful for someone. Or only for me as reminder.

But if you are interested of this deep dive to cave, then please go ahead.

1. How idea was born. Gamedesign.

First was an idea. And the idea was to model Gravity Assist. Why? Just because it seemed to be cool. (Omg;)) At this stage it was not so wrong though. 

Then the idea quickly evolved into some "enhanced" agar.io clone.

Players quickly became planets, and "food" - asteroids. Basically player wanders around, collects asteroids and eventually fights with other players. All this increases players mass and score.

After some thinkings how gravity assist should work I eventually came to the idea to create 3 zones around player with different radiuses.

Those zones work when a smaller player is in influence area of the other player.

Closest to the player zone - is a zone of simple attraction. There smaller objects are simply attracted to bigger, force is increasing with reducing of the distance.

Next zone is a zone of gravity assist itself. If player made his way to this zone, he receives bonus speed and score.

And the last zone is an orbiting zone - there smaller objects are rotating around bigger ones.

2. Idea is worth nothing without implementation. Technical side.

That all sounds just casual. There was no mind-blowing idea which could quickly attract some folk. But that is not so important and, to be honest, it is just too rare case when a completely new idea arrives to this world. Basic approach is either usage of different ideas combination which were not combined yet, or usage of some established idea with new elements. So I didn't throw this idea at early stage.

I decided to use javascript ecosystem, just because I was a bit familiar with it and wanted to master my skills.

I chose Phaser as client game engine because I knew it a bit, and honestly there are not that many alternatives for js.

For the backend I decided to use Node.js with socket.io.

So, basic tools were selected and I started implementation. And very first mistake was already made at this stage. I created two repositories, for client and backend parts. Scale of the project was too small at that point, and I could not early feel problems with chosen solution. 

Basic mechanics with absorption, border conditions, visualizations and client-server interaction went relatively fast. Few evenings and I had agar.io parody (yeah, parody, I meant that). Then was statistics, leaderboard, UI, etc. Everything is simple, without real graphics:

So far so good.

Then I started to implement interactions in zones. Attraction and orbiting zones were also implemented like a charm. But implementation of gravity assist zone was long, painful and buggy. I spent too much time polishing it and making it decent. Spoiler: It still works bad, at least worse then everything else in the game.

And that was my second mistake. This feature's impact on gameplay was dramatically less than efforts to implement it. 

Eventually I made it just work and went further.

There was time for the first tests with real users. It was relatively fine in local network and a bit later in the Internet, but I saw some tiny lags, and that was just in time.

The size of packages exchanged between server and client was too big. I made it hundred times smaller by optimizing amount of data (by sending only user related data) and by using binary format (lib https://github.com/darrachequesne/socket.io-msgpack-parser was pretty handy).

Now size of rapidly (every 30ms) exchanging packages is around 500 bytes. Can be even smaller, but efforts were not worth it. I learned the lesson :).

Game was crystalizing, and I started to care about better UI, deploying it somewhere for public access, or at least for testing by small group of people, updating process and all other not so interesting things.

Parallelly my girlfriend performed few commits with dramatical graphics improvement:

And then soon few commits brought final appearance:

I noticed that client rendering was not smooth enough. This issue was fixed very quickly by optimizing assets (images). I didn't think that size of images could affect anything except page load time, but I was wrong. Finally I achieved 60 fps on almost all devices except of few extremely low-end.

After some experiments I figured out that performance can be slightly improved on such kind of devices by using canvas instead of WebGL. But that was not always true, and I didn't find a reliable pattern when WebGL should be disabled. So I quickly added a checkbox so user could disable WebGL just in case.

I was preparing to first release and suddenly understood that online game without initial users just will not take off.

Solution was so unpredictable) :

I created a new repository for bots (forth one, third was for deploy system, bend your fingers ;) ). For bots I wanted to make same rules as for real players. So they are in the same sandbox, connected to server in same way and so on.

Now I understood that I already implemented low-level client which synchronised backend data and stored it in local objects. So, what? Right, I extracted it to the fifth repository. So, I had physical boundaries, no way to mess dependencies and blah blah blah. Also I needed to spread out every change in dependent library among all dependers, and only then perform integration testing. And that was not fun at all. So now I think you got an idea why "first mistake" was really a mistake. 

And it is time for next bucket of my mistakes)

I tried 3 different algorithms for implementing bots. I wrote off my notebook with formulas like long time ago when I studied in university) However results didn't satisfy me.

As you can see, I carefully blurred the name of the company which kindly gave me that notebook

This took a month for me. I wrote tests to verify my math algorithms, I even wrote integration tests. But all together it just didn't work correctly in runtime.

I don't want to make you tired with explanation of first algorithms (I would do if they were right, I swear ;)). Will only say that I tried to find intersections on the possible movement directions, then sort this directions by maximizing reward (object to absorb) and minimizing risk to be absorbed by bigger object.

After a month of unsuccessful tryings, I remembered about agar.io and googled something like "agario bots" and went to the porngithub to find inspiration. And I found it! I read few repos for maybe half an hour and found an awesome and simple idea. 

Bot should just select closest target, then move to it. Once it sees danger, it changes direction to 90 degrees, travels some time and then repeats the loop. Simple as that and it worked glorious! I added some small random dispersion to 90 degrees, just to avoid rare "looping" and make it look more real. And for it I spent one evening after wasting almost a month!

And that definitely was my third mistake. I just underestimated complexity of the task and arrogantly thought that it wasn't worth to google that.

Later I used faker to generate names.

Later I spent some time fighting memory leaks in server and bots services by using nodejs inspect mode (run "node --inspect") and by attaching Chrome dev tools.

With bots I quickly estimated how many users online server was capable to handle reliably. So I added connections limit (40 users) to backend and self balancing system for bots. They randomly populate the world, but once real user logins, some of bots disconnect accordingly to free up place for humans. (So far they obey me ;) ) 

And... That was final release of the game)

Virtual world populated with artificial creatures which try to survive and beat other creatures.

3.  Let's summarize

So what I did wrong? And what I would change if I made this game again?

1. I'd use one repository for it. If I did that, it would be much easier to sync changes between components or share data structures.

2. Realize efforts to implement an idea and don't set too ambitious goals. This was only my second game, but problem was not even that. Problem was that implementation and decent support of such online game was not possible for pet project with 10 development hours per week. 

To understand what was planned, just check trello board of the project: https://trello.com/b/udbODP6r/attraction-wars. I somehow finished MVP after 6 months of dev time, but implementing the rest of features requires at least one year. And that doesn't include development of scalability to handle more than 40 users (except simplest variant of random user distribution by nginx on the batch of unconnected nodes). To make it 100% production ready, one more sophisticated feature is required - network latency toleration. And that is also difficult to achieve within that time... And Android version with its own control system... I think you got an idea.

3. Think more about game idea and mechanics. Implementation has to be after planning and sketches. That will not only save tons of time, but also will just make game better. Do not waste time on features which are almost invisible for users or are not important.

4. Think twice if you want to implement online game. It is harder than you think, even if you are familiar with web development.

5. Learn more powerful game engines like Unity (and I did that) or Unreal Engine. Time for studying will save a lot of your dev time, and resulting game will be much better.

4. Attraction Wars related resources

1. Repositories:

https://github.com/harentius/attraction-wars-server

https://github.com/harentius/attraction-wars-client

https://github.com/harentius/attraction-wars-client-storage

https://github.com/harentius/attraction-wars-bots

https://github.com/harentius/attraction-wars

2. Trello board:

https://trello.com/b/udbODP6r/attraction-wars

3. Game itself:

https://aw.folkprog.net/

5. Bonus resources

I seriously interested in game dev, so I'd like to share resources I checked the last few months and which I found very useful ;)

1. Free Unity Course https://learn.unity.com/course/create-with-code. After finishing it, you will be able to build your games with Unity. Not too sophisticated, but I think it is very decent for indie game dev. Example of what I did just to check that I mastered the course: https://www.youtube.com/watch?v=sXL2hECK8KQ

2. Jesse Schell "The Art of Game Design: A Book of Lenses" - awesome book to sort your thinking

3. Scott Rogers "Level Up! The Guide to Great Video Game Design"