Service Startup
ShowcaseService starts during mod initialization.
No coding required. Generate Fabric and Cobblemon mods through natural language, test quickly, and iterate.
Showcase Overview
Showcase syncs Pokemon data from your Minecraft server to web endpoints. The frontend is only a renderer over synced player data.
ShowcaseService starts during mod initialization.
Sync starts only when showcase.isShowcaseEnabled is true and apiSecret is valid.
The task runs every max(syncIntervalMinutes, 1) minutes.
Additional syncs run on login after 10 seconds and on logout.
Players toggle visibility with /showcase on and /showcase off.
From your server showcase config JSON
showcase.isShowcaseEnabled (bool)showcase.apiSecret (string)showcase.syncIntervalMinutes (int, minimum effective value: 1)showcase.debug (bool)Base URL: https://your-domain.com/api
/api/syncBase64(apiSecret) (not Bearer)application/json (payload is compressed base64 text){
"players": [
{
"uuid": "player-uuid",
"name": "PlayerName",
"party": [null, {}, {}, null, {}, {}],
"pc": [[null, {}, "... 30 slots"], "... boxes"],
"lastUpdated": 1730000000000
}
]
}
Pokemon data contains Cobblemon save JSON plus extra fields like Nature, DexNumber, Ability, FormName, Type1 and Type2, and MoveSet entries.
/api/playerBase64(apiSecret)application/json{
"uuid": "player-uuid",
"showcaseEnabled": true
}
/api/sync and /api/player.(serverId, playerUuid).showcaseEnabled and expose read endpoints.Starter pages: / and /player.html
SITE_URL=https://challenged-gamers.com in .env.CORS_ORIGIN=https://challenged-gamers.com.SHOWCASE_API_PREFIX=/api/showcase.SHOWCASE_SECRETS.showcase.apiBaseUrl to https://challenged-gamers.com/api/showcase.{
"showcase": {
"apiBaseUrl": "https://challenged-gamers.com/api/showcase"
}
}
import express from "express";
import zlib from "node:zlib";
const app = express();
app.post("/api/sync", express.text({ type: "*/*", limit: "20mb" }), (req, res) => {
const encoded = req.body;
const compressed = Buffer.from(encoded, "base64");
const inflated = zlib.inflateSync(compressed).toString("utf8");
const payload = JSON.parse(inflated);
// TODO: validate auth header and upsert payload.players
res.status(200).json({ ok: true, players: payload.players?.length ?? 0 });
});
apiSecret is expected to include a UUID suffix in the current validation path./api/sync body is compressed text even with JSON header./showcase command exists only when showcase is enabled in config.