Modpack updates

How new modpack versions reach your client, and what to do when you see a “version mismatch” block.

Table of contents

TL;DR

  • Every time you click Play, a ~1-second check compares your installed modpack version to the server’s current version.
  • If you match: the game launches normally, no extra delay.
  • If you don’t match: Prism shows a hard block with on-screen instructions. Close Prism, double-click the Update Craft to Exile 2 launcher on your Desktop, then relaunch.
  • First install still downloads one prebuilt zip from Azure Blob Storage. Updates now delta-sync with packwiz-installer, so only changed modpack files are downloaded.
  • If GitHub is unreachable: the check fails open so offline play still works.

You’re never auto-updated during launch any more — updating is a deliberate action (double-click the Desktop launcher, or run nz update), so you’re never surprised by a multi-minute “Running pre-launch command” delay with no progress bar.


Setup vs update delivery

The client uses a split delivery model:

  • First install (nz setup) downloads a prebuilt modpack zip from https://stmcminecraftprod.blob.core.windows.net/minecraft-modpack/. This stays fast because Azure serves it from CDN (~2 min) and avoids the slow CurseForge cold-install path.
  • Updates (nz update) no longer download the whole zip. They fetch latest.json, then delta-sync .minecraft with packwiz-installer against a SHA-pinned pack.toml URL such as https://raw.githubusercontent.com/camcast3/MinecraftInfra/<SHA>/packwiz/pack.toml. This is the same mechanism the server uses via PACKWIZ_URL, and usually downloads only 10–50 MB instead of ~1 GB — especially helpful for AUS or high-latency players.

The published latest.json manifest includes:

  • version
  • url (first-install zip)
  • sha256
  • sizeBytes
  • instance
  • publishedAt
  • packwizUrl (SHA-pinned raw pack.toml)
  • optional allowDowngrade

How the launch-time check works

When you click Play, Prism runs the nz check hook (its PreLaunchCommand). It:

  1. Reads your installed version from %APPDATA%\PrismLauncher\instances\Craft to Exile 2\.negativezone-version.
  2. Fetches latest-version.txt from raw.githubusercontent.com (CDN-cached, free, ~100 ms).
  3. Compares the two as strict equality.

Cost: one tiny GET per launch. GitHub’s CDN serves it, so we don’t pay Azure egress per player launch, and you don’t depend on the modpack blob being warm.

Outcomes:

Installed Server Result
0.4.2 0.4.2 Silent pass — game launches
0.4.1 0.4.2 Hard block, “behind” — update via the launcher
0.5.0 0.4.2 Hard block, “ahead” — usually means a rollback is needed
anything unreachable (no internet, 404, 5xx) Pass with allowing launch notice; offline play works

What the block looks like

When your version doesn’t match, you’ll see this in Prism’s pre-launch console window:

════════════════════════════════════════════════════════════
  MODPACK VERSION MISMATCH
  installed: v0.4.1
  server:    v0.4.2  (behind)
════════════════════════════════════════════════════════════

The server is pinned to a specific modpack version.
Joining with a different client version would fail at the FML handshake.

Run this to update:

  nz update

Walk-through: https://wiki.negativezone.cc/updating
(Set NEGATIVEZONE_SKIP_VERSION_CHECK=1 to bypass for offline play.)

The block says nz update, but nz isn’t on your PATH — the no-typing way is to double-click the Update Craft to Exile 2 launcher on your Desktop (see below).

The direction hint (behind or ahead) tells you what’s going on:

  • behind — you’re on an older version. Update via the Update Craft to Exile 2 launcher.
  • ahead — you’re on a newer version than the server. This usually means you tested a pre-release and the server hasn’t moved up to it yet, or the admin rolled the server back to fix a bug. Re-run the update — by default it refuses to “downgrade” you, so the admin will need to set allowDowngrade: true in the manifest. Reach out and they’ll do it.

Updating manually

When you see the block:

  1. Close Prism completely (file → quit, or close the window). The update touches files in your instance and can’t do that while Prism has them open.
  2. Double-click Update Craft to Exile 2 on your Desktop. A console window opens, runs the update, and tells you when it’s done.

    Prefer a terminal? Open a new PowerShell window and run:

    & "$env:LOCALAPPDATA\NegativeZone\nz.exe" update
    
  3. nz update:
    • Auto-detects the Craft to Exile 2 instance and refuses to run while Prism is open.
    • Fetches latest.json from Azure Blob Storage.
    • Compares your .negativezone-version to manifest.version and skips if they already match.
    • Refuses downgrades unless the manifest has allowDowngrade: true.
    • Forces a safety snapshot first (waypoints, options, etc. — see Backups).
    • Runs packwiz-installer with CWD set to .minecraft:
      java -jar packwiz-installer-bootstrap.jar --bootstrap-no-update --bootstrap-main-jar packwiz-installer.jar -g -s client <packwizUrl>
      
    • Bumps your .negativezone-version marker to match the server.

    The packwiz jars (packwiz-installer-bootstrap v0.0.3 and packwiz-installer v0.5.14) ship inside the modpack zip under .minecraft\ (and nz caches them under .negativezone\ as a fallback), so update doesn’t re-download those tools each time. They need Java 17+, which Path A installs via Temurin 17 during onboarding.

    packwiz-installer only touches tracked modpack files, so personal state like saves, options, Xaero maps, shaderpacks, and preserve-list configs stays in place. The old atomic .minecraft swap/restore logic was only for the first-install zip path.

  4. Reopen Prism, click Play. The version check now silent-passes, the game launches normally.

A typical update downloads 10–50 MB and takes 30–90 seconds depending on your internet speed and how big the version delta is.

Resetting a tuned setting back to pack defaults: Just delete the relevant config file from %APPDATA%\PrismLauncher\instances\Craft to Exile 2\.minecraft\config\ (e.g. embeddium-options.json, oculus.properties) — the next pack update will reseed the pack-recommended baseline. The pack ships opinionated defaults for graphics, shaders, and UI on first install; from there it’s yours to tweak.


Bypassing the check (offline play)

If you want to launch a known-mismatched client (e.g. the server is down and you just want to wander a single-player world), set this in your user environment once:

[Environment]::SetEnvironmentVariable('NEGATIVEZONE_SKIP_VERSION_CHECK', '1', 'User')

Close and reopen Prism for the env var to take effect. The version check will print one line saying it’s bypassed and let you launch. Note that the multiplayer server will kick you at the FML handshake if your mods don’t match — this bypass is only for offline / dev work. Unset by setting the value to an empty string and restarting Prism.

You can also disable the check by unchecking Custom commands in Prism (instance → EditSettingsCustom commands), but that also disables the periodic backup hook, so prefer the env var.


Upgrading to v0.5.0 — the nz client cutover

v0.5.0 adds new mods, so every player has to upgrade to keep playing. Until your client matches the server’s mod list, you’ll be kicked at the FML handshake when you try to join. Upgrading also moves you onto the new nz client — a single nz.exe that replaces the old PowerShell scripts (prelaunch-check.ps1, update.ps1, backup.ps1).

Do this once

  1. Close Prism completely.
  2. Open PowerShell (Windows key → powershellEnter) and run:

    irm https://github.com/camcast3/MinecraftInfra/releases/download/nz-latest/install.ps1 | iex
    

That single command installs the nz client and the v0.5.0 modpack in one pass. It preserves your worlds, waypoints, options, and tuned settings, and saves your previous install as a Craft to Exile 2.bak folder you can roll back to.

What changes after you upgrade

  • Launch check & backups run through nz. Your Prism hooks are rewritten from the old prelaunch-check.ps1 / backup.ps1 to nz check / nz backup automatically — nothing for you to wire up.
  • Updating is a double-click. A new Update Craft to Exile 2 launcher lands on your Desktop. From now on you update by double-clicking it (or running nz update) — not the old irm …/update.ps1 | iex command.
  • Your settings carry over. Same NEGATIVEZONE_* environment variables and the same .negativezone-version marker — no reconfiguration needed.

Coming from an even older, non-version-checked install? Same fix: run the one-liner above once. You’ll get the launch-time check, the auto-backups, and the Desktop update launcher all in one step. It preserves your worlds, waypoints, options, and any other user state.


Release cadence

What you can expect from each version bump:

Bump Example What it means for you
PATCH 0.4.10.4.2 Client-only change (config tweak, single-mod swap, performance fix). Server keeps running. Update via the launcher from the block banner, you’re good.
MINOR 0.4.x0.5.0 Client + server in sync — usually a new mod or a major mod upgrade that needs the server-side too. The server briefly restarts on publish (~30 sec); you might see “Server unavailable” for a moment.
MAJOR 0.x.y1.0.0 Reserved for “we’ve gone a full month without management-caused downtime” — a stability milestone, not a content gate.

The strict-equality check blocks every delta — including PATCH — until the update pipeline is rock-solid in production. We may relax this to “MINOR-or-greater only” once a few real releases have been exercised end-to-end without surprises.