---
title: Ebitengine
url: 'https://wiki.teletypegames.org/platforms/ebitengine'
markdown: 'https://wiki.teletypegames.org/platforms/ebitengine.md'
lang: en
date: '2026-03-03'
description: 'Ebitengine (formerly Ebiten) is a fast and portable 2D game engine for Go. Website: https://ebitengine.org Projects built with this engine: Rabbit Roller Makefile Go compiles to a native binary or to WebAssembly. The web build needs three files: game.wasm, wasm_exec.js and index.html. Variables …'
taxonomy:
  tag:
    - howto
---

# Ebitengine

Ebitengine (formerly Ebiten) is a fast and portable 2D game engine for Go.

**Website:** https://ebitengine.org **Projects built with this engine:** [Rabbit Roller](https://wiki.teletypegames.org/projects/rabbitroller)

---

# Makefile

Go compiles to a native binary or to WebAssembly. The web build needs three files: `game.wasm`, `wasm_exec.js` and `index.html`.

## Variables

| Variable | Description | Default |
|---|---|---|
| `PROJECT` | Name used in output filenames | `ebitenginedemo` |
| `BIN_DIR` | Native executable | `bin` |
| `DIST_DIR` | WASM and packaged artifacts | `dist` |
| `WASM_NAME` | WebAssembly filename | `game.wasm` |
| `VERSION_FILE` | Version file for CI | `.version` |
| `INDEX_HTML_URL` | index.html template | ebitengine-tools repo |

## Targets

```sh
make build                   # go build -> bin/<PROJECT> for the current OS
make wasm                    # dist/game.wasm + wasm_exec.js
make export VERSION=1.0.0     # wasm + index.html zipped as ebitenginedemo-1.0.0.html.zip
make watch                   # rebuild the native binary on change in . (needs fswatch)
make clean                   # remove bin/ and dist/
```

## VS Code

Copy `example-tasks.json` to `.vscode/tasks.json` and replace `ebitenginedemo` with your `PROJECT`. Tasks: **Run** (default, `Cmd+Shift+B`), **Build & Run**, **Build WASM**, **Make build**.

## Generated artifacts

| File | Description |
|---|---|
| `bin/ebitenginedemo` | Native executable, current OS |
| `dist/game.wasm` | WebAssembly binary |
| `dist/wasm_exec.js` | Go WASM runtime helper |
| `ebitenginedemo-<version>.html.zip` | Web build (index.html + WASM + runtime) |

## Requirements

Local only: `make`, `go` 1.11+, `curl`, `zip`, and `fswatch` for watch mode. CI images bring their own tools.

---

# Pipeline

The pipeline is not in the game repo. Woodpecker asks the update server, and WarpEngine serves the whole config from `/build/config` (template `lib/warp_engine/ci/woodpecker/platforms/ebitengine/pipeline.yaml.erb`).

The repo needs three things:

```yaml
# .woodpecker.yaml
platform: ebitengine
```

- `metadata.json`
- the `application_token` Woodpecker secret: a WarpEngine ApplicationToken with `update` + `upload` scopes
- `name: <software>` in the marker only when the software name differs from the repo name

Builder images come from the update server's `ci_platforms` config. On teletypegames.org the builder is `ebitengine-ttg`: the `ebitengine-builder` image with the Go modules of every TTG Go project preloaded, so the build, binaries and test steps no longer download them (a new dependency is still downloaded as usual). The helper steps (version, upload, publish) run in the `ci-tools` image, which has git, jq, curl and zip preinstalled, so they install nothing. Preview the served pipeline:

```sh
curl "https://teletypegames.org/build/config?platform=ebitengine"
```

## Steps

| Step | What it does |
|---|---|
| 1. version | the engine's shared step (since WarpEngine 1.7): the version from `metadata.json`; on a tag a version tag has to match it; outside the repo's default branch and on a `dev-<branch>` tag `dev-<version>-<branch>`, with no version `dev-<commit>`; write `.version` |
| 2. build | `GOOS=js GOARCH=wasm`, add `wasm_exec.js` and `index.html`, zip them |
| 3. binaries | cross-compile `win-x86`, `win-x64`, `linux-x64`, one versioned zip each |
| 4. upload | **on the tag only:** copy `metadata.json` to its versioned name, then `POST /build/upload` with the `X-Update-Secret` header |
| 5. publish | **on the tag only:** `POST /build/publish?platform=ebitengine` |
| 6. tag | the engine's shared step (since WarpEngine 1.9), **after a push only**: a new version in the source gets its `v<version>` tag, whose pipeline runs the steps marked *on the tag only*; a version tagged already releases nothing; a dev build moves the branch's `dev-<branch>` tag onto the commit, so the newest dev build is published. See *Versions and releases* on the [WarpEngine](https://wiki.teletypegames.org/engines/warp-engine) page |

Raising the version is the release: a push builds and tags, and the tag's pipeline uploads and publishes (WarpEngine 1.9). A push that leaves the version as it is only builds.

## Result

A versioned web build plus Windows and Linux binaries, uploaded and published. The public game index updates itself.

'; var prevLevel = 2; for (var i = 0; i < headings.length; i++) { var h = headings\[i\]; var text = h.textContent.trim(); var slug = text.toLowerCase() .replace(/\[áàâä\]/g,'a').replace(/\[éèêë\]/g,'e').replace(/\[íìîï\]/g,'i') .replace(/\[óòôöő\]/g,'o').replace(/\[úùûüű\]/g,'u') .replace(/\[^a-z0-9\]+/g, '-').replace(/^-|-$/g, ''); if (!slug) slug = 'heading-' + i; if (used\[slug\]) { slug += '-' + i; } used\[slug\] = true; h.id = slug; var level = parseInt(h.tagName.charAt(1)); var cls = level > 2 ? ' class="toc-child"' : ''; html += '- [' + text + '](#'%20+%20slug%20+%20')
'; } html += '
'; toc.innerHTML = html; // Scroll-spy: highlight current heading var links = toc.querySelectorAll('a'); var ids = \[\]; for (var j = 0; j < links.length; j++) ids.push(links\[j\].getAttribute('href').slice(1)); function updateActive() { var current = ''; for (var k = 0; k < ids.length; k++) { var el = document.getElementById(ids\[k\]); if (el && el.getBoundingClientRect().top <= 80) current = ids\[k\]; } for (var m = 0; m < links.length; m++) { links\[m\].parentNode.classList.toggle('active', links\[m\].getAttribute('href') === '#' + current); } } window.addEventListener('scroll', updateActive, { passive: true }); updateActive(); })();

---

## Navigation

- Parent: [Platforms](https://wiki.teletypegames.org/platforms.md)
- Previous: [DOS](https://wiki.teletypegames.org/platforms/dos.md)
- Next: [Godot](https://wiki.teletypegames.org/platforms/godot.md)
- Children:
  - [Steam publication plan](https://wiki.teletypegames.org/platforms/ebitengine/steam-publication-plan.md)
