# 2. itch.io Pages and butler
Part of [[Publishing to itch.io and Steam]]. Prev: [[1. Artifacts and a Non-Commercial Policy]]. Next: [[3. Steam Apps Depots and SteamPipe]].
Official tool: **butler**, itch.io's command-line uploader. Manual: [https://itch.io/docs/butler/](https://itch.io/docs/butler/). Confirm install steps and flags on that page if a year has passed - do not trust a remembered installer URL.
## 2.1 Page first, push second
1. Log in at itch.io and create a **new project** (creator dashboard).
2. Set the **URL slug**. butler addresses the project as `user/game`, all lower case (official example shape: `finji/overland` for that studio's page).
3. Kind of project: **Downloadable** for this series. HTML5 / "playable in the browser" is a later queue item - see the short pointer in 2.6.
4. Visibility can start as **draft** or restricted until a successful push and a self-download work.
5. Write a short description, attach a screenshot if you have one, and state the engine and OS. You can also drag a zip into the dashboard; butler is better for class CI because it is scriptable and incremental.
## 2.2 Install and login
Install butler as the official [installing](https://itch.io/docs/butler/installing.html) page describes for your OS. Then log in with the documented command (`butler login`, or the equivalent on the current page). The credential stays in your **user profile**, not in the repo, not in a screenshot in Discord, not in a GitHub Actions YAML file.
If CI will push, store the key as a **repository secret** ([[3. GameCI and GitHub Actions]]). A failed Unity build must not run butler on a half-written folder.
## 2.3 Push a channel
Official shape, from the butler [pushing](https://itch.io/docs/butler/pushing.html) page (fetched 2026-11-10):
```bash
butler push directory user/game:channel
```
`directory` may also be a `.zip`. A concrete classroom example:
```bash
butler push dist/windows-0.1.0 yourname/classroom-arena:windows --userversion 0.1.0
```
### Channels
A **channel** is a slot on the project (`windows`, `linux`, `osx`, `windows-beta`, …). Official rules worth teaching:
- The **name has meaning**. If it contains `win` or `windows`, itch tags it as a Windows executable; `linux` → Linux; `mac` or `osx` → Mac; `android` → Android. You can fix tags later on the Edit game page (and you must click **Save**).
- Convention: lower-case, dashes (`kebab-case`). Official examples include `windows-beta`, `osx-bonus`, `linux-universal`.
- A second platform is a **second push** to a second channel, not an overwrite of `windows` with a macOS folder.
- Pushing to a **new** channel makes a corresponding file appear on the page (once processed / unhidden).
- Official limit at the time of writing: the backend rejects builds whose total **uncompressed** size exceeds 30 GB. A class vertical slice will not hit this; a careless upload of `Library` might look like it is trying.
### Version numbers
By default itch assigns a rising integer per channel. If you already have a Player Settings version, pass it:
```bash
butler push dist/windows-0.1.0 yourname/classroom-arena:windows --userversion 0.1.0
```
Or read a single-line UTF-8 (no BOM) file:
```bash
butler push dist/windows-0.1.0 yourname/classroom-arena:windows --userversion-file buildnumber.txt
```
Official note: user versions have **no required format**; itch orders builds by **upload time**, not by parsing `0.1.0` as semver.
### Hidden first push
```bash
butler push dist/windows-0.1.0 yourname/classroom-arena:windows --userversion 0.1.0 --hidden
```
Official behavior (2026-11-10 pushing page): `--hidden` only applies when the push **creates a new channel**. The upload stays off the public page until you unhide it in Edit game. Pushing `--hidden` onto an **existing** channel errors - itch does not currently support hidden patches on top of a live channel. For a classroom, the first push to a new draft project can use `--hidden`, or you can leave the whole **game** draft.
### Preview before you push
```bash
butler push-preview dist/windows-0.1.0 yourname/classroom-arena:windows
butler push dist/windows-0.1.0 yourname/classroom-arena:windows --dry-run
```
Official distinction: `--dry-run` lists files that would be sent. `push-preview` authenticates, diffs against the previous build, and classifies `NEW` / `MODIFIED` / `DELETED` / `SAME`. `--changes-only` hides unchanged entries. Use a preview on CI if you want a log of what is about to go public.
### Ignore, zip-in-zip, and "if changed"
The official page recommends pushing a folder that is **exactly** the release player. `--ignore '*.pdb'` exists (two dashes; pattern rules on that page) if you cannot scrub debug files first. If the directory contains **exactly one** `.zip` and nothing else, butler **unpacks** it by default so you do not ship a zip-in-a-zip; `--no-auto-unzip` turns that off. `--if-changed` skips a push when the disk contents match the latest build - useful in multi-channel CI, easy to misuse if you wanted a consistent version number on every platform even when one OS did not change.
After a push, `butler status yourname/classroom-arena` (or the status command on the current docs) should show the channel. Incremental pushes only upload a patch; the first push still takes longer.
## 2.4 You must download your own build
Open the page incognito (or a second machine), download, unzip if needed, and run the player **outside** the Editor. If you cannot download it, visibility, channel tags, or `--hidden` are wrong - fix that before Steam.
## 2.5 CI sketch
A GameCI / GitHub Actions job, after a green Windows Build Profile:
1. Download the artifact to a known folder.
2. Confirm the exe exists (fail the job if not).
3. Run butler with the key from a secret, the same `--userversion` as Player Settings, and the `windows` channel.
4. Do not push from a failed or cancelled Editor build.
## 2.6 HTML5 pointer only
Official butler note: tagging a channel as **HTML5 / Playable in browser** is done from the **Edit game** page after the first build is pushed, and the project kind must be set to **HTML** rather than Downloadable. That is the entire pointer. Player settings, memory, and a WebGL Build Profile belong to the later **Web / WebGL Builds** queue item. Do not treat a desktop `windows` channel as a web build.
## 2.7 Exercise
Push a **draft** or `--hidden` Windows channel of the vertical slice to *your* itch account with `--userversion` set. `push-preview` once. Download and run. Attach the butler log and a screenshot of the running downloaded build to the assignment.
## Sources
- butler manual: https://itch.io/docs/butler/
- Installing: https://itch.io/docs/butler/installing.html
- Pushing (channels, `--userversion`, `--hidden`, `push-preview`): https://itch.io/docs/butler/pushing.html
- [[3. GameCI and GitHub Actions]]