Our Problems Banner Our Problems Banner Mobile

OurProblems is a browser based math mmo rpg video game.

OurProblems features four avatars each of which have unique abilities that assist them in their rpg role when solving problems. The player must control their avatar's movement to aim at other players and to dodge other player abilities all the while simultaneously trying to solve arithmetic problems. We hope you have a NUMBERPAD on your keyboard!!!!

Game Lore

The denizens of the game Our Problems were accustomed to solving problems in their own myopic perspective until they were struck with the ability to see the problems of others. The characters are somewhat sterotypical personifications of various professions. Anyone can do math though regardless of profession. What problems can a scientist, businessman, artist or therapist solve for you that are related to Math??? Who knows, things made sense during initial development. Perhaps all characters are exagerated aspects of each us....so this introduction has been a labor of fitting lore to a game. This is what happens when lore is the last thing created in a video game. This is a simple 2d game, leave logic at the door and have a little fun. There is only one server running so you may not even be able to play at this time.

A lot of what you will read here is about how this game was made. Also some detail will be presented into how to build a near realtime multiplayer game. The advice and suggestions given here are NOT from professionals. This is simply an account of what it took to accomplish what has been done for this game.

The World

The world of Our Problems is idealistic fantasy. The world is a fictional utopia depicting the possibilities derived from solving problems. One where we have miraculously solved the problem of nuclear fusion for cheap endless energy. If they ever prove it to be impossible the art will be changed. All the denizens of the OP seek to solve problems in their world their own way.

The world is 8192x8192 pixels featuring at most anywhere from 50 - 100 characters concurrently at a time. The 100 player max was chosen to provide a decent amount of space for players when moving around the world between opposing players. The second factor for choosing this number of players is to reduce packet drops on the internet. The max player count is still being tuned as internet testing continues. The more players you have in a game the higher the bandwidth cost. Bandwidth costs money with most hosting providers. Also the higher the potential for network delays when attempting to send a large data payload to a player. During development testing the game was being tested at 500 plus characters on a local area network without compression. The moment though you get on the internet with a geographically distant server everything starts getting dicey.

The art for the world took many turns and is a 0 budget piece of work. The original direction for the art was going to be a world in ruins with broken or dilapidated machinery and buildings. Conceptually it would have been a world with problems that needed to be fixed or solved with hard work and cleverness. The new direction was simply to build an optimistic zaney inane world where we have managed to solve miraculous problems and pursue near unrealistic idealistic goals. We have an artist that seeks to inspire cleverness, we have a businessman that owns everything, we have a therapist that wants to guide individuals behavior towards an answer and a scientist that always has the answer. The result of the art is what happens when a world is developed part time and with 0 budget. The four corners of the world are embodiments of the origins of the four central characters.

Character Concept

The problems each denizen has is abstractly represented as a Math problem floating near them. How does this make sense??? Who knows! Maybe the denizens are thinking of a problem or maybe they are being nettled by a problem. This is just art and is fully subjective, you decide. The bulging eyes the characters ability to see the problems. The characters abilities while solving problems are loosely tied to their professions. All art in this game is subject to change at any time. The clothing selected is sterotypical for those professions. Each Character is motivated by their own tenets for solving problems.

Character Controls

Math Combat

THE GOAL OF THE GAME

The goal of the game is simply survival. Do your best to collect joy solving problems lest you disappear from the world. When solving others problems you will be challenged with 3 problems ranging from addition, subtraction and multiplication. When you run out of joy you will be presented with a score board.

HOW TO CREATE A SINGLE PLAYER CANVAS GAME?

HOW TO CREATE A MULTIPLYER CANVAS GAME?

The below is a list of the knowledge and resources used to create this simple 2D canvas game. The majority of the game logic for this game is completely original. As noted before this is not professional work. The game does have bugs and is still a work in progress. OP does NOT recommend building a custom game engine. Writing a single player 2d canvas game is easy but adding multiplayer on top of that is almost triple the effort. This is not an easy undertaking. If possible find an open source premade game engine.

Knowledge

Tools

Resources (Just Recommendations)

MATH USED IN THE ENGINE

What math skills were needed for this 2d math game?

Most common Equations!!

Given this game is centered around solving problems it seems fitting to provide some of the most commonly used equations in the game engine. These few are perhaps the most frequently invoked functions. Only several are provided as not to inundate the content here with minor use cases.

Javascript Tips

The below is a summary of some general javascript performance tips for computation speed or memory use. The below list does not take into account any performance optimizations the browser may be doing to your code.

Timers

Obviously use the windows.requestAnimationFrame() to control your animations. Perhaps not so intuitive is try to use the time argument from requestAnimationFrame for anything and everything you might need to do dealing with time. The event loop will attempt to keep this render function call in sync with the browser refresh rate. This is literally the most reliable timer you have available.

Smooth Animations

Unfortunately the majority of the animations in this game are not very smooth. This is because all of the animations are running at 20 fps. This may change in the future. The original thinking was to minimize the download time for the art spritesheets by reducing their download size. As mentioned before this is not professional work. This is the result of 0 budget and no time. There could have been 40 additional frames for the animated legs, arms, and head which given we have four players would definitely increase the size of the sheet by at least 480 images. If you want beautiful flowing and fluid animations then you'd definitely want to go higher than 20fps. Notice all the characters are using the same pants. The whole same pants thing drastically cut down on animation work. Changing the color of the pants per character at the very least would require all those frames to be rendered and added to the sheet. That would be around 80ish more images for multicolored legs. This might be done in the future....anything could change. This is by no means a limitation for browser games, there are plenty of browser games rendering far more resources than this one. Especially games using webgl. This game is literally a first work concept. If there were only one player the one avatar could have had prolific and fluid animations done in the same amount of production time. Things being what they are the first design is where the game landed and stuck. All animations are being done at 20fps but this should not be confused with movement. Actual movement is being interpolated over time for every frame. The ideal place to be with animations is above 33 fps to make choppy animations almost imperceptible. The nice thing about this being a browser game is updates can be easily made and redistributed.

Smooth Movement

Our Problems had many issues dealing with the smooth movement of players. So many in fact that this was one of the last few major issues addressed. The initial version only moved players based on action ticks from a fauilty understanding of the unreal valve article. The original solution amazingly worked as long as one specific scenario was avoided. The scenario that made the lack of smoothness extremely noticeable was when two players walked side by side parallel to each other in the same direction. This is when the makeshift raft of a custom game engine started coming apart. The primary player would move using client side prediction from time sampled inputs controlled by checks inside of requestAnimationFrame(). The secondary player however was controlled by network ping, minor backend server processing loop timer fluctuations and a bad history buffer implementation on the client. Needless to say the secondary player was jittering quite frequently. The primary player was moving normally. This is a tale of how these issues were addressed.

The initial troubleshooting process was targeted at player action input pulse timing and sever process loop timing. Regardless of actual sample rate lets suppose that a player is moving at 6 pixels per input sample. The player presses the up key to move forward then at the end of the sample period that action input is sent to the server and the player advances forward. Lets suppose that both the server and the client are on the same period. That the browser client is sending action inputs every 33.33 ms and the server process loop is processing those actions and sending a world update every 33.33 ms. With both client and server on the same period the ideal scenario would be that 1 client player input is recieved every server period. Networking though throws a wrench into the ideal scenario but before we get into networking you will see that timer fluctuations are also a culprit. Knowing that there are minor fluctuations in time on BOTH the browser client requestAnimationFrame and also the backend server process loop it may be possible for the server to receive two action inputs within the same pulse period. The initial thought process was to do as much as possible to make sure that one action input is being recieved on the server per server pulse. This concept is much easier to diagram when using a much smaller pulse range.

Lets suppose that we were cycling/pulsing at an INCREDIBLE (FAKE) RATE of 5ms on the server for demonstration purposes only. Also suppose the client is being intentionally pulsed even faster at an INCREDIBLE (FAKE) RATE of 4ms. Also posit that latency is near 0 for the sake of demonstration. This is so we understand what happens if a client timer is fluctuating slightly faster than the server. You will repeatedly end up in scenarios where the server gets two action inputs at once causing the enemy player to move at double the speed for a single pulse of the server. Effectively you will see random jitter where the enemy player moves at double the speed every so often then returns to normal speed.

Example of what causes an enemy player to jitter when client sends inputs to fast.

This is only half the story. As mentioned before the timers on both the server and client are wobbly or fluctuating although they should both try to auto correct on the next iteration to stay on time. Lets explore what happens when the server is fluctuating faster and the client is fluctuating slower. You should end up in a scenario where the exact same world update with no change in enemy position is sent to the client since the browser player input didn't arrive within that period. Diagram:

Example of what causes an enemy player to jitter when server runs to quickly.

Now as you can see if the server ever fluctuates to quickly you end up in scenarios where some of the server pulses get no action inputs from the client. This means that when the server sends out the server pulse at the end of the period there effectively will be no change in the enemy player position. This will present the visible effect to the player that the enemy was moving then suddenly stopped then moved again thusly causing jitter. Also note a wobly network ping can cause the action inputs to arrive at the server arbitrarily. All of these wobly fluctuating timers causes the enemy players to move normally, double in speed, possibly stop or return to normal repeatedly.

So how was enemy player jitter fixed?

Bandwidth and Data Usage

A critical concern with creating an online multiplayer game is your data payload byte size. Many server hosting providers for your game nodes will charge exorbitant fees for your data usage. When the server sends out the world update it needs to send that data payload to every single player in the game. Assuming for example that your server has 10 players and every player has a total size of 60 bytes. When sending the world state to the browser client of every player that would total to (10 * 60 * 10) per pulse from the servers perspective, 6000 bytes per pulse. The original version of Our Problems was played with 500+ uncompressed characters on a local area network. Now if in our 10 player game example we are pulsing world states at 20fps or 50ms you would then be required to calculate your monthly data usage to determine if your hosting provider might be able support your data load. In other words (6000bytes * 20 TimesAsecond * 60seconds * 60minutes * 24hours * 30days) or 311GB assuming maximum game load for that month. Given a large number of hosting providers provide their compute instance packages based on 1TB or 2TB per month before charging overages this might seem great at first. That is until you start thinking about how to support 1000 players or even 10000 players. Then thinking about architecting such a solution becomes a wholy separate skill that will need to be developed. Creating a simple 2d networked multiplayer game looks easy on the outside but requires a ton of work underneath the hood. Had all precepts and tenets associated with creating a multiplayer game been understood prior to the development of Our Problems, such a high player count would not have been chosen. In coming months the player count may be tuned down and extra game mechanics added. Also we only have a several nodes at this time.

How is game ping measured?

Ping is what most people in gaming refer to as the round trip time it takes for a packet to travel from your computer to the server and back again. Latency is the time it takes for a packet to travel from your computer to the game server. The way ping works for this browser game is that it relies on the requestAnimationFrame timer to send the player action input to the server and waits for it to return to be processed on the next requestAnimationFrame. A detailed illustration has been provided for how the ping works:

Illustration of how game ping is being measured for the game.

Latency1 + Latency2 + Render Delay - Pulse Delay

Is a websocket fast enough for a multiplayer game?

Our Problems certainly hopes so....hahaha. OP is also researching newer technologies though. When testing on a local area network the ping is around 0-1ms. This is with no network congestion and an extremely basic echo response returned upon reciept of a message. Interestingly in production this game was validated on a server located 1063km away using a websocket connection and getting an initial ping of 28ms over a vpn. However when switching vpn endpoints even if the vpn servers were located in the same city, different results were produced yielding a range 20-50ms depending on vpn endpoint chosen. The only conclusion was that different vpn endpoints could have different hardware associated with them and different levels of network congestion. The network path taken, the hardware along that route and the congestion has an impact on the speed of your response. If you are a gamer with bad ping no matter what game you are playing and going across a vpn, try switching endpoints. Even if an alternate endpoint is in the same city. Let's not forget this game is using websockets which is based on tcp. Hopefully this will change very soon.

What hardware is needed for the server?

The Our Problems server is currently using an event loop. No particular research has been done on what hardware is needed. Given that this is an event loop the presumption was simply to get the fastest processor available so that all the instructions could be finished before the end of a server pulse. This thinking though IS somewhat naive. The initial metrics of simply checking the process time inside of the server processLoop shows that the computation does indeed finish well under the pulse period. The game is currently running on a AMD 3.4GHZ processor in production. However during the early days of testing OP did not have a linux server on which to validate in the development phase. OP started off using a Raspberry PIs for linux development, using the Raspberry Pi OS Lite operating system. The raspberry pis were overclocked from 1.5GHZ to 2GHZ based again on a presumption that it would be best without actual testing. Amazingly everything actually worked. This was literally a zero budget operation and still is currently. Later on OP started using a refurbished intel i3 computer for the linux OS development.

AI Bots and Scripts

In the current simple design without any bots there would be nothing for a player to do when initially joining a game. Currently when a player joins a game, two bots will appear if the player count is under 8, or some other configurable low threshold. Perhaps the most difficult algorithm built for this type of 2d game was for the bot pathing and that is the AStar algorithm. This algorithm finds the shortest path between any two points. Thusly the path between the bot and the player. Given that our node count is pretty low the pathing the bots take can get a little wacky.

Challenges and Concerns

Future Updates

Publish: 06/28/2024 Edit: 08/11/2024