Login

Ebitengine

Ebitengine (formerly Ebiten) is a simple and efficient 2D game engine for Go. It focuses on performance, portability, and ease of use, making it suitable for both prototypes and production-ready games.

Website: https://ebitengine.org


Makefile

This Makefile provides a simple, reproducible workflow for building Ebitengine Go projects for both native desktop and WebAssembly (WASM) targets. It is designed for indie game development with automated version management and CI/CD deployment support.

Overview

The workflow is based on four core ideas:

  • Go source code is compiled to native binaries or WebAssembly (WASM)
  • Version management is handled automatically from metadata.json or git commit hash
  • WASM exports include all necessary runtime files (wasm_exec.js, index.html)
  • CI/CD targets enable automated build, versioning, and deployment

This approach keeps the build process simple while supporting both desktop and web platforms.

Configuration Variables

Variable Description Default
PROJECT Project name (used in output filenames) ebitenginedemo
BIN_DIR Directory for native executable bin
DIST_DIR Directory for WASM and packaged artifacts dist
WASM_NAME WebAssembly filename game.wasm
VERSION_FILE File storing version for CI/CD .version
INDEX_HTML_URL URL to download index.html template Remote ebitengine-tools repo

Usage

Build (default)

SH
make build
  • Compiles Go source code to native executable
  • Creates bin/ebitenginedemo (or bin/<PROJECT> if PROJECT is changed)
  • Uses standard go build with current platform (Linux, macOS, Windows)

Build WebAssembly (WASM)

SH
make wasm
  • Compiles Go source to WebAssembly (dist/game.wasm)
  • Copies Go runtime helper file (wasm_exec.js) to dist/
  • Requires Go 1.11+

Export

SH
make export VERSION=1.0.0
  • Requires a VERSION variable.
  • Builds WebAssembly if not already built (runs make wasm)
  • Downloads index.html template from remote repository
  • Packages all WASM files into a single ZIP archive:
    • game.wasm
    • wasm_exec.js
    • index.html
  • Creates versioned output: ebitenginedemo-1.0.0.html.zip
  • Cleans up temporary files after packaging

Watch Mode

SH
make watch
  • Watches the project directory for changes
  • Automatically rebuilds (native binary) on any file change
  • Requires fswatch to be installed
  • Only watches current directory (.)

Clean

SH
make clean
  • Removes generated build artifacts:
    • bin/ directory (native executable)
    • dist/ directory (WASM, runtime, packaged files)

CI/CD Targets

make ci-version

  • Extracts version from metadata.json (if exists) or uses git short commit hash
  • Checks the current git branch
  • If the branch is not main or master, prefixes version as dev-<version>-<branch>
  • Writes the final version to .version file for use in subsequent CI steps

Example outputs:

  • Main branch: 1.0.0
  • Development branch: dev-1.0.0-feature-branch

make ci-export

  • Reads version from .version file
  • Runs make export with the stored VERSION
  • Generates versioned HTML/WASM package

make ci-upload

  • Reads version from .version file
  • Copies metadata.json to ebitenginedemo-<version>.metadata.json
  • Uploads both files via SCP to remote server
  • Requires environment variables:
    • DROPAREA_SSH_PASSWORD - SSH password
    • DROPAREA_PORT - SSH port
    • DROPAREA_USER - SSH username
    • DROPAREA_HOST - Server hostname
    • DROPAREA_TARGET_PATH - Target directory on server

make ci-update

  • Reads version from .version file
  • Sends HTTP request to update server with:
    • Project name: ebitengine
    • Platform: ebitengine
    • Version: from .version
  • Requires environment variables:
    • UPDATE_SERVER - Update server URL
    • UPDATE_SECRET - Authentication secret

Generated Artifacts

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

Requirements

  • make
  • go (1.11+)
  • curl (for downloading index.html)
  • zip (for packaging exports)
  • fswatch (only for watch mode)
  • sshpass and scp (for ci-upload target)
  • jq (for parsing metadata.json in ci-version)
  • git (for version fallback and branch detection in ci-version)

Pipeline

This document describes the Woodpecker CI pipeline used to build, export, upload, and publish an Ebitengine game project.

Overview

The pipeline logic is almost entirely encapsulated within a Makefile, which is called by each pipeline step. This approach simplifies the CI configuration and keeps the build logic centralized.

The pipeline performs the following steps:

  1. Version Extraction: Extracts the game version from metadata.json or git commit hash.
  2. Build & Export: Compiles the game to WebAssembly and packages it with all runtime files.
  3. Upload Artifacts: Uploads the generated artifacts to a remote server.
  4. Notify Update Server: Triggers a remote service to publish the new version.

Each step corresponds to a make ci-* target.

Step 1: Version Extraction

YAML
- name: version
  image: alpine
  commands:
    - 'apk add --no-cache make git jq'
    - 'make ci-version'

What it does:

  • Uses a minimal Alpine Linux image.
  • Installs make, git, and jq for processing JSON.
  • Runs make ci-version, which:
    • Reads the version from metadata.json (if exists) or falls back to git short commit hash.
    • Checks the current branch.
    • If on a development branch (not main or master), prefixes the version as dev-<version>-<branch>.
    • Saves the final version to .version file for subsequent steps to use.

Step 2: Build & Export

YAML
- name: build
  image: golang:1.21
  environment:
    GOFLAGS: -mod=readonly
  commands:
    - 'apt-get update && apt-get install -y make curl zip'
    - 'make ci-export'

What it does:

  • Uses an official Go image (1.21 or later).
  • Installs make, curl, and zip for packaging.
  • Runs make ci-export, which:
    • Reads the version from the .version file.
    • Compiles the Go source to WebAssembly (GOOS=js GOARCH=wasm).
    • Copies the Go WASM runtime helper (wasm_exec.js) to the output directory.
    • Downloads the index.html template from the remote ebitengine-tools repository.
    • Packages all files (WASM, runtime, HTML) into a single ZIP: ebitenginedemo-<version>.html.zip.

Step 3: Artifact Upload

YAML
- name: artifact
  image: alpine
  environment:
    DROPAREA_HOST: vps.teletype.hu
    DROPAREA_PORT: 2223
    DROPAREA_TARGET_PATH: /home/drop
    DROPAREA_USER: drop
    DROPAREA_SSH_PASSWORD:
      from_secret: droparea_ssh_password
  commands:
    - 'apk add --no-cache make openssh-client sshpass'
    - 'make ci-upload'

What it does:

  • Installs make and SSH tooling (openssh-client, sshpass).
  • Runs make ci-upload, which:
    • Reads the version from the .version file.
    • Copies metadata.json to ebitenginedemo-<version>.metadata.json.
    • Uploads both the .html.zip and .metadata.json files to a remote server using scp.
    • Uses environment variables for SSH credentials (stored as secrets).

Step 4: Update Notification

YAML
- name: update
  image: alpine
  environment:
    UPDATE_SERVER: https://games.vps.teletype.hu
    UPDATE_SECRET:
      from_secret: update_secret_key
  commands:
    - 'apk add --no-cache make curl'
    - 'make ci-update'

What it does:

  • Installs make and curl.
  • Runs make ci-update, which:
    • Reads the version from the .version file.
    • Sends an HTTP request to the update server with query parameters:
    • secret - Authorization token
    • name - Project name (ebitenginedemo)
    • platform - Platform identifier (ebitengine)
    • version - Version from .version file
    • This notifies the server that a new build is available for publishing.

Example request:

TXT
https://games.vps.teletype.hu/update?secret=<SECRET>&name=ebitenginedemo&platform=ebitengine&version=1.0.0

Result

After a successful run:

  • The game is compiled to WebAssembly with a version derived from its metadata or source control.
  • All runtime files are packaged into a single, deployable ZIP archive.
  • Artifacts are uploaded to the server.
  • The public game index is updated automatically.

This pipeline enables fully automated Ebitengine releases where the entire build and release logic is managed by the project's Makefile.

Example file

https://git.teletype.hu/tools/ebitengine-tools/src/branch/master/example-woodpecker.yaml