Start a whole game from one adventure zip: RollQuest checks the zip, shows you what it will build, and sets up every scene for you.

For: Game Masters · Plan: Pro · 39 minutes

An adventure zip is a single file that holds an adventure ready for the table: its maps, token pictures, music and sounds, and a description of how they fit together, such as where each wall, door and light goes and which creatures wait, hidden, in each room. Importing it saves you building each scene by hand. You might get a zip from a creator who makes adventures for RollQuest, make one with your own tools, or write one by hand: the second half of this page, How an adventure zip is built, describes the format in full.

Plan: importing an adventure is on Pro. On Free and Starter you can see Import Adventure, but choosing a zip opens a window explaining the feature instead.

Import an adventure

  1. On your dashboard, click New Game. Or, in a game, open the menu (three lines, top left) and click Create Game. The Create New Game window opens.
  2. Click Import Adventure, the third button under the description.
  3. Click Choose an adventure .zip and pick the zip on your computer.
  4. Wait while it uploads (Uploading…, with a percentage) and then while RollQuest checks it (Checking your adventure…). A big adventure can take a minute or two.
  5. Read the report. It lists each scene with what it holds, then the playlists, tracks, sounds and journal notes. Anything you should know is listed under it; anything that stops the import is listed in red under This adventure can't be imported yet. See The check report, below.
  6. If the adventure has no game system of its own, Game System asks which rules your table plays. It starts on the first system the adventure says it works best with, and the line under it says so, such as Works best with 5e Compatible. You can pick any system, or None. Pick another if you like. An adventure made for one of RollQuest's own systems doesn't ask: it starts on that system. See Game system, below.
  7. Check the Game Name. If you left it empty, it fills in with the adventure's title. Change it if you like, up to 50 characters. A Description (Optional) you type replaces the adventure's own on the game's card; leave it empty to keep the adventure's.
  8. Click Create Game. The window shows Importing, the adventure's title and Storing, then the size, while the files are stored. Then you go straight into the new game, on the adventure's starting scene.
On the dashboard, New Game, then Import Adventure and Choose an adventure .zip: the-repo-yard.zip uploads (Uploading…, with its bar), the report for The Repo Yard, 32.7 MB, appears and the Game Name fills in; Create Game, Importing The Repo Yard… while the files are stored, and the new game opens on its first scene. The wait for the upload and the check is cut short.
The report for The Old Mill, which has no game system of its own: under it, Game System starts on 5e Compatible, with Works best with 5e Compatible. You can pick any system, or None. under the box; then up to Description (Optional), there to type in.

Nothing is added to your account until you click Create Game: the check only reads the zip. The first time you start a game this way, the short video Your campaign is ready plays, the same one a game from a content pack shows. See Start from a content pack.

The adventure's journal notes arrive in the game's campaign journal a moment after the game opens, one entry under Notes for each note.

Leave and come back

Closing the window doesn't stop an import. RollQuest keeps working on the server, and when you open Create New Game again and click Import Adventure, you pick up where you left off:

  • Still checking: you see it working, then the report.
  • Checked and ready: the report is waiting, so you can name the game and click Create Game whenever you like. It waits until you import it, remove it or upload another zip.
  • Still importing: you see it working, then is imported. Click Create Game to make the game.
  • Finished importing while the window was closed: the panel starts afresh, but the adventure is already yours, with a card of its own on your dashboard. Click Start a Game on that card, or Use Content Pack in this window and pick it, then click Create Game. See After the import, below.

Who can import

Plan What happens
Free Import Adventure shows. Choose an adventure .zip carries a Pro badge, and clicking it opens Import an adventure, a short explanation with a video, Included with Pro, Not now and Upgrade to Pro.
Starter The same as Free.
Pro You can import.

The Import Adventure panel, state by state

The panel sits under the three buttons while Import Adventure is picked.

What you see What it means What you can do
Choose an adventure .zip, with Maps, tokens, walls, doors, lights, music and notes, set up for you. We check everything before anything is added. Nothing chosen yet. Click it to pick a zip.
Uploading…, a bar and a percentage The zip is on its way to RollQuest. Wait.
Checking your adventure… and Every map, token, track and note in, then the file's name RollQuest is reading every file in the zip and checking how they fit together. Cancel stops the check and takes you back to the start.
The report, with no red box The adventure is ready to import. Name the game and click Create Game. Choose another file checks a different zip instead; Remove clears it.
The report with This adventure can't be imported yet Something in the zip has to be fixed first. Create Game stays greyed out. Fix the zip and use Choose another file, or Remove.
Importing, the title, Storing and a size, This can take a minute. You clicked Create Game and the files are being stored. Wait. It can't be cancelled now.
The title and is imported., Press Create Game to start playing it. The adventure is stored but the game isn't made yet. Click Create Game.
A red line, such as The adventure could not be checked. Try uploading it again. The check or the import failed. Nothing was added. Choose another file to try again, or Remove.

The other parts of the window work as they do for any game, with two differences while Import Adventure is picked: there's no Game Image (Optional), because the adventure brings its own cover, and Game System shows only once the report is in, and only for an adventure with no system of its own. Description (Optional) works as usual: what you type goes on the new game's card in place of the adventure's own description. See Create a game.

Messages you can see while choosing and uploading:

  • Choose a .zip file. The file you picked doesn't end in .zip.
  • An adventure is still being checked or imported. Let it finish first. You have one import at a time; wait for the other to finish.
  • The zip is larger than 1024 MB. The zip is over the 1 GB limit.
  • The upload failed. Check your connection and try again. The connection dropped during the upload.
  • The adventure could not be uploaded. Try again. Something went wrong on RollQuest's side.
  • Adventure import is a Pro feature. Your plan doesn't include it.

The check report

At the top: the adventure's title and how much storage its files will take, such as 32.7 MB. Then one line per scene:

  • The scene's name (or Untitled scene), with Starts here on the scene the game opens on. Exactly one scene has it: the scene the zip's activeScene names, or else the one marked as its starting scene, or else the first.
  • What it holds, such as 82 walls · 6 doors · 9 lights · 14 tokens (11 hidden) · 6 markers, then any vistas and phases. Hidden tokens are on the map for you but not for your players. A scene with none of these says An empty scene.

Under the scenes, a line for the whole adventure, such as 2 playlists · 12 tracks · 0 sounds · 6 journal notes.

The report for The Seven Seals of Kethmar, 76.5 MB, scrolled through its seven scene lines: Starts here on Level 1, and each level's walls, doors, lights, tokens, markers, vistas and phases.

Things to know (warnings)

A yellow box headed with how many there are, such as 3 things to know, lists what the import will do differently from what the zip asks. They don't stop the import. The first five show; Show all lists the rest, and Show fewer folds them again. When the same kind of warning comes up more than 25 times, the 25 are followed by …and, the number, and more like this.

Under a warning about one part of the adventure, a smaller line says where it is, by name, then the field: such as Scene "The Old Mill" › enemy "Goblin" › avatarKey for a goblin's portrait. Blockers show the same line.

You see What it means What to do
There is no Game System and its name here, so the game will have no system. The zip names a game system RollQuest doesn't have built in. Pick one in Game System, which shows under the report, or leave it on None. You can still change it later in Game Settings, until the game has its first character sheet.
A number and character sheet(s) are not imported yet; add them in the game. The zip has character sheets. They're left out. Make the characters in the game.
A number and card deck(s) are not imported yet. The zip has card decks. They're left out. Build the decks in the game if you need them.
A number and homebrew Game System(s) are not imported; the game will have no system. The zip carries a homebrew game system. It's left out. Pick a system in Game Settings.
Art credits in the zip are not carried into your game. The zip names the artists or sellers of its art. The names don't come across. Nothing.
A number and file(s) were missing when the zip was made. Whoever made the zip listed files they couldn't include. Anything that used them is left empty (see the next row).
A number and file(s) in the zip are not used by anything that is imported (only by character sheets, or by nothing), and are left out. The zip has files that nothing imported points at. They aren't stored or counted against your storage. Nothing.
A file name in quotes and is not in the zip, so it is left empty. Something points at a file the zip doesn't have. That picture or sound is left blank. Add the file to the zip, or ignore it.
A file name in quotes and is not in the zip, so this, then image, track, sound, vista or the like, is left out. A library entry or a vista whose file the zip doesn't have. The whole entry is dropped; a scene that was showing that vista opens on its map. Add the file to the zip, or ignore it.
A file name in quotes, has a space in it (or is not a stored file name (content-packs//...)), so its file is not imported and this is left empty. Rename it in pack.json and manifest.json. The zip names a file in a form RollQuest can't store, such as with a space or as a relative path. The file isn't stored; the picture or sound is left blank, or the library entry or vista is left out (the message then says this, the kind, is left out). Rename the file in both files, as the message says. See How pack.json points at a file, below.
A wall (or door, light, map marker, token) sits outside the map, its x and y, Positions are 0 to 1 of the background. Something is placed off the edge of the map picture. Check that position in the zip.
Playlist, its name, names a track that is not in the music library. A playlist lists a track the adventure doesn't have. The playlist plays without it.
Scene, its name, names a playlist that is not in the pack. A scene's music, or its battle music, names a playlist the adventure doesn't have. The scene has no playlist.
activeScene does not name one of the scenes; the game will start on the starting scene or the first one. The zip's opening scene doesn't match any of its scenes. Nothing, or fix the zip.
The report for old-mill-warnings.zip, the worked example with seven warnings: the yellow box 7 things to know with the first five, each with where it is on a line under it, such as Scene "The Old Mill" › enemy "Goblin" › avatarKey; then Show all 7 lists the other two, and Show fewer folds them again. Nothing is imported.

Things that stop the import (blockers)

A red box headed This adventure can't be imported yet lists what has to be fixed in the zip first. Create Game stays greyed out until you choose a zip that passes. These messages are for whoever made the zip: if you didn't make it, send them the message.

You see What it means
This is not a readable zip, with a reason The file isn't a zip, or it's damaged.
The zip has more than 20000 entries. Too many files inside.
The zip contains, a name, which a content pack export never writes. The zip has something the format doesn't allow, such as a folder entry, a .DS_Store file or a __MACOSX folder. See Making the zip, below.
The zip contains, a name, twice. Two files inside have the same name.
A name and is larger than 200 MB. (or 64 MB. for manifest.json and pack.json) One file inside is over its limit.
The zip unpacks to more than 2048 MB. Everything inside adds up to more than 2 GB.
The zip has no manifest.json., The zip has no pack.json. or The zip has no and a files/ name A file the format needs is missing.
A name and is not valid JSON, with a reason manifest.json or pack.json can't be read.
manifest.json is not valid: and a list manifest.json is missing a field or has one in the wrong form. Each line of the list names one. See manifest.json, below.
pack.json is not the pack the manifest names. pack.json's _id isn't the manifest's pack.id.
pack.json is not a content pack (isContentPack must be true). pack.json lacks "isContentPack": true.
The adventure has no scenes. pack.json has no scenes.
A files/ name, a file name and does not match its checksum or size in manifest.json. A file's bytes aren't what the manifest says: the zip is damaged, or the manifest is out of date.
A file name and cannot be stored as a key here. A file's name can't be used, for example because it has .. in it.
Two different files would both be stored at and a name Two different files have the same name.
pack.json could not be read as a game or pack.json has a value of an unexpected shape, with a reason Something in pack.json isn't the shape it should be, such as text where a list should be.
A message about one field, such as Path x (1.2) is more than maximum allowed value (1). A value in pack.json breaks a rule of the game format, such as a light off the map or a word that isn't one of the allowed values. The message names the field.
pack.json is, a size, once stored; the most a game can hold is 15 MB. Split it into smaller adventures. pack.json itself is too big to store as one game. The pictures and sounds don't count towards this; very long notes or thousands of walls do.
The adventure needs, a size, and you have, a size, of storage left. Its files won't fit in your remaining storage. Free some space or upgrade.
The report for old-mill-damaged.zip, the worked example with one byte changed in files/000002: the red box This adventure can't be imported yet says the file does not match its checksum or size in manifest.json, Create Game stays greyed out, then Choose another file.

When Create Game says no

Clicking Create Game checks a few things again, because time may have passed since the check. A message tells you if:

  • you've reached your plan's game limit: You have reached your campaign limit of, the number, Upgrade your subscription, or delete a game, to import another adventure. (Before that, the Upgrade Required window may open, as it does for any new game.)
  • your storage filled up since the check: The adventure needs, a size, and you have, a size, of storage left.
  • something else changed since the check: Something changed since the check. Read the report below. The report shows what.

Nothing is added in any of these cases.

What comes across, and what doesn't

From the zip, the new game gets:

  • every scene, with its map, grid, walls, doors (secret and locked ones included), lights, light level, phases (other versions of the map, such as before and after a flood), vistas (pictures shown to players instead of the map) and fog of war setting,
  • tokens: creatures and NPCs (the characters you play) where the adventure puts them, hidden ones included, and player tokens with nobody assigned to them,
  • elevation: how high a token, a light or a roof sits,
  • map markers, the private notes pinned to the map,
  • each scene's music, battle music and playlists, and the music and sound effects libraries,
  • the image and asset libraries, pause screens, the cover picture, conditions, stat blocks, rollable tables and the calendar,
  • the adventure's journal notes, in the campaign journal: notes for the Game Master (GM) are private, notes for players go in the players' journal. Up to 100 notes.

Left out, each with a warning in the report:

  • character sheets,
  • card decks,
  • homebrew game systems,
  • art credits.

The game system: a zip made for one of RollQuest's own systems, such as Ninefold or 5e Compatible, starts on that system. For anything else, Game System asks before you create the game, starting on the first system the adventure works best with; leave it on None for no system. You can still change it in Game Settings until the game has its first character sheet. See Game systems.

When the game is on a system, a creature token named after exactly one creature in that system's bestiary, such as "Goblin" or "Goblin 2", is linked to its stat block, so its numbers are filled in, unless the zip gave the token numbers of its own. A creature on a No System game keeps only what the zip gave it.

After the import

The adventure becomes a private content pack of your own: a saved copy that games are started from. Only you can see it.

  • On your dashboard it has a card of its own, marked Imported adventure (hover: An adventure you imported. Start a game from it, or delete it while no game uses it.). That card is the adventure itself, kept so you can start it again: its button is Start a Game, not Continue Game, and it has no invite button. Play in the game you made, not in it.
  • Start it again for a second group: click Start a Game on its card. The Create New Game window opens with Use Content Pack chosen, the adventure picked and the Game Name filled in, such as The Old Mill - Copy. Or click New Game, then Use Content Pack, and pick it: it shows with Draft and Yours. See Start from a content pack.
  • Storage: its files count once towards your storage, however many games you start from it.
  • Game limit: each game you start from it counts towards your plan's game limit. The adventure's own card doesn't.
  • Each import is new: importing the same zip twice gives you two separate adventures.
The dashboard card for The Old Mill, marked Imported adventure, with its hover text; Start a Game opens Create New Game with The Old Mill picked under Use Content Pack and The Old Mill - Copy in Game Name; Cancel.

Delete it

While no game uses the adventure, its card has a bin (hover: Delete imported adventure). That happens when an import finished while the window was closed, or after you've deleted every game you made from it.

  1. Click the bin on the adventure's card.
  2. Delete Adventure asks whether to delete the imported adventure, by name, and warns Its maps and files are removed and the storage they used is given back. This action cannot be undone. Click Confirm. The card goes, and a message says Game deleted successfully.
The bin on The Old Mill's card, Delete imported adventure; Delete Adventure asks, Confirm, and the card goes.

While a game you started from it still uses it, the bin is a padlock (hover: A game you started from this adventure still uses it. It goes when you delete that game.), and clicking it does nothing. Delete that game as usual: when you delete the last game made from the adventure, the adventure goes too, with its files, and the storage it took is given back. A picture from it that you saved to your Asset Drawer stays in your drawer. See Delete or leave a game.

An adventure you've made public or published as a content pack keeps its padlock, like any other content pack.

Limits

What Limit
The zip 1 GB (1024 MB) to upload
Everything inside, unpacked 2 GB (2048 MB)
Files inside the zip 20,000
One picture, sound or video inside 200 MB
manifest.json or pack.json 64 MB each, and pack.json must come to no more than 15 MB once stored
Storage The adventure's files must fit in what's left of your plan's storage (25 GB on Pro). The report shows how much they take.
Imports at a time One. Uploading a new zip while one is checked and waiting replaces it.
Journal notes The first 100 are written to the journal.

An import that's still checking or importing after 45 minutes has stopped: the panel says This import stopped before it finished. Nothing was added; upload the adventure again. If RollQuest can't reach the server four times in a row while you wait, the panel stops following the import and says so; close the window and reopen it to check on it.

How an adventure zip is built

This part is for a creator, or a GM, who wants to make an adventure zip by hand or with their own tools. It's RollQuest's own format for content packs, so pack.json describes the adventure the same way RollQuest stores a game.

An adventure zip holds:

  • manifest.json: what's in the zip, with a checksum for every file,
  • pack.json: the adventure itself, as one game: its scenes, libraries and notes,
  • files/: the pictures, sounds and videos, each under a numbered name.
the-old-mill.zip
├── manifest.json
├── pack.json
└── files/
    ├── 000001        the map (a WebP picture)
    ├── 000002        a goblin's token (a PNG picture)
    ├── 000003        a music track (an MP3)
    └── 000004        the cover (a WebP picture)

Nothing else is allowed in the zip. Three more kinds of entry exist in the format, decks/<id>.json, sheets/<id>.json and systems/<id>.json, for card decks, character sheets and homebrew game systems; an import reads them and leaves them out, with a warning.

Making the zip

  • Put manifest.json, pack.json and the files/ folder at the top level of the zip, not inside another folder.
  • Name each file files/ and six digits, such as files/000001, with no extension. The manifest says what each one is.
  • Leave out folder entries. Many zip tools add an entry for each folder (files/), and the import refuses it: on the command line use zip -D, which leaves folder entries out. Don't zip with your computer's own "Compress" command if it adds hidden files such as __MACOSX/ or .DS_Store.
  • Compressed (deflate) or stored entries both work. Encrypted zips don't.

manifest.json

Plain JSON: one object.

Field Type Required What it holds
kind text yes Always "rollquest-content-pack".
schemaVersion number yes Always 1.
exportedAt text yes When the zip was made, as a date and time, such as "2026-10-17T09:00:00.000Z".
sourceEnv text no A short name for whatever made the zip, such as "my-tool". Kept with the adventure for reference.
pack.id text yes A 24-character id (0 to 9 and a to f, lowercase), the same as pack.json's _id. Make one up; RollQuest gives the adventure a new one when it imports it.
pack.lineageId text yes Another 24-character id. Any will do.
pack.version number yes A whole number, 1 or more. Use 1.
pack.title text no The adventure's title. Used if pack.json has none.
pack.price number no A whole number of cents, 0 or more. Ignored: an imported adventure is always free and private.
systemPacks list yes The game system the adventure is for: [] for none, or one entry (see Game system, below).
droppedSystemPackIds list yes [].
decks list yes [].
sheets list yes [].
missing list yes [], or the names of files you meant to include but couldn't. Each one shows as a warning.
files list yes One entry per file in files/ (see below).

providers, droppedProviderIds and bundledSystems may be left out.

The files list

Each entry in files describes one file in the zip:

Field Type What it holds
entry text Its name in the zip, such as "files/000001". Each one listed once, and each one must be in the zip.
key text The name the file is stored under, such as "content-packs/6710a0000000000000000001/maps/old-mill.webp". See How pack.json points at a file, below.
refs list of text Every way pack.json writes this file's name. For a zip you make, one: the same as key. Must not be empty.
sha256 text The SHA-256 checksum of the file's bytes: 64 characters, 0 to 9 and a to f, lowercase.
size number The file's size in bytes, exactly.
contentType text Its type, such as "image/webp", "image/png", "image/jpeg", "audio/mpeg" or "video/mp4".

Every file is read in full during the check, and its checksum and size must match, or the import stops. On a Mac or Linux, shasum -a 256 files/000001 gives the checksum and wc -c < files/000001 the size; on Windows, certutil -hashfile files\000001 SHA256 and the file's properties.

A file that no refs entry matches anywhere in pack.json isn't stored, and the report says how many were left out.

How pack.json points at a file

Wherever pack.json needs a picture or a sound, such as a scene's map or a token's portrait, it gives the file's name as text. Write every such name like this:

content-packs/<pack.id>/<folder>/<file name>

for example content-packs/6710a0000000000000000001/tokens/goblin.png, where the 24 characters are your pack.id. The folder and file name after it are yours to choose. RollQuest stores the file under its own new id with the same folder and file name.

  • The name must match a refs entry in the manifest exactly, letter for letter.
  • No spaces anywhere in it: a name with a space isn't recognised as a file at all, so it isn't stored and the picture is left broken. Use - or _ instead.
  • No .., no \, nothing like https://, and no / at the start.
  • The same file can be named in as many places as you like.

A name in that form with no file in the zip is left empty, with a warning (see the report, above). Names for RollQuest's own built-in art, starting system/, system-assets/, backgrounds/, map-asset-packs/ or stickers/, are kept as they are without a file.

Positions and sizes

Everything placed on a map is placed by where it sits on the map picture, from 0 to 1 across and down: x 0 is the left edge and 1 the right, y 0 the top and 1 the bottom. So { "x": 0.5, "y": 0.5 } is the middle of the map, whatever the picture's size.

  • Walls, doors, map markers and tokens a little off the edge (up to 0.05) pass; further out, each gets a warning.
  • Lights must be between 0 and 1 exactly, or the import stops.
  • Sizes are in the map picture's own pixels: gridSize is one square's width and height, and a token's size is its width. With gridSize 64, a token of size 64 fills one square.
  • Light radii, brightRadius and dimRadius, are in the game system's unit: feet, at 5 feet a square, for No System and the D&D systems. The board reads them in squares of that size, whatever the map's own scale: on a town overview where one square stands for 25 ft, a lantern meant to reach 30 ft needs a radius of 6 (30 ÷ 25 × 5).
  • elevation, on tokens, lights and assets, is height off the ground in feet: 30 is flying, -10 is down a pit, 0 is the ground.

Ids

Many things in pack.json have an id: the adventure (_id), each scene, each music track and playlist. An id is 24 characters, 0 to 9 and a to f. Write it as { "$oid": "6710a00000000000000000a1" }, which is how RollQuest writes them, or as plain text, "6710a00000000000000000a1"; both work. Where one thing points at another by id, such as a playlist's trackIds or a scene's musicPlaylistId, write the id as plain text.

Walls, doors, lights, tokens and markers have an id of their own instead: any text, unique within its scene, such as "wall-1" or "goblin-2". RollQuest gives them all new ids when it makes a game.

Dates can be text, such as "2026-10-17T09:00:00.000Z", or { "$date": "2026-10-17T09:00:00.000Z" }.

pack.json: the adventure

One object. The import keeps only the fields below and ignores everything else.

Field Type Required What it holds
_id id yes The same as the manifest's pack.id.
isContentPack true or false yes Always true.
name text no The adventure's name.
description text no The description the new game shows on its card, unless the GM types one in Description (Optional) when importing.
contentPackMetadata object no How the adventure is listed: title (the name in the report and in Use Content Pack), description, category (such as "Dungeon", "Town", "Wilderness", "Campaign" or "Other"), tags (a list of words) and worksBestWith (up to 4 game system names, such as "Ninefold (2d10)"). For an adventure with no system of its own, Game System starts on the first of them when you import it, and Use Content Pack suggests them for a second game. Everything else in it is replaced.
systemPackId id no The game system, or null. See Game system, below.
scenes list yes At least one scene (see below).
activeScene id no The _id of the scene the adventure opens on. It wins over isStartingScene.
gameImageKey file name no The cover picture on the game's card.
gameImageFraming object no Which part of the cover shows: x and y from 0 to 100 (50 is the middle) and scale from 1 to 3.
imageLibrary list no The game's image library (see Libraries, below).
assetLibrary list no The asset library: pictures to place on the map.
musicLibrary list no The music library.
musicPlaylists list no Playlists of tracks from the music library.
soundLibrary list no The sound effects library.
pauseScreens list no Pictures shown to players while the game is paused. Keep to 6, the most a game can have.
journal list no Notes for the campaign journal.
state object no Leave it out: it's rebuilt from the opening scene. Its players list is the one place for player tokens (see Tokens, below).
statBlocks, rollableTables, conditionLibrary, conditionIconLibrary, journalCalendar, sightUnits, playerCardsBarEnabled, playerShortcutBarEnabled various no Carried into the game as they are, in the form RollQuest stores them in a game. Leave them out unless you know that form.

A scene

Each entry in scenes:

Field Type What it holds
_id id The scene's id.
name text The scene's name.
isStartingScene true or false true on the scene the game opens on, if activeScene doesn't name one. The import marks exactly one scene as the starting scene in the game it makes: activeScene's, else the one marked here, else the first.
backgroundImage file name The map: a picture, or an MP4 or WebM video for an animated map.
backgroundImageWidth, backgroundImageHeight number The map's size in pixels.
thumbnail file name The picture in the scene list. Usually the map.
gridType text "square" (the default), "hexFlat" or "hexPointy".
gridSize object { "width": 64, "height": 64 }: one square, in the map's pixels. A hex grid uses width. Default 100.
gridOffset object { "x": 0, "y": 0 }: where the grid starts, in pixels.
showGrid, snapToGrid true or false Whether the grid shows, and whether tokens snap to it.
blockTokenMovement true or false Block Wall Passage: walls stop tokens.
fogOfWarEnabled true or false Fog of war on. Default true.
lightingEnvironment text The light level: "brightLight" (the default), "dimLight" or "darkness", or a light level of the game's system.
walls, doors, lights lists See below.
enemies, npcs lists Creature and NPC tokens. See Tokens, below.
mapMarkers list GM-only notes on the map.
phases, activePhaseId list, id Other versions of the map, and the one it opens on.
vistas list Pictures shown to players instead of the map. Keep to 12, the most a scene can have.
backgroundMusic, battleMusic object One track: { "_id": …, "name": "…", "key": "<file name>", "loop": true }. Played if the scene has no playlist.
musicPlaylistId, battleMusicPlaylistId text The _id of a playlist in musicPlaylists, for the scene and for its battles.
soundEffects list { "_id": …, "name": "…", "key": "<file name>" } for each sound the scene uses.
boardAssets list Assets placed on the map: assetId (an asset library _id), position (0 to 1), size, rotation, elevation, layer ("map", "foreground" or "gm").
partyStart object { "x": 0.7, "y": 0.6 }: where the characters' tokens are put, one square apart around it.
clocks list Progress clocks, { "name": "…", "segments": 4, "visibility": "everyone" } (or "gm"), for a system that has clocks. Segments 4, 6, 8 or 12.
weather object { "type": "rain", "intensity": 0.5 }: a weather preset, such as rain, snow, mist or ash, and how strong, from 0.05 to 1.

Walls, doors and lights

A wall is a straight line from one point to another:

{ "id": "wall-1", "x1": 0.1, "y1": 0.2, "x2": 0.4, "y2": 0.2 }

A door is a line too, given as its two ends:

Field What it holds
id Its id.
points Its two ends: [{ "x": 0.45, "y": 0.5 }, { "x": 0.55, "y": 0.5 }].
isOpen, locked, isSecret Open, locked, or a secret door. All false by default.
name Optional.

A light:

Field What it holds
id, name Its id and name.
x, y Where it is, 0 to 1. Required.
type "torch" (the default), "lantern", "candle", "magic" or "custom".
brightRadius, dimRadius How far it's at full strength, and where it fades to nothing. Defaults 20 and 40.
color A colour, such as "#FFA500".
elevation Height in feet. A light above a roof's height doesn't light under the roof.
cone Optional: { "angle": 90, "facing": 180 } makes it shine in a wedge, in degrees, facing measured clockwise from the top of the map.
emissionOpacity How strongly its glow tints the map, from 0 to 1 (Emission Overlay Transparency in the Edit Light window). Leave it out for 0.05 (5%), the same as a light you place on the board.

On a scene with phases, a wall, door or light can carry phaseIds: a list of the phase _ids it's on. Leave it out to put it on every phase. A lamp lit only at night, say, lists only the night phase: it fades in as the GM swaps to night and out again at daybreak.

Tokens

Each entry in enemies and npcs:

Field What it holds
id, name Its id and name. A creature named after one in the game system's bestiary, such as "Goblin" or "Goblin 2", gets that stat block.
position { "x": 0.6, "y": 0.3 }: where its centre is.
size Its width in the map's pixels.
avatarKey File name of its portrait.
visible false hides it from players (the GM still sees it). "isHidden": true does the same.
elevation Height in feet.
hp, maxHp, ac Optional numbers. A token with numbers of its own isn't linked to a stat block.
prompt Optional notes about it.

Player tokens go in state.players, with the same fields; they arrive with nobody assigned, ready for your players' characters.

Map markers

Field What it holds
id Its id.
x, y Where it is, 0 to 1.
label Its title, up to 120 characters.
notes What it says when opened, up to 20,000 characters.
icon "diamond", "star", "skull", "key", "door", "chest", "eye", "book", "flame", "question", "exclamation" or "circle".
color "#e0b341", "#d1495b", "#2a9d8f", "#4a7fd4", "#8f5cd1" or "#8a93a6".
glyphText Up to 3 letters or numbers to show on the pin instead of the icon, such as "1" or "B3".
phaseId On a scene with phases, the _id of the phase it's on; null on a scene without. Or give phaseIds, a list, with [] for every phase.

A scene can hold up to 200 markers.

Phases and vistas

A phase is another version of the same map, such as a room before and after a flood. Once a scene has phases, list every version, the first included; activePhaseId names the one it opens on (the first, if left out).

Phase field What it holds
_id Its id.
label Its name.
backgroundImage, backgroundImageWidth, backgroundImageHeight Its map, the same size as the scene's.
transition { "type": "fade", "durationMs": 600 }: fade, blur, shake or cut, up to 10,000 milliseconds.
musicPlaylistId Optional: a playlist to switch to.
lightingEnvironment Optional: a light level to switch to, such as "darkness".
Vista field What it holds
_id, label Its id and name.
imageKey File name of the picture. Required: a vista whose picture isn't in the zip is left out, with a warning, and a scene that was showing it opens on its map. Put the picture in imageLibrary too.
imageWidth, imageHeight Its size in pixels.
transition { "type": "fade", "durationMs": 800 }: fade or cut.

Libraries

List Each entry Notes
imageLibrary name, key (file name), width, height, size (bytes), tags Put every map and vista picture here, so the GM can find them.
assetLibrary _id, name, key, type, contentType, width, height, size, tags, defaultLayer ("map", "foreground" or "gm") Pictures to place on the map, such as tokens and props.
musicLibrary _id, name, key, contentType (such as "audio/mpeg"), size, tags Each track's _id is what playlists list.
musicPlaylists _id, name (required), trackIds (a list of track _ids), shuffle, repeat A scene or phase plays one by its _id.
soundLibrary _id, name, key, contentType, size, tags
pauseScreens _id, imageKey (required), imageSize, label
journal key (required: any text, unique), title, body, type ("gm" or "player") One journal entry per note, in this order. "gm" notes are private; "player" notes go in the players' journal.

An entry whose file is missing from the zip is dropped from its library.

Game system

To start the game on one of RollQuest's own systems, name it in the manifest and point systemPackId at it:

"systemPacks": [ { "id": "6710a00000000000000000f1", "slug": "ninefold-core", "name": "Ninefold" } ]

and in pack.json:

"systemPackId": { "$oid": "6710a00000000000000000f1" }

The id is any 24-character id you choose, the same in both places. The slug decides the system:

Slug System
5e-core 5e Compatible
5-5e-core 5.5e Compatible
ashfall-core Ashfall
brightline-core Brightline
ninefold-core Ninefold
tidewrack-core Tidewrack

Any other slug imports as No System, with a warning. Leave systemPacks empty and systemPackId null for No System.

File types and sizes

Store pictures, sound and video in formats the app plays: pictures as PNG, JPG, WebP, GIF or SVG; animated maps as MP4 or WebM; music and sounds as MP3, OGG, WAV or WebM. A file whose contentType isn't a picture, sound, video or PDF is stored as a plain download, so give each file its true type. No file inside may be over 200 MB. See Limits and file types.

A worked example

A one-scene adventure, The Old Mill: a map, one hidden goblin, one wall, a door, a light, a marker, a music track in a playlist, a cover and a note for the GM. pack.id is 6710a0000000000000000001.

manifest.json (checksums and sizes shortened here: use the real ones):

{
  "kind": "rollquest-content-pack",
  "schemaVersion": 1,
  "exportedAt": "2026-10-17T09:00:00.000Z",
  "sourceEnv": "hand-made",
  "pack": {
    "id": "6710a0000000000000000001",
    "lineageId": "6710a0000000000000000002",
    "version": 1,
    "title": "The Old Mill"
  },
  "systemPacks": [],
  "droppedSystemPackIds": [],
  "decks": [],
  "sheets": [],
  "missing": [],
  "files": [
    {
      "entry": "files/000001",
      "key": "content-packs/6710a0000000000000000001/maps/old-mill.webp",
      "refs": ["content-packs/6710a0000000000000000001/maps/old-mill.webp"],
      "sha256": "3f5a…",
      "size": 812345,
      "contentType": "image/webp"
    },
    {
      "entry": "files/000002",
      "key": "content-packs/6710a0000000000000000001/tokens/goblin.png",
      "refs": ["content-packs/6710a0000000000000000001/tokens/goblin.png"],
      "sha256": "9b01…",
      "size": 48211,
      "contentType": "image/png"
    },
    {
      "entry": "files/000003",
      "key": "content-packs/6710a0000000000000000001/music/mill-wheel.mp3",
      "refs": ["content-packs/6710a0000000000000000001/music/mill-wheel.mp3"],
      "sha256": "c47e…",
      "size": 2880618,
      "contentType": "audio/mpeg"
    },
    {
      "entry": "files/000004",
      "key": "content-packs/6710a0000000000000000001/art/cover.webp",
      "refs": ["content-packs/6710a0000000000000000001/art/cover.webp"],
      "sha256": "0d2c…",
      "size": 201876,
      "contentType": "image/webp"
    }
  ]
}

pack.json:

{
  "_id": { "$oid": "6710a0000000000000000001" },
  "isContentPack": true,
  "name": "The Old Mill",
  "description": "Goblins have taken the old mill. One evening, one map.",
  "contentPackMetadata": {
    "title": "The Old Mill",
    "category": "Dungeon",
    "tags": ["goblins", "one-shot"],
    "worksBestWith": ["5e Compatible"]
  },
  "systemPackId": null,
  "gameImageKey": "content-packs/6710a0000000000000000001/art/cover.webp",
  "activeScene": { "$oid": "6710a00000000000000000a1" },
  "imageLibrary": [
    { "name": "The Old Mill", "key": "content-packs/6710a0000000000000000001/maps/old-mill.webp", "width": 2048, "height": 1536 }
  ],
  "assetLibrary": [
    { "_id": { "$oid": "6710a00000000000000000d1" }, "name": "Goblin", "key": "content-packs/6710a0000000000000000001/tokens/goblin.png", "type": "token", "contentType": "image/png", "width": 256, "height": 256 }
  ],
  "musicLibrary": [
    { "_id": { "$oid": "6710a00000000000000000b1" }, "name": "Mill Wheel", "key": "content-packs/6710a0000000000000000001/music/mill-wheel.mp3", "contentType": "audio/mpeg" }
  ],
  "musicPlaylists": [
    { "_id": { "$oid": "6710a00000000000000000c1" }, "name": "The Old Mill", "trackIds": ["6710a00000000000000000b1"], "shuffle": false, "repeat": true }
  ],
  "journal": [
    { "key": "note-1", "title": "Running the mill", "body": "The goblins hide in the wheel room until the party opens the door.", "type": "gm" }
  ],
  "scenes": [
    {
      "_id": { "$oid": "6710a00000000000000000a1" },
      "name": "The Old Mill",
      "isStartingScene": true,
      "backgroundImage": "content-packs/6710a0000000000000000001/maps/old-mill.webp",
      "backgroundImageWidth": 2048,
      "backgroundImageHeight": 1536,
      "thumbnail": "content-packs/6710a0000000000000000001/maps/old-mill.webp",
      "gridType": "square",
      "gridSize": { "width": 64, "height": 64 },
      "gridOffset": { "x": 0, "y": 0 },
      "showGrid": true,
      "snapToGrid": true,
      "blockTokenMovement": true,
      "fogOfWarEnabled": true,
      "lightingEnvironment": "dimLight",
      "walls": [
        { "id": "wall-1", "x1": 0.1, "y1": 0.5, "x2": 0.45, "y2": 0.5 }
      ],
      "doors": [
        { "id": "door-1", "points": [{ "x": 0.45, "y": 0.5 }, { "x": 0.55, "y": 0.5 }], "isOpen": false, "locked": false, "isSecret": false }
      ],
      "lights": [
        { "id": "light-1", "name": "Hearth", "type": "torch", "x": 0.3, "y": 0.7, "brightRadius": 20, "dimRadius": 40, "color": "#FFA500" }
      ],
      "enemies": [
        { "id": "goblin-1", "name": "Goblin", "position": { "x": 0.6, "y": 0.3 }, "size": 64, "avatarKey": "content-packs/6710a0000000000000000001/tokens/goblin.png", "visible": false }
      ],
      "npcs": [],
      "mapMarkers": [
        { "id": "marker-1", "x": 0.6, "y": 0.25, "icon": "key", "color": "#e0b341", "glyphText": "1", "label": "1 The wheel room", "notes": "Four goblins wait here.", "phaseId": null }
      ],
      "musicPlaylistId": "6710a00000000000000000c1",
      "partyStart": { "x": 0.5, "y": 0.9 }
    }
  ]
}

Before you upload

  • manifest.json, pack.json and files/ at the top of the zip, and nothing else: no folder entries, no __MACOSX, no .DS_Store.
  • pack.json's _id is the manifest's pack.id, and isContentPack is true.
  • Every file name in pack.json starts content-packs/<pack.id>/, has no spaces, and is a refs entry in the manifest.
  • Every files entry has the file's real SHA-256 (lowercase) and its exact size.
  • activeScene names the scene to open on, or one scene has isStartingScene: true.
  • Lights are between 0 and 1.
  • Every vista's picture is in the zip, or the vista is left out.

Then upload it. The report tells you anything else to fix, and nothing is added until it passes and you click Create Game.

Create a game · Start from a content pack · Publish a content pack · Delete or leave a game · Limits and file types