Your first bundle
A bundle is a folder with index.html at its root, zipped. This page takes the playground’s sample game
through every step; your own game follows the same path.
The playground
Section titled “The playground”The playground loads a bundle in an iframe, plays each host around it and logs every SDK call and host
message. Open developers.filudi.com/playground/: nothing to
install. If you have the Filudi repository, the same app runs locally from apps/sdk-playground.
pnpm installpnpm --filter @filudi/game-sdk build # the sample game loads dist/filudi-sdk.iife.jspnpm --filter @filudi/sdk-playground dev # http://localhost:5173pnpm installpnpm --filter @filudi/game-sdk build # the sample game loads dist/filudi-sdk.iife.jspnpm --filter @filudi/sdk-playground dev # http://localhost:5173Pick “Sample game” and the filudi host, press Load. The log shows the handshake: filudi:ready from the
bundle, filudi:init from the host with a game token that starts with fg1., then filudi:loaded when
the game calls ready(). Tap the canvas: filudi:gameplay { running: true }. Fall: the score goes out,
the board comes back, every third fall asks for an interstitial and the host answers with the result you
set. Tick “Mock API” so saves and scores hit an in-memory API and show as requests with their bearer.
Untick it to use a real API: type its origin in “API URL”, or open the playground with ?api=:
/playground/?host=filudi&mockApi=0&api=https://api.filudi.com for production,
api=http://localhost:8080 for the API you run. That API must list the playground’s origin in its
HUB_URLS, and the game slug must exist on the site, else the log says game token refused.
The other hosts install the portal’s global in the frame before the bundle runs: CrazyGames.SDK,
PokiSDK, Playgama’s bridge. Each call the game makes is a game→host line, each answer a host→game
line. Change the ad outcome, the data module, the leaderboard type, and watch what the game does.
The sample game
Section titled “The sample game”The sample game is two files, index.html
and main.js (apps/sdk-playground/public/sample-game/
in the repository). main.js calls every SDK method at least once; it is the shortest complete
integration. Read it next to the SDK overview.
const sdk = window.FiludiSDK;
async function boot() { await sdk.init({ gameId: 'infinijump', version: '1.0.0' }); corner = { nickname: sdk.player.get().nickname, locale: sdk.i18n.locale() }; applySave(await sdk.save.get()); sdk.save.on('replaced', applySave); sdk.ads.on('start', () => (muted = true)); sdk.ads.on('end', () => (muted = false)); requestAnimationFrame(frame); // the first frame calls sdk.ready()}import { sdk } from '@filudi/game-sdk';
async function boot(): Promise<void> { await sdk.init({ gameId: 'infinijump', version: '1.0.0' }); corner = { nickname: sdk.player.get().nickname, locale: sdk.i18n.locale() }; applySave(await sdk.save.get<{ best: number }>()); sdk.save.on('replaced', applySave); sdk.ads.on('start', () => { muted = true; }); sdk.ads.on('end', () => { muted = false; }); requestAnimationFrame(frame); // the first frame calls sdk.ready()}Your own game in the playground
Section titled “Your own game in the playground”Run your dev server, choose “Bundle URL”, paste http://localhost:5174/index.html, pick a host, press
Load. The hosted playground frames a localhost URL from its https page: browsers treat localhost as
secure. Your server must let the playground’s origin frame it, https://developers.filudi.com (or
http://localhost:5173 when you run the playground from the repository): no X-Frame-Options: DENY,
and frame-ancestors must list it if you send a CSP. The portal hosts fetch your index.html, so the
server answers that origin with CORS. Vite’s default CORS allows localhost origins only: add
server: { cors: { origin: ['https://developers.filudi.com'] } } to its config while you test.
Add <script src="https://developers.filudi.com/playground/sdk-trace.js"></script> after the SDK script
while you work (http://localhost:5173/sdk-trace.js for the local playground): the log then shows each
SDK call. Remove it before the build.
Tick “Production CSP” on the filudi host. The playground’s server then sends the policy filudi.com
applies to bundles it serves itself, and the log gives you the header to send from your own server. Each
violation shows as a CSP violation line. An inline script or a call to another host works without it
and fails in production.
The zip
Section titled “The zip”Build, then zip the content of the build folder, not the folder itself. index.html must be at the root
of the archive. Leave the source maps out unless you want them public.
npm run buildcd dist && zip -r ../gloop-1.4.0.zip . -x '*.map' && cd ..unzip -l gloop-1.4.0.zip | head -5 # index.html first, at the rootpnpm buildcd dist && zip -r ../gloop-1.4.0.zip . -x '*.map' && cd ..unzip -l gloop-1.4.0.zip | head -5 # index.html first, at the rootLimits: 200 MB for the zip, 500 MB unpacked, 10,000 files, 64 MB per file, no .. in a path, no symbolic
link, no encrypted entry. The upload refuses a zip that breaks one and names the entry.
Upload
Section titled “Upload”In the console, open the game, Versions, “Upload a version”. The version string follows semantic
versioning (1.4.0, 2.0.0-beta.1) and is unique for the game. Pass the same string to init({ version })
in the build so events carry it. The browser uploads the zip straight to the files service; the console
then finalizes: the API unpacks the zip under games/<slug>/<version>/, checks index.html, counts files
and bytes. The version is a draft.
Preview
Section titled “Preview”“Preview” opens a signed link, valid one hour, in a new tab. It serves the draft from the preview host under the same CSP as production, at the top level. The SDK is on its mock there: check loading, layout and play. Saves and scores need the frame on filudi.com; the playground covers them.
Request review
Section titled “Request review”When the draft is right, press “Request review” on the version. Staff gets an email, plays the preview and activates it. A pending game needs its approval first; the overview says which step is next. Once the version is live, open the game on filudi.com and play it once: saves, the leaderboard and your statistics now run against production.
Game lifecycle on filudi.com explains what happened in that frame. The release checklist is the list to run before every zip.