### Initialize game with taploka.ready() Source: https://taploka.io/docs/game-sdk Call once at startup to get game info, version, player, studio, and room. Returns null fields if no host is present, so provide fallbacks for standalone mode. ```javascript const { game, version, player, studio, sdk, room } = await taploka.ready(); ``` -------------------------------- ### Minimal Taploka SDK Integration Example Source: https://taploka.io/docs/game-sdk Use this snippet to initialize the Taploka SDK, load the game state, and hook up level end and game over events. It handles the case where load() returns null by defaulting to level 1, and submits the score and saves state on game over. ```html ``` -------------------------------- ### Read catalog (GET /api/v1/harness/games and /games/{game}) Source: https://taploka.io/docs/harness-api Fetches the game catalog. The list endpoint returns slugs, titles, statuses, version counts, active versions, and play URLs. The detail endpoint adds metadata, all versions with rollout, SDK minimum, size, changelog, total scores, and leaderboard URL. ```http GET /api/v1/harness/games GET /api/v1/harness/games/{game} ``` -------------------------------- ### Listen to room events and start/send moves Source: https://taploka.io/docs/multiplayer Registers listeners for members, started, message, and closed events. The message handler ignores your own echoed moves. Then the host starts the match and sends a move payload. ```javascript taploka.room.on('members', (state) => renderLobby(state)); taploka.room.on('started', (event) => beginMatch(event.payload.seats)); taploka.room.on('message', (event) => { if (event.mine) return; // gerakanmu sendiri, dipantulkan balik applyMove(event.from, event.payload); }); taploka.room.on('closed', () => showLobbyAgain()); await taploka.room.start(); // host saja, butuh dua pemain await taploka.room.send({ card: 'red-7' }); ``` -------------------------------- ### GET /api/v1/harness/games/{game} Source: https://taploka.io/docs/harness-api Retrieves detailed information for a specific game, including metadata, all versions with rollout and SDK info, scores, and leaderboard URL. ```APIDOC ## GET /api/v1/harness/games/{game} ### Description Retrieves detailed information for a specific game, including metadata, all versions with rollout and SDK info, scores, and leaderboard URL. ### Method GET ### Endpoint /api/v1/harness/games/{game} ### Parameters #### Path Parameters - **game** (string) - Required - The slug of the game. ### Request Example (No request body) ### Response #### Success Response (200) - **slug** (string) - Game slug. - **title** (string) - Game title. - **status** (string) - Game status. - **versions** (array) - Array of version objects, each containing: - **version** (integer) - Version number. - **rollout** (integer) - Rollout percentage. - **sdk_min** (integer) - Minimum SDK version. - **size_bytes** (integer) - Size in bytes. - **changelog** (string) - Changelog for the version. - **total_score** (integer) - Total score. - **flagged_for_review** (integer) - Number of scores flagged for review. - **leaderboard_url** (string) - URL to the leaderboard. - **metadata** (object) - Additional metadata block. #### Response Example (No explicit response example provided in source) ### Error Handling (No explicit error handling documented) ``` -------------------------------- ### GET /api/v1/harness/games Source: https://taploka.io/docs/harness-api Lists all games in the catalog with basic information such as slug, title, status, version count, active version, and play URL. ```APIDOC ## GET /api/v1/harness/games ### Description Lists all games in the catalog with basic information such as slug, title, status, version count, active version, and play URL. ### Method GET ### Endpoint /api/v1/harness/games ### Parameters None ### Request Example (No request body) ### Response #### Success Response (200) - **games** (array) - Array of game objects, each containing: - **slug** (string) - Game slug. - **title** (string) - Game title. - **status** (string) - Game status. - **version_count** (integer) - Number of versions. - **active_version** (integer) - Active version number. - **play_url** (string) - URL to play the game. #### Response Example (No explicit response example provided in source) ### Error Handling (No explicit error handling documented) ``` -------------------------------- ### market.buy(id) Source: https://taploka.io/docs/game-sdk Purchases the listing with the given ID. The item is delivered immediately to the buyer. If two buyers attempt to buy the same listing simultaneously, one will receive the item and the other will get a LISTING_GONE error. ```APIDOC ## market.buy(id) ### Description Purchases the listing with the given ID. The item is delivered immediately to the buyer. If two buyers attempt to buy the same listing simultaneously, one will receive the item and the other will get a LISTING_GONE error. ### Method market.buy(id) ### Parameters - **id** (string) - The ID of the listing to purchase ### Returns - **item** (object) - The purchased item ### Errors - **LISTING_GONE** - Returned when the listing is no longer available (e.g., already purchased by another buyer) ### Example ```javascript const { item } = await taploka.market.buy(listings[0].id); ``` ``` -------------------------------- ### update_game with shop configuration Source: https://taploka.io/docs/mcp-server Updates the game's shop by replacing the entire coin price list. The shop parameter is an exception to the 'only sent columns' rule: it replaces the full list and disables any SKU not included. The example sets two SKUs: 'engine_lv2' (non-consumable) and 'fuel' (consumable). ```javascript update_game(game: 'rosok-garage', shop: [ { sku: 'engine_lv2', title: 'Mesin Lv2', coin_price: 800 }, { sku: 'fuel', title: 'Bensin', coin_price: 150, type: 'consumable' }, ]) ``` -------------------------------- ### ready() Source: https://taploka.io/docs/game-sdk Metode untuk inisialisasi game dan mendapatkan informasi konteks. ```APIDOC ## `ready()` ### Description Panggil sekali saat start-up untuk mengetahui bahwa game berjalan, versi bundle, dan pemain yang bermain. ### Method `ready()` ### Parameters Tidak ada parameter. ### Request Example ```javascript const { game, version, player, studio, sdk, room } = await taploka.ready(); ``` ### Response #### Success Response - **game** (string) - Nama game. - **version** (string) - Nomor versi bundle yang diterima pemain. - **player** (object) - Informasi pemain. - **studio** (string) - Kredit studio developer atau arcade. - **sdk** (string) - Versi SDK. - **room** (string|null) - Kode room multiplayer atau null pada peluncuran biasa. #### Response Example ```javascript { "game": "My Game", "version": "1.0.0", "player": {}, "studio": "My Studio", "sdk": "1.0", "room": null } ``` ``` -------------------------------- ### Masuk dari halaman game: ready() lalu join atau quick Source: https://taploka.io/docs/multiplayer Kode untuk masuk dari halaman game arcade. ready() memberikan room yang sudah dipilih (atau null pada peluncuran biasa), lalu join() dengan kode tersebut atau fallback ke quick(). Jika dapat error ROOM_NOT_FOUND, ROOM_FULL, atau ROOM_STARTED, mundur ke quick(). ```javascript const { room } = await taploka.ready(); await (room ? taploka.room.join(room) : taploka.room.quick({ max: 4 })); ``` -------------------------------- ### Shop, buy, and inventory operations Source: https://taploka.io/docs/game-sdk Prices come from a per-game list, so the bundle only needs to reference SKU names. Ownership is server-side; read inventory() at startup, not client-written cloud saves. Purchases are idempotent, and buy() is rejected with ITEM_OWNED, ITEM_UNKNOWN, or INSUFFICIENT_BALANCE. ```javascript const { items } = await taploka.shop(); // [{ sku, title, coin_price, type, owned, qty }] const { item, balance } = await taploka.buy('engine_lv2'); const owned = await taploka.inventory(); // [{ sku, qty, granted_at }] ``` -------------------------------- ### Start and Manage Turns with taploka.room Source: https://taploka.io/docs/multiplayer Use these methods to initialize a turn-based game, submit moves, or pass turns. The move method is validated by the server to ensure it is the player's turn. ```javascript await taploka.room.start({ turnSeconds: 30 }); await taploka.room.move({ tile: 4 }); // ditolak dengan NOT_YOUR_TURN kalau bukan giliranmu await taploka.room.pass(); // serahkan giliran lebih awal ``` -------------------------------- ### wallet() Source: https://taploka.io/docs/game-sdk Mengambil saldo koin pemain. ```APIDOC ## `wallet()` ### Description Mengambil saldo koin pemain. Koin adalah mata uang arcade dan mengikuti pemain lintas game. ### Method `wallet()` ### Parameters Tidak ada parameter. ### Request Example ```javascript const { balance, earned, spent } = await taploka.wallet(); ``` ### Response #### Success Response - **balance** (number) - Saldo koin saat ini. - **earned** (number) - Total koin yang diperoleh. - **spent** (number) - Total koin yang dibelanjakan. #### Response Example ```javascript { "balance": 100, "earned": 200, "spent": 100 } ``` ``` -------------------------------- ### Masuk ke room: quick match, buat privat, dan join dengan kode Source: https://taploka.io/docs/multiplayer Tiga cara masuk ke room: quick() untuk main dengan orang asing (room terlama dengan kursi kosong atau buat baru), create() untuk membuat room privat dengan kode yang dibagikan, dan join() untuk bergabung dengan kode tersebut. Semua memanggil API taploka.room dan mengembalikan state room. ```javascript // Main dengan orang asing: masuk ke room terlama yang punya kursi kosong, atau buka yang baru. const room = await taploka.room.quick({ max: 4 }); // Main dengan teman: satu orang membuat, yang lain mengetik kodenya. const mine = await taploka.room.create({ max: 2, private: true }); showCode(mine.code); // "KX7Q" const theirs = await taploka.room.join('KX7Q'); ``` -------------------------------- ### Respons push pertama: game created Source: https://taploka.io/docs/quickstart Respons menunjukkan game dibuat, versi rilis, rollout 100%, sdk_min, jumlah file, dan status. ```text rosok-garage v1 released · rollout 100% · sdk_min 1 · 5 files · game created ``` -------------------------------- ### Login ke arcade Source: https://taploka.io/docs/mcp-server Perintah untuk menyambungkan mesin ke arcade. Meminta kode pendek, membuka halaman persetujuan, dan menyimpan kunci di ~/.taploka/credentials.json. ```bash npx -y taploka-mcp@latest login ``` -------------------------------- ### load() Source: https://taploka.io/docs/game-sdk Memuat state game dari cloud. ```APIDOC ## `load()` ### Description Memuat state game dari cloud. Mengembalikan objek terurai, atau null untuk pemain baru. ### Method `load()` ### Parameters Tidak ada parameter. ### Request Example ```javascript const state = await taploka.load(); ``` ### Response #### Success Response - **state** (object|null) - State game yang disimpan, atau null jika pemain baru. #### Response Example ```javascript { "level": 3, "coins": 120 } ``` ``` -------------------------------- ### Market API: list, sell, buy, cancel, claim Source: https://taploka.io/docs/game-sdk Market API untuk jual-beli antar pemain dengan uang game sendiri. `buy()` mengunci baris listing sehingga satu truk tidak bisa terjual dua kali; pembeli kedua mendapat `LISTING_GONE`. `claim()` hanya membayar sekali meski dipanggil dua kali. Khusus pemain berakun (tamu ditolak `ACCOUNT_REQUIRED`) dan maksimal 12 lapak terbuka per pemain per game. ```javascript const { listings, proceeds } = await taploka.market.list(); // [{ id, price, item, mine, seller, listed_at }] const { listing } = await taploka.market.sell({ truck: 'hino', wear: 12 }, 7500000); const { item } = await taploka.market.buy(listings[0].id); // barangnya, diserahkan sekali await taploka.market.cancel(listing.id); // turunkan lapak, barang kembali const { total, sales } = await taploka.market.claim(); // yang laku selagi kamu pergi ``` -------------------------------- ### POST /api/v1/harness/bundles Source: https://taploka.io/docs/harness-api Pushes a new game bundle as a ZIP file. Validates the bundle structure and returns the created game version or a 422 error with validation details. ```APIDOC ## POST /api/v1/harness/bundles ### Description Pushes a new game bundle as a ZIP file. Validates the bundle structure and returns the created game version or a 422 error with validation details. ### Method POST ### Endpoint /api/v1/harness/bundles ### Parameters #### Request Body (multipart/form-data) - **bundle** (file) - Required - The ZIP file containing the game bundle. - **game** (string) - Optional (required unless `title` is provided) - Slug of an existing game. - **title** (string) - Optional - Name for the first push; slug is derived from this. - **rollout** (integer) - Optional - Rollout percentage (0-100), default 100. - **changelog** (string) - Optional - Short changelog note. - **draft** (integer) - Optional - Set to `1` to save without releasing. ### Request Example (No explicit request example provided in source) ### Response #### Success Response (200) - **game** (string) - Slug of the game. - **game_created** (boolean) - Whether the game was newly created. - **version** (integer) - Version number of the bundle. - **status** (string) - Status of the release (e.g., "released"). - **rollout** (integer) - Rollout percentage. - **sdk_min** (integer) - Minimum SDK version. - **size_bytes** (integer) - Size of the bundle in bytes. - **files** (integer) - Number of files in the bundle. - **play_url** (string) - URL to play the game. - **checks** (array) - Array of validation check objects with `label`, `detail`, and `ok` fields. #### Response Example ```json { "game": "rosok-garage", "game_created": true, "version": 1, "status": "released", "rollout": 100, "sdk_min": 1, "size_bytes": 69414, "files": 5, "play_url": "https://your-arcade.example.com/main/rosok-garage", "checks": [{ "label": "Struktur wajib", "detail": "index.html + game.json ditemukan", "ok": true }] } ``` ### Error Handling - **422** - Returns `BUNDLE_INVALID` code and an array of `checks` indicating validation failures. ``` -------------------------------- ### Verifikasi koneksi: whoami Source: https://taploka.io/docs/quickstart Perintah `whoami` memastikan koneksi berhasil setelah login. ```bash npx -y taploka-mcp@latest whoami ``` -------------------------------- ### buy(sku, options?) Source: https://taploka.io/docs/game-sdk Membeli item dari toko. ```APIDOC ## `buy(sku, options?)` ### Description Membeli item dari toko. Pembelian bersifat idempoten. Ditolak dengan `ITEM_OWNED`, `ITEM_UNKNOWN`, atau `INSUFFICIENT_BALANCE`. ### Method `buy(sku, options?)` ### Parameters #### Request Body - **sku** (string) - Required - SKU item yang akan dibeli. - **options** (object) - Optional - Opsi tambahan. ### Request Example ```javascript const { item, balance } = await taploka.buy('engine_lv2'); ``` ### Response #### Success Response - **item** (object) - Item yang dibeli. - **balance** (number) - Saldo setelah pembelian. #### Response Example ```javascript { "item": { "sku": "engine_lv2", "title": "Engine Level 2", "coin_price": 100, "type": "upgrade", "owned": true, "qty": 1 }, "balance": 0 } ``` #### Error Response - **error.code** (string) - `ITEM_OWNED`, `ITEM_UNKNOWN`, atau `INSUFFICIENT_BALANCE`. ``` -------------------------------- ### Sambungkan mesin: tambahkan server MCP dan login Source: https://taploka.io/docs/quickstart Tambahkan server MCP Taploka dan login. Perintah `login` mencetak kode pendek seperti `RT2H-Z46S` dan membuka konsol admin arcade; administrator menyetujui kode, lalu kunci disimpan di `~/.taploka/credentials.json`. ```bash claude mcp add taploka -- npx -y taploka-mcp@latest npx -y taploka-mcp@latest login ``` -------------------------------- ### Login dan tambahkan profil taploka-mcp Source: https://taploka.io/docs/mcp-server Login dengan profil 'prod' dan URL arcade, lalu tambahkan profil ke Claude MCP dengan variabel lingkungan TAPLOKA_PROFILE. Profil tidak pernah jatuh ke pengaturan profil lain; jika tidak punya kunci, push berhenti dengan pesan. ```bash npx -y taploka-mcp@latest login --profile=prod --url=https://your-arcade.example.com claude mcp add taploka-prod -e TAPLOKA_PROFILE=prod -- npx -y taploka-mcp@latest ``` -------------------------------- ### shop() Source: https://taploka.io/docs/game-sdk Mengambil daftar item yang tersedia di toko. ```APIDOC ## `shop()` ### Description Mengambil daftar item yang tersedia di toko game. ### Method `shop()` ### Parameters Tidak ada parameter. ### Request Example ```javascript const { items } = await taploka.shop(); ``` ### Response #### Success Response - **items** (array) - Daftar item. - **sku** (string) - SKU item. - **title** (string) - Judul item. - **coin_price** (number) - Harga dalam koin. - **type** (string) - Tipe item. - **owned** (boolean) - Apakah item sudah dimiliki. - **qty** (number) - Jumlah item. #### Response Example ```javascript { "items": [ { "sku": "engine_lv2", "title": "Engine Level 2", "coin_price": 100, "type": "upgrade", "owned": false, "qty": 0 } ] } ``` ``` -------------------------------- ### Konfigurasi JSON untuk harness lain Source: https://taploka.io/docs/mcp-server Blok konfigurasi JSON yang digunakan oleh harness lain seperti Codex, Cursor, VS Code, dan Gemini CLI untuk mendaftarkan server MCP taploka-mcp. ```json { "mcpServers": { "taploka": { "command": "npx", "args": ["-y", "taploka-mcp@latest"] } } } ``` -------------------------------- ### inventory() Source: https://taploka.io/docs/game-sdk Mengambil daftar item yang dimiliki pemain. ```APIDOC ## `inventory()` ### Description Mengambil daftar item yang dimiliki pemain. Kepemilikan disimpan di sisi server, jadi baca saat start-up. ### Method `inventory()` ### Parameters Tidak ada parameter. ### Request Example ```javascript const owned = await taploka.inventory(); ``` ### Response #### Success Response - **owned** (array) - Daftar item yang dimiliki. - **sku** (string) - SKU item. - **qty** (number) - Jumlah item. - **granted_at** (string) - Waktu item diberikan. #### Response Example ```javascript [ { "sku": "engine_lv2", "qty": 1, "granted_at": "2023-01-01T00:00:00Z" } ] ``` ``` -------------------------------- ### Push a bundle (POST /api/v1/harness/bundles) Source: https://taploka.io/docs/harness-api Pushes a new game bundle as multipart/form-data. Requires the 'bundle' file and either 'game' or 'title'. Optional fields include rollout (default 100), changelog, and draft. On success, returns a JSON object with game details, version, status, and play URL. Failed validation returns 422 with code BUNDLE_INVALID and a checks array. ```http POST /api/v1/harness/bundles Content-Type: multipart/form-data ``` ```json { "game": "rosok-garage", "game_created": true, "version": 1, "status": "released", "rollout": 100, "sdk_min": 1, "size_bytes": 69414, "files": 5, "play_url": "https://your-arcade.example.com/main/rosok-garage", "checks": [{ "label": "Struktur wajib", "detail": "index.html + game.json ditemukan", "ok": true }] } ``` -------------------------------- ### Push berikutnya: push_game dengan slug dan changelog Source: https://taploka.io/docs/quickstart Push berikutnya menyapa game lewat slug, sehingga versi bertambah, bukan membuat game kedua. ```json push_game { game: "rosok-garage", zip: "/path/to/rosok-garage", changelog: "perbaikan hitbox" } ``` -------------------------------- ### Publish bundle from CI with curl Source: https://taploka.io/docs/harness-api Publishes a game bundle to the Taploka harness API using curl. Requires `$TAPLOKA_URL` and `$TAPLOKA_KEY` environment variables. Sends the bundle file, sets a rollout percentage, and includes the latest git commit message as the changelog. ```bash curl -sS -X POST "$TAPLOKA_URL/api/v1/harness/bundles" \ -H "Authorization: Bearer $TAPLOKA_KEY" \ -H "Accept: application/json" \ -F "game=rosok-garage" \ -F "bundle=@build/game.zip" \ -F "rollout=20" \ -F "changelog=$(git log -1 --pretty=%s)" ``` -------------------------------- ### push_game Source: https://taploka.io/docs/mcp-server Uploads a game bundle and releases it. Accepts a ZIP file or folder, game title, existing game slug, rollout percentage, changelog, and draft flag. Returns version number, status, rollout, file count, play URL, and validation checks. ```APIDOC ## push_game ### Description Unggah bundle lalu rilis. Mengembalikan nomor versi, status, rollout, jumlah berkas, URL main, dan daftar lengkap pemeriksaan validasi. ### Method push_game ### Parameters #### Arguments - **zip** (path) - Required - Path ke ZIP atau folder. Folder di-zip lokal, melewati dotfile dan `node_modules`. - **title** (string) - Required - Nama game. Di push pertama slug diturunkan dari sini; setelah itu diabaikan. - **game** (string) - Optional - Slug game yang sudah ada. Pakai ini di setiap push setelah yang pertama. - **rollout** (number) - Optional - Persentase pemain yang disajikan versi ini, 0-100. Default 100. - **changelog** (string) - Optional - Catatan pendek yang disimpan bersama versinya. - **draft** (boolean) - Optional - Simpan dan validasi tanpa merilis. Default false. ### Response Mengembalikan nomor versi, status, rollout, jumlah berkas, URL main, dan daftar lengkap pemeriksaan validasi. ``` -------------------------------- ### spend(amount, reason, options?) Source: https://taploka.io/docs/game-sdk Memotong koin dari saldo pemain. ```APIDOC ## `spend(amount, reason, options?)` ### Description Memotong koin dari saldo pemain tanpa memberikan apa pun. Digunakan untuk konsumsi yang tidak bisa diwakili toko. Ditolak dengan `error.code === 'INSUFFICIENT_BALANCE'` jika saldo kurang. ### Method `spend(amount, reason, options?)` ### Parameters #### Request Body - **amount** (number) - Required - Jumlah koin yang akan dipotong. - **reason** (string) - Required - Alasan pengeluaran. - **options** (object) - Optional - Opsi tambahan. - **key** (string) - Optional - Kunci unik untuk idempotensi. ### Request Example ```javascript const after = await taploka.spend(50, 'continue', { key: `continue-${runId}` }); ``` ### Response #### Success Response - **balance** (number) - Saldo setelah pengeluaran. #### Response Example ```javascript { "balance": 50 } ``` #### Error Response - **error.code** (string) - `INSUFFICIENT_BALANCE` jika saldo tidak mencukupi. ``` -------------------------------- ### Buy with stable key for idempotent retry Source: https://taploka.io/docs/coins Use a stable key (e.g., `fuel-${runId}`) to ensure retried purchases are only charged once. The key must be stable across retries of the same logical purchase. ```javascript await taploka.buy('fuel', { key: `fuel-${runId}` }); ``` -------------------------------- ### Contoh game.json Source: https://taploka.io/docs/bundles Manifes bundle dengan id, sdk_version minimal 1, orientation portrait/landscape, dan settings objek bebas yang diserahkan ke game saat runtime. ```json { "id": "rosok-garage", "sdk_version": 1, "orientation": "portrait", "settings": {} } ``` -------------------------------- ### Menambahkan taploka-mcp ke Claude Code Source: https://taploka.io/docs/mcp-server Perintah untuk menambahkan server MCP taploka-mcp ke Claude Code. Menjalankan server MCP stdio dengan npx. ```bash claude mcp add taploka -- npx -y taploka-mcp@latest ``` -------------------------------- ### list_games Source: https://taploka.io/docs/mcp-server Lists all games with their status, number of versions, live version, and play URL. ```APIDOC ## list_games ### Description Semua game dengan status, jumlah versi, versi yang tayang, dan URL main. ### Method list_games ### Parameters Tidak ada parameter. ### Response Daftar game dengan status, jumlah versi, versi yang tayang, dan URL main. ``` -------------------------------- ### State room yang dihasilkan oleh operasi room Source: https://taploka.io/docs/multiplayer Contoh JSON state room yang dikembalikan oleh quick(), create(), atau join(). Menunjukkan properti seperti id, code, status, seq, host, max_players, dan members. Seat stabil selama pemain ada di room dan harus dipakai untuk urutan giliran. ```json { "id": "01M2…", "code": "KX7Q", "status": "open", "seq": 12, "host": "01M1…", "max_players": 4, "members": [ { "id": "01M1…", "name": "Dika", "seat": 0, "is_host": true }, { "id": "01M2…", "name": "Salsa", "seat": 1, "is_host": false } ] } ``` -------------------------------- ### exit() Source: https://taploka.io/docs/game-sdk Requests the host to close the game and return the player to the catalog. Should be called from the player's own exit button, not when lives run out. ```APIDOC ## exit() ### Description Requests the host to close the game and return the player to the catalog. Should be called from the player's own exit button, not when lives run out. ### Method exit() ### Parameters None ### Returns None ### Example ```javascript taploka.exit(); ``` ``` -------------------------------- ### Baca kepemilikan item dengan taploka.inventory Source: https://taploka.io/docs/coins Mengambil inventori pemain saat start-up. Jangan percaya cloud save karena save ditulis klien dan bisa diedit; gunakan inventori untuk kepemilikan. ```javascript const { items } = await taploka.inventory(); // [{ sku, qty, granted_at }] ``` -------------------------------- ### POST /api/v1/harness/bundles Source: https://taploka.io/docs/harness-api Publishes a new game bundle to Taploka. Requires authentication via Bearer token. Accepts multipart form data with game identifier, bundle file, rollout percentage, and optional changelog. ```APIDOC ## POST /api/v1/harness/bundles ### Description Publishes a new game bundle to Taploka. Requires authentication via Bearer token. Accepts multipart form data with game identifier, bundle file, rollout percentage, and optional changelog. ### Method POST ### Endpoint /api/v1/harness/bundles ### Parameters #### Headers - **Authorization** (string) - Required - Bearer token for authentication. - **Accept** (string) - Required - Must be `application/json`. #### Form Data - **game** (string) - Required - Game identifier (e.g., `rosok-garage`). - **bundle** (file) - Required - The bundle file to upload (e.g., `@build/game.zip`). - **rollout** (integer) - Required - Rollout percentage (e.g., `20`). - **changelog** (string) - Optional - Changelog message (e.g., from `git log`). ### Request Example ``` curl -sS -X POST "$TAPLOKA_URL/api/v1/harness/bundles" \ -H "Authorization: Bearer $TAPLOKA_KEY" \ -H "Accept: application/json" \ -F "game=rosok-garage" \ -F "bundle=@build/game.zip" \ -F "rollout=20" \ -F "changelog=$(git log -1 --pretty=%s)" ``` ### Response #### Success Response (200) No response body is documented. #### Error Response - **400 Bad Request** - Returns an error object with `message`, `code`, and `data` fields. #### Error Example ``` { "message": "…", "code": "BUNDLE_INVALID", "data": { "checks": [] } } ``` ### Error Codes - **BUNDLE_INVALID** - Validation checks failed; `data.checks` indicates which ones. - **DEVICE_UNKNOWN** - Device code is unknown, already used, or expired. - **DEVICE_EXPIRED** - Link was not approved in time; restart from the beginning. ``` -------------------------------- ### POST /api/v1/harness/device Source: https://taploka.io/docs/harness-api Initiates the device link handshake by requesting a device code. This is the first step of the three-step device link flow used by `taploka-mcp login`. ```APIDOC ## POST /api/v1/harness/device ### Description Initiates the device link handshake by requesting a device code. This is the first step of the three-step device link flow used by `taploka-mcp login`. ### Method POST ### Endpoint /api/v1/harness/device ### Parameters #### Request Body - **name** (string) - Required - A name for the device, e.g., "build-box". ### Request Example { "name": "build-box" } ### Response #### Success Response (200) - **device_code** (string) - The device code used in the polling step. - **user_code** (string) - The user code to be approved in the console. - **verification_uri** (string) - The URI where the user code can be approved. - **verification_uri_complete** (string) - The complete URI with the user code embedded. - **interval** (integer) - The polling interval in seconds. - **expires_in** (integer) - The time in seconds until the device code expires. #### Response Example { "device_code": "…", "user_code": "RT2H-Z46S", "verification_uri": "https://your-arcade.example.com/admin/link", "verification_uri_complete": "https://your-arcade.example.com/admin/link?code=RT2H-Z46S", "interval": 2, "expires_in": 600 } ``` -------------------------------- ### Push game pertama: push_game dengan judul dan zip Source: https://taploka.io/docs/quickstart Push pertama membuat game dan menurunkan slug dari judul. Folder build di-zip saat dikirim. ```json push_game { title: "Rosok Garage", zip: "/path/to/rosok-garage" } ``` -------------------------------- ### Beli item dari dalam game dengan taploka.buy Source: https://taploka.io/docs/coins Mengambil daftar item yang tersedia lalu membeli item berdasarkan sku. Arcade membaca harga dari katalog, memotong dompet, dan mencatat item dalam satu transaksi. Jika saldo tidak cukup, error dengan kode `INSUFFICIENT_BALANCE` akan muncul. ```javascript const { items } = await taploka.shop(); // [{ sku: 'engine_lv2', title: 'Mesin Lv2', coin_price: 800, type, owned: false, qty: 0 }] try { const { item, balance } = await taploka.buy('engine_lv2'); unlockEngine(item.sku); showBalance(balance); } catch (error) { if (error.code === 'INSUFFICIENT_BALANCE') { showTopUpHint(); } } ``` -------------------------------- ### POST /api/v1/harness/games/{game} Source: https://taploka.io/docs/harness-api Updates metadata for an existing game. Only the fields you send are changed. Supports partial updates for most fields, but the `shop` field replaces the entire price list. ```APIDOC ## POST /api/v1/harness/games/{game} ### Description Updates metadata for an existing game. Only the fields you send are changed. Supports partial updates for most fields, but the `shop` field replaces the entire price list. ### Method POST ### Endpoint /api/v1/harness/games/{game} ### Parameters #### Path Parameters - **game** (string) - Required - The slug of the game. #### Request Body (JSON or multipart/form-data) - **title** (string) - Optional - New title. - **tagline** (string) - Optional - New tagline. - **description** (string) - Optional - New description. - **orientation** (string) - Optional - Orientation (e.g., "portrait", "landscape"). - **max_score** (integer) - Optional - Maximum score threshold. - **max_score_per_second** (integer) - Optional - Maximum score per second threshold. - **sort_order** (integer) - Optional - Sort order. - **categories** (array) - Optional - List of categories. - **features** (array) - Optional - List of features. - **cover_url** (string) - Optional - URL for the cover image. - **banner_url** (string) - Optional - URL for the banner image. - **coin_price** (integer) - Optional - Price in coins; makes the game premium. - **screenshots_url** (array) - Optional - List of screenshot URLs. - **cover** (file) - Optional - Cover image file (PNG, JPEG, or WebP, up to 3 MB). - **banner** (file) - Optional - Banner image file (PNG, JPEG, or WebP, up to 3 MB). - **screenshots[]** (file) - Optional - Screenshot files (up to 6 images). - **shop** (array) - Optional - Replaces the entire shop price list. Each item contains: - **sku** (string) - Required - SKU identifier. - **title** (string) - Required - Display title. - **coin_price** (integer) - Required - Price in coins. - **type** (string) - Optional - "non_consumable" (default) or "consumable". - **active** (boolean) - Optional - Set to false to retire an entry. ### Request Example ```json { "shop": [ { "sku": "engine_lv2", "title": "Mesin Lv2", "coin_price": 800 }, { "sku": "fuel", "title": "Bensin", "coin_price": 150, "type": "consumable" } ] } ``` ### Response #### Success Response (200) Same shape as reading a game (see GET /api/v1/harness/games/{game}). #### Response Example (No explicit response example provided in source) ### Error Handling (No explicit error handling documented) ``` -------------------------------- ### submitScore(score, meta?) Source: https://taploka.io/docs/game-sdk Metode untuk mengirim skor ke papan peringkat. ```APIDOC ## `submitScore(score, meta?)` ### Description Mengirimkan skor pemain ke papan peringkat. Skor dibulatkan ke bawah menjadi bilangan bulat non-negatif. Jika skor ditahan untuk ditinjau, `accepted` bernilai false. ### Method `submitScore(score, meta?)` ### Parameters #### Request Body - **score** (number) - Required - Skor yang akan dikirim. - **meta** (object) - Optional - Metadata tambahan, seperti nama pemain. - **name** (string) - Optional - Nama yang ditampilkan di papan peringkat. Dipotong 24 karakter dan dibersihkan dari karakter kontrol. ### Request Example ```javascript const { accepted, rank, best } = await taploka.submitScore(1200, { level: 4 }); ``` ### Response #### Success Response - **accepted** (boolean) - Apakah skor diterima. - **rank** (number) - Peringkat pemain. - **best** (number) - Skor terbaik pemain. #### Response Example ```javascript { "accepted": true, "rank": 1, "best": 1200 } ``` ``` -------------------------------- ### Keluar game dengan taploka.exit() Source: https://taploka.io/docs/game-sdk Meminta host menutup game dan mengembalikan pemain ke katalog. Panggil dari tombol keluar sendiri, bukan saat nyawa habis. ```javascript taploka.exit(); ``` -------------------------------- ### Update metadata (POST /api/v1/harness/games/{game}) Source: https://taploka.io/docs/harness-api Updates game metadata by sending only the fields to change. Accepts fields like title, tagline, description, orientation, max_score, max_score_per_second, sort_order, categories, features, cover_url, banner_url, coin_price, screenshots_url, or multipart files cover/banner/screenshots[]. The response matches the read-game shape. Sending screenshots replaces the entire set (up to 6 images); cover and banner are re-encoded to WebP. coin_price makes the game premium; null makes it free. max_score flags scores above a limit; max_score_per_second flags scores rising too fast. ```http POST /api/v1/harness/games/{game} ``` -------------------------------- ### market.sell(item, price) Source: https://taploka.io/docs/game-sdk Creates a new market listing for the specified item at the given price. The item is held by the arcade while the listing is active, preventing duplicate sales. ```APIDOC ## market.sell(item, price) ### Description Creates a new market listing for the specified item at the given price. The item is held by the arcade while the listing is active, preventing duplicate sales. ### Method market.sell(item, price) ### Parameters - **item** (object) - The item to sell, e.g., `{ truck: 'hino', wear: 12 }` - **price** (number) - The selling price in game currency ### Returns - **listing** (object) - The created listing object ### Example ```javascript const { listing } = await taploka.market.sell({ truck: 'hino', wear: 12 }, 7500000); ``` ```