A generation is one published state of the modpack. It consists of a manifest describing every file, the content token that identifies the state, and the file bytes in the server's object store. Publishing is how changes reach players. How a pack is built follows one publish end to end, from the pack sources to the bytes a client downloads.
Publishing
/automodpack generate scans the pack sources described in building the modpack and computes a content token from the result. When the token matches the current generation, pack files did not change and the journal stays still. A changed waiting-music.ogg still rewrites the head document so the advertised track stays current. Otherwise the scan becomes a new generation, appended to the journal, and connecting clients receive it.
With generate-modpack-on-start on (the default), the server publishes on every start the same way: a generation appears when the content changed, and a changed waiting track is published even when the content token did not.
Patch notes travel with the generation. Pass them inline with generate notes <text...>, or write them to automodpack/host-modpack/patch-notes.md, which is read and cleared when a publish succeeds. A preview with generate preview shows the same diff a publish would produce, without publishing.
To caption a generation that already shipped, run /automodpack generate replace-notes (reads the same file) or /automodpack generate replace-notes <text...>. That replaces the live generation's notes only: the content token and journal sequence stay put, and a later publish freezes that line. Empty notes are refused. Auto-generate on start never does this, so a leftover file still waits for the next real generation.
generate if-content <content-token> publishes only while the pack still matches a token you name. A script that copies files and then publishes can therefore never publish a state it has not seen: if someone changed the pack in between, the command reports the mismatch instead of racing it.
The journal
The server keeps every published generation in an append-only journal at automodpack/server/journal.jsonl. Entries never disappear, so the full history of the pack, with patch notes, stays visible in generate history and restorable in principle.
generate revert <seq> previews a rollback; generate revert <seq> confirm publishes the old state as a new generation. Rolling back produces a forward entry in the journal, so the previous head is never rewritten.
generate storage collect confirm is the only deletion. It deletes the object bytes the current generation does not serve. It keeps every journal entry's policy document and any object another server process sharing the data root still pins. Older generations stay listed in the journal but can no longer be restored. The command prints exactly what it deleted.
Growth
The journal is append-only and grows forever by design. The ownership ledger inside each head document is cumulative, so the head document grows with every distinct content state the pack has ever had. Every join downloads the head document and the journal, so both travel to every client. generate storage collect confirm frees object bytes, not journal entries: the list of generations keeps its length either way.
What clients keep
Each generation's head document includes a cumulative ownership ledger: every historical hash and size each managed path ever had. Clients use it to prove that a local file belongs to the pack before deleting it, which is why client deletions are safe even after content moved around across many updates.