A Dart client for spacetraders.io.
- cli - The main CLI for "playing" the game.
- db - Postgres bindings for storing client state.
- openapi - A generated Dart client for the Space Traders API.
- server - A very basic server for supporting the UI.
- types - Shared types between the packages.
- ui - A Flutter UI for the Space Traders API.
cli
, db
and types
are the most complete and useful packages.
openapi
is generated (and pretty terrible code).
server
and ui
are mostly stubs.
This requires Dart 3.0.0 or later.
The easiest way to get Dart is typically via Flutter. See https://flutter.dev/docs/get-started/install for instructions.
On ubuntu:
sudo snap install flutter --classic
If you're running this in a docker container, or otherwise as root Dart and Flutter will print a warning about running as root. You can ignore it or disable it with:
export BOT=true
The client originally ran as a single program using JSON files for state. At this time it's been partially refactored to use a Postgres database for state. Thus you need to run the database server first.
See instructions in packages/db/README.md.
Note: currently our notify/listen code seems to cause a leak on the server side of the connection. Thus you may need to restart both the cli and network executor every 12 hours or so, depending on how much RAM you have.
I run the cli, db and network executor all in the same instance which has 4GB of RAM. I typically restart the cli and network executor every 12 hours.
The network executor is the rate limited client for the Space Traders API. It's a separate process to allow us to eventually have multiple clients running at once.
The CLI does not require the network executor (it knows how to do) in process rate limiting, but it's recommended if you plan to be running things for long periods of time.
I typically run the network executor in a separate terminal window or tmux or screen session. e.g.
screen -S net
cd packages/cli
dart run bin/network_executor.dart
The CLI is the main way to play the game. It's a single process that handles all the game logic and logging. It does require user input to register, but after that it can run unattended.
Similar to the network executor, I typically run the CLI in a separate terminal window or tmux or screen session. e.g.
screen -S cli
cd packages/cli
dart run
dart run
Building package executable... (1.6s)
Built space_traders_cli:space_traders_cli.
Welcome to Space Traders! π
πΈ#1 βοΈ 6 COPPER_ORE π¦ 57/60
πΈ#2 βοΈ 3 AMMONIA_ICE π¦ 17/30
πΈ#1 Docking at X1-VS75-67965Z
πΈ#1 π€ 6 COPPER_ORE -14% -8c per, 6 x 48c = +288c -> π¦ 30,624c
πΈ#1 π€ 6 ICE_WATER -13% -2c per, 6 x 13c = +78c -> π¦ 30,702c
πΈ#1 π€ 12 QUARTZ_SAND π per, 12 x 21c = +252c -> π¦ 30,954c
πΈ#1 π€ 7 IRON_ORE +52% 13c per, 7 x 38c = +266c -> π¦ 31,220c
πΈ#1 π€ 11 ALUMINUM_ORE -6% -3c per, 11 x 48c = +528c -> π¦ 31,748c
β±οΈ 62s until 2023-05-20 10:25:38.984
πΈ#1 Moving to orbit at X1-VS75-67965Z
πΈ#1 βοΈ 6 QUARTZ_SAND π¦ 21/60
πΈ#2 βοΈ 5 ICE_WATER π¦ 22/30
β±οΈ 66s until 2023-05-20 10:26:52.461
πΈ#1 βοΈ 8 AMMONIA_ICE π¦ 29/60
πΈ#2 βοΈ 8 AMMONIA_ICE π¦ 30/30
πΈ#2 Docking at X1-VS75-67965Z
πΈ#2 π€ 11 ICE_WATER -13% -2c per, 11 x 13c = +143c -> π¦ 31,891c
πΈ#2 π€ 11 AMMONIA_ICE -5% -2c per, 11 x 40c = +440c -> π¦ 32,331c
πΈ#2 π€ 8 SILICON_CRYSTALS -14% -5c per, 8 x 31c = +248c -> π¦ 32,579c
β±οΈ 63s until 2023-05-20 10:28:05.339
πΈ#1 βοΈ 4 ICE_WATER π¦ 33/60
πΈ#2 Moving to orbit at X1-VS75-67965Z
πΈ#2 βοΈ 5 AMMONIA_ICE π¦ 5/30
β±οΈ 65s until 2023-05-20 10:29:18.158
πΈ#1 βοΈ 8 SILICON_CRYSTALS π¦ 41/60
πΈ#2 βοΈ 6 COPPER_ORE π¦ 11/30
β±οΈ 66s until 2023-05-20 10:30:31.109
πΈ#1 βοΈ 4 ICE_WATER π¦ 45/60
πΈ#2 βοΈ 7 COPPER_ORE π¦ 18/30
β±οΈ 66s until 2023-05-20 10:31:43.985
There are a variety of scripts I've written in packages/cli/bin which can be used to query the database, or do other things. They're not documented yet, but you can see what they do by reading the source. I've tried to sort them by area of interest.
Most scripts run completely on cached data, but the ones which do talk to the API are smart enough to use the db and network executor if available otherwise they will use the API directly via an in-process rate limiter.
You can run individual packages tests locally by cd'ing into the package
directory and running dart test
.
There are also tools like very_good
which can run tests across multiple
packages, e.g. dart pub global activate very_good_cli
then very_good test -r
.
I've slowly been adding tests and increasing coverage. See codecov for the current coverage.
You can run all the tests locally and collect coverage by running
./coverage.sh
. This will run all the tests and generate a coverage
report in coverage/lcov.info
. You can then view the coverage report
by running genhtml coverage/lcov.info
(on linux) and opening the
generated index.html
file in your browser. There are also a variety
of other tools for viewing lcov.info files, including extensions for
VSCode. Mostly I just use codecov for viewing coverage.
cd packages/cli
dart run bin/reset.dart
cd ../db
docker exec spacetraders_postgres /scripts/init_db.sh spacetraders
- Update
open_api_config.yaml
to have the latest git hash. - regenerate space_traders_api
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
dart pub global activate openapi_generator_cli
rm -rf packages/openapi/
openapi-generator generate -c open_api_config.yaml
rm -rf packages/openapi/test
dart pub -C packages/openapi get
dart format packages/openapi
git add packages/openapi
Then modified:
- Fixed handling of required num fields:
packages/openapi/lib/model/jump_gate.dart
Due to: OpenAPITools/openapi-generator#10637 (review)
- Required arguments in request body should make body required/non-nullable. Example: RegisterRequest for POST /users/register
- The generated "enums" do not have equals or hashCode. e.g. ShipRole. It doesn't end up mattering because they're singletons though.
- Generated toJson methods are not recursive (e.g. Survey.toJson doesn't call SurveyDeposit.toJson).
- Seems to lack anyOf support (GetSystemWaypointsTraitsParameter).
See TODO.md for a list of of issues I'm working on.