Giter Club home page Giter Club logo

oraladder's Introduction

OpenRA ladder

This repository contains all the sources used by the OpenRA community competitive 1v1 ladder hosted on oraladder.net.

It contains:

  • the web frontend written in Flask (Python)
  • the backend tools (ora-ladder, ora-replay)
  • the game server configuration
  • detailed explanations on the setup
  • a work-in-progress RAGL integration

For some context and history on the project, you can also read the following blog post: Building a competitive ladder for OpenRA.

Developers

Bootstrap

The only dependency is Python. To run the ladder locally, just type make. This will create a local Python virtualenv, bootstrap all the dependencies into it, and start a local development server.

The site should be accessible through http://127.0.0.1:5000 and any change in the sources will be reflected there immediately.

Initially the database is empty so what's being displayed has little to no interest. We can fill it using the ora-ladder backend command:

# Enter the virtualenv
. venv/bin/activate

# Create the 2 databases (all times and periodic) with your local RA replays
ora-ladder -d db-ra-all.sqlite3 ~/.config/openra/Replays/ra
ora-ladder -d db-ra-2m.sqlite3 -p 2m ~/.config/openra/Replays/ra

# If everything went well, update the DB of the website atomically
cp db-ra-all.sqlite3 db-ra-2m.sqlite3 instance/

Docker

The web services can be run in Docker containers. Please refer to the Docker instructions for more information.

Architecture

The general architecture used on oraladder.net is pretty simple:

Architecture

The game server instances are configured to record the replays. Then on a regular basis, the backend parses them to find the outcomes, identify the players, and finally update their rank. During the process of ranking, the backend also has to query the OpenRA user accounts API (external) to identify the players and obtain more information (the display name typically). Finally, the web frontend is just a dumb way of displaying the information contained in the database.

Each brick can technically be separated. For example, game servers can be on other machines, and replay files synchronized for the backend to read. This means adding matches from other sources is just about synchronizing files. Similarly, the website could be hosted elsewhere (even thought it might not make much sense). This also means the backend could easily be adjusted to craft the data in another form for a different frontend.

Another handy aspect of this approach is that an admin doesn't need any special interface for maintainance: only the replays have to be managed. They can be arbitrarily organized into folders since the backend searches through all the configured paths. To remove a match, (re)moving the file and make sure the DB is reset is enough.

Last but not least, since the replays contain pretty much all information about the matches, additional statistics and analysis could be added in the future.

Production infrastructure

In production, the setup requires a bit more work than in development mode. Following is a suggestion of setup.

Let's assume we have 2 users: ora and web. ora is running the game server, and web runs the backend script and the web frontend (this could be split further but let's keep it simple for now):

useradd -m ora
useradd -m web

# allow the web to read the replays
usermod -a -G ora web
chmod g+rx /home/ora

Game server instances

ora needs a virtualenv with the ladder installed in it. For that, we need to build a Python wheel of oraladder. This can be done with make wheel. It will create an oraladder-*-py3-none-any.whl file. After uploading it into ora home directory, we can setup the game server instances:

# Setup virtualenv
python -m venv venv

# Enter the virtualenv
. venv/bin/activate

# Install the ladder wheel
pip install oraladder-*-py3-none-any.whl

The game server instances need a map pool. Map pool examples can be found in misc/map-pools/.

ora-srvwrap (available in the venv) is a helper to bootstrap (if needed) and run the game server with competitive settings. This tool does a lot of things:

  1. it fetches the OpenRA sources (if needed) at the specified version and build them
  2. it creates an isolated game server instance directory in which these sources are copied
  3. it patches the specified mod with locked competitive settings
  4. it downloads all the maps of the map pool if not available in its cache
  5. it drops all the internal maps and replace them with the previously downloaded map pool
  6. it finally runs the game server instance on a port derived from the specified argument

Assuming misc/map-pools was uploaded in the home directory, here is an example for running 3 game server instances:

ora-srvwrap map-pools/ladder.maps --label 'My Competitive 1v1 Ladder Server {id}' --baseport 10100 --basewkdir srv-ladder --instance-id 0
ora-srvwrap map-pools/ladder.maps --label 'My Competitive 1v1 Ladder Server {id}' --baseport 10100 --basewkdir srv-ladder --instance-id 1
ora-srvwrap map-pools/ladder.maps --label 'My Competitive 1v1 Ladder Server {id}' --baseport 10100 --basewkdir srv-ladder --instance-id 2

Note: a different shell will be required for each since this is not running in background.

A motd template file can also be specified with --motd-file. See ora-srvwrap --help for more information.

With our previous example, each instance will have their replays recording stored into ~/srv-ladder/instance-*/support_dir/Replays.

Backend

Just like ora, web needs a virtualenv with the ladder installed in it. Upload oraladder-*-py3-none-any.whl again, this time in web home directory. Then we can setup the ladder:

# Setup virtualenv
python -m venv venv

# Enter the virtualenv
. venv/bin/activate

# Install the ladder wheel
pip install oraladder-*-py3-none-any.whl

# Create initial empty databases
mkdir -p venv/var/ladderweb-instance
ora-ladder -d venv/var/ladderweb-instance/db-ra-all.sqlite3  # all-time DB
ora-ladder -d venv/var/ladderweb-instance/db-ra-2m.sqlite3 -p 2m  # periodic DB

# Create a useful DB update script
cat <<EOF > ~/update-ladderdb.sh
#!/bin/sh
set -xeu
~/venv/bin/ora-ladder -d db-ra-all.sqlite3      /home/ora/srv-ladder/instance-*/support_dir/Replays/
~/venv/bin/ora-ladder -d db-ra-2m.sqlite3 -p 2m /home/ora/srv-ladder/instance-*/support_dir/Replays/
cp db-ra-all.sqlite3 db-ra-2m.sqlite3 /home/web/venv/var/ladderweb-instance
EOF
chmod +x ~/update-ladderdb.sh

The last step is to setup a crontab to update the database regularly; in crontab -e we can for example do:

*/5 * * * * ~/update-ladderdb.sh
0   0 * * * rm -f ~/db-*.sqlite3

This will update the database every 5 minutes. And every day, we remove the cached db-ra-all.sqlite3 (and db-ra-2m.sqlite3) so that the next update causes a full reconstruction of the databases. This is an arbitrary trade-off to avoid spamming OpenRA user account service, and still get relatively up-to-date information displayed.

Frontend

The front-end is the last step. So as web user:

# Re-enter the virtualenv (if not already in)
. venv/bin/activate

# Install Green Unicorn (Python WSGI HTTP Server)
pip install gunicorn

# Generate a secret key
# Following https://flask.palletsprojects.com/en/1.1.x/tutorial/deploy/#configure-the-secret-key
python -c 'import os;print(f"SECRET_KEY = {repr(os.urandom(16))}")' > ~/venv/var/ladderweb-instance/config.py

# Start the service (listening on 127.0.0.1:8000)
gunicorn ladderweb:app

Now that the server is listening in local, we can use nginx to expose it to the outside. A nginx.conf configuration example file is available in the misc directory.

Since the outcomes are stored in UTC time in the replays, you will likely want to align the system clock as well so that the website behaves in coordination (typically with regards to period resets) using for example timedatectl set-timezone Etc/UTC.

oraladder's People

Contributors

kvalv avatar suhrm1 avatar tttppp avatar ubitux avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

tttppp

oraladder's Issues

Player level

Introduce a "level" attribute for players so that they can rise through ranks as a non-volatile, permanent reward

(i.e. after re-vamp of all-time ladder)

Open Ladder

In addition to classic 1v1 competitive ladder with a pre-set map pool using fixed balance iteration, create a ladder instance open for any maps and gameplay. Ranking algorithms should already support this and it would eliminate maintenance overhead regarding map pools and balances

Rankings in Team games

Currently oraladder uses trueskill to rank players. Trueskill and the used library is readily able to rank players in team matches. So why dont we make that available?

Player achievements

Create achievements for players to collect through playing:

  • play / win n games
    • as faction...
    • in a day / week / month
  • play vs n different opponents
  • win vs n opponents
  • win n games in a row
  • reach n points (in a season)
  • finish season in top n% of players (depends on number of active players per season)
  • ...

Ideas welcome

All-time ranking overhaul

The current all-time ranking is too static - active players have little to no chance of reaching the top after top players retire

Map statistics

Display map statistics (per season)

  • games played
  • faction win rate
  • avg duration
  • ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.