Skip to main content
A Turntable game is one HTML document. Here’s a complete, valid one:
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style>
  body { margin: 0; height: 100vh; display: flex; flex-direction: column;
         align-items: center; justify-content: center; gap: 16px;
         background: #101018; color: #fff;
         font-family: -apple-system, system-ui, sans-serif;
         -webkit-user-select: none; user-select: none; }
  #tap { width: 200px; height: 200px; border-radius: 50%; border: 0;
         background: #FFD400; color: #333; font-size: 28px; font-weight: 700; }
</style>
</head>
<body>
<div id="info">Tap fast — 5 seconds!</div>
<button id="tap">GO</button>
<script>
var n = 0, timer = null, best = 0;
var tap = document.getElementById('tap'), info = document.getElementById('info');
Turntable.loadState().then(function (s) {
  if (s && s.best) { best = s.best; info.textContent = 'Best: ' + best + ' — tap to start'; }
});
tap.onclick = function () {
  if (!timer) { n = 0; timer = setTimeout(end, 5000); }
  tap.textContent = ++n;
};
function end() {
  timer = null;
  if (n > best) { best = n; Turntable.saveState({ best: best }); }
  Turntable.submitScore(n);
  info.textContent = 'Score: ' + n + ' · Best: ' + best;
  tap.textContent = 'GO';
}
</script>
</body>
</html>
Three SDK calls and it’s a real platform citizen: the score lands in the player’s stats and the feed UI, and the best score survives forever — even if the player was a guest who signs up later.

The rules that matter

  1. Self-contained: all CSS/JS inline, no external resources or network calls. The game document contract has the full list.
  2. Never define window.Turntable — the platform injects it before your code runs.
  3. Legible in 2 seconds: one-line on-screen instruction, no menus.
  4. Short rounds (5–60s), instantly restartable.

Publishing

Today, games are published through the Turntable app’s AI generator. Direct publishing for external developers and agents (publish_game via the MCP server and REST API) is on the roadmap — the contract you build against is identical.