Pericynth
Docs
A few basics to get oriented.
Work in progress. Pericynth and these docs are still in development. Examples may change; installation instructions are not available yet.
Overview
Pericynth tests Minecraft plugins with a server and automated clients inside a disposable VM. You provide a built plugin and JSON test steps; the service runs them and returns results and logs.
The current workflow requires a configured service and authorized developer access. These examples describe the project files for that setup.
Project configuration
Keep settings in ci.json. Paths are relative to that file. This example uses one client, an already built plugin JAR, and a folder of tests:
{
"plugins": ["build/libs/my-plugin.jar"],
"clients": 1,
"steps": [{"kind": "reference", "folder": "tests"}],
"logsDir": "logs"
}
Replace the JAR path with your own. The service must have the default server and client templates prepared. Direct .json files in tests/ run in filename order within the same session.
A minimal test
Save this as tests/00-smoke.json. Test files contain a steps array. Clients are named player0, player1, and so on.
{
"steps": [
{
"kind": "action",
"actor": "player0",
"type": "ping",
"args": {},
"expected": {"message": "pong"}
}
]
}
This checks that the client responds. It does not test your plugin's behavior yet. Later tests can add game actions and assertions about their results.
Running tests
Sign in, then create a personal API token on your account page and expose it to the client as PERICYNTH_API_TOKEN. The token is sent only to this website over HTTPS; it never reaches the uploaded bundle, the VM or the logs. Point client/service.json at this site (url, plus caFile when a private CA is used) and install the client dependency once with python3 -m pip install -r client/requirements.txt.
The example origin below is a placeholder; replace it with the address of the Pericynth service you use.
{
"url": "https://pericynth.example",
"timeoutSeconds": 30,
"pollIntervalSeconds": 0.5
}
Then run the usual Gradle task. The client uploads the project over HTTPS, streams the live logs, keeps the run alive, downloads the final logs into logsDir/RUN_ID/ and exits 0 when the assertions pass:
cd demoProject
./gradlew runCI
./gradlew runCI --keep-open
--keep-open opens the ci> prompt after the predefined tests: link | player0 view | join | player0 ACTION {JSON} | player0 command "COMMAND" | player0 chat "MESSAGE" | server "COMMAND" | stop. The browser link opens a player viewer in the account that owns the run; join prints a local 127.0.0.1 address that bridges into the run's Minecraft port over an authenticated WebSocket. Closing the browser or an observer (python3 client/ci.py --view RUN_ID player0) never stops the run, while Ctrl+C, standard-input EOF and broken output stop it gracefully and then cancel it if the host does not finish in time.
Run reports
Downloaded logs go under logsDir/RUN_ID/. When website reporting is enabled, the run also prints a report link. Open it, or paste the 32-character run ID on the homepage, to see status, test results, and published logs.
/runs/RUN_ID
Replace RUN_ID with your actual run ID. Reports of CI runs stay private to the account that submitted them; sign in with that account before opening the link. Older runs published without an owner remain readable by anyone with the ID. Passing test assertions and a successfully completed run are separate: cleanup can still fail.
Developer accounts
On servers with authentication enabled, create an account with an email address and a password, or sign in with Google or GitHub. Passwords are 12 to 72 bytes and are never trimmed; accented or emoji text uses more than one byte per character. After signing up, use the emailed link to confirm the address and then sign in with the password you chose. Forgot it? Request a reset link; setting a new password signs out every browser session and revokes all API tokens for the account.
Each sign-in method keeps its own account: an email account, a Google account and a GitHub account are separate even when they share an address, and their balances do not merge. Your account page shows the sign-in methods, the credits balance and a billing identifier. Load free credits through the credit page with that identifier. The page also creates API tokens: copy a new token once, keep it outside this project, and use it as PERICYNTH_API_TOKEN. Revoke tokens you no longer need; revocation applies to the next request.
Optional AI
Scripted tests like the example above need no AI credentials. Natural-language prompt actions use an ai block in ci.json. API credentials alone belong in environment variables: OPENAI_API_KEY for byok mode, or PERICYNTH_API_TOKEN for pericynth mode. A personal or operator token in pericynth mode spends the credits of the account it belongs to. Keep credentials out of project files, bundles, guest environments, and logs.
For LLMs: this page's full text is available without JavaScript or login. Documentation links are listed in /llms.txt.