Skip to content

Developing for 18xx.games

Jennifer Freeman edited this page Mar 17, 2021 · 11 revisions

Getting Started

Set up your development environment using the information in DEVELOPMENT.md

Adding new games

Source of JSON for new games: 18xx-maker

Directory structure

  • meta.rb - Metadata, player count etc
  • game.rb - Main game code
  • map.rb - Tiles and maps constants needed for the game (just constants)
  • entities.rb - Corporations and companies needed for the game (just constants)

Developing on Windows

This section will show you how to setup a development environment on Windows using the Windows Subsystem for Linux (WSL).

Core tools

First, install WSL 2 using this guide.

Next, install Docker Desktop and configure it to use WSL 2 by following this guide.

Make sure you add your non privileged user on your WIN10 System to the docker users group in WIN10 via the Computer Management -> User Management otherwise if you use a non privileged user account on your machine (which you should for day to day work) the Docker for Desktop APP will not start.

At this point, you can develop directly in your preferred Linux distro or in VSCode using the "Remote - WSL" extension.

Additional configuration

Docker Desktop for Windows expects the path for volumes to be /c/; however, by default, WSL uses /mnt/c/. Nick Janetakis has an excellent guide on how to resolve this issue.

And that's it! If you want the web server to automatically pick-up code changes, make sure to run out of your Linux home directory. A known issue with WSL 2 is that changes on the Windows file system will not be detected.

Architecture of Design

Backend - lib/engine/

Frontend (UI) - assets/app/

Advice

  • Try and avoid massive PRs. They're very difficult to review.
  • Be careful of floating point numbers the ruby code tends to run as ints, the javascript code runs as floats.
  • Keep performance in mind when implementing games. Use your browser performance tracker to find hotspots in your code. The ruby -> opal bridge is not optimized so some methods cause a lot of GC like any? vs empty?.

Submitting Edits

  • Make sure you run docker-compose exec rack rake before submitting your PR
  • To automatically fix Rubocop violations: docker-compose exec rack rubocop -a

Testing

  • To access a pre-alpha game, use ?all in URL [e.g. http://localhost:9292/new_game?all]

Image files

  • Optimize image files before submitting them. Inkscape: Optimized SVG when saving (depends on scour). Usually best compression rate: nano (remove xmlns:v="https://vecta.io/nano" from files afterwards). For batch optimization check out image_optim.
  • If you only have jpg or png files you can use inkscape's autotrace or an online tool like pngtosvg to convert to svg.
  • If you need to export multiple icons from one svg file try multipage export.
  • There’s a script to generate simple logos: scripts/generate_logos.rb

Troubleshooting

Weird messages after updating code

Run make clean to force a rebuild of frontend javascript files under public/assets/, then rerun [either open any .rb-file and save to trigger a rerun or make dev_up_b]

Docker Make not working

ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?

  1. Try running with sudo or adding the user to the docker group (+ logout/-in)
  2. Try running systemctl start docker

Browser not seeing updated code

You need to completely clear the browser's cache. On Chrome: <ctrl><shift>R

Hotseat: Made an illegal move and want to remove it

  • a=JSON.parse(window.localStorage['hs_fhsvpepp_1599508832'])
  • a.actions.pop()
  • window.localStorage['hs_fhsvpepp_1599508832']=JSON.stringify(a)
  • Refresh your browser

Hotseat: Push a move (be careful)

hotseat='hs_fhsvpepp_1599508832'
a=JSON.parse(window.localStorage[hotseat])
new_action = {
      "type": "program_buy_shares",
      "entity": "Player 3",
      "entity_type": "player",
      "id": 8,
      "created_at": 1613076234,
      "corporation": "AR",
      "until_condition": "float"
    }
new_action.id=a.actions[a.actions.length-1].id
a.actions.push(new_action)
window.localStorage[hotseat]=JSON.stringify(a)
Clone this wiki locally