Download
πŸͺ Developer Guidelines

Build bite-sized games the whole jar can't put down.

Ship an HTML5 or Godot game, wire up two tiny hooks, and you're live in the feed β€” and in tournaments β€” in seconds. Here's everything you need. πŸš€

QuickstartπŸ† Tournaments

Two ways into the jar

HTML5 games

A single folder with an index.html. Canvas, Phaser, PixiJS, Three.js β€” if it runs in a mobile browser, it runs here.

Godot games

Export your Godot 4 project to HTML5, drop in the same folder, and talk to CookieJar through the JavaScript bridge.

Quickstart

From zero to playable in 4 steps

  1. 1

    Create your game folder

    Every game lives in its own folder. The folder name becomes the game id and its URL.

    folder structure
    public/
    └── games/
        └── my-game/          ←  the folder name IS your game id
            β”œβ”€β”€ index.html    ←  entry point (required)
            β”œβ”€β”€ game.js       ←  (optional) your code
            └── assets/       ←  (optional) images, audio, fonts
    
    # Live at:  games.thecookiejar.app/my-game
  2. 2

    Add the CookieJar bridge

    Pause when the player swipes away, resume when they come back. Paste this once into your game.

    cookiejar-bridge.js
    // Pause when the player swipes away, resume on return.
    let paused = false;
    
    // From the native WebView shell (postMessage)
    window.addEventListener('message', (e) => {
      if (!e.data?.cookiejar) return;
      if (e.data.cookiejar === 'pause')  paused = true;   // game.pause()
      if (e.data.cookiejar === 'resume') paused = false;  // game.resume()
    });
    
    // From the in-browser inject (custom events)
    window.addEventListener('cookiejar:pause',  () => { paused = true; });
    window.addEventListener('cookiejar:resume', () => { paused = false; });
  3. 3

    Report your score

    Call gameOver(score) the instant a run ends so it counts toward tournaments.

    report-score.js
    // Call ONCE per run, the moment the run ends (game over / out of lives).
    function reportScore(score) {
      score = Math.max(0, Math.floor(Number(score) || 0)); // clean integer
    
      if (window.CookieJar?.gameOver) {
        window.CookieJar.gameOver(score);        // preferred
      } else if (window.CookieJar?.submitScore) {
        window.CookieJar.submitScore(score);     // fallback
      }
      // No CookieJar object? You're running outside the app β€” that's fine,
      // your game still works standalone in the browser.
    }
    
    function endGame() {
      // ...show your game-over screen...
      reportScore(currentScore);
    }
  4. 4

    Submit & publish

    Send us your game folder. Once it's in, it's instantly live at games.thecookiejar.app/your-game-id and starts surfacing in the feed. πŸŽ‰

The CookieJar bridge

The bridge is how your game and the app talk. It's two small contracts β€” and both are optional safety nets, so your game always works on its own too.

⏸️ Pause & resume

CookieJar tells your game when it scrolls in and out of view. Listen for both the message and cookiejar:pause / cookiejar:resume events so you behave in the native app and the browser.

🎯 Score reporting

Call window.CookieJar.gameOver(score) exactly once per run. Always guard the call (window.CookieJar?.gameOver) and send a clean non-negative integer.

Tournaments

Make your game competitive

Tournaments turn any game into a leaderboard race. You don't build the leaderboard β€” CookieJar does. You just report an honest score and the platform handles ranking, timing, and prizes.

1️⃣

Run ends

Player loses, runs out of lives, or finishes a round.

2️⃣

You report

Your game calls gameOver(score) once, with a single integer.

3️⃣

We rank

CookieJar logs it against the live tournament and updates the board.

tournament-score.js
// Call ONCE per run, the moment the run ends (game over / out of lives).
function reportScore(score) {
  score = Math.max(0, Math.floor(Number(score) || 0)); // clean integer

  if (window.CookieJar?.gameOver) {
    window.CookieJar.gameOver(score);        // preferred
  } else if (window.CookieJar?.submitScore) {
    window.CookieJar.submitScore(score);     // fallback
  }
  // No CookieJar object? You're running outside the app β€” that's fine,
  // your game still works standalone in the browser.
}

function endGame() {
  // ...show your game-over screen...
  reportScore(currentScore);
}

⚠️ Fair play: send the score only when the run is genuinely over, never mid-run, and never more than once. Clamp negatives to zero and round to a whole number so every board stays clean.

Godot

Shipping a Godot game

Export your project to HTML5 (Project β†’ Export β†’ Web), then reach the bridge through JavaScriptBridge β€” Godot's window into the page's JavaScript.

cookiejar.gd
# Godot 4 β€” call the JS bridge from GDScript after exporting to HTML5.
func _report_score(score: int) -> void:
    if OS.has_feature("web"):
        JavaScriptBridge.eval("""
            (function(s){
              if (window.CookieJar && window.CookieJar.gameOver)
                window.CookieJar.gameOver(Math.max(0, Math.floor(s)));
            })(%d);
        """ % score)

# Pause / resume β€” listen for CookieJar events and toggle the tree.
func _ready() -> void:
    if OS.has_feature("web"):
        var cb := JavaScriptBridge.create_callback(_on_cookiejar)
        JavaScriptBridge.eval("window.__cjPause = null;")
        # bind cb to window events in your HTML shell, then:
    pass

func _on_cookiejar(args) -> void:
    get_tree().paused = (args[0] == "pause")

Tip: wrap every bridge call in OS.has_feature("web") so your desktop test builds don't choke on the missing browser APIs.

What makes a great jar game

πŸ“±

Portrait & touch-first

Design for a tall mobile viewport and one-handed play. Scale your canvas to the screen and support touch.

⚑

Instant to start

Bite-sized means fast. Keep the folder light, lazy-load heavy assets, and get to the first frame quickly.

πŸ”

Endless replay

Quick runs that beg for 'one more go'. A clear score and a fast restart loop keep players in the feed.

🧱

Self-contained

Everything in one folder with relative paths. No external build server, no cross-origin dependencies.

Ready to drop your game in the jar?

Send us your game folder and we'll get it live in the feed. Got a question first? We're happy to help.

Submit a gameAsk a question

Developer FAQ

The questions we get most from game makers.

Still stuck? Email us