Thank you for considering contributing to OpenDominion! This document contains some guidelines to explain the contributing process and hopefully answer some common questions.
- For code contributions, make sure you have a GitHub account.
- Make sure you read, understand and agree to the Code of Conduct.
- The project's development is governed BDFL-style. See Governance for more details.
- Join the OpenDominion Discord server.
The Discord is used for both for the playerbase community, as well as development-related communication, announcements and game updates.
OpenDominion is an open source clone of Dominion (round 70-74 ruleset), with a few key changes and improvements:
- An open source project with (hopefully) well-written, documented and (unit-)tested code.
- A modern and responsive design, developed and tested for desktop, tablet and mobile.
- Full free to play. Meaning: no premium accounts or features, no microtransactions, no lootboxes, and no advertisements either.
- Lifetime accounts by default. Meaning you can use the same user account across multiple rounds, instead of having to re-register for each round.
While the original Dominion community back in the day was quite sizable, the OpenDominion project started a few years after Dominion closed down and the when the original community had already dwindled to a fraction of its former size. When starting OpenDominion, the goal was to code and work on the project as much as possible, before trying to gain popularity and build a community.
By time of writing, a few years of hard work have passed and significant progress has been made. Though still incomplete and under development, OpenDominion is slowly gaining players, code contributions, and people on Discord (players, developers, and people otherwise interested in the project).
As authors of the OpenDominion project, we'd like to personally invite you (yes you, you're reading this, after all) to join us in the journey if you're interested in the project! Which we assume you somewhat are, since you're reading this!
It doesn't matter if you're a Dominion veteran or if you're new, feel free to:
- Participate in the beta!
- Join the Discord
- Spread the word to those you know might be interested.
- Praise the project by starring it on GitHub.
The beta of OpenDominion is currently running at https://beta.opendominion.net.
Feel free to register and play around! On the website homepage are links to help you get started if you're new to the game.
At time of creating this contributing document, quite some key information was still missing about the game. Notably how invasions worked, amongst other miscellaneous things. Nowadays most information has been recovered bit by bit, and reconstructed into either working features implemented in OpenDominion, or issues on the issue tracker.
There's still a few open issues which require investigation or are up for discussion. If possible, browse through the issue tracker, look for issues with the label "help wanted" or "discussion" and feel free to reply with your thoughts. Or hop onto the Discord and communicate with us there.
Not every issue that we require help with is related to coding, like design, and some legal stuff (terms and conditions and privacy policy).
Additionally, if want to bring up a topic that you think should get looked into that's not on the issue list, don't hesitate to poke us on Discord or create a new issue on the issue tracker.
You can report bugs to the issue tracker or on Discord in the #bug-reports channel. Since you're reading this on GitHub (probably), it's preferred to raise an issue on the tracker instead, as the Discord bug report channel is used primarily by players and most don't have a GitHub account.
Please search the issue tracker first if the particular bug already has an open issue. If it does, add your message to the existing issue instead of opening a new issue.
If a closed or resolved issue exists for your particular bug, reopen it. If in doubt, ask us on Discord, or just feel free to open a new issue anyway.
First, make sure the changes you're going to do adhere to the vision of OpenDominion.
Fork the repository on GitHub, make a new branch off develop and start from there. When making changes, try to add or modify relevant tests with your changes if it involves game mechanic-related code (like calculators or services).
Once you're satisfied with your modifications, raise a pull request and we will review it, edit it as needed, and merge it with the develop branch.
Most of the stuff that needs coding is domain logic, meaning you have to know the ins and outs of the game (except if you're someone who played Dominion in the past). If the project seems interesting to you and you want to help with the project, play the game and join us on Discord. If you want to learn, we (both devs and players) will gladly help you out to get accustomed to things and explain how Dominion worked.
There's also some non-domain coding issues open from time to time. We'll try to label these as "good first issue". This mostly consists of refactoring and UI stuff, however. If you need more info or something, feel free to request more information on the issue. Or as always, poke us on Discord.
OpenDominion is built on the Laravel 5.7 PHP framework, using PHP 7.3 as the main programming language.
The frontend is based off the AdminLTE open source dashboard theme, using Font Awesome and RPG Awesome as font icons, alongside some additional NPM packages like Select2 for improved UX. It's built with Laravel's Blade templating language to serve static HTML responses.
If you're going to use PhpStorm to tinker around in the code, there's a partially gitignored .idea directory in Git with some sensible default project configuration.
- You have PHP 7.3 or higher installed and in your path.
- Your PHP has the extensions: curl, fileinfo, gd OR imagick, mbstring, openssl, pdo_mysql and optionally xdebug.
- You have Composer installed and in your path.
- You have NPM 10 or higher installed and in your path.
- You have a MySQL 5.7+ or MariaDB 10.0+ SQL database server installed.
- You have a basic understanding of the Laravel framework. See sections deviation from Laravel and directory structure for the current architectural setup, which slightly differs from a traditional Laravel project.
Notes:
- Previously there was support for Sqlite for local development. This has since been dropped (due to reasons I forgot at time of updating this document).
- If you're not going to use the internal PHP webserver, you need to have a webserver like Nginx or Apache setup according to the Laravel documentation.
If you don't want to hassle too much with setting the aforementioned up, there's Laravel Homestead configuration files available for your convenience. Docker Compose files are also present in the repository, but these are currently unmaintained and untested, and might potentially not work in their current state.
$ git clone https://github.com/WaveHack/OpenDominion
$ cd OpenDominionInstall PHP dependencies:
$ composer installCopy the provided .env example file and generate a fresh application encryption key.
$ cp .env.example .env
$ php artisan key:generateEdit the .env file and set the correct database configuration in the DB_* fields. If in doubt, consult the Laravel documentation for this.
After this, migrate the database and seed development testing data:
$ php artisan migrate --seedIf your database is setup correctly then the migrations and seeders will run without errors, and you will receive user credentials for an automatically generated user account and dominion.
Now link the storage directory:
$ php artisan storage:linkOptional: If your editor or IDE supports code inspection and autocompletion, there are some additional Artisan commands you can run to generate helper files:
$ php artisan ide-helper:generate
$ php artisan ide-helper:models -N
$ php artisan ide-helper:metaNow install the frontend dependencies. Note that if you're on Linux you need to have libpng-dev installed.
$ npm install # Optionally with --no-bin-links on mounted drives, like with Vagrant
# If using Vagrant, node-sass might fail to install properly.
# If so, run: npm rebuild node-sass --no-bin-linksAnd build the frontend:
$ npm run devMake sure the directories bootstrap/cache and storage (and every directory under storage) are writable.
Optional but recommended: Run a self-diagnostic check to see if everything was setup correctly.
$ php artisan self-diagnosisIt should pass most checks and you're good to go! Note that the following checks might fail in certain conditions, which you can safely ignore:
- Locale check on Windows, which is not supported on that platform.
Setup your webserver of choice, or run the internal PHP webserver with a helper command through Artisan:
$ php artisan serveOpen your web browser, navigate to localhost:8000 and login with the credentials provided to you after migrating and seeding the database.
If you want to tinker with stuff through the command-line with an interactive shell (i.e. a REPL), you can run php artisan tinker. Note that you need to restart the tinker process every time you make a change in the code.
For more info about Artisan and Tinker, consult the documentation.
Note: If you want to use an SMTP server like Mailtrap.io for testing emails, change the MAIL_* fields accordingly in .env. By default emails are logged in the Laravel log file at storage/logs/laravel*.log.
OpenDominion uses an experimental Laravel project structure. This might be reverted back in the future to use the standard Laravel project boilerplate layout (PHP source in app/, resources in the project root etc).
.
+-- app
| +-- config # Laravel config
| +-- data # Custom folder with JSON/YAML data files. Most notably units, races, perks and round leagues
| +-- database # Laravel database folder
| +-- resources # Laravel resources folder
| | +-- assets # Application Sass, JavaScript, images etc
| | +-- lang # Language files. Currently unused
| | +-- views # Blade template views
| | +-- errors # Laravel errors
| | +-- layouts # Layouts
| | +-- pages # Page contents. Subdirectories by route segments (e.g. route('foo.bar.baz') => foo/bar/baz.blade.php)
| | +-- partials # Partial views to split up layouts or to reuse template blocks
| | +-- vendor # Vendor views. Currently unused
| +-- routes # Laravel route config
+-- bootstrap # Laravel bootstrap
+-- public # Web root
| +-- assets # Generated assets folder. Don't put your resources here, put them in app/resources/ instead and update webpack.mix.js to copy them
| +-- app # Application assets, compiled and/or copied from app/resources/
| +-- vendor # Vendor assets, usually copied from node_modules/$library/dist using Webpack during 'npm run dev'
+-- src # Source files. These are pretty Laravel generic, with the addition of:
| +-- Calculators # Calculator classes which just do calculations. No touching database or session or anything. Just input-output
| | +-- Dominion # Calculator classes which operate on a Dominion instance
| +-- Factories # DominionFactory and RealmFactory
| +-- Helpers # Helper classes which contains like building types and land types
| +-- Models # Eloquent models
| +-- Services # Misc business logic classes which can touch sessions, database etc
| +-- Traits # Traits to use in other classes
| +-- Application.php # Custom application class to overwrite Laravel's default paths
| +-- helpers.php # Custom helper function that live in the global scope
+-- storage # Laravel storage folder. Contains an additional databases directory with local.sqlite for local development
+-- tests # Unit and feature testsThe rest should be pretty self-explanatory, assuming you're at least somewhat comfortable with the Laravel framework.
OpenDominion is built with the Laravel framework, but doesn't necessarily follow the Laravel boiler plate layout.
With that said, here are some things to keep in mind if you're used to the Laravel boiler plate project code:
- Source code is in
srcinstead ofapp. - Config, database, resources and routes are in
app. - As a result of this, the
$appinstance is our custom application class, residing atsrc/Application.php, to override all the paths that Laravel uses by default.
This is experimental and is subject to change. Please keep an eye on the #dev-announcements channel in the Discord server.
- The most exciting game-related code are in calculator classes (
src/Calculators), most of which operate on a Dominion instance without any interactions with database, sessions etc, and service classes (src/Services). - Classes for actions that a user takes with a dominion (e.g. exploring, invading) are called 'action services' and reside in
src/Services/Actions. - Misc code that doesn't belong in a calculator or factory should generally go in a service class.
- This project heavily relies on Laravel's service container for all the calculator and service classes.
- Also see
AppServiceProvider.phpfor this. - There's a concept of a 'selected Dominion', which is the Dominion instance the user is currently 'playing'. A user can have multiple Dominions, but he/she can play only one at a time. It's initialized and shared to the views in the
ShareSelectedDominionmiddleware. - The
Game\TickCommandcommand is executed every hour at xx:00 from the console kernel. - Slim controllers, slim models, many slim services.
Tests are ran in an in-memory Sqlite database. You need to have the php-sqlite3 extension installed for this.
You can run the full test suite with:
$ vendor/bin/phpunitNote: The rest of this section is largely out of date as tests need refactoring. This section will be updated later.
There are two test suites, named as follows:
- Feature Tests
- Unit Tests
The term "should (not) touch the database" below refers to the inclusion of the Laravel DatabaseMigrations trait in a testcase. Using this trait allows the test to communicate with a in-memory Sqlite database. This will increase the time the test takes to run significantly and should be used with caution.
Feature tests can be seen as user stories if you're familiar with Agile. These should generally touch the database because of their nature.
Unit test classes are tests that generally correspond to a single source class to test the implementation of the business logic. Unit tests may touch the database if the class under test is interacting with the database (such as factory classes), but generally should not do so otherwise. Unit tests methods should correspond to a matching source class method under test using a testNameOfMethodUnderTest naming convention.
Consult PHPUnit's manual for running specific test suites or individual files.
For updating your local development environment, do a git pull, optionally followed by a composer install, npm install and/or npm run dev, depending on which files have changed.
If you want to reset the database, run the following:
$ php artisan migrate:fresh --seedIf that doesn't work, empty your database which you use for OpenDominion, and then rerun the migrations and seeders:
$ php artisan migrate --seedNote: Any additionally registered user accounts and dominions next to the ones provided by the database seeding process will have to be re-registered (and activated in the case of a user account).
You can activate newly created users by either:
- Inspecting the registration mail sent (either through a SMTP server like Mailtrap.io, or fishing the activation link out of the logged email if your MAIL_DRIVER is set to 'log' in .env),
- Use a database client and set
users.activated = 1on the relevant user account, - Using Tinker to manually set the activated field to 1. For example (using
php artisan tinker):
>>> $u = User::find(2);
>>> $u->activated = 1;
>>> $u->save();PHP code should be in PSR2-style with a few additional rules. See .styleci.yml for the defined preset and additional rules.
Please add relevant unit tests or feature tests if possible.
You can find resources that we use to help us develop OpenDominion in the resources branch. See its readme for more info.