Zaytun Project

Releases

What changed in each version, and what a game written or compiled against an older one needs before it will run on this one. The current release is 1.1.0.

The changelogs in the repositories are the complete record and run to a few thousand lines each, written for somebody who has the previous version in front of them. This page is the short version, written for somebody deciding whether to care: the zaytunc changelog, the zaytunplay changelog and the zaytun-web-player changelog.

1.1.0 — 21 September 2026

Bytecode format 16 · eight platform builds, up from seven · download it

A large release. The language gained vehicles — things the player sits in, and hulls with rooms of their own that the player steers — regions, a while loop, and about thirty smaller additions. The guide moved out and became the handbook, a site of its own. Both players learned to read more of what a player actually types.

Before you upgrade

Three things need a hand, and one of them happens without a word said.

  1. Recompile every game. The bytecode format moved from 15 to 16 and a player refuses an older file rather than misreading it, so a .zaytunb built by 1.0.0 will not play. Keep the .zaytun source and one command does it — that is what the version number promises.
  2. turns: false is now status { turns: false }. The old spelling is refused rather than ignored, and the compiler names the replacement. It is one line, and nothing else about the game moves.
  3. / keeps a fraction now when it is given one. In 1.0.0 every division truncated: 7.5 / 2 was 3. Now a real on either side keeps the fraction, so that is 3.75, while two whole numbers still divide as whole numbers and 3 / 2 is still 1. A game that divided whole numbers is unaffected; a game that divided reals gets a different answer and gets it silently, which is the one change here worth reading your own source for.

Vehicles, and hulls you steer

A room is where the player is. A vehicle is a thing standing in a room that the player can be inside — a car, a cart, a horse — and it moves when the room it is in changes. A vehicle can also have rooms of its own, and then it is a hull: a ship with a deck and a hold, steered from whichever room controls: names, where STEER north takes the ship and GO north takes the person walking about inside her. A room of a hull can see out of her and reach out of her, so the deck sees the harbour.

Vehicles hold people and creatures as well as things, and both can be put aboard while the game runs. Two conditions decide what a vehicle shows: sealed if hides the room and keeps the vehicle, and bare if — added last in this release — does the reverse, for the cart with nothing to say about itself whose rider wants to see the field they are crossing.

A cart that stops describing itself once the tarpaulin is off.
flag tarpaulin_off = false

room lane "The Lane" {
  description: "Hedges, and the smell of somebody's fire."
  vehicle dray "The Dray" {
    description: "Straw, and a plank to sit on."
    bare if tarpaulin_off
  }
}
Boarding it with the tarpaulin off: the whole INSIDE block goes, and the label saying what you are sitting in stays.
> enter dray

OUTSIDE The Dray
The Lane
Hedges, and the smell of somebody's fire.
Exits: north.

Regions

A region is the larger area several rooms belong to, with its own on enter, on exit and on turn — one place to write the weather of a forest rather than repeating it in every clearing. regionof(<room>) asks which region any room belongs to.

The language grew

while loops, with a step budget at the interpreter rather than a cap on repeat; break and continue; sqrt and a pow that takes any exponent; sort <flag> as shuffle's mirror; random() as a fraction; elapsed for the player's own seconds; padleft and padright; isint; roomof, exitto, roomtitle and maxehp; examine: on a person; pass to spend a turn and reset turn to put the count back to nought for a story that starts again; a verb a game declares now owns its word; and a set that reaches as many subscripts deep as the value goes.

The compiler also started warning. Every diagnostic it had was fatal, and some mistakes are not worth stopping for — a field given true where text is expected being the first of them. It now refuses a source file that is not valid UTF-8, and says which byte.

Both players read more of what you type

A direction can carry an article and a preposition in front of it, a topic can be asked about when its keyword carries its own article, and a name with a preposition inside it can be typed at all. TAKE looks at the floor and names the container a thing is in rather than claiming the thing is absent, and EXAMINE reaches a person. In the terminal, TAB completes a command or the name of anything you can see.

Fixes worth naming

An eighth build

FreeBSD on 64-bit ARM joined the seven platforms 0.9.0 shipped, so make cross now names eight targets. It and the two Linux ARM builds were tested on a Raspberry Pi; the downloads page says what was run where.


1.0.0 — 19 August 2026

Bytecode format 15, and it still reads format 14

The first release to call itself one. Subjects can advertise themselves — topic "x" suggest marks a subject the TOPICS command will list, while a topic without it still answers and stays worth guessing. A cast can be declared at top level the way a bestiary is, and placed by whichever room it starts in, with spawn and remove for putting a person into a story and taking them out again. turns: false arrived, asking for no move counter. The compiler grew --version, reporting both numbers, and --help.

The guide gained the three things every parser defect in this project had hidden behind: the player's command language, the expression grammar, and the bytecode layout.

Upgrading from 0.9.0 needed nothing. Format 15 appends its new fields after the old ones, so a format 14 layout stays a prefix of a format 15 one, and this release reads both. That is the contrast with 1.1.0, where the shape of a record moved and a prefix was no longer a prefix.


0.9.0 — 17 August 2026

Bytecode format 14 · seven platform builds

The first release: the language, the compiler, and seven platform builds. Four formats came and went inside it — 11 brought dark if, rooms that hide what is in them until lit; 12 brought aliases:, so talk luthien finds Lúthien; 13 brought proc and do, on search as a handler of its own, and a way for an author's verb to tell that the player named a person rather than a thing; and 14 brought the capability word, computed from what a game actually contains, so HELP offers only commands that can do something.

An undeclared flag became a compile error rather than reading as false and carrying on, and include cycles were reported rather than silently ignored.


What the two version numbers promise

There are two numbers and they mean different things. The release version is 1.1.0. The bytecode format is 16, and it is the one that decides whether a player can read a game; zaytunc --version reports both, and so does zaytunplay --version.

The promise is made about source, not about compiled files: a .zaytun file goes on compiling, and a .zaytunb file is a build artefact that a new player may refuse. Keep the source. The handbook's Versions and compatibility has the whole of the reasoning, including the two narrow places where the source promise is not unconditional.