The idea and the goal
The theme of the js13kgame contest for 2019 was 'back', and I started to play with this 'misc controls pointerlock' example but after several tests, the final idea was to make a 'Simon' game with 5 colors and 5 shapes, where to select the color you could change the way where you are going.How it works on Desktop/iOS/Android/WebXR
With this pet project, I wanna learn how is the status of the WebXR API now and if it was possible to make a progressive enhancement interactive site that works on desktop, mobile/tablet, and VR/AR. As a summary, it is possible to make it all except on AR that is very advanced using a web component like model-viewer but is not possible to make complex interactions with the elements on the augmented reality (or at least, I didn't know how to integrate it).
What I learned in this phase For me, it is very important to have these examples to start to play and experiment with different user interactions.
The first days I made a long main.js file with all the code, as the three.js examples, until I had a playable prototype. With this prototype, I tested with my two daughters and my wife, without telling anything about how to play it. And then, after two or three iterations (I needed to make some changes to the usability), I had a first valid prototype.
This prototype had a lot of draw calls and it was very monocromatic, and as I said it was all in a big main.js file. Then my next step was to optimize it and to make it modular with a bunch of Classes to organize better the code.Screenshots of the gameplay
What I learned in this phase That I prefer to have an 'easy to make' fast iterations workflow to test the usability and if it is fun to play it, and making all on a big main.js file and make it playable with your desktop browser is a fast way to have it.
Organizing the code
I tried to use the minimum dependencies needed and to have ES6 support and to use webpack to have 'live reload' and to compress it all in a single bundle.js, this would be useful to me to apply it in the project that I was going to start in my daily work (another of the advantages of doing pet projects).
The package.json only had:
- babel to use ES6
- glslify to make easy to load and use fragment and vertex shaders
- webpack to bundle all the code and to have other advantages as 'live reload' when you make a change on the js code.
Dividing into Classes
I divided the code into around 20 different files:
- Most of them (that are placed on the THREE.Scene) as an extension of 'THREE.Group' Class like this AudioBtn.js that is the button to turn on/off the audio.
- Others like Singleton like Utils.js or Config.js to have accessible some methods or variables.
- And one App.js as an extension of EventEmitter to make it easy to emit and listen to events between Classes.
I used two shaders, one to have multiple Sky color and easy to make transitions between colors, another to have instanced objects instancedObjs.js to have 300 triangles changing their position and opacity with only one draw call (this shader was a mix of Buffer Geometry Instancing 2 and Buffer Geometry Instancing Dynamic examples).
Fitting on 13Kb
As I did not load any external file, 3D models or images for textures, the main problem was to add music without exceeding 13Kb. The solution was to make music with oscillators:
First, I tested part of the code of this post but if you dispatch these methods several times on mobile appears some audio distortion. Then at the end, I used a custom solution based on MiniMusic project. In this Synth.js Class is all the code needed to make things happen.