What I learned by making a game in JavaScript
I recently completed and released a small game that I wrote in JavaScript.
Here is what I learned.
1. Making games in JavaScript is quite easy for 2D.
The debate between using an existing engine (Unity, Godot, Unreal) or doing it in JS for 2D games really doesn't apply. Often times it's much faster to write your game in JS then work around how those engines work. This also depends on what tools you select within the JS world that will dictate how fast you'll go.
For example I used a library called Kaboom.js which has pretty much everything you need to start making games. It does have limitations but I designed my game around that.
Here is a list of tools/approaches to making games in JavaScript that goes from hardest to easiest.
- WebGL API (Only takes care of rendering) + Matter.js or another physics library.
- Canvas API (Same as the above but easier) + same as the above.
- Pixi.js. (Only takes care of rendering but makes it easy to use WebGL) + same as the above.
- P5.js + same as the above.
- Kontra.js (Takes care of more than just rendering)
- Phaser.js (Has Matter.js physics under the hood) <-- The most famous option. (Vampire Survivor is made in it) .
- Little.js (Performant but not documented/popular enough).
- Melon.js (Old but is having a renaissance and is now actively developed again).
- Kaboom.js (Really easy but has limitations. Cannot use Tiled. It had performance issues but now with kaboom v3000 it's no longer an issue. Offers a new paradigm for making games away from OOP and using a component system. You have a bunch of components you can use and a lot of things are already taken care of.) If you want an example of what game someone can produce with it, you can check out my game here : https://jslegend.itch.io/harvest-move
- Ct.js (This one is an engine with an editor and everything. Might give this a shot for my next project.)
2. If your game is not UI heavy just make the UI in the canvas rather then using the DOM.
Using CSS/HTML for your UI is just too much work for no reason. You have to fight the quirks of CSS and most often than not your UI is really something custom to your game so why not just draw it in your canvas instead? This is the approach I took and did not regret it.
However, this might change if you're making something really UI heavy like a management game or games like Geoguessr and Wordle. In that case HTML/CSS/JS using a framework like React, Solid, Vue, Svelte is probably the way to go.
3. The easiest way to wrap your game as a desktop app is to use Tauri.
The three main solutions for this are Electron, Tauri and Neutralino. Electron is harder to use but more mature and has support for the steam api. Tauri is the easiest and really performant but can't produce executables for all 3 platforms on the same machine yet. Neutralino is slightly harder to use than Tauri. You also have to use a ressource hacker to change the default icon of the produced executable but can produce all 3 executables on one machine as opposed to Tauri.
I had the best dev experience with Tauri. Everything just worked and I didn't even need to know Rust as there is a JS api you can use. In the end I decided to just release my game on the web as my game is rather small and thought that no one would bother downloading it.
4. Newgrounds is an underrated platform to publish your web game.
I've noticed that I get more feedback and I'm less ignored than publishing on itch where unless you're submitting your game as part of a game jam there is no discovery. I think the way to go is just to publish on as many platforms as you can.
Game design lessons
I made a small game called HARVEST MOVE. It's an arcade puzzle harvesting game where you have to harvest as many plants as possible without getting killed by crows and other creatures. The game is played on a board where you move on tiles. The creatures that can kill you move in predefined patterns.
To succeed in the game you must carefully plan your next move a little bit like chess. You also need to learn the creatures pattern as to not collide with them. Plants of various value will spawn on the board randomly.
If you want to give the game a go, you can play it in any desktop web browser here : https://jslegend.itch.io/harvest-move
Now let's get started with the game design lessons.
1. You can't really know if an idea is actually fun until you prototype it.
The initial idea for HARVEST MOVE was a bit different than what I ended up making. Originally the player would have to plant a limited number of seeds and move around the board for them to grow. Time would only pass when the player made a step. Once the plants grew they would be available for havesting for a limited amount of time before starting to decay.
If you collected a decayed plant you would gain 3 seeds to try to plant again. If you collected a fully grown plant it would count as one crop harvested.
I thought this game idea would be fun because you had to manage your seeds and adopt a balanced strategy between harvesting all grown plants and waiting for some to decay to gain more seeds to plant again.
In practice the game was tedious. The planting phase wasn't fun at all.
2. Playtests with others.
I only realized how bad my game was going to be when I let my brother play it. I could see with my own eyes how boring it was to play. However, I noticed that he had fun avoiding the crow enemy I just added to the game.
This is were I realized that I needed to pivot to something else or I would risk making a boring game.
3. If your initial vision doesn't work you can always pivot.
Making games can be a very fun experimental process. I ended up removing the planting phase + plant decaying mechanic in favor of moving to avoid enemies. Then, I gave my brother the game to play and collected any feedback. I then refined the gameplay and repeated the same process.
In the end I ended up with a game albeit different than what I originally wanted but at least it was fun to play.
4. Reduce the role of randomness as much as possible.
I realized in my game dev journey, I used randomness a lot but that was due to laziness. It's easier to give the illusion of a rich gameplay by using randomness. I also realized that players don't like it because it takes away control from them.
Thinking about it, this makes total sense. A game is the only medium in which the consumer can do things/is put in charge.
This is something I tried to do in my game. Initially the crows and other creatures would be spawned randomly on the board. I removed that.
I also tried to randomize the crow movements but ended up removing it. It was a very good choice to stick with predictable patterns. This made it that if you lost it was your fault and not some random event that was responsible for it. It also became a game of skill which was really fun.
In the end the only role randomness had in my game was for which plant was spawned where but how you would get to this plant was entirely determined by your own skill.
The lesson I learned from all of this is that randomness should be mitigated as much as possible but there are still some places where it makes sense to have it.
5. Glad I went with pixel art.
After my prototype using rectangles was done, it was time to do the art. I'm not that bad of an artist so I initially tried to hand draw the art. I immediately backtracked because my game was starting to look like a flash game. I could do better but it would take me too much time.
I went the pixel art route. What I learned is that it's easier to look more professional but colors can make and break the pixel art. Each pixel has so much impact. I received some feedback that a player didn't recognize the rat enemy as being a rat. I guess there's still room for improvement.
6. Should have put more thought into sound design.
I should have put more thought into sound design but I started to get tired of the project. So I quickly took some public domain sounds and put them in my game. This is something I wish I did better. Sounds can have a huge impact on how enjoyable a game is. For example, it could make player movement really statisfying.
In the end I'm glad I made this game because I demonstrated to myself that I could make something fun and more importantly FINISH SOMETHING.