For my first Three.JS (tiny) game, I'm trying to mix Townscaper and the Monument Valley games together

Posted on: 2022-04-03
Software versions:

For this first project, I wanted to learn ThreeJS, so I decided to try to do something inspired by Townscaper, a game that uses elements of procedural generation to allow you to build cute-looking little towns (try it here in your browser, it's really awesome!) Also, I love minimalist isometric styles such as what the ones you can find in Monument Valley, so I decided to go with that in terms of graphic style.

Of course I knew I wouldn't be able to do something nearly as good as those two games... and that was not even the goal here... I ended up with something I feel is maybe like 0.1% as cool and for me it's a success. Again, I think it's important to be extra aware, when starting a project, of what is your goal and here it was pretty clear: learning Three.JS.

So, introducing... Faerie City!

How I did it and what did I learned?

At first I hesitated between using classic, vanilla Three.JS or going with react-three-fiber a.k.a. write-a-three-js-application-in-react. I chose to go with plain javascript because I thought it would be a good thing to take a vacation from the react mindset. We sometime forget that working with react makes you think and reason in a very particular way, because of the, well, reactive nature of it. We tend to forget that there is a world out there where you can build stuff without using only pure functions, immutable states etc...

Even if I decided to go with plain-js Three.JS, I still chose to use react for the user interface on top (more on that in a sec).

Things I learned/pondered on:

1. OOP is not that bad, and if you choose a library that relies on it, just go with it instead of fighting it. ThreeJS uses Object-Oriented Programming and coming from react the first I did, as a reflex, was to try to architecture my application with immutable states that would go through a react-like life-cycle etc... but I quickly realized that was hard, and made my code messy... OOP gets a bad rap, but it's not that bad when you're careful... so instead of trying to make it more functional, I realized it was a better idea to actually dive in a just try to write a decent OOP application (well actually I dont think my code is that good lol, but you get the idea)

2. On the other end though, it's true that, in the particular case of ThreeJS, it made me realize that it actually makes sense to use react and now I think I want to try react-three-fiber. In ThreeJS, you create meshes, that you put into groups, that you can put into other groups, that you put in a scene... all that hierarchical works... does that sound familiar ? Yeah it's a like a DOM, right ? SO it does make sense to use something like react. Plus, the life-cycle of 3d objects, materials and geometries in ThreeJS is sometime a bit of a pain (you have to dispose of them manually), so I would be curious to see if react-three-fiber makes all of this easier.

3. It's awesome to be in a browser (because is simplifies the UI a lot). Your Three.JS application is essentially rendered in a `<canvas/>` tag, so it means that you can - and this is what I did- create a react application and display it on top (`position: absolute`) to create you UI ! That way, you dont have to make your UI with ThreeJS and I think I saved a ton of time on that one. Just being able to use tailwind + icons from bootstrap made building and interface much easier, I recommend it ! Actually that's again where react-three-fiber might be cool to use here also: instead of having a Three.Js application for the game + a react application for the user interface on top, you could just have one react application that does both. BTW even if you choose to go with vanilla javascript for three.js, you can still make it communicate with your react UI with a store, like MobX (also what I did !)

3b. It's also awesome to be in a browser... for sound management. There is cool and easy-to-use sound libraries out there, that allowed me to add some little sounds to my game in like, an hour or two, that's pretty cool. I used howler.

Anyway, I really enjoyed doing 3d and building something with ThreeJS, it's true that doing 3d is sometime math-heavy (sin and cos are your friends!) but it's refreshing and satisfying to work on something that is that visual and that you can show to you friends. Will definitely do it again !