battlechoc tech stack


Hi everybody


We want to share some insights on the setup and stack of technologies involved in the development of battlechoc. Still quite high level but hopefully good enough to get an overview.

The main battlechoc application is a so called progressive web app (https://web.dev/what-are-pwas/). A PWA is in very short words a website which  might appear as a native app and use mechanisms like the service worker (https://developers.google.com/web/ilt/pwa/introduction-to-service-worker) to cache online ressources for offline usage resulting in the ability to have the app run without the need to be online.
The idea was to support more than one platform (Android, iOS, PC) from the beginning but preserving the download and own experience of native apps. During the development we figured out that it would also be nice to have at least a native App for one of the major mobile operating systems. We chose Android for that purpose and implemented a simple Android App with a splash screen and fullscreen webview which hosts the PWA. This allowed us to place battlechoc also in the Google Playstore. A further idea we implemented was to introduce an Electron (https://www.electronjs.org/) application and package native Linux, Windows and OSX apps based on the Electron platform. The goal was to also access Steam as distribution platform for battlechoc. So far we question ourselves if the audience on Steam for battlechoc is worth the 100$ or if it is more oriented on action games. If you got any suggestion we are very grateful to receive your comments.

The PWA
The general stack is pretty straight forward. battlechoc is a React (https://reactjs.org/) single page application using Babylon.js (https://www.babylonjs.com/) for all the 3d rendering stuff. Babylon is really great for our purpose. It offers all the features needed without beeing too heavy weight. Lately we switched from bitmap graphics for all sprites and ui graphics to SVG increasing the quality and also performance of the application. Here is the dependencies and devDependencies portion of the package.json of our PWA for anybody who is interested to learn more about the basic setup.

"dependencies": {
    "axios": "^0.19.0",
    "babylonjs": "^4.2.0-alpha.15",
    "babylonjs-loaders": "^4.2.0-alpha.15",
    "battlechoc-shared-functions": "https://chocnonymous:R1kARoNw7xmF8eAvuk6s@gitlab.com/battlechoc/battlechoc-shared-functions.git",
    "confetti-js": "^0.0.18",
    "firebase": "^7.6.0",
    "idb": "^4.0.3",
    "javascript-time-ago": "^2.0.1",
    "react": "^16.7.0",
    "react-countup": "^4.3.3",
    "react-dom": "^16.7.0",
    "react-firebaseui": "^4.0.0",
    "react-jss": "^10.1.1",
    "react-redux": "^7.1.0",
    "react-scripts": "^3.0.1",
    "redux": "^4.0.1",
    "redux-starter-kit": "^0.5.1",
    "typescript": "^3.5.2",
    "uuid": "^3.3.2"
  }
"devDependencies": {
    "chalk": "^2.4.2",
    "customize-cra": "^0.9.1",
    "expect-puppeteer": "^4.1.1",
    "puppeteer": "^2.0.0",
    "react-app-rewired": "^2.1.5",
    "rimraf": "^2.6.3",
    "workbox-webpack-plugin": "^4.3.1"
  }

The backend
The backend facilitates Google's Firebase (https://firebase.google.com) including serverless components like Google functions (Google's AWS Lambda pendant), Firestore (realtime NoSQL database), Google Cloud SQL (with a Postgres DB as backend), Firebase authentication for identity federation and account management and the Firebase hosting services for serving the pure website content including its CDN functionalities. The server side code itself is implemented using Javascript and in more detail Express (https://expressjs.com/de/) which can easily be used within Google's serverless environment. The only remarkable experience we had was that the Firestore NoSQL database did not perform that good maybe caused by an inefficient data model. We tried several things but it all ended up in that the connection time for the serverless functions hosting our REST backend to the Firestore database was too much with respect to the usability. That's why we migrated to Cloud SQL for most of our data but leaving the event queue and session data (which is not that deeply nested) on the Firestore which provides in its client SDK a very convenient way to react on changes on data collections instead of having to poll the database/backend continuously. 

Native applications
While on the first try it was very easy to implement the webview Android native App we needed to host battlechoc.com, we had a lot more hassle dealing with things like push notifications, the sound, firebase authentication and some issues due to CORS. There are some mechanisms which allow us to execure Javascript code triggered from the Android native code in our web application which allowed us to interface between the Android push message implementation and our PWA. 
It was even easier for us to get the Electron apps setup and running. It took us almost 3 evenings to have native apps for all platforms available. Furthermore, the packaging for OSX, Windows and Linux including cross compiling/building from OSX for Linux was very convenient. The only thing that did not work out of the box was cross compiling from OSX for Windows caused by some incompatibilities between OSX Catalina and Wine. But setting up the build system on a separate Windows PC was again easy due to our platform independent tech stack based on Node.js. The only downside of Electron seems to be the size of the packaged applications which was more than 200 MB for all three (Linux, Windows, OSX). If you got any suggestions regarding the reduction of the footprint of the Electron packages, please let us know. Just in comparison, the Android native app has a footprint of less than 4 MB.

Pipeline and project setup
The development pipeline facilitates a complete continuous integration and deployment system based on Gitlab and Gitlab CI. The project itself is divided in several sub projects. Those are the PWA itself, the backend code, shared Javascript functions and data structures between the backend and the PWA, a small Rust-based translation programm we use for bulk processing of our translations, the Electron project, the Android project and a separate project hosting a website that visualizes some KPIs using Vue.js of the current application. We also implemented unit test for the three main modules (PWA, server, shared functions) using Jest, Puppeteer and Docker which is also incorporated in the automated build and deployment process. It turned out that unit tests are very cool in order to  preserve the quality of the app but to be honest, we could do better regarding test coverage.

If you are interested in any more details on certain points, just get in touch with us on Instagram (battlechoc), Twitter (@battlechoc), itch.io or mail (info@battlechoc.com). We are happy to share what we learned during the last month.

All the best from your battlechoc team!

Leave a comment

Log in with itch.io to leave a comment.