Prophesizer is part of the SIBR Archiving Pipelineā¢.
Prophesizer runs continuously, waking every minute to ask Chronicler (https://github.com/xSke/Chronicler) for new data. It does the following:
- Get the latest data from the Blaseball
/games
endpoint and store it in thegames
table - Check the DB's
chronicler_meta
table to see what the last day/time processed was - Check Blaseball's
/simulationData
endpoint to see what the current season/day is - Batch-process any updates for days up to the current day
- Incrementally ask Chronicler for updates from the current day
Typically on first run Prophesizer will batch-process many seasons of data into the DB, and only grab a minute's worth of updates every minute after that.
Prophesizer also asks Chronicler for updates to players
and teams
:
- Add entries to
teams
for any team data changes (like name changes) - Add entries to
team_roster
to reflect any lineup/rotation/etc changes - Add entries to
team_modifications
to reflect any new "tags" (like the blood bath tags) for a team - Add entries to
players
for any player data changes (names, attributes) - Add entries to
player_modifications
for any new "tags" (like SHELLED) for a player
These are logs of the individual (one every ~4seconds) streamData
updates for gameplay.
Prophesizer sends these through Cauldron to convert them into SIBR's "Game Event" format.
Game Events roughly correspond to one at-bat (with some exceptions like a runner caught stealing) and are more easily queried for statistics than the raw JSON updates from the stream.
These Game Events are added to the game_events
table, with child tables game_event_base_runners
for baserunning information and outcomes
for Outcome (incineration, peanuts, partying, etc).
The following instructions are written for Windows PCs.
- Prophesizer depends on git, PostgreSQL, Visual Studio Code (or full Visual Studio if you've got it). You can manually download and install all of these, but if you have the package manager Chocolatey installed, you can automatically install these tools by opening a prompt (cmd/powershell) as administrator and running:
choco install git postgresql vscode nodejs
- Use git to clone Prophesizer from github into your desired directory:
git clone https://github.com/Society-for-Internet-Blaseball-Research/prophesizer/
. - Set the environment var PSQL_CONNECTION_STRING to "Host=localhost;username=[postgres username, default 'postgres'];password=[postgres password];database=blaseball", with
setx
, making appropriate changes if any are necessary. - Make sure psql is added to PATH (you can test by typing it in as a command), and your C# connection string environment variable is correctly set.
- Using pgAdmin or
psql
, create a database namedblaseball
. - Compile and run Prophesizer from VS Code via File -> Open Folder, selecting Prophesizer's folder, going to 'Run' in the menu bar, and selecting "Run Without Debugging". As part of the build process, you should see Evolve perform a migration on your database.
Prophesizer is now using the Evolve package to manage database schema migrations.
All modification of the DB schema happens via .pgsql
files in the migrations
folder.
These come in two varieties:
- Versioned migrations start with a V, such as
V_2_8_1__Unaccent.pgsql
. - The filename denotes the version number (2.8.1), then (after a
__
separator) a description of the schema change. - Currently the DB schema version is being kept in sync with the Prophesizer version (though not every Prophesizer change involves a schema change).
- Versioned migrations are applied in version order and must be used when tables change.
- The SQL code in the file must alter the tables in such a way that data is not lost, so that DB schema migrations can happen without having to completely drop the DB.
- Old migration files should not be modified after they've been released; they will not successfully migrate because their checksums won't match (and if you think about it, you can't go back and change what version 2.8.0 means at the time you're checking in version 2.8.5)
- Repeatable migrations start with an R, such as
R__4_Create_Views.pgsql
. The filename only contains a description (after the__
separator). - They are applied in alphabetical order - Prophesizer numbers the descriptions to enforce the correct dependencies.
- Repeatable migrations are useful for elements of the database that can simply be dropped and re-created, such as Functions, Procedures, and Views.
- Prophesizer also uses a repeatable migration for the
taxa
schema which consists only of taxonomy data that always comes from these files.
Evolve doesn't support the following PostgreSQL commands in migrations:
- CREATE INDEX CONCURRENTLY
- CREATE/DROP DATABASE
- COPY FROM STDIN
- VACUUM
At the moment only @lilserf and @shibboh have the permissions to do this process, but it should be documented for the future.
- Stop the
datablasedev
prophesizer container. - Clear the
datablasedev
DB using pgAdmin. BE SURE YOU'RE ON THE DEV DB:
drop schema data cascade;
drop schema taxa cascade;
drop table changelog;
- Update the
datablasedev
stack to the new Prophesizer version. - Wait for prophesizer to populate the dev DB
- Run the Postman tests against the dev stack!
- Once the DB exists and the tests pass, back it up by right-clicking the dev DB, choosing
Backup...
and naming the DB according to the prophesizer version number (e.g.blaseball-2.12.2
) - In pgAdmin, move to the prod server and add a new Database named
blaseball-X.Y.Z
using the new version number - Right-click the prod DB and choose
Restore...
and type in the filename you used to backup above. This will populate this new database with the backup from the dev stack. - Change the
datablase
(prod) stack to use the new version of prophesizer; don't save yet, though. - Change all instances of the database name in the
datablase
stack to the new DB version name - there should be 5 or 6 instances amongst all the containers. - Profit: now the prod stack should be using the new prophesizer version, and talking to a new DB
- Over time as guests start accessing the new DB you should eventually be able to delete the old one