← Back

Publish your AI-made HTML game

FOR CREATORS

Made a game with ChatGPT, Claude or Claude Code?
Now give it a home.

Just upload one HTML file. It's free to publish and free to play. You'll need to log in to publish, but players don't. When 10, 50, 100… people have played your game, you'll get a notification.

  1. 1

    Have an AI make your gameJust paste in the prompt below

  2. 2

    Upload one HTML filePick a file, or paste the code

  3. 3

    Goes live in the feed after reviewPlayers find it as they swipe

Video walkthrough (4:33)

One unedited real run, from copying the prompt to going live on the feed. Narration is in Japanese, but every step is shown on screen.

Technical requirements

  • A single self-contained HTML file is the default. Put the CSS and JavaScript inside that same file. Games with many images or sounds can also be uploaded as a zip of the game folder (index.html plus its assets): the upload screen packs it into one HTML file, and the game reads the files in the zip without going online.
  • The finished game may be up to 5 MB (for a zip, after it is packed into one HTML file; allowed CDN libraries count after they are inlined). Images and sounds grow about 1.33x when packed. The zip file itself can be up to 25 MB, and HTML sent from older versions of the app is limited to 1 MB.
  • Only the allowed CDN libraries below may be loaded externally (in a zip, you can also include library files and load them with a relative path). Plain JavaScript is recommended by default.
    • https://cdn.tailwindcss.com/
    • https://cdnjs.cloudflare.com/ajax/libs/matter-js/
    • https://cdnjs.cloudflare.com/ajax/libs/three.js/
    • https://cdnjs.cloudflare.com/ajax/libs/howler/
    • https://cdnjs.cloudflare.com/ajax/libs/phaser/
  • Runs in <iframe sandbox="allow-scripts"> (an opaque origin) with a strict CSP, so network access (fetch and the like), eval, and document.cookie do not work (a zip game's fetch of the files in its zip does work). localStorage is replaced with a memory-only polyfill that empties on every reload — never use it for high scores or save data. Navigating away or opening links (window.open / location) is blocked too — express it as an in-game screen change.
  • Must follow the real screen aspect ratio, never a fixed one — a fixed ratio letterboxes or gets cut off on other devices. The game's frame changes shape from device to device, but it is portrait on phones and on portrait tablets alike. Make everything fit at width 4 : height 5 (for example, 800 wide × 1000 tall), and on taller screens (phones) let the layout spread into the extra height.
  • If your game ends (game over, clear, time up and so on), always call parent.postMessage({ type: 'gameOver', score }, '*') when it ends. Put a number in score if the game has a score; if it has none, send it without score (without a score, the result screen appears without a ranking). That call is also the cue to move to the result screen: PUNIPO starts watching the game the moment it arrives and lays the result over it once the picture stops moving (1.5 seconds at most). If you want an ending animation — an explosion, a collapse — play it out first, then make the call. After the call, stop drawing, background animation and blinking text included: if the picture keeps moving, PUNIPO cannot tell the ending is over and the player waits out the full 1.5 seconds. Only games that never end (a simulator you can keep playing, for example) don't call it: they never move to the result screen and keep running until the player swipes to the next card. Play counts are recorded either way.

How to publish

  1. Open /create
  2. Pick an HTML or zip file, or paste code
  3. On the check screen, see how it looks on a phone and read the warnings (fix any ✕ items first)
  4. Enter a name and description
  5. Submit it
  6. It goes live in the feed after review

Prompt for your AI assistant

This covers the technical requirements above. Paste it into an AI chat as-is to generate a game.

Build a single HTML5 mini game for PUNIPO (https://punipo.com). Follow every rule below.

- Everything must be in one self-contained HTML file: CSS and JavaScript both go inside that same file. Do not load anything external, except optionally one of these approved CDN libraries if you need it: https://cdn.tailwindcss.com/, https://cdnjs.cloudflare.com/ajax/libs/matter-js/, https://cdnjs.cloudflare.com/ajax/libs/three.js/, https://cdnjs.cloudflare.com/ajax/libs/howler/, https://cdnjs.cloudflare.com/ajax/libs/phaser/. Plain JavaScript with no library at all is preferred.
- Keep the finished file under 1 MB (it may grow up to 5 MB once an allowed CDN library is inlined).
- Make it playable on a phone with a finger alone: taps and swipes, never keyboard-only controls.
- The game runs inside a sandboxed iframe under a strict CSP: fetch, XMLHttpRequest, eval, and document.cookie do not work. localStorage is replaced with a memory-only polyfill that empties on every reload — never use it for high scores or save data.
- Do not navigate away or open links (window.open, location): the frame is blocked from leaving the game. Even to show a reference page, keep every screen change inside the game.
- Never fix the screen to specific pixels or a fixed aspect ratio. Read the real width and height of the screen and adapt to it, so nothing letterboxes or gets cut off on tall or wide screens. Make everything fit in a portrait shape of width 4 : height 5 (for example, 800 wide × 1000 tall), and on taller screens (phones) let the layout spread into the extra height.
- If the game ends (game over, clear, time up and so on), always call parent.postMessage({ type: 'gameOver', score }, '*') when it ends. Put a numeric score in score if the game has one; if it has no score, call it without score. The result screen is laid over the game right after that call, so if the game has a game-over animation, play it out first and call this afterwards. Once it is called, stop drawing (background animation and blinking text included): a picture that keeps moving delays the result screen. For a game that never ends (a simulator you can keep playing, for example), don't call it: the game then never moves to the result screen and keeps running until the player swipes to the next card.

When it is done, publish it at https://punipo.com/create.

Common mistakes

  • A fixed aspect ratio that letterboxes on tall phones.
  • Computing the coordinates of adjacent UI elements independently, so they overlap at certain ratios (derive one from the other's measured size instead).
  • Trying to fetch data from another site — the CSP blocks all network access (put the data in the HTML, or in the zip).
  • Sending a single HTML file that loads other files (game.js, style.css, images). If the game is split into several files, zip the whole folder and send that.
  • Making a game that only works with a keyboard (phones have none — make it playable with taps and swipes).
  • Adding a link or navigation that opens an external site (window.open / location are blocked — express it as an in-game screen change).
  • A game that ends on game over or clear but never sends the end-of-game report (gameOver), so no result screen appears.

Next steps

When you're ready, submit your game from /create. Common questions are answered in the FAQ.