Live data puts a real contest into your game as it happens: the score, the clock, each side's numbers, and every moment, a goal, a try, a wicket, a card, seconds after it happens. Any sport. Your page asks for it with one call, game.live(), and draws it however it likes: a scoreboard, a momentum chart, a 3D pitch. Scoring a prediction from the live feed is not available yet.
Live data is open to Monterosa workspaces today. A deploy from any other workspace that declares it is refused with live_not_enabled, and says how to deploy without it.
How a contest reaches a fan
1 You switch it on: `gamestage live on`, then deploy.
gamestage.yaml gains a live: section. Nothing else changes.
|
v
2 A producer names the contest on the edition in Studio.
Each edition of a live game has a "Live contest" setting.
|
v
3 Gamestage follows that contest, by itself.
It reads the provider and publishes what happens.
|
v
4 Every fan's page gets it on the connection it already has.
A page that opens late is sent the contest so far, at once.Your game holds no provider key, makes no request to a provider and opens no second connection. The contest arrives on the same Monterosa Interaction Cloud connection the Gamestage library already holds for your game.
Switch it on
In your game's folder:
gamestage live on
gamestage deploy <game> --dir .gamestage live on adds this to gamestage.yaml, and leaves the rest of the file, comments included, as it was:
live:
provider: sportmonksThe provider is where the contest's data comes from. SportMonks is the provider today. gamestage live off takes the section out again, and the same command with neither on nor off says which it is.
After the deploy, every edition of the game has a Live contest setting in Studio. A producer types the provider's id for the contest there: for SportMonks, the fixture id. Leave it empty and the game shows no live data. A producer can change it at any time, and every page that is open moves to the new contest without a reload.
Draw it
game.live() hands over the contest the edition names:
const game = await start();
const contest = game.live();
// The contest so far, at once, then every change.
contest.on("state", (state) => {
scoreboard(state.sides.map((side) => `${side.short} ${side.score}`).join(" "));
});
// Only what happens from now on.
contest.on("moment", (moment) => {
if (moment.kind === "GOAL") celebrate(moment.actor, moment.display);
});
// Connected, reconnecting, offline: for your own badge.
contest.onStatus((status) => badge(status.state));What arrives, under each name you can listen to:
| Name | What it holds |
|---|---|
state | The contest's name and status (scheduled, running, paused, finished), its period, and each side's name, short name, colour and score. |
clock | Seconds since the start, what a fan reads (34'), and whether it is running. |
side | One side's numbers, by the provider's names: SHOTS_TOTAL, BALL_POSSESSION and the rest. Called once per side. |
moments | Every moment so far, oldest first. |
moment | The newest moment, the instant it is seen. |
timeline | Each side's numbers at each point in the contest, for a chart. |
health | When Gamestage last heard from the provider, and whether that worked. |
The same values are there to read at any time: contest.state(), contest.clock(), contest.sides(), contest.moments(), contest.timeline() and contest.health().
The contest so far and news are different things. A fan who opens your page after a goal is sent that goal as part of the contest so far, and your page should draw it in the score rather than celebrate it. A moment listener hears only what happens after the page opened. Any other listener can ask for the same with { news: true }.
A page can follow a contest of its own choosing rather than the edition's: game.live({ contest: "19722153" }).
Try it locally
gamestage dev --serve plays a made-up contest for a game with live data, so game.live() works on your laptop with no provider, no key and no Studio. The two sides and everyone in them are invented. A whole contest takes about four minutes; set GAMESTAGE_LIVE_SPEED to change how fast it runs.
gamestage verify checks that a game declaring live data ships the Gamestage library, gamestage.js. Live data reaches a page only through it.
When the connection drops
The library reconnects by itself and reports what it is doing through onStatus: connecting, live, reconnecting with the attempt and when the next one is, or offline. When it is back, the page is sent the contest as it stands, so it catches up without replaying a moment it already showed. If Gamestage cannot reach the provider, health says so with ok: false, and your page can tell fans the data is delayed rather than letting a frozen score look live.