• Public
  • Public/Protected
  • All

YORG.io 3 Docs

YORG.io 3 Codebase

This is the full documentation for the YORG.io 3 Codebase.


  • node.js
  • yarn
  • FFPMEG.exe in your path
  • yarn install
  • git submodule update --init

Build Process

We use gulp for almost everything. Here is what happens during the build / which steps are required:

  1. We clear the build folder in case its there. Path: <root>/www. It needs to be called like that because phonegap build / cordova expects it.

  2. Atlas: Optimizes and copies the atlas

  3. Sounds: Copies the optimized sounds. We do not optimize them in the CI, only on local builds. They are thus committed both raw and optimized into the repo.

  4. UI Resources: Optimizes and copies the UI resources (=used by css exclusively)

  5. Non-UI Resources: Optimizes and copies any non-UI resources (fonts + favicon)

  6. CSS: Builds the stylesheet, this is the whole UI

  7. Translations: Builds and generates the translation data

  8. Javascript: Builds and optimizes the javascript code of the game

  9. HTML: Builds the html, this generates the index.html, which is the main entry point.

Build Tasks and Documentation


We use the GDX Texture Packer GUI to pack all non-ui game assets. There are seperate atlases, which are subject to change.

The atlases are built locally, however the generated PNG images are optimized during the build step. So we run GDX Texture Packer, but the CI still compresses the built images.

The atlases look like this:

combined: Contains the Map Resources, Buildings, Some icons, Particles, etc

sprites_lossless: Contains gradients and other sprites which must not get compressed lossly:

preview: Contains the first level sprite of every building + resources. Used within the UI:

streets: Contains the street rendering sprites since those are drawn to a seperate buffer and thus need different caching:

ui_sprites: Contains sprites which are required by the ingame ui, outside of the css:

When building the resources, the atlas is compressed lossly using imagemin and pngquant afterwards.

Additionally we also copy app/res/other (to res/other in the build folder) which contains sprites used for rendering, but only initially (E.g. the map background gets used once when loading the game, then never again - it would be a waste of space to have it in the atlas).

File locations

  • Texture Packer Project file: app/res_raw/atlas.tpproj.
  • Input of the atlases: app/res_raw/*
  • Other sprites: app/res/other
  • Built Atlas Output: app/res_built/atlas


There are 2 categories: Music and SFX. Music is stored in app/res_raw/sounds/music, and SFX is stored in app/res_raw/sounds/ui and app/res_raw/sounds/game.

We build the sounds locally with FFPMEG since the CI would take to long otherwise. You need ffmpeg.exe on your path if you want to build them. There are two gulp tasks which take the sounds, strip any empty in the beginning and compress it down to a lower bitrate and monochannel.

The built sounds can be found at app/res_built/sounds and will be copied to the final output dir.

UI Resources

We copy everything which matches (.png, .svg, .jpg) to the output folder. To reduce the bundle size, we compress it with gulp-imagemin and pngquant.

Files containing .lossless (for example top_gradient.lossless.png) will not compressed using lossy compression.

Source: app/res/ui

Non UI Resources

These are the fonts, and the favicon. They are copied 1:1.

Source: app/res/fonts, app/res/favicon.ico


We build the CSS using SASS and postcss. The CSS documentation can be found in docs/CSS.md.

Source files: app/src/css


We use onesky to manage our translations. The project is hosted at translate.yorg.io.

The base strings are stored as YAML in app/src/translations/base. Because onesky can not handle YAML, the build process involves converting it into JSON. The task gulp buildTranslations does this.

If you change any strings, make sure to upload app/src/translations/base.gen.json to onesky. Thats the file generated by the task (Obviously run it before).

To update the translations, run gulp updateOnesky. This will do the following:

  1. Build the translations
  2. Fetch the available languages from onesky
  3. Generate app/src/translations/meta.gen.json storing the available languages
  4. For every language, perform checks on every phrase (I.e. is it different, do the placeholders match etc), and then write it to app/src/translations/data/<LANGUAGE>.js. The file contains a string compressed with LZString so its smaller, and it will get loaded dynamically on application start.
  5. Upload the translation report to https://static.yorg.app/translation-report which contains the invalid phrases, so the translators can look it up.


We build the JS using webpack.

Documentation: docs/JS.md

Source files: app/src/js.


The html task does the following:

  1. Use the template from app/src/index.html
  2. Apply link to the css, with the commit as cache key, e.g. main.css?85235cd
  3. Add <link rel="preload"> for all images (Atlas + UI)
  4. Add <link rel="prefetch"> for the API
  5. Add the loader javascript from app/bundle-loader.js which loads the right bundle depending on the supported features.

Common Typing Errors

Following typing errors appear quite often in the codebase since I always get them wrong as a non-native speaker. Hope you dont mind too much, at some point I'll do a simple string-replace of those.

  • recived
  • controll (E.g. Controll Effects)
  • ressources
  • unkown

Stuff to notice and schemas

There are some schemas in the game which need to be manually generated (Usually they open a new popup once the game is loaded if you set the debugflag to true, whose contents you then can copy).

Savegame schema

For each savegame version there is a json schema generated and stored, as well as its corresponding interface. You can generate a schema for the current game data by setting d.generateSavegameSchema = true in the debugflags.

Multiplayer schema

The server needs some basic knowledge about the game schema, which is why there is game_shared_data.json. You can regenerate it with d.generateMpSchema = true.

Deploying an update

  1. Prepare standalone:
  2. Build the standalone on the windows host using gulp main.standalone.beta
  3. Test the builds! They are available in app/tmp_standalone_files
  4. Upload to steam using electron/steampipe/upload.bat

  5. Prepare servers and api:

  6. Update gameservers shared git to latest version
  7. Spawn new gameservers and lobbyservers
  8. Prepare database (migrate etc)
  9. Push New Api

  10. Push new game

  11. Run main.deploy.beta which will upload it to ftp
  12. In the meantime set live on steam
  13. After the deploy finished purge cloudflare cache