-
Notifications
You must be signed in to change notification settings - Fork 8
Packaging Your Pack
EmoTracker accepts a pack in two physical forms: a loose directory (the dev mode) or a zip archive (the shipping form). This page covers both — when to use each, where to put them on disk, and how to prepare a clean zip without the most common packaging mistake.
It also covers EmoTracker's -dev command-line flag, which gives you a separate sandboxed user directory so you can iterate on a pack without disturbing your main install.
See Authoring a Manifest for the
manifest.jsonreference and Hosting a Package Repository for publishing the finished.zipto other users.
EmoTracker scans for installed packs at startup in the packs/ subdirectory of its user data directory. The exact path depends on whether you launch EmoTracker normally or with the -dev flag:
| Mode | Path |
|---|---|
| Normal | <UserDirectory>/EmoTracker/packs/ |
-dev |
<UserDirectory>/EmoTracker/dev/packs/ |
<UserDirectory> is your platform's user-files folder — typically Documents on Windows / macOS / Linux, or %APPDATA% on Windows if Documents isn't usable. See Map Location Colors → Where the file goes for the full lookup order EmoTracker uses to pick between them. The fastest way to confirm which one is active on your system is to look for application_settings.json next to it.
Both physical pack forms live in that packs/ directory as siblings:
<UserDirectory>/EmoTracker/packs/
├── alttpr_my_tracker_yourname/ ← loose directory (dev mode)
│ ├── manifest.json
│ ├── scripts/
│ ├── items/
│ └── ...
└── another_pack_yourname.zip ← shipped zip
The scanner walks every immediate subdirectory and every *.zip file at the root of packs/. Each becomes a candidate pack. Packs whose manifest.json is missing, malformed, or has no uid / version are silently rejected — see Authoring a Manifest for the parser's rules.
While you're authoring a pack, the easiest workflow is to keep it as a loose directory in your packs/ folder. EmoTracker treats every subdirectory of packs/ as a candidate pack and reads its files directly from disk via DirectoryPackageSource. No zip / unzip step, no copy step — edit a file, reload the pack, see the change.
-
Name the directory after your pack's
uid. For example, if your manifest has"uid": "alttpr_my_tracker_yourname", the folder should bealttpr_my_tracker_yourname/. EmoTracker doesn't strictly require this, but it matches what the Package Manager produces when it installs your pack from a repository (<uid>.zip), keeps your dev folder distinguishable from other packs, and avoidsuidconfusion if you ever ship and re-install your own pack. -
Place it directly under
packs/. EmoTracker only scans the immediate children ofpacks/; nested folders aren't picked up. -
Make sure
manifest.jsonis at the root of the directory. That is, the path should bepacks/<uid>/manifest.json, notpacks/<uid>/<uid>/manifest.json. - Reload the pack to pick up changes — see Reloading after edits below.
<UserDirectory>/EmoTracker/packs/
└── alttpr_my_tracker_yourname/
├── manifest.json
├── scripts/
│ └── init.lua
├── items/
├── locations/
├── layouts/
└── images/
EmoTracker doesn't watch the filesystem for changes — when you edit a file, you need to tell the tracker to reload the pack so the runtime re-runs init.lua and re-parses the JSON.
The fastest way to reload is:
-
Press
F5in the main window, or - Click the reload icon in the status bar (bottom-left of the main window)
Both invoke the same RefreshCommand, which calls Tracker.Reload() — that resets the pack's runtime state, re-runs your init.lua, and re-parses every items / locations / layouts file you load from it. Use this for anything you edit inside the pack: items, locations, layouts, Lua scripts, the pack-level settings.json, image files, etc.
The standard authoring pattern is to keep EmoTracker open in one window and your editor open in another, then F5 after every iteration. The script console (developer view) is where any errors and print calls go — leave it visible while you iterate.
The one thing reload doesn't pick up is manifest.json changes. The manifest is read when EmoTracker first scans the packs/ directory at startup, before the pack is ever "loaded". If you edit manifest.json (e.g., to bump the version, add a variant, or add the platform field for autotracking), you need to fully restart EmoTracker for the new manifest to take effect. Everything else can be picked up with F5.
When you're ready to publish your pack, you bundle it into a single .zip file and host that file somewhere. The zip is what users actually download — the Package Manager saves it as <uid>.zip in their packs/ directory and loads it via ZipPackageSource.
The zip's internal structure must match what EmoTracker's ZipPackageSource expects: file paths inside the zip are looked up directly with mArchive.GetEntry(path), with no folder prefix. Your manifest.json must be at the root of the zip, not nested inside a directory.
The right structure looks like this (unzip -l view):
my_pack.zip:
manifest.json ← at the root
scripts/init.lua
items/common.json
locations/dungeons.json
layouts/tracker.json
images/...
The wrong structure looks like this:
my_pack.zip:
alttpr_my_tracker_yourname/ ← UNWANTED top-level directory
manifest.json
scripts/init.lua
...
When EmoTracker tries to open manifest.json, the zip lookup returns null because the actual entry is alttpr_my_tracker_yourname/manifest.json, not manifest.json. The pack silently fails to load.
The most common way to produce a broken zip is:
Right-click your pack folder → "Compress" / "Send to → Compressed (zipped) folder"
Most operating-system zip tools, when given a folder, create a zip whose first entry is the folder itself. That puts every file one level too deep. Even though your zip looks fine when you double-click it (you see the folder, then your files inside), EmoTracker sees <uid>/manifest.json instead of manifest.json and rejects it.
The fix is to compress the contents of the folder, not the folder itself. Two reliable ways:
Option A — cd into the folder first (Windows / macOS / Linux command line):
cd packs/alttpr_my_tracker_yourname
zip -r ../alttpr_my_tracker_yourname.zip .
The . tells zip to add everything in the current directory, with paths relative to here, so manifest.json ends up at the zip root.
Option B — select all files inside the folder, then compress:
Open the folder, select every file and subfolder inside (Ctrl+A), and right-click → Compress / Send to → Compressed folder. This zips the selected items, not the parent folder, so paths inside the zip are correct.
After zipping, always verify with unzip -l my_pack.zip (or by opening the zip in any archive viewer): you should see manifest.json listed at the top level, not under a folder.
Name your zip after your pack's uid — <uid>.zip. Three reasons:
-
The Package Manager uses
<uid>.zipas the install filename when it downloads your pack from a repository. Matching that on the source side keeps the file's identity consistent across hosting, downloading, and installation. -
uidcollisions overwrite each other at install time. Two zips with the sameuidcan't coexist; naming the file after theuidmakes the intended identity obvious. -
It avoids confusion if you ever drop your shipping zip into a
packs/folder that already has the loose dev directory — both have the same identity, so the runtime picks one consistently.
Before publishing, do a full round-trip on your own machine:
- Build the zip as described above.
- Drop it into your
<UserDirectory>/EmoTracker/packs/folder (or, if you want to test the install path, host it locally and add a one-packrepository.jsonas an Additional Repository in the Package Manager — see Hosting a Package Repository → Test your repository locally). - Restart EmoTracker so the new zip is picked up by the next
packs/scan. - Confirm the pack appears in Installed Packages under the gear menu, loads cleanly, and behaves the same as the loose directory you authored against.
If the pack doesn't show up, check the script console for errors and re-verify the zip structure with unzip -l.
Launching EmoTracker with -dev on the command line redirects EmoTracker's user data directory to a separate dev sandbox. Instead of using <UserDirectory>/EmoTracker/, the runtime uses <UserDirectory>/EmoTracker/dev/ — and so packs live in <UserDirectory>/EmoTracker/dev/packs/ instead of <UserDirectory>/EmoTracker/packs/.
This is implemented in EmoTracker.Core/UserDirectory.cs — when the command line contains -dev, the user-data path has dev appended and the runtime exposes an IsDevMode flag.
The dev sandbox is a complete second copy of everything user-data-related. It has its own:
-
packs/directory -
saves/directory application_settings.jsonapplication_colors.json-
application_version.json(legacy) - Pack overrides
- Logs
Nothing in the dev directory affects your normal install, and vice versa. You can install different packs, use different colors, save different runs, and reset the dev directory at any time without losing your main tracker state.
-
Authoring a new pack — drop your dev directory in
<UserDirectory>/EmoTracker/dev/packs/and run EmoTracker with-dev. Your main install's pack list stays clean, and your pack's settings and saves don't pollute your normal usage. - Testing pre-release versions of someone else's pack without removing the stable version from your main install.
- Reproducing a bug from scratch — wipe the dev directory between runs without losing your real saves.
The exact syntax depends on how EmoTracker is installed.
| Platform | Launch |
|---|---|
| Windows (installed via the installer) | Open a Command Prompt or PowerShell, navigate to the install folder, and run EmoTracker.exe -dev. Or create a shortcut and append -dev to the Target field. |
| Windows (portable) | Same — append -dev to the executable invocation or shortcut. |
| macOS |
open -a EmoTracker.app --args -dev from Terminal, or invoke the binary directly inside the .app bundle. |
| Linux | Run the EmoTracker binary with -dev as an argument. |
The tracker title bar / window doesn't currently advertise that you're in dev mode visually, so the easiest way to confirm is to check the path of application_settings.json next to it — it'll be under a dev/ subdirectory.
-
Set up a dedicated shortcut (
EmoTracker (Dev)) so you can launch the dev sandbox with one click. Append-devto the Target field on Windows or pass it as an argument in your launcher of choice. -
Symlink your pack folder if you want to share data between dev and main installs. On Windows you can
mklink /D <UserDirectory>\EmoTracker\dev\packs\<uid> <repo path>\<uid>to keep your dev pack pointing at a working git repo. - Don't run dev and main side-by-side editing the same pack. Both processes scan the same pack zip / folder; if both are loaded, both consume the same files and the picture gets confusing fast. Pick one at a time.
-
Folder/zip name should match
uid. Not strictly required by the loader, but matching the Package Manager's install convention prevents identity confusion. -
manifest.jsonmust be at the root of the zip. No folder prefix. Verify withunzip -lbefore publishing. - Don't right-click-compress your pack folder. Most OS zip tools wrap the folder in another directory inside the zip. Compress the folder's contents instead.
-
Dev directory and zip both work — pick one per install. EmoTracker sees both loose directories and
*.zipfiles in the samepacks/scan; if both have the sameuid, only one is loaded and the precedence isn't guaranteed. -
Use
-devwhile authoring. A clean sandbox keeps your main install untouched and makes it easy to verify your pack works on a "fresh" environment without uninstalling your real packs. -
F5for everything exceptmanifest.json.F5(or the status-bar reload icon) re-runs yourinit.luaand re-parses every JSON file inside the pack. The only edit that requires a full app restart is a change tomanifest.json, which is read once when EmoTracker scanspacks/at startup.
- Developer Setup — tools, schema validation, and the pack directory layout
-
Authoring a Manifest — the
manifest.jsonreference, includinguidrequirements - Image Filters — the filter spec used in image references
- Hosting a Package Repository — once your zip is built, publish it
- Installing and Loading Packages — how end users will install and load your finished pack
- Installation
- Installing and Loading Packages
- Item Types and Mouse Controls
- Map Locations
- Map Location Colors
- Saving and Loading
- Multi-Tab and Window
- Autotracking
- NDI Broadcasting
- Twitch Chat HUD
- Note Taking
- Voice Control
- Keyboard Shortcuts