MCP 服务器

YouGame

co.yougame/yougame
开发者工具 游戏 公开且可连接 MCP 2026-07-28

此 MCP 可以做什么

Supports browser game documentation, build validation, multiplayer testing, staged uploads, publishing, updates, and remixes for YouGame.

check_build
Runs static file and source-reference checks, not the game. Runtime behavior is always not_run; detected SDK references do not prove menu, matchmaking, friends, or ranked behavior. Returns a verdict: ready, risky (warnings), or broken (the game will not start). Pass every file path in the folder (relative to the folder, forward slashes) and the text of index.html; also pass the text of .html/.css/.js files worth scanning (8 MB of text in total). Fix what it reports and run it again until the verdict is ready, then zip the folder's contents for upload at https://yougame.co/upload.
只读 幂等
输入模式
{'type': 'object', 'required': ['files'], 'properties': {'files': {'type': 'array', 'items': {'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Path relative to the build folder, e.g. assets/player.png'}, 'size': {'type': 'number', 'description': 'Size in bytes (optional, enables the size checks)'}, 'text': {'type': 'string', 'description': 'File contents for index.html and other text files worth scanning (optional)'}}}, 'minItems': 1, 'description': 'Every file in the build folder.'}}}
close_test_session
Delete only this session's disposable test accounts and test game. Saved submission reports remain. Does not touch production accounts, builds or games.
可能执行破坏性操作
输入模式
{'type': 'object', 'required': ['sessionId'], 'properties': {'sessionId': {'type': 'string'}}, 'additionalProperties': False}
fetch
Returns the full text of one YouGame documentation section by the id search returned (for example "sdk#leaderboards").
只读 幂等
输入模式
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'Section id from search, e.g. sdk#leaderboards'}}}
get_publish_guide
The rules a browser game must follow to run on YouGame (build layout, paths, limits, the runtime sandbox, desktop/mobile reserved button areas, what usually breaks and how to fix it) plus how to verify and upload. Read this first when making a game YouGame-ready.
只读 幂等
输入模式
{'type': 'object', 'properties': {}, 'additionalProperties': False}
get_sdk_reference
The complete YouGame SDK reference: desktop/mobile button positions and reserved screen areas, touch controls, leaderboards (gameOver / submitScore), beat-my-score links, saves (save / load, kept on the player's account), online multiplayer with matchmaking, friend invites, skill ratings, voice chat between friends that a game with a map can turn into proximity chat (YouGame.voice), persistent worlds (shared state kept between visits; not a game server), replays (YouGame.replay: record the game's state frame by frame, play it back with pause and seek, watch links; input recording for deterministic games), and coins. One script tag, no account needed.
只读 幂等
输入模式
{'type': 'object', 'properties': {}, 'additionalProperties': False}
my_games
The games the API key's creator has published on YouGame: slug, URL, title, version, plays, SDK features. Needs the creator's API key.
只读 幂等
输入模式
{'type': 'object', 'properties': {}, 'additionalProperties': False}
prepare_submission
Fills in the whole YouGame listing of a staged build and saves it as a draft for the creator to review. Needs the creator signed in on this connection (or their API key). Stage a local build folder with Node 22+: download https://yougame.co/upload-build.mjs, then run node upload-build.mjs <build-folder> with YOUGAME_UPLOAD_TOKEN (from upload_token) or YOUGAME_API_KEY set. It applies the website's path fixes locally and streams files through POST /api/upload/start, PUT /api/upload/file, and POST /api/upload/complete. The same limits as the website apply: 5 GB total, 100 MB per file, 5,000 files. Unzip archives locally first. The result includes uploadId, testUrl and the static check report; fix a broken verdict and upload again. The older /api/agent/upload ZIP route is only a small-build compatibility option. A ROM mod (kind "patch") is its one patch file (.ips, .ups, .bps or .xdelta) and no index.html: pass the file itself to the helper and it is staged as a package with no page to check; a cosmetic's folder is staged with --package (by hand, POST /api/upload/start with package: true beside files). The reply has the uploadId, a testUrl where the build already runs, and the check report; if the verdict is broken, fix it and upload again. Then call this tool with the uploadId and every listing field, decided from what you know about the game: title, description, genres, controls, play mode, phones, mature, the score kind (time when the build posts a run's milliseconds to gameOver, else points), a maximum score (or fastest possible time) if the game has a natural one, the paywalls it charges, and a thumbnail. Ask the creator first about anything you cannot decide from the game itself (a thumbnail when the build has no 16:9 image: offer to make one or to use theirs; whether it is for adults; paywall prices), and again about anything the reply lists under questions, then call this tool again with the answers. The reply has the review link: give it to the creator. They see every field filled in, change what they want, and press Publish; nothing is live until they do. Never call publish_game instead of handing over the link unless the creator explicitly asked you to publish without reviewing.
幂等
输入模式
{'type': 'object', 'required': ['uploadId', 'title', 'description', 'genres', 'controls', 'play_mode', 'mobile', 'mature'], 'properties': {'kind': {'enum': ['game', 'patch', 'mod'], 'type': 'string', 'description': '"game" (default). "patch": a remix of a game the player already owns and that YouGame must never host, such as an N64 ROM or a disc image: a port, a balance patch, new characters, an engine like OpenSmash64. Anything that changes how the game plays, however slightly, is a remix. It is listed as a Remix of the base game (its own page, online play and ladder; remixes are not compatible with each other online), the player picks their own copy of the base game once on the site (hashed and kept in their browser, never uploaded), and the build asks for the bytes with YouGame.baseGame() at launch. "mod": a cosmetic (skins, textures, stage art, music, HUD) a remix loads on top through YouGame.cosmetics(); it changes looks and sounds only, has no build to run (no index.html), players add it from the base game\'s hub, and it never changes a match. Both need base_game, must contain none of the base game\'s data (uploads are scanned for game images), and have no money on them: no paywalls, tips or remix fees.'}, 'notes': {'type': 'string', 'description': 'Up to 2000 characters, shown to the creator above the form: what you chose and why, and what you assumed (the genres, the score kind, the max score, why mobile is off).'}, 'remix': {'type': 'object', 'properties': {'fee': {'type': 'number', 'description': 'The play fee: coins every player pays once, to the creator, before playing any remix of the game (paid in gold as creator earnings, like a paywall). 0 to 5000; default 0. Making a remix itself costs nothing.'}, 'merge': {'enum': ['no', 'free', 'flat', 'negotiated'], 'type': 'string', 'description': 'Whether a remixer may propose their build as the original\'s next version: "free" (default: yes, for nothing), "no", "flat" (the creator pays merge_fee gold, above 0, when they accept), or "negotiated" (the remixer names a price; either side may counter until the creator accepts).'}, 'charge': {'type': 'boolean', 'description': 'May a remix add paywalls of its own. Default false.'}, 'allowed': {'type': 'boolean', 'description': 'May anyone remix the game at all. Default false.'}, 'merge_fee': {'type': 'number', 'description': 'With merge "flat": gold the creator pays the remixer on accepting a merge, 1 to 100000 (0 means "free").'}, 'royalty_bps': {'type': 'number', 'description': "The creator's share of every gold purchase inside a remix, in basis points (250 = 2.5%). Only with charge. Default 0."}, 'royalty_flat': {'type': 'number', 'description': 'A flat gold amount the creator gets per purchase inside a remix, 0 to 5000, on top of the share. Only with charge. Default 0.'}}, 'description': "Whether other people may remix this game (copy its build, change it, and publish the result as their own game) and on what terms. Ask the creator; leave it out for the default, no remixes. The terms bind every remix made while they stand: the original's paywalls stay inside every remix and keep paying its creator whatever else is set; a remix made under given terms keeps them even if the creator changes them later.", 'additionalProperties': False}, 'title': {'type': 'string', 'description': '1–80 characters.'}, 'genres': {'type': 'array', 'items': {'enum': ['Action', 'Adventure', 'RPG', 'Arcade', 'Puzzle', 'Platformer', 'Shooter', 'Fighting', 'Strategy', 'Simulation', 'Sports', 'Racing', 'Party', 'Horror', 'Roguelike', 'Card', 'Idle', 'Rhythm', 'Tower defense', 'Word', 'Other'], 'type': 'string'}, 'description': 'Up to 3; the first is the main one.'}, 'ladder': {'type': 'boolean', 'description': 'The ranked ladder that ranked online matches feed (findMatch with ranked: true), shown on the game page. Default true; only matters for a game with online multiplayer.'}, 'mature': {'type': 'boolean', 'description': "True when the game is for adults only (blood and gore, realistic violence against people such as real-looking people hurt or killed or a realistic war setting, strong language, mature themes, casino-style gambling such as poker, slots or roulette even with play money). Cartoon, fantasy and stylized combat is not mature. Ask the creator if the game's content leaves it unclear."}, 'mobile': {'type': 'boolean', 'description': 'True only when you played the whole game with touch: every menu and action by tap or through YouGame.input, the layout right after fullscreen and rotation at 390×844 and 1024×768 (an iPad), no page scroll or zoom. Phones and iPads list only games with this on and Play there is the whole experience, so a wrong true puts an unplayable game in front of everyone it is shown to. The check report says what input the source handles; a keyboard-only or mouse-only build is false. Not sure, or could not run it on a touch screen or emulator: false, and say why in notes. A ROM mod (kind "patch" with base_game.rom_patch) is the exception: it runs in the site\'s emulator, which has its own on-screen controls, so pass true unless the mod cannot be played that way.'}, 'controls': {'enum': ['Keyboard', 'Mouse', 'Keyboard + Mouse', 'Touch', 'Gamepad'], 'type': 'string', 'description': 'How the game is played. Default Keyboard.'}, 'paywalls': {'type': 'array', 'items': {'type': 'object', 'required': ['key', 'label', 'price', 'kind'], 'properties': {'key': {'type': 'string', 'description': 'The key the game passes to YouGame.coins.charge.'}, 'kind': {'enum': ['unlock', 'play'], 'type': 'string', 'description': 'unlock: pay once, owned forever. play: pay every time.'}, 'label': {'type': 'string', 'description': 'What the player sees on the purchase sheet, up to 60 characters.'}, 'price': {'type': 'number', 'description': 'Whole coins, 1 to 5000.'}}}, 'maxItems': 20, 'description': 'The paywalls the build charges with YouGame.coins.charge(key), each priced by the creator: ask them for the price and kind. Leave it out when the game charges nothing.'}, 'uploadId': {'type': 'string', 'description': 'From the upload reply (32 hex characters).'}, 'base_game': {'type': 'object', 'required': ['key', 'name'], 'properties': {'key': {'type': 'string', 'description': 'Groups patches of the same base so one stored copy serves them all: "n64/ssb-usa". 2–64 characters of a-z, 0-9, /, _ or -.'}, 'mod': {'type': 'object', 'required': ['category', 'format'], 'properties': {'format': {'type': 'string', 'description': 'The package format a remix has to list in mod_formats to load it, like "texture-pack".'}, 'ranked': {'type': 'boolean', 'description': 'false when the cosmetic shows information other players do not see (hitboxes, frame data, a radar): players cannot have it on in a ranked match. Omit otherwise.'}, 'category': {'enum': ['characters', 'stages', 'music', 'hud', 'textures'], 'type': 'string', 'description': 'What the cosmetic changes; the hub filters by it.'}}, 'description': 'A cosmetic only: what it changes and its package format.'}, 'name': {'type': 'string', 'description': 'What the player must own, up to 80 characters: "Super Smash Bros. (N64)".'}, 'system': {'enum': ['n64', 'snes', 'nes', 'gb', 'gbc', 'gba', 'genesis', 'sms', 'gg', 'gamecube', 'wii', 'ps1', 'ps2', 'psp', 'dreamcast', 'nds', 'file'], 'type': 'string', 'description': '"n64": the file is an N64 ROM; .z64, .v64 and .n64 byte orders and a copier header are normalised before hashing, so list the big-endian (.z64) SHA-1. "file" (default): the bytes are hashed as they are.'}, 'catalog': {'type': 'string', 'description': 'The game\'s Wikidata id in YouGame\'s game catalog, like "Q870981" for Super Smash Bros.: a base game has to be a known game. Search the catalog over plain HTTP, no sign-in: GET https://yougame.co/api/base/search?q=<title> (each match lists the base games already defined for it: reuse one\'s key and this can be left out). A new key without it is accepted only when name, less any "(System, Region)" tail, is exactly one catalog game\'s name.'}, 'accepted': {'type': 'array', 'items': {'type': 'object', 'required': ['sha1', 'name', 'size'], 'properties': {'name': {'type': 'string', 'description': 'What the player sees when it matched: "Super Smash Bros. (USA)".'}, 'sha1': {'type': 'string', 'description': '40 hex characters.'}, 'size': {'type': 'number', 'description': 'Bytes of the canonical image.'}}}, 'maxItems': 16, 'description': 'The dumps the patch runs on (No-Intro or Redump hashes of the canonical image).'}, 'emulator': {'type': 'boolean', 'description': 'A version with a build of its own only: false keeps the system\'s emulator (the browser runtime and RetroArch) off the page, so players only get the build; for a build with online play the emulator lacks. Omit to offer both. A ROM mod (kind "patch" with base_game.rom_patch) cannot turn it off.'}, 'rejected': {'type': 'array', 'items': {'type': 'object', 'required': ['sha1', 'name', 'size', 'reason'], 'properties': {'name': {'type': 'string'}, 'sha1': {'type': 'string'}, 'size': {'type': 'number'}, 'reason': {'type': 'string', 'description': 'Up to 200 characters: "the Europe release; only the USA ROM is supported".'}}}, 'maxItems': 32, 'description': 'Real dumps the patch recognises but cannot use (other regions, revisions), each with the reason the player reads.'}, 'extensions': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 8, 'description': 'File extensions the picker offers, without dots: ["z64", "n64", "v64"].'}, 'plays_with': {'type': 'string', 'description': "The slug of your own full listing this patch is the same game as: with the player's base game applied it runs the same simulation, so the two listings share one set of online rooms, ratings and ladders and their players match each other. Both builds must come from the same source and use the same multiplayer compatibility string. The full listing must be published first, public, with online play on. Omit when the patch stands alone, and send it again whenever you resend base_game: the spec is replaced as a whole."}, 'mod_formats': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 8, 'description': 'A remix only: the cosmetic package formats its build loads through YouGame.cosmetics(), short handles like "texture-pack" or "o2r-overlay" (1–32 characters of a-z, 0-9, -). Cosmetics on the base game with one of these formats are offered to its players. Omit for none.'}}, 'description': 'With kind "patch" or "mod": the base game the player must own. For a remix, the player\'s file is normalised for the system and its SHA-1 compared with `accepted`; a match in `rejected` tells the player why that dump will not do. For a cosmetic only key, name and system matter, plus `mod`.'}, 'max_score': {'type': 'number', 'description': 'Optional: the highest score the game can produce (a points board), or the fastest run it can possibly produce in milliseconds (a time board). Scores past it are refused. Work it out from the game, or leave it out.'}, 'play_mode': {'enum': ['single', 'multiplayer', 'both'], 'type': 'string', 'description': 'single (solo only), multiplayer (online only), or both. Default: multiplayer when the build calls findMatch, else single.'}, 'thumbnail': {'type': 'string', 'description': "The path, inside the build, of a 16:9 PNG/JPG/WebP/GIF under 8 MB for the game's card. Not needed again once one was sent with PUT /api/agent/media."}, 'score_kind': {'enum': ['points', 'time', 'none'], 'type': 'string', 'description': 'The leaderboard this game gets, if any. "points" (default): the game calls YouGame.gameOver(score) with whatever it counts, higher is better. "time": a game against the clock (a speedrun, a level or puzzle to finish fast) calls YouGame.gameOver(elapsedMs) with the run in milliseconds; the board ranks fastest first and shows runs as times (1:23.45). Pick "time" whenever the build posts a time. "none": no leaderboard at all, which is the right answer for a head-to-head game (a fighter, a chess clone, anything only ever played one against one) that has no solo run worth ranking; the game page shows its ranked ladder instead. Never invent points so a game can have a board. Who sees a points or time board is the creator\'s call, carried by leaderboard and friends_board below; the ranked ladder by ladder.'}, 'visibility': {'enum': ['public', 'private'], 'type': 'string', 'description': '"public" (default) lists the game everywhere at once. "private" is a private launch: the game is published but nothing on YouGame lists it, and only the creator and people who open one of its invite links can see or play it (an alpha or beta for testers before the public launch). Publishing makes the first invite link; the creator makes more, sees who joined, and launches publicly from the game\'s Manage page. Pick it when the creator says the build is for testers, a private group, or not ready for everyone.'}, 'description': {'type': 'string', 'description': 'Up to 1000 characters, but keep it to two or three short, casual sentences a player reads on the game page: what the game is and what makes it fun (online play, a leaderboard). No control lists, rules tables, tech details or how YouGame works. Write it from the game.'}, 'leaderboard': {'type': 'boolean', 'description': 'The everyone leaderboard: every player ranked together, and the top score on the game\'s card. Default true with a points or time board. false with friends_board true is a friends-only board, the right pick for a game meant to be played among friends. score_kind "none" turns both switches off whatever is sent.'}, 'screenshots': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional: up to 8 image paths inside the build.'}, 'friends_board': {'type': 'boolean', 'description': 'The friends leaderboard: the same scores, each signed-in player seeing only themself and their friends. Default true with a points or time board. Needs no game code: the one gameOver call feeds both boards.'}, 'voice_everyone': {'type': 'boolean', 'description': 'Voice chat with everyone in a match, not just friends. Default false: players hear only their friends (and everyone in a friends lobby), which is right for almost every game. true only when the creator asked for it, for a game built around talking to other players (proximity chat as a core mechanic, social deduction): then every signed-in player seated in a match can hear every other one, matched by the queue or not. Needs no game code; blocked players stay muted and nobody is on the mic until they join. Covers match rooms (the first ten players seated in each), not worlds.'}}, 'additionalProperties': False}
publish_game
Publishes a staged build as a game on YouGame, live at once, skipping the creator's review. Needs the creator's API key and their explicit instruction: the normal path is prepare_submission, which hands the creator a review link where they press Publish themselves. Call this only when the creator explicitly told you, in their own words, to publish without opening the review page ("looks good" about a draft is not that); never because it is faster. After prepare_submission the uploadId alone is enough (every other field keeps the draft's value); otherwise pass the listing fields.
幂等
输入模式
{'type': 'object', 'required': ['uploadId', 'creator_approved'], 'properties': {'kind': {'enum': ['game', 'patch', 'mod'], 'type': 'string', 'description': '"game" (default). "patch": a remix of a game the player already owns and that YouGame must never host, such as an N64 ROM or a disc image: a port, a balance patch, new characters, an engine like OpenSmash64. Anything that changes how the game plays, however slightly, is a remix. It is listed as a Remix of the base game (its own page, online play and ladder; remixes are not compatible with each other online), the player picks their own copy of the base game once on the site (hashed and kept in their browser, never uploaded), and the build asks for the bytes with YouGame.baseGame() at launch. "mod": a cosmetic (skins, textures, stage art, music, HUD) a remix loads on top through YouGame.cosmetics(); it changes looks and sounds only, has no build to run (no index.html), players add it from the base game\'s hub, and it never changes a match. Both need base_game, must contain none of the base game\'s data (uploads are scanned for game images), and have no money on them: no paywalls, tips or remix fees.'}, 'save': {'type': 'boolean', 'description': "Put the game in the creator's Saved games. Default true; pass false only when the creator asked not to."}, 'remix': {'type': 'object', 'properties': {'fee': {'type': 'number', 'description': 'The play fee: coins every player pays once, to the creator, before playing any remix of the game (paid in gold as creator earnings, like a paywall). 0 to 5000; default 0. Making a remix itself costs nothing.'}, 'merge': {'enum': ['no', 'free', 'flat', 'negotiated'], 'type': 'string', 'description': 'Whether a remixer may propose their build as the original\'s next version: "free" (default: yes, for nothing), "no", "flat" (the creator pays merge_fee gold, above 0, when they accept), or "negotiated" (the remixer names a price; either side may counter until the creator accepts).'}, 'charge': {'type': 'boolean', 'description': 'May a remix add paywalls of its own. Default false.'}, 'allowed': {'type': 'boolean', 'description': 'May anyone remix the game at all. Default false.'}, 'merge_fee': {'type': 'number', 'description': 'With merge "flat": gold the creator pays the remixer on accepting a merge, 1 to 100000 (0 means "free").'}, 'royalty_bps': {'type': 'number', 'description': "The creator's share of every gold purchase inside a remix, in basis points (250 = 2.5%). Only with charge. Default 0."}, 'royalty_flat': {'type': 'number', 'description': 'A flat gold amount the creator gets per purchase inside a remix, 0 to 5000, on top of the share. Only with charge. Default 0.'}}, 'description': "Whether other people may remix this game (copy its build, change it, and publish the result as their own game) and on what terms. Ask the creator; leave it out for the default, no remixes. The terms bind every remix made while they stand: the original's paywalls stay inside every remix and keep paying its creator whatever else is set; a remix made under given terms keeps them even if the creator changes them later.", 'additionalProperties': False}, 'title': {'type': 'string', 'description': '1–80 characters.'}, 'genres': {'type': 'array', 'items': {'enum': ['Action', 'Adventure', 'RPG', 'Arcade', 'Puzzle', 'Platformer', 'Shooter', 'Fighting', 'Strategy', 'Simulation', 'Sports', 'Racing', 'Party', 'Horror', 'Roguelike', 'Card', 'Idle', 'Rhythm', 'Tower defense', 'Word', 'Other'], 'type': 'string'}, 'description': 'Up to 3; the first is the main one.'}, 'ladder': {'type': 'boolean', 'description': 'The ranked ladder that ranked online matches feed (findMatch with ranked: true), shown on the game page. Default true; only matters for a game with online multiplayer.'}, 'mature': {'type': 'boolean', 'description': "True when the game is for adults only (blood and gore, realistic violence against people such as real-looking people hurt or killed or a realistic war setting, strong language, mature themes, casino-style gambling such as poker, slots or roulette even with play money). Cartoon, fantasy and stylized combat is not mature. Ask the creator if the game's content leaves it unclear."}, 'mobile': {'type': 'boolean', 'description': 'True only when you played the whole game with touch: every menu and action by tap or through YouGame.input, the layout right after fullscreen and rotation at 390×844 and 1024×768 (an iPad), no page scroll or zoom. Phones and iPads list only games with this on and Play there is the whole experience, so a wrong true puts an unplayable game in front of everyone it is shown to. The check report says what input the source handles; a keyboard-only or mouse-only build is false. Not sure, or could not run it on a touch screen or emulator: false, and say why in notes. A ROM mod (kind "patch" with base_game.rom_patch) is the exception: it runs in the site\'s emulator, which has its own on-screen controls, so pass true unless the mod cannot be played that way.'}, 'controls': {'enum': ['Keyboard', 'Mouse', 'Keyboard + Mouse', 'Touch', 'Gamepad'], 'type': 'string', 'description': 'How the game is played. Default Keyboard.'}, 'paywalls': {'type': 'array', 'items': {'type': 'object', 'required': ['key', 'label', 'price', 'kind'], 'properties': {'key': {'type': 'string', 'description': 'The key the game passes to YouGame.coins.charge.'}, 'kind': {'enum': ['unlock', 'play'], 'type': 'string', 'description': 'unlock: pay once, owned forever. play: pay every time.'}, 'label': {'type': 'string', 'description': 'What the player sees on the purchase sheet, up to 60 characters.'}, 'price': {'type': 'number', 'description': 'Whole coins, 1 to 5000.'}}}, 'maxItems': 20, 'description': 'The paywalls the build charges with YouGame.coins.charge(key), each priced by the creator: ask them for the price and kind. Leave it out when the game charges nothing.'}, 'uploadId': {'type': 'string', 'description': 'From the upload reply (32 hex characters).'}, 'base_game': {'type': 'object', 'required': ['key', 'name'], 'properties': {'key': {'type': 'string', 'description': 'Groups patches of the same base so one stored copy serves them all: "n64/ssb-usa". 2–64 characters of a-z, 0-9, /, _ or -.'}, 'mod': {'type': 'object', 'required': ['category', 'format'], 'properties': {'format': {'type': 'string', 'description': 'The package format a remix has to list in mod_formats to load it, like "texture-pack".'}, 'ranked': {'type': 'boolean', 'description': 'false when the cosmetic shows information other players do not see (hitboxes, frame data, a radar): players cannot have it on in a ranked match. Omit otherwise.'}, 'category': {'enum': ['characters', 'stages', 'music', 'hud', 'textures'], 'type': 'string', 'description': 'What the cosmetic changes; the hub filters by it.'}}, 'description': 'A cosmetic only: what it changes and its package format.'}, 'name': {'type': 'string', 'description': 'What the player must own, up to 80 characters: "Super Smash Bros. (N64)".'}, 'system': {'enum': ['n64', 'snes', 'nes', 'gb', 'gbc', 'gba', 'genesis', 'sms', 'gg', 'gamecube', 'wii', 'ps1', 'ps2', 'psp', 'dreamcast', 'nds', 'file'], 'type': 'string', 'description': '"n64": the file is an N64 ROM; .z64, .v64 and .n64 byte orders and a copier header are normalised before hashing, so list the big-endian (.z64) SHA-1. "file" (default): the bytes are hashed as they are.'}, 'catalog': {'type': 'string', 'description': 'The game\'s Wikidata id in YouGame\'s game catalog, like "Q870981" for Super Smash Bros.: a base game has to be a known game. Search the catalog over plain HTTP, no sign-in: GET https://yougame.co/api/base/search?q=<title> (each match lists the base games already defined for it: reuse one\'s key and this can be left out). A new key without it is accepted only when name, less any "(System, Region)" tail, is exactly one catalog game\'s name.'}, 'accepted': {'type': 'array', 'items': {'type': 'object', 'required': ['sha1', 'name', 'size'], 'properties': {'name': {'type': 'string', 'description': 'What the player sees when it matched: "Super Smash Bros. (USA)".'}, 'sha1': {'type': 'string', 'description': '40 hex characters.'}, 'size': {'type': 'number', 'description': 'Bytes of the canonical image.'}}}, 'maxItems': 16, 'description': 'The dumps the patch runs on (No-Intro or Redump hashes of the canonical image).'}, 'emulator': {'type': 'boolean', 'description': 'A version with a build of its own only: false keeps the system\'s emulator (the browser runtime and RetroArch) off the page, so players only get the build; for a build with online play the emulator lacks. Omit to offer both. A ROM mod (kind "patch" with base_game.rom_patch) cannot turn it off.'}, 'rejected': {'type': 'array', 'items': {'type': 'object', 'required': ['sha1', 'name', 'size', 'reason'], 'properties': {'name': {'type': 'string'}, 'sha1': {'type': 'string'}, 'size': {'type': 'number'}, 'reason': {'type': 'string', 'description': 'Up to 200 characters: "the Europe release; only the USA ROM is supported".'}}}, 'maxItems': 32, 'description': 'Real dumps the patch recognises but cannot use (other regions, revisions), each with the reason the player reads.'}, 'extensions': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 8, 'description': 'File extensions the picker offers, without dots: ["z64", "n64", "v64"].'}, 'plays_with': {'type': 'string', 'description': "The slug of your own full listing this patch is the same game as: with the player's base game applied it runs the same simulation, so the two listings share one set of online rooms, ratings and ladders and their players match each other. Both builds must come from the same source and use the same multiplayer compatibility string. The full listing must be published first, public, with online play on. Omit when the patch stands alone, and send it again whenever you resend base_game: the spec is replaced as a whole."}, 'mod_formats': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 8, 'description': 'A remix only: the cosmetic package formats its build loads through YouGame.cosmetics(), short handles like "texture-pack" or "o2r-overlay" (1–32 characters of a-z, 0-9, -). Cosmetics on the base game with one of these formats are offered to its players. Omit for none.'}}, 'description': 'With kind "patch" or "mod": the base game the player must own. For a remix, the player\'s file is normalised for the system and its SHA-1 compared with `accepted`; a match in `rejected` tells the player why that dump will not do. For a cosmetic only key, name and system matter, plus `mod`.'}, 'max_score': {'type': 'number', 'description': 'Optional: the highest score the game can produce (a points board), or the fastest run it can possibly produce in milliseconds (a time board). Scores past it are refused. Work it out from the game, or leave it out.'}, 'play_mode': {'enum': ['single', 'multiplayer', 'both'], 'type': 'string', 'description': 'single (solo only), multiplayer (online only), or both. Default: multiplayer when the build calls findMatch, else single.'}, 'thumbnail': {'type': 'string', 'description': "The path, inside the build, of a 16:9 PNG/JPG/WebP/GIF under 8 MB for the game's card. Not needed again once one was sent with PUT /api/agent/media."}, 'score_kind': {'enum': ['points', 'time', 'none'], 'type': 'string', 'description': 'The leaderboard this game gets, if any. "points" (default): the game calls YouGame.gameOver(score) with whatever it counts, higher is better. "time": a game against the clock (a speedrun, a level or puzzle to finish fast) calls YouGame.gameOver(elapsedMs) with the run in milliseconds; the board ranks fastest first and shows runs as times (1:23.45). Pick "time" whenever the build posts a time. "none": no leaderboard at all, which is the right answer for a head-to-head game (a fighter, a chess clone, anything only ever played one against one) that has no solo run worth ranking; the game page shows its ranked ladder instead. Never invent points so a game can have a board. Who sees a points or time board is the creator\'s call, carried by leaderboard and friends_board below; the ranked ladder by ladder.'}, 'visibility': {'enum': ['public', 'private'], 'type': 'string', 'description': '"public" (default) lists the game everywhere at once. "private" is a private launch: the game is published but nothing on YouGame lists it, and only the creator and people who open one of its invite links can see or play it (an alpha or beta for testers before the public launch). Publishing makes the first invite link; the creator makes more, sees who joined, and launches publicly from the game\'s Manage page. Pick it when the creator says the build is for testers, a private group, or not ready for everyone.'}, 'description': {'type': 'string', 'description': 'Up to 1000 characters, but keep it to two or three short, casual sentences a player reads on the game page: what the game is and what makes it fun (online play, a leaderboard). No control lists, rules tables, tech details or how YouGame works. Write it from the game.'}, 'leaderboard': {'type': 'boolean', 'description': 'The everyone leaderboard: every player ranked together, and the top score on the game\'s card. Default true with a points or time board. false with friends_board true is a friends-only board, the right pick for a game meant to be played among friends. score_kind "none" turns both switches off whatever is sent.'}, 'screenshots': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional: up to 8 image paths inside the build.'}, 'friends_board': {'type': 'boolean', 'description': 'The friends leaderboard: the same scores, each signed-in player seeing only themself and their friends. Default true with a points or time board. Needs no game code: the one gameOver call feeds both boards.'}, 'voice_everyone': {'type': 'boolean', 'description': 'Voice chat with everyone in a match, not just friends. Default false: players hear only their friends (and everyone in a friends lobby), which is right for almost every game. true only when the creator asked for it, for a game built around talking to other players (proximity chat as a core mechanic, social deduction): then every signed-in player seated in a match can hear every other one, matched by the queue or not. Needs no game code; blocked players stay muted and nobody is on the mic until they join. Covers match rooms (the first ten players seated in each), not worlds.'}, 'creator_approved': {'type': 'boolean', 'description': 'True only when the creator explicitly told you, in their own words, to publish this game without opening the review page. Approval of a draft summary in chat does not count. Never assume it; the tool refuses without it.'}}, 'additionalProperties': False}
record_test_evidence
Record actual browser test outcomes for this build. Include browser, viewport, player identities, inputs, expected/observed behavior, and artifact paths. A passed result is explicitly agent-reported. Unrun cases stay not_run. Never submit inferred results from source inspection.
幂等
输入模式
{'type': 'object', 'required': ['sessionId', 'evidence'], 'properties': {'evidence': {'type': 'array', 'items': {'type': 'object', 'required': ['case', 'status', 'detail'], 'properties': {'case': {'enum': ['boot', 'desktop_controls', 'phone_controls', 'layout', 'restart', 'audio', 'scores', 'friends_board', 'saves', 'casual', 'ranked', 'friends_invite', 'ready', 'result', 'rematch', 'disconnect', 'friend_request', 'chat', 'notifications', 'presence', 'worlds', 'ux'], 'type': 'string'}, 'detail': {'type': 'string', 'maxLength': 4000, 'minLength': 1}, 'status': {'enum': ['passed', 'failed', 'not_run'], 'type': 'string'}, 'artifacts': {'type': 'array', 'items': {'type': 'string', 'maxLength': 2000}, 'maxItems': 8}}, 'additionalProperties': False}, 'maxItems': 22}, 'sessionId': {'type': 'string'}}, 'additionalProperties': False}
remix_game
Makes a remix of a game on YouGame for the creator: a copy of that game's current build, under the terms its creator set (shown on https://yougame.co/g/<slug>/remix), published at once as a new game of the creator's own. Needs the creator's API key or sign-in, and a game whose creator allows remixes. Making a remix costs nothing; if the terms name a play fee, every player (the remixer included) pays it once to the original's creator before playing any remix of that game. The remix starts as a minor variant, available from the original game rather than discovery. For substantially different gameplay, upload the changed build, then choose Major remix on its Manage page with a distinct title and thumbnail. The reply has the new game's slug and a download link for its build (GET it with the same Authorization header): download the zip, make the changes, and ship them with update_game on the new slug. The original's paywalls stay in the remix and keep paying the original's creator: keep every YouGame.coins.charge call the build has, or the update is refused. A remix may add paywalls of its own only when the terms allow charging.
输入模式
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'The game to remix: the last part of its URL, https://yougame.co/g/<slug>.'}, 'title': {'type': 'string', 'description': "The remix's title, 1–80 characters. Default: the original's title followed by “remix”."}}, 'additionalProperties': False}
search
Searches the YouGame documentation (the publish guide and the SDK reference) and returns matching sections with ids. Use it to answer a specific question — how scores are posted, what multiplayer guarantees, what breaks a build — without reading a whole document, then call fetch with an id.
只读 幂等
输入模式
{'type': 'object', 'required': ['query'], 'properties': {'query': {'type': 'string', 'description': 'What to look for, e.g. "submit a score" or "Unity compression"'}}}
start_test_session
Run a staged build in the isolated YouGame testing site, with 2–10 disposable signed-in players, real social features and multiplayer. Does not publish. Returns separate player login URLs, a build fingerprint, and an untested scenario checklist. Open each player loginUrl in a separate browser context/profile (tabs alone share login cookies). Use real browser inputs on the game's actual menus. Test desktop at 1440x900 and touch at 375x812, capture screenshots, console errors, failed requests, and interaction steps. For online play, seat two identities, verify Casual/Ranked/Friends, Ready, synchronized play, result, rematch, disconnect/rejoin, and an invite accepted from a fresh page. To test friend requests, use strangers or unfriend a disposable player through the UI. Record results with record_test_evidence, then read test_report before prepare_submission. Static checks and backend counts do not prove runtime behavior or good UX. Payments and voice are not enabled in the test environment; report them as untested. Close the session when done. Login URLs are private credentials and expire with the session.
输入模式
{'type': 'object', 'required': ['uploadId'], 'properties': {'listing': {'type': 'object', 'required': ['title'], 'properties': {'kind': {'enum': ['game', 'patch', 'mod'], 'type': 'string', 'description': '"game" (default). "patch": a remix of a game the player already owns and that YouGame must never host, such as an N64 ROM or a disc image: a port, a balance patch, new characters, an engine like OpenSmash64. Anything that changes how the game plays, however slightly, is a remix. It is listed as a Remix of the base game (its own page, online play and ladder; remixes are not compatible with each other online), the player picks their own copy of the base game once on the site (hashed and kept in their browser, never uploaded), and the build asks for the bytes with YouGame.baseGame() at launch. "mod": a cosmetic (skins, textures, stage art, music, HUD) a remix loads on top through YouGame.cosmetics(); it changes looks and sounds only, has no build to run (no index.html), players add it from the base game\'s hub, and it never changes a match. Both need base_game, must contain none of the base game\'s data (uploads are scanned for game images), and have no money on them: no paywalls, tips or remix fees.'}, 'remix': {'type': 'object', 'properties': {'fee': {'type': 'number', 'description': 'The play fee: coins every player pays once, to the creator, before playing any remix of the game (paid in gold as creator earnings, like a paywall). 0 to 5000; default 0. Making a remix itself costs nothing.'}, 'merge': {'enum': ['no', 'free', 'flat', 'negotiated'], 'type': 'string', 'description': 'Whether a remixer may propose their build as the original\'s next version: "free" (default: yes, for nothing), "no", "flat" (the creator pays merge_fee gold, above 0, when they accept), or "negotiated" (the remixer names a price; either side may counter until the creator accepts).'}, 'charge': {'type': 'boolean', 'description': 'May a remix add paywalls of its own. Default false.'}, 'allowed': {'type': 'boolean', 'description': 'May anyone remix the game at all. Default false.'}, 'merge_fee': {'type': 'number', 'description': 'With merge "flat": gold the creator pays the remixer on accepting a merge, 1 to 100000 (0 means "free").'}, 'royalty_bps': {'type': 'number', 'description': "The creator's share of every gold purchase inside a remix, in basis points (250 = 2.5%). Only with charge. Default 0."}, 'royalty_flat': {'type': 'number', 'description': 'A flat gold amount the creator gets per purchase inside a remix, 0 to 5000, on top of the share. Only with charge. Default 0.'}}, 'description': "Whether other people may remix this game (copy its build, change it, and publish the result as their own game) and on what terms. Ask the creator; leave it out for the default, no remixes. The terms bind every remix made while they stand: the original's paywalls stay inside every remix and keep paying its creator whatever else is set; a remix made under given terms keeps them even if the creator changes them later.", 'additionalProperties': False}, 'title': {'type': 'string', 'description': '1–80 characters.'}, 'genres': {'type': 'array', 'items': {'enum': ['Action', 'Adventure', 'RPG', 'Arcade', 'Puzzle', 'Platformer', 'Shooter', 'Fighting', 'Strategy', 'Simulation', 'Sports', 'Racing', 'Party', 'Horror', 'Roguelike', 'Card', 'Idle', 'Rhythm', 'Tower defense', 'Word', 'Other'], 'type': 'string'}, 'description': 'Up to 3; the first is the main one.'}, 'ladder': {'type': 'boolean', 'description': 'The ranked ladder that ranked online matches feed (findMatch with ranked: true), shown on the game page. Default true; only matters for a game with online multiplayer.'}, 'mature': {'type': 'boolean', 'description': "True when the game is for adults only (blood and gore, realistic violence against people such as real-looking people hurt or killed or a realistic war setting, strong language, mature themes, casino-style gambling such as poker, slots or roulette even with play money). Cartoon, fantasy and stylized combat is not mature. Ask the creator if the game's content leaves it unclear."}, 'mobile': {'type': 'boolean', 'description': 'True only when you played the whole game with touch: every menu and action by tap or through YouGame.input, the layout right after fullscreen and rotation at 390×844 and 1024×768 (an iPad), no page scroll or zoom. Phones and iPads list only games with this on and Play there is the whole experience, so a wrong true puts an unplayable game in front of everyone it is shown to. The check report says what input the source handles; a keyboard-only or mouse-only build is false. Not sure, or could not run it on a touch screen or emulator: false, and say why in notes. A ROM mod (kind "patch" with base_game.rom_patch) is the exception: it runs in the site\'s emulator, which has its own on-screen controls, so pass true unless the mod cannot be played that way.'}, 'controls': {'enum': ['Keyboard', 'Mouse', 'Keyboard + Mouse', 'Touch', 'Gamepad'], 'type': 'string', 'description': 'How the game is played. Default Keyboard.'}, 'paywalls': {'type': 'array', 'items': {'type': 'object', 'required': ['key', 'label', 'price', 'kind'], 'properties': {'key': {'type': 'string', 'description': 'The key the game passes to YouGame.coins.charge.'}, 'kind': {'enum': ['unlock', 'play'], 'type': 'string', 'description': 'unlock: pay once, owned forever. play: pay every time.'}, 'label': {'type': 'string', 'description': 'What the player sees on the purchase sheet, up to 60 characters.'}, 'price': {'type': 'number', 'description': 'Whole coins, 1 to 5000.'}}}, 'maxItems': 20, 'description': 'The paywalls the build charges with YouGame.coins.charge(key), each priced by the creator: ask them for the price and kind. Leave it out when the game charges nothing.'}, 'base_game': {'type': 'object', 'required': ['key', 'name'], 'properties': {'key': {'type': 'string', 'description': 'Groups patches of the same base so one stored copy serves them all: "n64/ssb-usa". 2–64 characters of a-z, 0-9, /, _ or -.'}, 'mod': {'type': 'object', 'required': ['category', 'format'], 'properties': {'format': {'type': 'string', 'description': 'The package format a remix has to list in mod_formats to load it, like "texture-pack".'}, 'ranked': {'type': 'boolean', 'description': 'false when the cosmetic shows information other players do not see (hitboxes, frame data, a radar): players cannot have it on in a ranked match. Omit otherwise.'}, 'category': {'enum': ['characters', 'stages', 'music', 'hud', 'textures'], 'type': 'string', 'description': 'What the cosmetic changes; the hub filters by it.'}}, 'description': 'A cosmetic only: what it changes and its package format.'}, 'name': {'type': 'string', 'description': 'What the player must own, up to 80 characters: "Super Smash Bros. (N64)".'}, 'system': {'enum': ['n64', 'snes', 'nes', 'gb', 'gbc', 'gba', 'genesis', 'sms', 'gg', 'gamecube', 'wii', 'ps1', 'ps2', 'psp', 'dreamcast', 'nds', 'file'], 'type': 'string', 'description': '"n64": the file is an N64 ROM; .z64, .v64 and .n64 byte orders and a copier header are normalised before hashing, so list the big-endian (.z64) SHA-1. "file" (default): the bytes are hashed as they are.'}, 'catalog': {'type': 'string', 'description': 'The game\'s Wikidata id in YouGame\'s game catalog, like "Q870981" for Super Smash Bros.: a base game has to be a known game. Search the catalog over plain HTTP, no sign-in: GET https://yougame.co/api/base/search?q=<title> (each match lists the base games already defined for it: reuse one\'s key and this can be left out). A new key without it is accepted only when name, less any "(System, Region)" tail, is exactly one catalog game\'s name.'}, 'accepted': {'type': 'array', 'items': {'type': 'object', 'required': ['sha1', 'name', 'size'], 'properties': {'name': {'type': 'string', 'description': 'What the player sees when it matched: "Super Smash Bros. (USA)".'}, 'sha1': {'type': 'string', 'description': '40 hex characters.'}, 'size': {'type': 'number', 'description': 'Bytes of the canonical image.'}}}, 'maxItems': 16, 'description': 'The dumps the patch runs on (No-Intro or Redump hashes of the canonical image).'}, 'emulator': {'type': 'boolean', 'description': 'A version with a build of its own only: false keeps the system\'s emulator (the browser runtime and RetroArch) off the page, so players only get the build; for a build with online play the emulator lacks. Omit to offer both. A ROM mod (kind "patch" with base_game.rom_patch) cannot turn it off.'}, 'rejected': {'type': 'array', 'items': {'type': 'object', 'required': ['sha1', 'name', 'size', 'reason'], 'properties': {'name': {'type': 'string'}, 'sha1': {'type': 'string'}, 'size': {'type': 'number'}, 'reason': {'type': 'string', 'description': 'Up to 200 characters: "the Europe release; only the USA ROM is supported".'}}}, 'maxItems': 32, 'description': 'Real dumps the patch recognises but cannot use (other regions, revisions), each with the reason the player reads.'}, 'extensions': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 8, 'description': 'File extensions the picker offers, without dots: ["z64", "n64", "v64"].'}, 'plays_with': {'type': 'string', 'description': "The slug of your own full listing this patch is the same game as: with the player's base game applied it runs the same simulation, so the two listings share one set of online rooms, ratings and ladders and their players match each other. Both builds must come from the same source and use the same multiplayer compatibility string. The full listing must be published first, public, with online play on. Omit when the patch stands alone, and send it again whenever you resend base_game: the spec is replaced as a whole."}, 'mod_formats': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 8, 'description': 'A remix only: the cosmetic package formats its build loads through YouGame.cosmetics(), short handles like "texture-pack" or "o2r-overlay" (1–32 characters of a-z, 0-9, -). Cosmetics on the base game with one of these formats are offered to its players. Omit for none.'}}, 'description': 'With kind "patch" or "mod": the base game the player must own. For a remix, the player\'s file is normalised for the system and its SHA-1 compared with `accepted`; a match in `rejected` tells the player why that dump will not do. For a cosmetic only key, name and system matter, plus `mod`.'}, 'max_score': {'type': 'number', 'description': 'Optional: the highest score the game can produce (a points board), or the fastest run it can possibly produce in milliseconds (a time board). Scores past it are refused. Work it out from the game, or leave it out.'}, 'play_mode': {'enum': ['single', 'multiplayer', 'both'], 'type': 'string', 'description': 'single (solo only), multiplayer (online only), or both. Default: multiplayer when the build calls findMatch, else single.'}, 'thumbnail': {'type': 'string', 'description': "The path, inside the build, of a 16:9 PNG/JPG/WebP/GIF under 8 MB for the game's card. Not needed again once one was sent with PUT /api/agent/media."}, 'score_kind': {'enum': ['points', 'time', 'none'], 'type': 'string', 'description': 'The leaderboard this game gets, if any. "points" (default): the game calls YouGame.gameOver(score) with whatever it counts, higher is better. "time": a game against the clock (a speedrun, a level or puzzle to finish fast) calls YouGame.gameOver(elapsedMs) with the run in milliseconds; the board ranks fastest first and shows runs as times (1:23.45). Pick "time" whenever the build posts a time. "none": no leaderboard at all, which is the right answer for a head-to-head game (a fighter, a chess clone, anything only ever played one against one) that has no solo run worth ranking; the game page shows its ranked ladder instead. Never invent points so a game can have a board. Who sees a points or time board is the creator\'s call, carried by leaderboard and friends_board below; the ranked ladder by ladder.'}, 'visibility': {'enum': ['public', 'private'], 'type': 'string', 'description': '"public" (default) lists the game everywhere at once. "private" is a private launch: the game is published but nothing on YouGame lists it, and only the creator and people who open one of its invite links can see or play it (an alpha or beta for testers before the public launch). Publishing makes the first invite link; the creator makes more, sees who joined, and launches publicly from the game\'s Manage page. Pick it when the creator says the build is for testers, a private group, or not ready for everyone.'}, 'description': {'type': 'string', 'description': 'Up to 1000 characters, but keep it to two or three short, casual sentences a player reads on the game page: what the game is and what makes it fun (online play, a leaderboard). No control lists, rules tables, tech details or how YouGame works. Write it from the game.'}, 'leaderboard': {'type': 'boolean', 'description': 'The everyone leaderboard: every player ranked together, and the top score on the game\'s card. Default true with a points or time board. false with friends_board true is a friends-only board, the right pick for a game meant to be played among friends. score_kind "none" turns both switches off whatever is sent.'}, 'screenshots': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional: up to 8 image paths inside the build.'}, 'friends_board': {'type': 'boolean', 'description': 'The friends leaderboard: the same scores, each signed-in player seeing only themself and their friends. Default true with a points or time board. Needs no game code: the one gameOver call feeds both boards.'}, 'voice_everyone': {'type': 'boolean', 'description': 'Voice chat with everyone in a match, not just friends. Default false: players hear only their friends (and everyone in a friends lobby), which is right for almost every game. true only when the creator asked for it, for a game built around talking to other players (proximity chat as a core mechanic, social deduction): then every signed-in player seated in a match can hear every other one, matched by the queue or not. Needs no game code; blocked players stay muted and nobody is on the mic until they join. Covers match rooms (the first ten players seated in each), not worlds.'}}}, 'players': {'type': 'integer', 'maximum': 10, 'minimum': 2}, 'uploadId': {'type': 'string'}, 'relationships': {'enum': ['friends', 'strangers'], 'type': 'string'}}, 'additionalProperties': False}
sync_remix
Brings the original's newest build into one of the creator's remixes, the way a branch is rebased on the branch it came from. Every remix records which build of its original it is based on; when the original ships a version, its creator is told and this tool (or the Bring in the update button on the remix's Manage page) does the merge: files the original changed that the remix left alone are taken, the remix's own changes stay, and the result ships as the remix's next minor version. Files both sides changed differently are conflicts: by default nothing changes and the reply lists them. Then either pass resolve "mine" (keep the remix's file for each conflict) or "theirs" (take the original's), or merge by hand: download the remix's build (GET /api/agent/download?slug=<remix>), the original's (…&build=parent) and, when it still exists, the base (…&build=base), three-way merge the conflicting files, upload the merged build like any update, and call update_game on the remix with `upstream` set to the original's build id from this reply (origin.upload_id), so the remix's base moves. Needs the creator's API key or sign-in.
幂等
输入模式
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': "The remix's slug: the last part of its URL, https://yougame.co/g/<slug>."}, 'apply': {'type': 'boolean', 'description': 'false to only report the plan (what would be taken, kept, dropped, and the conflicts) without shipping anything. Default true.'}, 'resolve': {'enum': ['stop', 'mine', 'theirs'], 'type': 'string', 'description': "What to do with files changed on both sides: stop (default: report them, change nothing), mine (keep the remix's), theirs (take the original's)."}}, 'additionalProperties': False}
test_report
Read this test session's backend observations and recorded browser evidence. Checks the uploaded build fingerprint and marks evidence stale if files changed. Backend counts do not prove correctness. Call before prepare_submission.
幂等
输入模式
{'type': 'object', 'required': ['sessionId'], 'properties': {'sessionId': {'type': 'string'}}, 'additionalProperties': False}
update_game
Ships a new build of a game the creator already published, as its next version: same link, same origin, scores and comments kept. Needs the creator's API key. Stage a local build folder with Node 22+: download https://yougame.co/upload-build.mjs, then run node upload-build.mjs <build-folder> with YOUGAME_UPLOAD_TOKEN (from upload_token) or YOUGAME_API_KEY set. It applies the website's path fixes locally and streams files through POST /api/upload/start, PUT /api/upload/file, and POST /api/upload/complete. The same limits as the website apply: 5 GB total, 100 MB per file, 5,000 files. Unzip archives locally first. The result includes uploadId, testUrl and the static check report; fix a broken verdict and upload again. The older /api/agent/upload ZIP route is only a small-build compatibility option. A ROM mod (kind "patch") is its one patch file (.ips, .ups, .bps or .xdelta) and no index.html: pass the file itself to the helper and it is staged as a package with no page to check; a cosmetic's folder is staged with --package (by hand, POST /api/upload/start with package: true beside files). Then call this tool (or POST the same fields to https://yougame.co/api/agent/update) with the game's slug (from my_games or its URL), the new uploadId, the kind of update, and patch notes. kind "major" (2.0) is for a big change: everyone who saved or liked the game is notified with the notes, and the home feed features the game for a week. kind "minor" (1.1) is for fixes and small changes: listed in the version history, nobody is pinged. Default to minor unless the creator says the update is big.
幂等
输入模式
{'type': 'object', 'required': ['slug', 'uploadId'], 'properties': {'kind': {'enum': ['major', 'minor'], 'type': 'string', 'description': 'major (big change, players are notified) or minor (fixes, silent). Default minor.'}, 'slug': {'type': 'string', 'description': "The game's slug: the last part of its URL, https://yougame.co/g/<slug>."}, 'notes': {'type': 'string', 'description': 'Patch notes, up to 2000 characters: what changed, for players. Shown on the game page and, for a major update, in the notification.'}, 'uploadId': {'type': 'string', 'description': 'The new build, from the upload reply (32 hex characters).'}, 'upstream': {'type': 'string', 'description': "For a remix whose build was merged by hand after sync_remix reported conflicts: the original's build id the merge took (origin.upload_id in that reply), recorded as the remix's new base."}, 'thumbnail': {'type': 'string', 'description': 'Optional: a new thumbnail, as a path inside the new build (16:9 PNG/JPG/WebP/GIF under 8 MB). Omit to keep the current one.'}, 'screenshots': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional: new screenshots, as paths inside the new build. Omit to keep the current ones.'}}, 'additionalProperties': False}
upload_token
Mints a short-lived bearer token for staging builds and media, without revealing the connection's sign-in token. It cannot publish. Stage a local build folder with Node 22+: download https://yougame.co/upload-build.mjs, then run node upload-build.mjs <build-folder> with YOUGAME_UPLOAD_TOKEN (from upload_token) or YOUGAME_API_KEY set. It applies the website's path fixes locally and streams files through POST /api/upload/start, PUT /api/upload/file, and POST /api/upload/complete. The same limits as the website apply: 5 GB total, 100 MB per file, 5,000 files. Unzip archives locally first. The result includes uploadId, testUrl and the static check report; fix a broken verdict and upload again. The older /api/agent/upload ZIP route is only a small-build compatibility option. A ROM mod (kind "patch") is its one patch file (.ips, .ups, .bps or .xdelta) and no index.html: pass the file itself to the helper and it is staged as a package with no page to check; a cosmetic's folder is staged with --package (by hand, POST /api/upload/start with package: true beside files).
输入模式
{'type': 'object', 'properties': {}, 'additionalProperties': False}
已更改
publish_game
2026年10月1日 02:43
已更改
prepare_submission
2026年10月1日 02:43
已更改
start_test_session
2026年10月1日 02:43
已更改
publish_game
2026年9月29日 02:50
已更改
prepare_submission
2026年9月29日 02:50
已更改
start_test_session
2026年9月29日 02:50
已更改
update_game
2026年9月27日 02:42
已更改
publish_game
2026年9月27日 02:42
已更改
prepare_submission
2026年9月27日 02:42
已更改
upload_token
2026年9月27日 02:42
已更改
start_test_session
2026年9月27日 02:42
已更改
update_game
2026年9月23日 02:41
已更改
publish_game
2026年9月23日 02:41
已更改
prepare_submission
2026年9月23日 02:41
已更改
upload_token
2026年9月23日 02:41
已更改
start_test_session
2026年9月23日 02:41
已更改
update_game
2026年9月21日 02:49
已更改
publish_game
2026年9月21日 02:49
已更改
prepare_submission
2026年9月21日 02:49
已更改
upload_token
2026年9月21日 02:49
已更改
start_test_session
2026年9月21日 02:49
已更改
publish_game
2026年9月19日 02:40
已更改
prepare_submission
2026年9月19日 02:40
已更改
start_test_session
2026年9月19日 02:40
已添加
my_games
2026年9月17日 12:38
已添加
sync_remix
2026年9月17日 12:38
已添加
remix_game
2026年9月17日 12:38
已添加
update_game
2026年9月17日 12:38
已添加
publish_game
2026年9月17日 12:38
已添加
prepare_submission
2026年9月17日 12:38