This is the full developer documentation for Oasis
# Introduction
> Oasis is a free block logging and rollback plugin for Paper. Here's what it does, who it's for, and where to start.
Oasis keeps a history of everything that happens on your Minecraft server. When someone griefs a build, you can see who did it and put it back the way it was, usually with one command.
## What Oasis does
[Section titled “What Oasis does”](#what-oasis-does)
Think of Oasis as a security camera for your world. It writes down blocks broken and placed, items taken from and put in chests, mobs killed, items dropped and picked up, signs, chat, commands and more. Each entry says who did it, where and when.
When something goes wrong, your staff can:
* **Look.** Click a block and see who changed it, and when.
* **Search.** Find everything a player did in the last hour, or everything that happened near a spot.
* **Fix.** Roll back a player’s damage, from the first block they broke to the last tree their fire burned.
## Who it’s for
[Section titled “Who it’s for”](#who-its-for)
**Server owners.** Oasis is one jar. It brings its own storage, so there’s no database to set up and nothing else to keep running. It keeps all of your history for as long as you want, so a grief from last year rolls back as easily as one from last night.
**Staff and moderators**, including new ones. Commands use a few plain words, like `user`, `last` and `near`, and Tab shows you what fits next. A rollback leaves other players’ repairs alone, so it’s hard to make things worse.
**Busy and wild servers.** Oasis was built for a free-op anarchy server, where players change millions of blocks at a time with WorldEdit. If it keeps up there, a normal day on a survival server barely registers.
**Your players**, even though they never type an Oasis command. They get a server that doesn’t lag, and their builds come back quickly after a grief.
## What it costs
[Section titled “What it costs”](#what-it-costs)
Nothing. Oasis is free and open source. There’s no paid edition, and every update is for everyone.
## Where to start
[Section titled “Where to start”](#where-to-start)
* [Install Oasis](/docs/install/). It takes a few minutes, from an empty `plugins` folder to a server that logs.
* [Why Oasis](/why/) tells the full story, with pictures.
* [Import from CoreProtect](/docs/guides/importing/) brings your old history with you, if you used CoreProtect before.
# Install Oasis
> Install Oasis on a Paper server, do the two recommended FastAsyncWorldEdit steps, and check that Oasis logs.
This page takes you from an empty `plugins` folder to a server that logs. It takes a few minutes.
## 1. What you need
[Section titled “1. What you need”](#1-what-you-need)
* **Paper** for Minecraft 1.21.11, 26.1, 26.2 or 26.3. One Oasis jar covers all of them.
* **Java 25** or newer. On an older Java, Oasis tells you the version it needs and does not start.
* **FastAsyncWorldEdit**, if you want WorldEdit changes logged. Oasis logs FAWE, not plain WorldEdit.
You don’t need a database. Oasis brings its own and runs it inside your server.
## 2. Install the jar
[Section titled “2. Install the jar”](#2-install-the-jar)
1. Stop the server.
2. Download Oasis from [Downloads](/downloads/) and put the jar in your server’s `plugins` folder. If you use FAWE, keep the FAWE jar there too.
3. Start the server. Oasis creates `plugins/Oasis/config.yml` and starts logging straight away. You don’t have to change anything in that file.
4. Give your staff the permissions they need. Every Oasis permission starts out as operator only. [Commands](/docs/reference/commands/) lists each one.
Oasis keeps its history in `plugins/Oasis/store`. If you move your server, take that folder with it, along with `plugins/Oasis/client-id`.
## 3. Recommended setup for FAWE
[Section titled “3. Recommended setup for FAWE”](#3-recommended-setup-for-fawe)
Skip this section if you don’t use FAWE. If you do, the console can show two warnings from Oasis at the first start:
```plaintext
FAWE's max-memory-percent is 95. A large FAWE edit can then fill the heap and stall the server in full garbage collections. Run /oasis fawe tune to set it to 75.
FAWE hands one queue to every edit on a thread, so Oasis can log a chunk under another player's name (FastAsyncWorldEdit#3668). Run /oasis fawe patch to fix it.
```
We recommend both fixes. You need the `oasis.fawe` permission, and you can run each command in game or from the console. Each command shows a preview first, which changes nothing. To confirm, click the link in chat, or type the `confirm` command in the console within two minutes.
### Lower FAWE’s memory limit
[Section titled “Lower FAWE’s memory limit”](#lower-fawes-memory-limit)
FAWE ships with `max-memory-percent` at 95. At that level, a big edit can fill almost all of your server’s memory, and TPS falls while Java cleans up.
1. Run `/oasis fawe tune`. Oasis names a safer value for your server: 75 if you use Aikar’s flags, 85 if you use Java’s defaults.
2. Click **\[tune FAWE]**, or type `/oasis fawe tune confirm` in the console. Oasis writes the value to FAWE’s config and applies it right away.
### Turn on the FAWE queue patch
[Section titled “Turn on the FAWE queue patch”](#turn-on-the-fawe-queue-patch)
FAWE has a bug. When two WorldEdit jobs run at the same time, Oasis can log part of one player’s edit under the other player’s name. A lookup can then blame the wrong person, and a rollback can miss part of an edit.
The patch makes the one-line fix from FAWE [pull request #3669](https://github.com/IntellectualSites/FastAsyncWorldEdit/pull/3669), in memory while your server runs. **Oasis never changes the FAWE jar.**
1. Run `/oasis fawe patch`. Oasis tells you what the bug does and what the patch changes.
2. Click **\[patch FAWE]**, or type `/oasis fawe patch confirm` in the console.
Oasis remembers your choice and patches FAWE again at each start, also after you update FAWE. To turn the patch off, run `/oasis fawe unpatch`.
Note
On Java 26 or newer, Java prints a warning when the patch turns on. That’s Java telling you that a plugin changed another plugin’s setting, which is what you asked for. [The FAWE patch](/docs/guides/fawe-patch/) explains the patch in full.
## 4. Check that it works
[Section titled “4. Check that it works”](#4-check-that-it-works)
Run `/oasis status` and look for these lines:
* `Database: Packs Embedded`. Oasis has its store open.
* `Logging: up to date`. Oasis has saved every edit so far.
* With FAWE, `FAWE: queue patch on · tuned`. If the line says `run /oasis fawe patch` or `run /oasis fawe tune`, go back to step 3.
Then place a block, run `/inspect`, and left-click the block. Oasis shows its history, with your edit in it. Run `/inspect` again to turn the inspector off.
That’s it. Oasis is logging.
## Updating Oasis
[Section titled “Updating Oasis”](#updating-oasis)
Oasis tells you in the console and in `/oasis status` when a newer build is out. Put the new jar in place of the old one and restart. Your history stays. [Updating](/docs/updating/) covers Packs Server, mismatched versions, and going back to an older version.
## Where to go next
[Section titled “Where to go next”](#where-to-go-next)
* [Commands](/docs/reference/commands/) lists every command, the words they take and the permissions. In game, type `/oasis help`.
* [Configuration](/docs/reference/config/) explains each setting in `config.yml`.
* [Import from CoreProtect](/docs/guides/importing/) brings your old history into Oasis.
* [Embedded or Packs Server?](/docs/guides/embedded-or-server/) answers the most common question about storage.
# Updating
> How Oasis tells you about a new build, how to update Oasis and Packs Server, what happens if their versions don't match, and how to go back to an older version.
On Packs Embedded, an update is a new jar and a restart. With Packs Server there are two parts to update, and Oasis tells you if the two don’t match. Your history isn’t converted, so an older version can usually read it again if you go back.
## Finding out about updates
[Section titled “Finding out about updates”](#finding-out-about-updates)
Oasis looks for a newer build when your server starts and every six hours after that. When it finds one, it names it in the console once each time the server starts. If you run Packs Server and the new build needs a newer one, Oasis says that too, as soon as it reaches Packs Server:
```plaintext
Oasis build 42 (3.2) is out. This server runs build 41. Get it from https://oasis-protection.com/downloads/
Before you update to Oasis build 42, update Packs Server to 3.2 (e4f5a6b) or newer. This Packs Server is 3.1 (c7d8e9f).
```
Until you install it, the last line of `/oasis status` names the build, the Packs Server it needs, and the Downloads page; click it to open the page. When you run the newest build, that line isn’t there.
* A dev build tells you about the newest build. A release tells you only about newer releases.
* Dev builds of Packs Server come from their own package repository. See [Install Packs Server](/docs/packs-server/setup/#1-install-packs-server).
* Oasis never downloads or installs an update by itself. Get the jar from [Downloads](/downloads/), which lists the changes in each build.
* The check reads one small file from oasis-protection.com and sends nothing about your server but the Oasis version. If the site can’t be reached, Oasis stays quiet and tries again at the next check.
* To turn the check off, set `updates.check` to `false` in `config.yml` and run `/oasis reload`.
* A jar you built yourself has no build number, so it doesn’t look for updates.
## Update Oasis on Packs Embedded
[Section titled “Update Oasis on Packs Embedded”](#update-oasis-on-packs-embedded)
If you run Packs Embedded (the default), there is only one jar to update.
1. Stop your server.
2. Put the new Oasis jar from [Downloads](/downloads/) in `plugins` in place of the old one.
3. Start your server.
4. Run `/oasis status` and check that it says `Logging: up to date`.
## Update Oasis and Packs Server
[Section titled “Update Oasis and Packs Server”](#update-oasis-and-packs-server)
If you run Packs Server, update both at the same time. Oasis and Packs Server come out together, and a matching pair always works.
1. Update Packs Server on its machine. This updates Packs Server and nothing else, and restarts it by itself:
SystemDebian and Ubuntu
* Debian and Ubuntu
* Fedora and RHEL
* openSUSE
* Arch Linux
```sh
apt update
apt install --only-upgrade packs
```
If `apt update` brings no new Packs Server, look at `/etc/apt/sources.list.d/packs.list`. It must name `packs-server-deb` or `packs-server-deb-dev`. If it names `packs-server` or `packs-server-dev`, run the block in [Install Packs Server](/docs/packs-server/setup/#1-install-packs-server) again.
```sh
dnf upgrade packs
```
```sh
zypper update packs
```
```sh
pacman -Syu
```
Arch updates the whole system at once, because it doesn’t support updating one package alone.
2. Stop your Minecraft server, put the new Oasis jar from [Downloads](/downloads/) in `plugins` in place of the old one, and start it again.
3. Run `/oasis status` and check that it says `Logging: up to date`.
Your server keeps logging between the two steps. If the new Packs Server needs the new Oasis, Oasis holds new edits in `plugins/Oasis/outbox` and sends them once both match. Lookups and rollbacks wait until then.
Tip
You can update Packs Server while your Minecraft server runs. Oasis connects again by itself.
## If the versions don’t match
[Section titled “If the versions don’t match”](#if-the-versions-dont-match)
Sometimes a newer Oasis works with an older Packs Server, or the other way around. Oasis checks this each time it connects. When the pair can’t work together, Oasis tells you in the console, in `/oasis status`, and in the reply to any command that needs Packs Server. The message names the part to update, the version to update to, and what changed. For example:
```plaintext
Oasis 3.2 (a1b2c3d) with Packs 3.2 (e4f5a6b) needs a newer Packs Server than 3.1 (c7d8e9f).
Update Packs Server to 3.2 (e4f5a6b) or newer. It lacks: Logins record the address of the player.
```
While the message shows:
* Oasis keeps logging. New edits wait in `plugins/Oasis/outbox`.
* Lookups, rollbacks, restores and purges refuse with the same message.
* Once you update the part it names, Oasis connects, sends the waiting edits, and everything works again. A Packs Server update needs no restart of your Minecraft server.
## Going back to an older version
[Section titled “Going back to an older version”](#going-back-to-an-older-version)
An update doesn’t convert your history. A newer version reads what older versions saved as it is, so you can go back as long as the newer version saved nothing the older one can’t read.
If it did, the older version refuses instead of guessing. It changes nothing, and its message names the version that saved the data and what that version added. Put that version back, or a newer one.
| What you went back on | What happens |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Oasis on Packs Embedded | Oasis doesn’t start logging, and leaves your history alone. The console names the Oasis version to install. |
| Packs Server | Packs Server doesn’t open that history, and Oasis stops logging until Packs Server can read it. The message names the Packs Server version to install. |
| A world | If a newer Oasis saved something new into a world, an older Oasis doesn’t roll back or restore in that world. Lookups still work, and the other worlds work as usual. `/oasis status` lists the world. |
Before a big jump
To be able to go back after you update across many versions, first copy `plugins/Oasis/store` (Packs Embedded) or `/var/lib/packs` (Packs Server) while it is stopped. The copy works with your old version whatever the new one saves.
## Updating Minecraft
[Section titled “Updating Minecraft”](#updating-minecraft)
One Oasis jar covers every Minecraft version on the [install page](/docs/install/#1-what-you-need). When you update Paper to a newer Minecraft version, update Oasis first if your Oasis doesn’t list that version yet.
Packs Server writes chunks directly for the fastest rollbacks. If Packs Server is older than your Minecraft version, those rollbacks run at normal speed until you update Packs Server. The result is the same.
# Commands
> Every Oasis command, what it does, and the permission it needs.
Type `/oasis help` in game to see the commands you’re allowed to use. Every command has Tab completion too, so if you forget a word, press Tab and Oasis shows you what fits.
| Command | What it does | Permission |
| ------------------------ | ------------------------------------------------------------- | ---------------- |
| `/lookup ` | Search the history | `oasis.lookup` |
| `/rollback ` | Undo changes | `oasis.rollback` |
| `/rs ` | Put back what a rollback removed | `oasis.restore` |
| `/undo` | Reverse your last rollback or restore | `oasis.undo` |
| `/inspect` | Click blocks to see their history | `oasis.inspect` |
| `/oasis kept` | See the blocks your last rollback kept | `oasis.lookup` |
| `/oasis status` | See how Oasis is doing | `oasis.status` |
| `/oasis incidents` | See the storage problems Oasis recorded | `oasis.status` |
| `/oasis incidents clear` | Clear them from the list and the status; the cairn keeps them | `oasis.purge` |
| `/oasis cancel` | Stop the rollback that’s running | `oasis.cancel` |
| `/oasis purge ` | Delete history for good | `oasis.purge` |
| `/oasis reload` | Read `config.yml` again | `oasis.reload` |
| `/oasis import` | Bring in CoreProtect history | `oasis.import` |
| `/oasis move` | Move history to or from Packs Server | `oasis.move` |
| `/oasis fawe patch` | Fix a FastAsyncWorldEdit bug | `oasis.fawe` |
| `/oasis fawe tune` | Make FAWE’s memory setting safer | `oasis.fawe` |
| `/cairn share` | Send the cairn to the Oasis team | `oasis.cairn` |
Two permissions have no command of their own. `oasis.alerts` lets someone see storage problems in chat, and `oasis.*` gives every permission at once. They all start out as operator only.
### Permission packs
[Section titled “Permission packs”](#permission-packs)
A pack is one permission that gives a whole group of them.
| Pack | Usually given to | What it gives |
| ------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `oasis.admin` | Trusted staff | Lookup, inspect, rollback, restore, undo, status and cancel |
| `oasis.owner` | Server owners and the people who run the server | Everything in `oasis.admin`, plus reload, purge, import, move, the FAWE commands, `/cairn share` and alerts |
Players who aren’t staff usually have `oasis.inspect` at most. It shows who changed a block, but it can’t change anything.
The everyday commands have short forms: `/lo`, `/rb` and `/ins`. The restore is only `/rs`, because FastAsyncWorldEdit has a `/restore` command of its own. Every command also works under `/oasis` (or `/oa`), so `/oa rb user Griefer last 2h` does the same as `/rollback user Griefer last 2h`, and `/oa restore` does the same as `/rs`. That helps if another plugin already uses `/rollback` or `/undo`.
## Filters
[Section titled “Filters”](#filters)
Lookup, rollback, restore and purge all understand the same filter words. Each word takes a value after it, and you can put them in any order.
| Filter | What it matches |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user Steve` | Whose changes. Also takes a natural cause: `#explosion`, `#fire`, `#water` or `#hopper`. |
| `last 2h` | How far back to look, in `m`, `h`, `d` or `w`. `day` means since midnight. |
| `older 30d` | Only changes older than this. Also takes `mo` and `y`. |
| `near 50` | Blocks around you |
| `in world_nether` | Worlds, or `sel` for your WorldEdit selection. A lookup and a purge also take a world that is not loaded. |
| `block *_sign` | A block, item or mob. A `*` matches any part of a name. |
| `cause explosion` | A kind of change, named like the [events in `config.yml`](/docs/reference/config/#logging-events) |
| `kind containers` | `blocks`, `containers` or `entities`, which a rollback changes, or `items`, `books`, `chat`, `commands` or `sessions`, which are for lookups only |
| `not user Alice` | Leaves out a `user`, an `in` world, a `block`, a `cause` or a `kind`. `not user` also leaves out what that player set going, like the fire they lit or the water they poured. |
| `page 2` | The next page of a lookup |
A comma adds more values to `user`, `in`, `block`, `cause` and `kind`, after `not` too. The line matches any of them:
```plaintext
/rollback user Steve, Alex last 1d not cause worldedit, sign
/rollback user Steve in world, world_nether
/rollback near 30 not user Alice, Bob
/lookup user Steve not in world_nether
```
You can type a space after the comma or not: `user Steve,Alex` means the same. You can also repeat the word, and you can mix both forms. These three lines name the same players:
```plaintext
/rollback user Steve, Alex, Notch
/rollback user Steve user Alex user Notch
/rollback user Steve, Alex user Notch
```
Tab completion helps with the list. After you pick one value, the list of suggestions stops. Type a comma to see the suggestions for the same filter again, without the values you already named. Type a space to see the next filter words. A comma needs a value on each side, and `last`, `older`, `near` and `page` take one value only. `in sel` stands alone: a WorldEdit selection lies in one world, so it joins no other world. You can’t use `not in sel`, and Oasis refuses a line that keeps and leaves out the same player or world, like `user Alice not user Alice`, because it matches nothing.
Oasis doesn’t understand CoreProtect’s `u:`, `t:` and `r:` words or its `#preview` flags. If you type them out of habit, Oasis runs nothing and shows you the same command in Oasis words, for example `'u:Griefer' is CoreProtect syntax. Did you mean /rollback user Griefer last 2h near 20?`
## Build a command
[Section titled “Build a command”](#build-a-command)
Pick a command, then add filter words and their values. The builder shows the command and what it would do. Copy it and paste it in game.
An interactive command builder. It starts empty. Pick /lookup, /rollback or /rs (restore), then add filter words such as user, last, near, block and cause, and pick a value for each. You can change or remove each part of the command, and a plain sentence says what the command does. Several values of one word, such as two players, join with a comma. For example, /rollback user Steve last 1d not cause worldedit rolls back everything Steve did in the last 24 hours, except WorldEdit changes.
/Pick a command below
Copy
Pick a command to start.
Start with what you want to do
/lookupsee who changed what/rollbackundo changes/rsrestore: put back what a rollback undid
Start over
Build a real Oasis command one word at a time, then paste it in game.
## The inspector
[Section titled “The inspector”](#the-inspector)
With `/inspect` on, left-click a block to see its history, or right-click a face to see the empty space in front of it, like the spot where a broken block used to be. Clicking won’t break or place anything while it’s on. Anything a rollback already undid is crossed out, and hovering over a line shows what caused it.
## Confirming
[Section titled “Confirming”](#confirming)
A really big rollback asks you to confirm before it starts. Click the link in chat, or type `/oa confirm`.
A rollback or restore with no `user` filter asks too, because it takes every player’s changes in that area, not just the griefer’s. The prompt shows the narrower command, like `/rollback user near 50`. After you confirm three of these, Oasis stops asking you for that reason. A really big one still asks.
Sometimes a rollback finds blocks that someone else has changed since the griefer was there. Oasis leaves those alone, so it doesn’t undo somebody’s repair, and tells you how many it kept. To roll those back as well, click the link or type `/oa force`. `/oasis kept` shows you which blocks they were.
With Packs Server, a rollback that covers a lot of chunks also offers **Confirm with turbo**. See [Embedded or Packs Server?](/docs/guides/embedded-or-server/#what-packs-server-is-for)
Oasis runs one rollback or restore at a time, and `/oasis cancel` stops the one that’s running. `/oasis purge` takes the same filters as a rollback and always asks you to confirm, because what it deletes is gone for good.
## Worlds that are not loaded
[Section titled “Worlds that are not loaded”](#worlds-that-are-not-loaded)
A lookup and a purge read the history and never touch the world. So `in` takes any world that is loaded, that Oasis saw loaded, or that still holds edits in the history. The world needs no folder. Tab completion after `in` lists these worlds and marks the ones that are not loaded. A name that no world has shows `No world named X` and the worlds that Oasis knows.
A rollback and a restore write the world. If the world is not loaded, Oasis loads it from its folder for the rollback. If the folder is gone, Oasis refuses and says `World X is not loaded, and Oasis cannot load it: its folder is gone.` Use `/lookup in ` to read its history, and `/oasis purge in ` to delete it.
## Purging a world
[Section titled “Purging a world”](#purging-a-world)
To delete every edit of a world, run `/oasis purge in world_nether` and confirm. A purge that names worlds and a time bound (`older`) and no other filter is a purge of whole worlds. It deletes the rollback edits of those worlds too, and the entries of those worlds in the operation log for each operation that finished before the cut, so the history of the world is gone. A cut inside an operation keeps the record and the undo of that operation. An operation that covered several worlds stays undoable in the other worlds.
Add `user`, `near`, `block`, `cause`, `kind`, `last` or `not` and the purge deletes only the edits that match. It then keeps the rollback edits, because they mark what a rollback reversed. The count in the confirmation leaves out the edits that it keeps.
When a purge leaves a world that is not loaded with no edit, Oasis forgets the world. A later lookup of it shows `No world named X`.
## Importing old history
[Section titled “Importing old history”](#importing-old-history)
`/oasis import coreprotect` brings in your CoreProtect history, whether it’s stored in MySQL, SQLite, DuckDB or ClickHouse. Oasis reads CoreProtect’s own settings, so there’s nothing to set up. That file can hold the database password, so Oasis asks before it reads it, every time.
Then it shows you a preview. Click the link, or type `/oasis import coreprotect confirm`, to start. The import runs in the background while your server stays up, and it never changes the CoreProtect database. `/oasis import status` shows how far it’s got, and `/oasis import cancel` stops it. If it stops partway, run the preview and confirm again, and it carries on from where it stopped. CoreProtect can run beside Oasis: the import reads only the rows from before Oasis’s first logged edit, and the preview names that time. Once an import finishes, Oasis won’t import CoreProtect again. [Import from CoreProtect](/docs/guides/importing/) walks you through it and explains what comes over.
## Sharing the cairn
[Section titled “Sharing the cairn”](#sharing-the-cairn)
The cairn is a log Oasis keeps of what it did, in `plugins/Oasis/cairn`: how each rollback went, and a few of the blocks it touched with the history of each. It helps us find what went wrong when you report a bug, without asking for your whole history.
If we ask for it in your [GitHub issue](https://github.com/oasis-protection/oasis/issues), run `/cairn share` and post the ID Oasis gives you. Once we approve it, Oasis sends the cairn and gives you a link to post. Nothing is sent before that.
## Everything else
[Section titled “Everything else”](#everything-else)
`/oasis move` moves your history between Packs Embedded and Packs Server. When it ends, Oasis renames the old store and deletes it 7 days later. A cancelled or failed move leaves the old store as it was. See [Set up Packs Server](/docs/packs-server/setup/#4-bring-your-history-along).
`/oasis fawe patch` and `/oasis fawe tune` are about FastAsyncWorldEdit. See [The FAWE patch](/docs/guides/fawe-patch/) and [Lagging? Check FAWE first](/docs/guides/embedded-or-server/#lagging-check-fastasyncworldedit-first).
If Oasis ever stops logging, everyone on the server is told in chat, with no permission needed: when it happens, when they join, and every five minutes until it’s fixed.
# Configuration
> What each setting in plugins/Oasis/config.yml does.
Oasis creates `plugins/Oasis/config.yml` the first time it starts. Out of the box it logs everything and keeps the history on your own server, so you don’t have to change anything to get going.
Below is the whole file with its default values. Click any setting to see what it does and what it accepts.
After you edit the file, run `/oasis reload`. Settings marked **Needs a restart** are read only when the server starts, so restart the server for those.
storage:[#](#storage)
engine: embedded[#](#storage-engine)
Where your history lives. `embedded` keeps it inside your server, in `plugins/Oasis/store`. `server` sends it to Packs Server instead. If you're not sure which you want, stay on `embedded` and read [Embedded or Packs Server?](/docs/guides/embedded-or-server/)
If you switch on a server that already has history, run `/oasis move` after the restart to bring that history along.
Accepts: `embedded` or `server`
Needs a restart
server:[#](#storage-server)
address: 127.0.0.1:7650[#](#storage-server-address)
Where Packs Server listens. The default is right when Packs Server runs on the same machine as Minecraft and outside a panel. If you use Pterodactyl or Pelican, see [Set up Packs Server](/docs/packs-server/setup/#pterodactyl-and-pelican).
The `unix:` form only works when Minecraft runs as the same user as Packs Server, so most servers should use `host:port`.
Accepts: `host:port`, or `unix:` for Packs Server's socket
Needs a restart
store: survival[#](#storage-server-store)
The store you made with `packs store create`. Each Minecraft server needs a store of its own.
Accepts: the name of a store on Packs Server
Needs a restart
key: ""[#](#storage-server-key)
The key Oasis uses to log in to Packs Server. Packs Server shows it only once, when you run `packs key add`. If you lose it, make a new one with `packs key add` and a new name.
Accepts: the private key that `packs key add` printed
Needs a restart
server-key: ""[#](#storage-server-server-key)
Packs Server's own key. Oasis refuses to talk to any Packs Server that can't prove it holds this key, so nobody can pose as your Packs Server.
Accepts: the server key that `packs key add` printed
Needs a restart
outage-after: 5s[#](#storage-server-outage-after)
How long Packs Server can stay silent before Oasis treats it as down. While it's down, Oasis keeps logging into `plugins/Oasis/outbox` and sends everything over once Packs Server is back, so nothing is lost.
Accepts: a length of time, like `5s` or `30s`
Needs a restart
logging:[#](#logging)
ignored-worlds: \[][#](#logging-ignored-worlds)
Worlds where Oasis logs nothing at all, like `[creative, minigames]`.
Accepts: a list of world names
redacted-commands: \[login, l, register, reg, changepassword, changepass, cp, unregister][#](#logging-redacted-commands)
Keeps passwords out of your history. Oasis still logs that someone ran the command, but it writes `` in place of everything after it.
Write each command without the slash and without a plugin name: `login` also covers `/authme:login`. If your login plugin uses other commands, add them here.
Accepts: a list of command names, without the slash
events:[#](#logging-events)
breaking: true[#](#logging-events-breaking)
Blocks, armor stands, boats, and minecarts broken. Like every event, this name is also a word you can use after `cause` in a command, like `/lookup cause breaking`.
Accepts: `true` or `false`
placing: true[#](#logging-events-placing)
Players placing blocks.
Accepts: `true` or `false`
explosion: true[#](#logging-events-explosion)
Blocks destroyed by TNT, creepers, beds and end crystals.
Accepts: `true` or `false`
fire: true[#](#logging-events-fire)
Fire burning blocks away.
Accepts: `true` or `false`
ignition: true[#](#logging-events-ignition)
Fire lit by flint and steel, fire charges, lava or lightning.
Accepts: `true` or `false`
flow: true[#](#logging-events-flow)
Water and lava flowing.
Accepts: `true` or `false`
melting: true[#](#logging-events-melting)
Ice and snow melting, and coral dying.
Accepts: `true` or `false`
forming: true[#](#logging-events-forming)
Ice, snow and concrete forming.
Accepts: `true` or `false`
spreading: true[#](#logging-events-spreading)
Fire, grass, mushrooms and vines spreading.
Accepts: `true` or `false`
decay: true[#](#logging-events-decay)
Leaves decaying.
Accepts: `true` or `false`
growth: true[#](#logging-events-growth)
Crops, saplings and trees growing.
Accepts: `true` or `false`
piston: true[#](#logging-events-piston)
Blocks pushed and pulled by pistons.
Accepts: `true` or `false`
bucket: true[#](#logging-events-bucket)
Water and lava poured or scooped up with buckets, or poured by dispensers.
Accepts: `true` or `false`
sign: true[#](#logging-events-sign)
Text written on signs.
Accepts: `true` or `false`
writing: true[#](#logging-events-writing)
Books written and signed, with their pages. This one is for lookups only: you can search it, but a rollback never touches it, since there's nothing in the world to put back.
Accepts: `true` or `false`
interaction: true[#](#logging-events-interaction)
Doors, gates, trapdoors, buttons and levers used. For lookups only.
Accepts: `true` or `false`
worldedit: true[#](#logging-events-worldedit)
WorldEdit and FAWE changes. Oasis logs FastAsyncWorldEdit, not plain WorldEdit.
Accepts: `true` or `false`
killing: true[#](#logging-events-killing)
Mobs and animals killed.
Accepts: `true` or `false`
spawning: true[#](#logging-events-spawning)
Boats, minecarts and armor stands placed, and mobs from spawn eggs, breeding and splits.
Accepts: `true` or `false`
hanging: true[#](#logging-events-hanging)
Paintings and item frames placed and broken.
Accepts: `true` or `false`
framing: true[#](#logging-events-framing)
Items put in, turned or taken out of item frames.
Accepts: `true` or `false`
equipping: true[#](#logging-events-equipping)
Armor and items put on or taken off armor stands.
Accepts: `true` or `false`
container: true[#](#logging-events-container)
Items moved in and out of chests and other containers.
Accepts: `true` or `false`
dropping: true[#](#logging-events-dropping)
Items players drop.
Accepts: `true` or `false`
pickup: true[#](#logging-events-pickup)
Items players pick up.
Accepts: `true` or `false`
chat: true[#](#logging-events-chat)
Chat messages. For lookups only.
Accepts: `true` or `false`
command: true[#](#logging-events-command)
Commands players run. For lookups only. Arguments of the commands in `redacted-commands` are never stored.
Accepts: `true` or `false`
login: true[#](#logging-events-login)
Players joining. For lookups only.
Accepts: `true` or `false`
logout: true[#](#logging-events-logout)
Players leaving. For lookups only.
Accepts: `true` or `false`
rollback:[#](#rollback)
confirm-above: 100000000[#](#rollback-confirm-above)
How many changes a rollback or restore can touch before Oasis asks you to confirm it. The default is 100 million, so in practice only enormous rollbacks ask.
Accepts: a number of changes
turbo-above-chunks: 2000[#](#rollback-turbo-above-chunks)
Only matters with Packs Server. A rollback or restore that covers more chunks than this offers the **Confirm with turbo** button. Turbo moves the players out of the affected area before the operation starts. This setting counts chunks, not changes. Raise it to offer turbo less often.
Accepts: a number of chunks
target-tick-ms: 45[#](#rollback-target-tick-ms)
The tick length Oasis protects while a rollback runs. Oasis places blocks with whatever time the tick has left, and it stops at this mark no matter what. A Minecraft tick is 50 ms, so the default of 45 leaves a little room to spare. Lower it if you'd rather have rollbacks take longer and the server feel smoother while they run.
Accepts: a number of milliseconds
updates:[#](#updates)
check: true[#](#updates-check)
Whether Oasis looks for a newer build. It looks when the server starts and every six hours after that, and names a newer build in the console and in `/oasis status`. A dev build tells you about the newest build, and a release only about newer releases. Oasis never downloads or installs an update by itself. [Updating](/docs/updating/#finding-out-about-updates) says more.
Accepts: `true` or `false`
diagnostics:[#](#diagnostics)
console: false[#](#diagnostics-console)
Oasis always records what each rollback, restore, undo, recovery, and lookup did and how long each step took, a few of the blocks each one met with their history, and the health of the server and the store each minute, in `plugins/Oasis/cairn`: every record for 90 days in `days`, in at most 512 MB. Starts, errors, outages, and failed operations also stay 12 months in `year`, in at most 64 MB. Nothing leaves the server unless you run [`/cairn share`](/docs/reference/commands/#sharing-the-cairn) when the Oasis team asks for it in a GitHub issue. Set this to `true` to also print the one-line summaries of the records in the console.
Accepts: `true` or `false`
# Embedded or Packs Server?
> Most servers never need Packs Server. Here is what it does, and when it's worth setting up.
Oasis keeps your history in Packs, its own storage engine. Packs can run in two ways:
* **Packs Embedded** runs inside your Minecraft server. It’s the default, and there’s nothing to set up.
* **Packs Server** runs as a separate program next to your Minecraft server, and Oasis talks to it.
## You don’t need Packs Server
[Section titled “You don’t need Packs Server”](#you-dont-need-packs-server)
A lot of people assume the separate server is the “real” option and the built-in one is a toy. With most logging plugins, that’s a fair guess. Their built-in SQLite storage is there so you can drop the plugin in and get going, and once your server gets busy, everyone tells you to move to MySQL because lookups and rollbacks have become painfully slow.
Oasis doesn’t work like that. We built Packs Embedded first, and we tested Oasis on it before anything else. It’s the same engine as Packs Server, running the same code. Most servers can run Packs Embedded forever, and that includes busy ones.
## What Packs Server is for
[Section titled “What Packs Server is for”](#what-packs-server-is-for)
This isn’t a toy against the real thing. Packs Embedded is a beast. Packs Server is the same beast with a home of its own.
With Packs Embedded, Oasis shares your server’s memory and CPU. Saving history, answering lookups and preparing rollbacks all happen in the same process as the game. Oasis does that work in the background and never on the main thread, but it still shares the machine with Minecraft, so it has to stay polite and leave the game room. On most servers there’s plenty of room for it.
Packs Server moves that work into a program of its own, with its own memory and its own threads. Two things get better:
* **Saving keeps up more easily.** Oasis writes new history to a journal first, then packs it into its long-term files. That packing is called sealing. On Packs Server, sealing never competes with the game for CPU or memory, so it keeps pace even when your server is at its busiest.
* **Memory cleanup gets out of the game’s way.** Packs Server always runs on Java 25 with the ZGC garbage collector, which cleans up memory without long pauses. Most Minecraft servers run G1, Java’s default and the one Aikar’s flags use, and you’d have to switch your whole game server to get ZGC. Packs Server sets it up for you, and its cleanups never pause your game.
The result is more breathing room for Minecraft and for every other plugin you run.
It also unlocks **turbo** rollbacks. When a rollback or restore covers more than 2,000 chunks (you can change that number), Oasis offers a **Confirm with turbo** button. Turbo moves players out of the area and lets Packs Server write the repaired chunks while nobody is using them, so your game server does far less of the work. That’s handy after a huge grief on a busy server.
So Packs Server is worth it when:
* your server is busy and every millisecond of the tick already counts,
* you run lots of heavy plugins that all want CPU time and memory,
* you often roll back huge areas and want turbo.
If none of that sounds like your server, stay on Packs Embedded. You lose nothing.
## Lagging? Check FastAsyncWorldEdit first
[Section titled “Lagging? Check FastAsyncWorldEdit first”](#lagging-check-fastasyncworldedit-first)
If your server stutters during big WorldEdit jobs, Packs Server usually isn’t the fix. A single FastAsyncWorldEdit setting matters far more.
FAWE has a setting called `max-memory-percent`, and it ships at 95. At that level, a big edit can fill almost all of your server’s memory before FAWE lets go of any of it. Java then spends its time cleaning up memory instead of running your game. On one of our test servers, a single large edit caused 134 long memory cleanups in two minutes, and TPS fell to 12. Lowering the setting made the stall go away.
Oasis can check this for you:
```plaintext
/oasis fawe tune
```
It looks at how your server’s Java is set up and suggests a value: 75 if you use Aikar’s flags, 85 if you use Java’s defaults. Run `/oasis fawe tune confirm` to apply it. If you’d rather do it by hand, change `max-memory-percent` in `plugins/FastAsyncWorldEdit/config.yml`.
On most laggy servers, this one change does more than a move to Packs Server. It matters most on Packs Embedded, because there Oasis and FAWE share the same memory.
## You can switch later
[Section titled “You can switch later”](#you-can-switch-later)
Nothing here is permanent. If you outgrow Packs Embedded, set up Packs Server, change a few lines in Oasis’s config, restart, and run `/oasis move` to bring your history across. You can move back the same way. After a move, Oasis keeps the old store for 7 days under a new name, and then deletes it.
Ready to set it up? See [Set up Packs Server](/docs/packs-server/setup/).
# The FAWE patch
> What /oasis fawe patch does, why it exists, and why it's entirely up to you.
If you run FastAsyncWorldEdit, you may see this in `/oasis status`:
```plaintext
FAWE: can log edits under the wrong player, run /oasis fawe patch
```
That line can look alarming, so here’s the whole story. The short version is that you don’t have to do anything. Oasis and FAWE work fine without the patch. The patch fixes one rare mix-up, and whether you turn it on is up to you.
## Why it exists
[Section titled “Why it exists”](#why-it-exists)
FAWE has a small bug. When two WorldEdit jobs run at the same time, FAWE can mix them up and hand a piece of one job to the other. For Oasis, that means part of one player’s edit can end up logged under the other player’s name.
For a logging plugin, the name is the whole point. If it’s wrong, a lookup can blame the wrong person, and a rollback of one player can miss part of their edit or touch part of someone else’s. The same mix-up can also trip up FAWE itself, in its own undo history and in pastes.
We found the bug while testing Oasis and reported it to the FAWE team as [issue #3668](https://github.com/IntellectualSites/FastAsyncWorldEdit/issues/3668). The fix is a one-line change, and it’s waiting to be merged as [pull request #3669](https://github.com/IntellectualSites/FastAsyncWorldEdit/pull/3669). Until FAWE ships it, the patch lets you have that fix today.
## What the patch does
[Section titled “What the patch does”](#what-the-patch-does)
The patch makes the same one-line change, in memory, while your server runs. **Oasis never touches the FAWE jar.** Your FAWE install stays exactly as you downloaded it, and if you take Oasis out, FAWE is back to normal on the next start.
Run this to see what it would do. This command doesn’t change anything:
```plaintext
/oasis fawe patch
```
If you’re happy with it, turn it on:
```plaintext
/oasis fawe patch confirm
```
Oasis remembers your choice and applies the patch again every time the server starts, even after you update FAWE. To turn it off, run:
```plaintext
/oasis fawe unpatch
```
That takes effect right away.
## Do you need it?
[Section titled “Do you need it?”](#do-you-need-it)
Probably not urgently. The mix-up only happens when edits overlap, so a server where builders rarely run WorldEdit jobs side by side may never see it. If lots of people use WorldEdit at once, or you want every name in your history to be right, turn it on.
You don’t need to keep track of FAWE’s progress either. When a FAWE release includes the fix, Oasis notices, stops patching, and the line disappears from `/oasis status`. Oasis also leaves alone any FAWE version it doesn’t recognise.
One small note: if your server runs on Java 26 or newer, Java prints a warning when the patch turns on. That’s Java pointing out that a plugin changed another plugin’s setting, which is exactly what you asked for.
## How it works, for the curious
[Section titled “How it works, for the curious”](#how-it-works-for-the-curious)
You don’t need any of this to use the patch. It’s here for anyone who wants to know exactly what Oasis changes before saying yes.
### The bug
[Section titled “The bug”](#the-bug)
When FAWE runs an edit, it collects the chunks the edit changes in a **queue**. Each queue carries its edit’s processors: the steps that check limits and masks, and the one Oasis adds to log the edit and name the player behind it.
FAWE gets that queue from `QueueHandler.getQueue`. To save a little work, `getQueue` keeps one queue per thread and hands that same queue to every edit that asks for one on that thread. So when two edits run on the same thread, they share a queue, and a chunk from one edit can run with the other edit’s processors. For Oasis, that chunk gets logged under the other player’s name. FAWE’s own undo history can get its wires crossed the same way.
### The fix
[Section titled “The fix”](#the-fix)
The fix in [pull request #3669](https://github.com/IntellectualSites/FastAsyncWorldEdit/pull/3669) is one line in `getQueue`: create a new queue every time instead of reusing the shared one.
```diff
final IQueueExtent queue = pool();
final IQueueExtent queue = create();
```
### What Oasis does
[Section titled “What Oasis does”](#what-oasis-does)
Oasis can’t edit FAWE’s code while it runs, and it doesn’t want to touch your jar. Instead, it swaps out the one piece that `pool()` reads from: the queue pool inside FAWE’s running `QueueHandler`. Oasis puts in a pool that never keeps a queue. Every time `pool()` looks in it, it finds nothing and creates a fresh queue, which is exactly what the fix does. `/oasis fawe unpatch` puts FAWE’s own pool back, and that takes effect immediately.
Before it changes anything, Oasis reads FAWE’s `getQueue` to make sure it’s the code it expects:
* If `getQueue` still uses the shared pool, the patch is available.
* If `getQueue` already creates a new queue, your FAWE has the fix, and Oasis does nothing.
* If the code looks different from either, Oasis leaves it alone and says so in `/oasis status`.
The patch only lives in memory, so it’s gone when the server stops. That’s why Oasis writes your choice to a small file, `plugins/Oasis/fawe-patch`, and patches again at each start while that file is there. `/oasis fawe unpatch` deletes the file.
### Why Java 26 warns
[Section titled “Why Java 26 warns”](#why-java-26-warns)
The pool sits in a field FAWE marks as `final`, which means it’s never supposed to change after FAWE sets it. Java 25 lets a plugin change such a field anyway. Java 26 still allows it but prints a warning, as part of Java’s plan to make `final` truly final ([JEP 500](https://openjdk.org/jeps/500)). A later version of Java may refuse unless the server is started with permission to allow it. By then we hope FAWE has shipped the fix and nobody needs the patch at all.
# Import from CoreProtect
> Bring your CoreProtect history into Oasis, step by step, and learn exactly what comes over, what doesn't, and why.
If your server ran CoreProtect before Oasis, you don’t have to lose that history. `/oasis import coreprotect` reads your CoreProtect database and writes it into the Oasis history, so your staff can look it up and roll it back with the same commands they use for everything else.
This page walks you through an import, then explains what comes over, what can’t, and how imported history behaves in lookups and rollbacks. Where something doesn’t come over, it tells you why. Almost always the reason is that CoreProtect never stored it.
## What an import does
[Section titled “What an import does”](#what-an-import-does)
The import reads every CoreProtect table that holds edits (blocks, containers, items, chat, commands, sessions, signs and vehicle inventories), oldest row first. It turns each row into an Oasis edit and writes it into your history.
A few things are worth knowing up front:
* **It only reads.** Oasis opens the CoreProtect database read-only and never writes anything back to it.
* **It runs in the background.** Oasis keeps logging while the import runs, and the import never gets in the way of the live log.
* **The history gets it all at once.** The imported edits join the history when the import ends, so a lookup sees the whole import or none of it.
* **It counts what it leaves out.** Every row that doesn’t come over is counted in the summary at the end, with the reason.
* **It runs once.** After an import finishes, Oasis refuses to import CoreProtect again, so make the first run count. See [An import runs once](#an-import-runs-once).
* **It never imports a row half right.** If CoreProtect kept only part of what a row changed, Oasis leaves the whole row out instead of guessing the rest. A rollback of a half-right row would put back something that never stood there.
## Before you start
[Section titled “Before you start”](#before-you-start)
### Run both plugins side by side
[Section titled “Run both plugins side by side”](#run-both-plugins-side-by-side)
You can install Oasis next to CoreProtect, run both for a while, and import later. CoreProtect can keep running, before and after the import. On DuckDB, this works when Oasis keeps its store embedded on Linux; see below.
Oasis logs every edit from its first logged edit on. The import reads only the CoreProtect rows from before that edit. It leaves out the whole second of that edit. So each edit enters the history once: the older rows come from CoreProtect, and the newer rows come from Oasis’s own log.
The preview names this time, for example `Oasis began logging at 2026-10-05 14:03:27 CEST`. The rows from that time on are already in Oasis, so the counts in the preview cover only the days before Oasis.
If Oasis has logged no edit yet, the import reads the CoreProtect rows from before the start of the import. Oasis logs every edit from then on.
**DuckDB:** A CoreProtect that runs on DuckDB holds its database file. On Linux with the embedded store, Oasis reads the file while CoreProtect runs, and keeps it open until the server stops so that CoreProtect keeps its lock. On Windows, or with Packs Server, Oasis cannot read the file while CoreProtect runs, and the preview says: `CoreProtect runs on DuckDB and holds its database file. Stop CoreProtect, then run /oasis import coreprotect again.` Stop CoreProtect, then run the import. You can run both plugins side by side until then: the import reads only the rows from before Oasis’s first logged edit.
Leave the `plugins/CoreProtect` folder where it is. When CoreProtect isn’t installed, Oasis looks for its settings in `plugins/CoreProtect/config.yml`, next to the Oasis folder.
### Make a backup
[Section titled “Make a backup”](#make-a-backup)
The import doesn’t change the CoreProtect database, but back up `plugins/Oasis/store` (or the store on Packs Server) before a big import anyway. If you don’t like the result, a backup is the quickest way back.
### Check the disk
[Section titled “Check the disk”](#check-the-disk)
Every row that comes over becomes an edit in your history, and each row CoreProtect rolled back brings one more edit. The preview tells you how many rows there are, so make sure the disk has room for a history that size before you start. The **Storage** line in `/oasis status` grows while the import runs.
### Which databases it reads
[Section titled “Which databases it reads”](#which-databases-it-reads)
Oasis reads CoreProtect on all four of its database engines: **MySQL**, **SQLite**, **DuckDB** and **ClickHouse**. You don’t pick one. Oasis takes the engine and the connection details from CoreProtect’s own `config.yml`, the same way CoreProtect reads them.
If your server ran Minecraft before 1.13, CoreProtect’s old block names still come over, because Oasis maps them to the modern names.
### Run the latest CoreProtect once first
[Section titled “Run the latest CoreProtect once first”](#run-the-latest-coreprotect-once-first)
We strongly recommend that you upgrade CoreProtect to a build of its latest source code before you import, and start your server with it once.
Oasis follows CoreProtect’s `master` branch on GitHub, not its numbered releases. Each time CoreProtect starts, it upgrades its own database: it adds new columns, fixes old rows, and applies its bug fixes. A database that a current CoreProtect has upgraded is the database Oasis reads best.
1. Build CoreProtect from the `master` branch of [PlayPro/CoreProtect](https://github.com/PlayPro/CoreProtect), or use the newest build you can get.
2. Put that jar in `plugins` in place of your old CoreProtect, and start the server.
3. Wait until the console says CoreProtect is enabled, then stop the server. CoreProtect has now upgraded its database.
4. Put Oasis in `plugins`, start the server, and run the import. CoreProtect can stay in `plugins`.
### Which CoreProtect versions Oasis reads
[Section titled “Which CoreProtect versions Oasis reads”](#which-coreprotect-versions-oasis-reads)
CoreProtect’s numbered releases don’t map cleanly onto its source code, so Oasis names its support by CoreProtect’s own database version. CoreProtect writes that version into its `version` table.
| Your database | What happens |
| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Database version 2.22 or later: written or upgraded by any CoreProtect build from mid-2023 on, release or `master` | Oasis imports it. Oasis is tested against CoreProtect’s databases from 2025 on and against its current `master`. |
| Older than database version 2.22 | Oasis refuses it at the preview and writes nothing: “This CoreProtect database is older than CoreProtect 2.22 (it records version …). Start it once with a current CoreProtect build so CoreProtect upgrades it, then import.” CoreProtect upgrades any database from version 2.0 on. |
A few things an older database lacks, and how they come over:
* **Player head skins.** CoreProtect stores skins from database version 2.23 on. Without one, a head comes over with its owner and no stored skin.
* **Sign text that CoreProtect rolled back.** The latest CoreProtect builds can roll back sign text, and they mark it in a new column of the sign table. CoreProtect adds that column to an existing database only from version 25 on. Without the column, Oasis can’t tell which sign edits CoreProtect rolled back, so every sign edit comes over as it was logged.
* **Vehicles and their inventories.** CoreProtect tracks these from mid-2026 on. An older database has none to bring.
**ClickHouse:** CoreProtect’s ClickHouse storage is new, and CoreProtect can’t upgrade a ClickHouse database from its first builds of July and early August 2026. Run a current CoreProtect build on ClickHouse once before you import. Oasis refuses a ClickHouse database that is newer than the versions it knows, and says so.
### With Packs Server, the store does the reading
[Section titled “With Packs Server, the store does the reading”](#with-packs-server-the-store-does-the-reading)
The import runs inside the store, not in your Minecraft server. With [Packs Server](/docs/packs-server/setup/), Packs Server connects to CoreProtect’s database. That means:
* a MySQL or ClickHouse host must be reachable **from the Packs Server machine**, so `127.0.0.1` means the Packs Server machine, not your Minecraft server;
* a SQLite or DuckDB file must be at the **same path on the Packs Server machine**.
With Packs Embedded, everything runs on your Minecraft server and none of this matters.
## Run the import
[Section titled “Run the import”](#run-the-import)
You need the `oasis.import` permission.
1. **Start the preview.**
```plaintext
/oasis import coreprotect
```
You can run it in game or from the console.
2. **Allow Oasis to read CoreProtect’s config.**
Before it reads anything, Oasis asks:
```plaintext
To import, Oasis reads the CoreProtect config at . That file can hold the password of the CoreProtect database. Is that okay?
[yes, read it] [no]
```
The path is `config.yml` in CoreProtect’s plugin folder, or `plugins/CoreProtect/config.yml` when CoreProtect isn’t installed. Oasis needs that file for the database engine, the address, the login and the table prefix. Because the file holds the database password, Oasis asks every time.
Click **\[yes, read it]**, and the preview goes on. Click **\[no]**, and Oasis tells you it read nothing and no import starts. In the console, type `/oasis import coreprotect confirm` to say yes. The question lasts two minutes.
3. **Read the preview.**
Oasis connects to the database, counts the rows in each table, and tells you how many it would read. It also lists what comes over and what it leaves out. It names the time that Oasis began logging. Nothing is written yet.
If the database doesn’t answer, you get one line with the reason, such as a wrong password or a missing file. See [Troubleshooting](#troubleshooting).
4. **Confirm.**
In game, click **\[start the import]**. In the console, type the same command again:
```plaintext
/oasis import coreprotect confirm
```
The confirmation lasts two minutes. After that, run the preview again.
5. **Watch it run.**
Oasis prints `Importing CoreProtect on ...` and goes to work. The console gets a progress line every 30 seconds. See [While it runs](#while-it-runs).
6. **Read the summary.**
When it’s done, you get a line like `Imported 12,000 rows from CoreProtect on SQLite at ... in 1 min.`, then one line per table. Each table line says how many rows came over and how many were left out, and why. The person who started the import sees it in chat, and the console always gets a copy.
Only one import runs at a time. If you start another, Oasis tells you one is already running.
## While it runs
[Section titled “While it runs”](#while-it-runs)
`/oasis status` gets an extra line while an import runs:
```plaintext
Import: CoreProtect on SQLite at plugins/CoreProtect/database.db · 12,000 rows in 1 min · 200 a second · in the history when it ends
```
It names the source, the rows written so far, how long the import has run, and its speed. The line counts rows, not edits: a row CoreProtect rolled back also brings a rollback edit with it (see [CoreProtect’s own rollbacks](#coreprotects-own-rollbacks)).
The **Edits** line doesn’t include the import until it ends, because the imported edits join the history all at once. The **Storage** line does grow while it runs, because the files are already on disk.
`/oasis import status` shows the same progress on its own: `Importing CoreProtect on ...: 6,000 rows in 1 min`. After the import ends, it shows the summary again.
## What comes over
[Section titled “What comes over”](#what-comes-over)
| CoreProtect logged | In Oasis | Notes |
| -------------------------------------------------------------------- | --------------------------- | --------------------------------------------------------------- |
| Blocks broken and placed | Block edits | With the block’s state, such as which way it faces. |
| Block clicks (doors, buttons, levers) | Interaction edits | For lookups. |
| Signs | Sign edits | The text on both sides, its colors, glow and wax. |
| Banners | Block edits | With their patterns. |
| Shulker boxes | Block edits | With the items inside, but not their slots. |
| Player heads | Block edits | With the owner and the skin. |
| Spawners | Block edits | With the mob they spawn. |
| Items taken from and put in containers | Container edits | |
| Boats and minecarts placed | Entity edits | |
| Items moved in and out of chest and hopper minecarts and chest boats | Entity edits | |
| Items dropped and picked up | Item edits | For lookups. |
| Chat and commands | Chat and command edits | For lookups. |
| Logins and logouts | Session edits | For lookups. |
| What CoreProtect rolled back | The same edits, crossed out | See [CoreProtect’s own rollbacks](#coreprotects-own-rollbacks). |
For every other block with a block entity (chests, furnaces, beds, beehives and the rest), the block comes over as a new block of that kind holds it. CoreProtect never kept their names, locks or other data, so there’s nothing more to bring. A chest’s items do come over, through its container rows.
## What doesn’t come over, and why
[Section titled “What doesn’t come over, and why”](#what-doesnt-come-over-and-why)
Each of these is counted and left out. The summary line of each table tells you how many.
| Not imported | Why |
| ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Mob kills | CoreProtect keeps a killed mob without its equipment, its potion effects or its health, so a rollback couldn’t bring it back as it was. |
| Mobs spawned from eggs | The game picks a new mob’s variant and traits, and CoreProtect doesn’t keep them. |
| Players killed by players | Oasis doesn’t log a player as an entity. CoreProtect’s own rollback skips these too. |
| Command blocks | CoreProtect keeps only the command, not whether the block runs on its own. A rollback would put back a command block that behaves differently. |
| Spawners placed by WorldEdit, and banners with no pattern data | Some ways of placing or breaking a block (WorldEdit, among others) keep none of its data in CoreProtect. Without it, Oasis can’t rebuild the block. |
| Paintings, item frames and armor stands, and items put on them | Oasis has no edit for these that a rollback can put back. |
| Items moved in and out of jukeboxes, lecterns, chiseled bookshelves, decorated pots and shelves | These blocks hold their items, but they aren’t containers. An Oasis rollback writes items into containers only. |
| Ender chest items | An ender chest belongs to a player, not to a block. A rollback has nowhere to write them. |
| Items thrown, shot, broken, crafted, sold and bought | Oasis has no edit for these. For crafts and trades, CoreProtect logs the recipe, not the items. |
| Clicks, shears and leashes on mobs | Oasis has no edit for these. CoreProtect stores no detail with them either. |
| Vehicle inventories that CoreProtect didn’t follow from the start | If CoreProtect first saw the vehicle after it was placed, the starting contents are unknown, so Oasis can’t rebuild them. |
| Rows with a block, item, mob, world or player this server doesn’t know | See below. |
| Rows whose items don’t read back | The item data CoreProtect saved doesn’t load on this server. Oasis won’t guess the item, so it leaves the row out. |
### Item data CoreProtect silently drops
[Section titled “Item data CoreProtect silently drops”](#item-data-coreprotect-silently-drops)
Sometimes CoreProtect can’t save an item’s data, for example an item with a custom equip sound or a custom music disc song. CoreProtect then drops the part that failed, or all of the item’s data, and it doesn’t tell you. It warns only on its development builds.
The database then holds no sign of the loss, so Oasis can’t see it either. Such an item comes over without the part CoreProtect dropped, or as a plain item with no name, enchantments or other data. A shulker box can come over with fewer items, or empty. These rows count as imported, because what CoreProtect kept reads back fine.
### Unknown names
[Section titled “Unknown names”](#unknown-names)
A row counts as **unknown** when it names something the current server doesn’t recognise:
* **A block or item that Minecraft has since renamed or removed.** CoreProtect stores the name as it was when the row was logged. If your server no longer knows that name, the row can’t be rebuilt. Pre-1.13 names are the exception: Oasis maps those to the modern names.
* **A mob type from an older server.** Older servers used some entity names that differ from today’s, such as `mushroom_cow`.
* **A world CoreProtect has no record of, or a user row that’s missing.**
* **A sign edit where no sign stands**, as far as the earlier rows show.
If the block name is known but its saved state doesn’t fit this server (a property that no longer exists, for example), the row isn’t left out. The block comes in with its default state instead, so the block is right but may face a different way.
## Rolling back imported history
[Section titled “Rolling back imported history”](#rolling-back-imported-history)
An imported block edit is an ordinary Oasis edit. You can roll it back and restore it by player, time, area, block or cause, just like history Oasis logged itself. Oasis’s careful rollbacks work on it too: if someone repaired a block after the griefer, Oasis still keeps the repair.
Some things differ, because CoreProtect stored less than Oasis does.
### No player behind lava, fire and the like
[Section titled “No player behind lava, fire and the like”](#no-player-behind-lava-fire-and-the-like)
When a player pours lava and it burns a house, Oasis normally knows who poured the lava, so one rollback of that player puts the house back. CoreProtect never stored that. It logs the burnt blocks under `#lava` or `#fire`, with no player behind them.
So imported natural changes arrive under their cause, with no player. A rollback of the player who lit the fire doesn’t reach them. To undo that damage in imported history, roll back the cause in the area instead, for example `/rollback user #fire near 30 last 3d`.
CoreProtect’s natural causes arrive like this:
| CoreProtect | Oasis |
| ------------------------------------------------------------------------------------------------------------------------- | -------------- |
| `#fire` | `#fire` |
| `#water`, `#flow` | `#water` |
| `#lava` | `#lava` |
| `#creeper` | `#creeper` |
| `#explosion`, `#tnt`, `#wither`, `#enderdragon`, `#ghast`, `#end_crystal`, `#bed`, `#respawn_anchor` and the wind charges | `#explosion` |
| `#decay` | `#decay` |
| `#natural`, `#tree`, `#vine`, `#mushroom`, `#bamboo`, `#chorus`, `#amethyst`, `#sculk_catalyst`, `#bonemeal` | `#growth` |
| `#piston` | `#piston` |
| `#gravity` | `#falling` |
| `#hopper` | `#hopper` |
| `#dispenser`, `#dropper` | `#dispenser` |
| `#worldedit`, `#we` | `#worldedit` |
| any other `#` name | `#environment` |
### Block data is only what CoreProtect kept
[Section titled “Block data is only what CoreProtect kept”](#block-data-is-only-what-coreprotect-kept)
A rollback puts back what the edit holds. For a banner that’s its patterns. For a shulker box it’s its items, filled from the first slot on, which is how CoreProtect’s own rollback puts them back. For a head it’s the owner and skin, for a spawner its mob with default settings, and for a sign its text. Anything CoreProtect didn’t keep, such as a chest’s custom name, comes back as a new block holds it.
### Containers have no slots
[Section titled “Containers have no slots”](#containers-have-no-slots)
CoreProtect sums up several clicks into one change per item: how many went in, and how many came out. It doesn’t keep the slot. So an imported container edit names the item and the amount, but not where in the chest it was.
### Vehicles
[Section titled “Vehicles”](#vehicles)
A rollback of an imported boat or minecart placement takes that exact vehicle out again, by its ID. A vehicle’s inventory is rebuilt from CoreProtect’s changes, so its slots are Oasis’s own arrangement. Oasis puts each item into the first stack of its kind with room, then the first empty slot.
### Item, chat and session edits are for lookups
[Section titled “Item, chat and session edits are for lookups”](#item-chat-and-session-edits-are-for-lookups)
Drops, pickups, chat, commands, logins and block clicks are for lookups only, the same as when Oasis logs them itself.
### CoreProtect’s own rollbacks
[Section titled “CoreProtect’s own rollbacks”](#coreprotects-own-rollbacks)
If CoreProtect had rolled back a row, the row comes over with a rollback edit on top, so lookups show it crossed out, just like an Oasis rollback. The block ends up as CoreProtect’s rollback left it. The same goes for sign text that CoreProtect rolled back.
CoreProtect marks a sign rollback only in a database that has its new rollback column. See [Which CoreProtect versions Oasis reads](#which-coreprotect-versions-oasis-reads).
There are two differences:
* **`/undo` can’t reach it.** CoreProtect kept no record of the rollback as a whole, only a flag on each row. Oasis has nothing to undo.
* **One case lands differently.** CoreProtect’s flags don’t say which rollback set them. Say one CoreProtect rollback covered two changes to a block, with a change it skipped in between. Oasis then writes two rollbacks, and the block ends up as the later one left it, which can differ from what CoreProtect left.
An inventory rollback in CoreProtect gave a player their items back. It didn’t change the world, so those rows come over as they were.
### Times are to the second
[Section titled “Times are to the second”](#times-are-to-the-second)
CoreProtect stores whole seconds, so imported edits do too. Within one second, Oasis keeps them in the order CoreProtect wrote them. For blocks and signs, CoreProtect stores the moment it saved the row, which can be a little after the change happened.
### Every row gets this server’s data version
[Section titled “Every row gets this server’s data version”](#every-row-gets-this-servers-data-version)
CoreProtect stores no Minecraft data version. Oasis gives each imported row the data version of your current server. After a Minecraft update, you can roll back imported edits like any other edit.
## Looking up imported history
[Section titled “Looking up imported history”](#looking-up-imported-history)
Imported edits show up in `/lookup` and in the inspector like any other edits, as soon as the import ends. Names come from CoreProtect.
For a player, Oasis takes the UUID from CoreProtect’s user table, or from its username log by name. If CoreProtect never stored a UUID for a name, Oasis makes the offline-mode UUID from that name. On an online-mode server, those rows may not match the player’s real account in a lookup by name.
## Stopping and carrying on
[Section titled “Stopping and carrying on”](#stopping-and-carrying-on)
To stop an import:
```plaintext
/oasis import cancel
```
Oasis stops after the rows it’s already working on. It keeps everything it wrote and remembers where it stopped.
To carry on, run the preview and confirm again. The preview says how many rows are still to do, and the import continues from where it stopped. It doesn’t start over. The same goes for a failure, and for a server restart with Packs Embedded: a restart stops the import, and the preview and confirm pick it up again.
With Packs Server, the import runs inside Packs Server and keeps its place while your Minecraft server restarts. It needs your Minecraft server to read CoreProtect’s items and blocks, so it waits for it. Once Oasis has opened the store again, the import goes on by itself, with no command. If the import ended while your Minecraft server was down, Oasis doesn’t announce it at startup. Run `/oasis import status` to see the summary.
A server that’s killed mid-import can lose the last chunk of work that wasn’t saved yet. Those rows are read again from CoreProtect when you carry on, so nothing is skipped and nothing is written twice.
### An import runs once
[Section titled “An import runs once”](#an-import-runs-once)
When an import finishes, the store keeps a record of it. After that, the preview reads no database and offers nothing. It says that CoreProtect was imported in full on that date and that Oasis doesn’t import it twice. A start is refused too. Without this record, a second run would read CoreProtect from the first row and write every row a second time.
The record is kept under the word `coreprotect`, not under one database. So a second, different CoreProtect database is refused as well. `/oasis purge` deletes edits but keeps the record, and there’s no command to import again on purpose. The record lasts as long as the store.
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
**“CoreProtect has no config at …”** Oasis couldn’t find `config.yml`. Put CoreProtect’s folder at `plugins/CoreProtect`, or install CoreProtect and start the server once so it writes the file.
**“database-type in … is …”** CoreProtect’s config names an engine Oasis doesn’t read. Oasis reads `mysql`, `sqlite`, `duckdb` and `clickhouse`.
**“CoreProtect on … did not answer: …”** Oasis couldn’t connect. The rest of the line is the database’s own reason. Check the host, port, user and password in CoreProtect’s config. With Packs Server, check them from the Packs Server machine.
**“CoreProtect runs on DuckDB and holds its database file”** CoreProtect on this server holds the file, and Oasis cannot read it beside CoreProtect here (Windows, or Packs Server). Stop CoreProtect, then run the import again.
**“DuckDB will not open … while another program holds it open for writing”** Another program holds the file, for example a CoreProtect on another server. Stop that program, or import a copy of the file that it closed.
**“… was imported in full on … Oasis does not import it twice.”** This store already holds a finished CoreProtect import. Oasis imports CoreProtect only once, whichever database it is. See [An import runs once](#an-import-runs-once).
**“Oasis did not read the CoreProtect config. No import starts.”** You answered no to the question about CoreProtect’s config. Run `/oasis import coreprotect` again and click **\[yes, read it]**.
**“Nothing to confirm.”** The confirmation ran out after two minutes, or there was no preview. Run `/oasis import coreprotect` again.
**“An import is already running.”** Only one import runs at a time. Check on it with `/oasis import status`.
**“Import failed: … Fix the cause, then run /oasis import coreprotect again to carry on.”** Something went wrong partway, such as a lost connection. The import keeps its place, so fix the cause, then run the preview and confirm again.
**Lots of rows counted as unknown** Usually these are blocks or items that Minecraft renamed since CoreProtect logged them, or mobs with old names. The summary tells you which table they’re in. Oasis can’t map them, because the current server doesn’t know those names.
# Set up Packs Server
> Install Packs Server on Linux and connect Oasis to it.
Most servers don’t need this. If you aren’t sure, read [Embedded or Packs Server?](/docs/guides/embedded-or-server/) first.
## What you need
[Section titled “What you need”](#what-you-need)
* A Linux machine with one of these systems:
* Debian 13 (trixie) or newer, or Ubuntu 24.04 or newer
* Fedora 44 or newer, or RHEL 10 and its rebuilds, such as Rocky Linux and AlmaLinux
* openSUSE Leap 16 or Tumbleweed
* Arch Linux
* Root access, through `sudo` or a root shell.
* About 2 GB of free memory for Packs Server. You can [change that later](/docs/packs-server/operations/#give-packs-server-more-memory).
The usual setup is Packs Server on the same machine as your Minecraft server, and that’s what this guide sets up.
## 1. Install Packs Server
[Section titled “1. Install Packs Server”](#1-install-packs-server)
Pick your system, then the tab that matches your Oasis: Release for a release of Oasis, Dev for a [dev build](/downloads/?channel=dev). Then run the whole block as root:
SystemDebian and Ubuntu
* Debian and Ubuntu
* Fedora and RHEL
* openSUSE
* Arch Linux
- Release
```sh
mkdir -p /etc/apt/keyrings
curl -fsSL https://oasis-protection.com/packs.asc -o /etc/apt/keyrings/packs.asc
echo "deb [signed-by=/etc/apt/keyrings/packs.asc] https://telesphorepo.com/debian/packs-server-deb/ stable main" > /etc/apt/sources.list.d/packs.list
apt update
apt install packs
```
- Dev
```sh
mkdir -p /etc/apt/keyrings
curl -fsSL https://oasis-protection.com/packs.asc -o /etc/apt/keyrings/packs.asc
echo "deb [signed-by=/etc/apt/keyrings/packs.asc] https://telesphorepo.com/debian/packs-server-deb-dev/ stable main" > /etc/apt/sources.list.d/packs.list
apt update
apt install packs
```
If `curl` is missing, install it first with `apt install curl`.
* Release
```sh
cat > /etc/yum.repos.d/packs.repo <<'EOF'
[packs]
name=Packs Server
baseurl=https://telesphorepo.com/rpm/packs-server-rpm/
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://oasis-protection.com/packs.asc
metadata_expire=1h
EOF
dnf install packs
```
* Dev
```sh
cat > /etc/yum.repos.d/packs.repo <<'EOF'
[packs]
name=Packs Server
baseurl=https://telesphorepo.com/rpm/packs-server-rpm-dev/
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://oasis-protection.com/packs.asc
metadata_expire=1h
EOF
dnf install packs
```
dnf asks once whether to trust the key of Packs Server. Say yes if its fingerprint is `E1BA EE0F B8E8 FD38 BD59 64ED 3515 7D66 8BB2 FA00`.
* Release
```sh
rpm --import https://oasis-protection.com/packs.asc
cat > /etc/zypp/repos.d/packs.repo <<'EOF'
[packs]
name=Packs Server
baseurl=https://telesphorepo.com/rpm/packs-server-rpm/
gpgcheck=1
repo_gpgcheck=1
autorefresh=1
EOF
zypper install packs
```
* Dev
```sh
rpm --import https://oasis-protection.com/packs.asc
cat > /etc/zypp/repos.d/packs.repo <<'EOF'
[packs]
name=Packs Server
baseurl=https://telesphorepo.com/rpm/packs-server-rpm-dev/
gpgcheck=1
repo_gpgcheck=1
autorefresh=1
EOF
zypper install packs
```
- Release
```sh
curl -fsSL https://oasis-protection.com/packs.asc -o /tmp/packs.asc
pacman-key --add /tmp/packs.asc
pacman-key --lsign-key E1BAEE0FB8E8FD38BD5964ED35157D668BB2FA00
grep -q '^Include = /etc/pacman.d/packs.conf' /etc/pacman.conf || echo 'Include = /etc/pacman.d/packs.conf' >> /etc/pacman.conf
printf '[packs-server-arch]\nSigLevel = Required\nServer = https://telesphorepo.com/arch/$repo/$arch\n' > /etc/pacman.d/packs.conf
pacman -Syu packs
```
- Dev
```sh
curl -fsSL https://oasis-protection.com/packs.asc -o /tmp/packs.asc
pacman-key --add /tmp/packs.asc
pacman-key --lsign-key E1BAEE0FB8E8FD38BD5964ED35157D668BB2FA00
grep -q '^Include = /etc/pacman.d/packs.conf' /etc/pacman.conf || echo 'Include = /etc/pacman.d/packs.conf' >> /etc/pacman.conf
printf '[packs-server-arch-dev]\nSigLevel = Required\nServer = https://telesphorepo.com/arch/$repo/$arch\n' > /etc/pacman.d/packs.conf
pacman -Syu packs
```
This installs Java 25 if you don’t have it already, then starts Packs Server. It starts again by itself whenever the machine reboots. [Run Packs Server](/docs/packs-server/operations/#update-it) shows how to update it.
To switch between dev builds and releases later, run the other tab’s block. A dev build you already have stays until the next release comes out, and then the update installs it as usual.
## 2. Make a store
[Section titled “2. Make a store”](#2-make-a-store)
A store holds the history of one Minecraft server. Make one, plus a key that your server uses to log in:
```sh
packs store create survival
packs key add survival paper
```
The second command prints two keys: **the private key** and **the server key**. Copy both now, because Packs Server shows the private key only once. If you lose it, run `packs key add` again with a new name.
[The `packs` command](/docs/packs-server/cli/) lists everything else it can do.
## 3. Connect Oasis
[Section titled “3. Connect Oasis”](#3-connect-oasis)
Open `plugins/Oasis/config.yml` on your Minecraft server and fill in the `storage` section:
```yaml
storage:
engine: server
server:
address: 127.0.0.1:7650
store: survival
key: "paste the private key here"
server-key: "paste the server key here"
```
Restart your Minecraft server. Then run `/oasis status`. It should say **Packs Server**.
### Pterodactyl and Pelican
[Section titled “Pterodactyl and Pelican”](#pterodactyl-and-pelican)
With a panel, your Minecraft server runs inside a container. Inside that container, `127.0.0.1` means the container itself, not the machine that runs Packs Server, so Oasis needs a different address. The panel gives every container a private network that reaches the machine, and Packs Server can listen there.
First, find that network’s address. Open Wings’ config file, `/etc/pterodactyl/config.yml` for Pterodactyl or `/etc/pelican/config.yml` for Pelican, and look under `docker`, then `network`, then `interface`. It’s usually `172.18.0.1`.
Next, tell Packs Server to listen on it. Open [`/etc/packs/packs-server.properties`](/docs/packs-server/properties/), change the `listen` line, and restart Packs Server:
```properties
listen = 172.18.0.1:7650
```
```sh
systemctl restart packs-server
```
Finally, use the same address in Oasis’s config:
```yaml
address: 172.18.0.1:7650
```
If you run a firewall like `ufw`, let the containers through with `ufw allow from 172.18.0.0/16 to any port 7650`.
### Packs Server on another machine
[Section titled “Packs Server on another machine”](#packs-server-on-another-machine)
Keep Packs Server on the same machine as your Minecraft server, or on the same local network, such as two VMs on one host. A longer distance makes lookups and rollbacks slower.
Nothing stops you from running it further away. Two servers in the same data center may be close enough that you never notice. If you try it, test lookups and rollbacks on your own setup and decide whether the delay is acceptable to you. Set [`listen`](/docs/packs-server/properties/#listen) to an address your Minecraft server can reach, put that address in Oasis’s config, and open port 7650 in the firewall to your Minecraft server’s address only.
The connection is encrypted over TCP, wherever the two run. The keys you made in step 2 prove each side to the other, and each connection gets fresh keys of its own, so nobody between the two machines can read your history or change what Oasis sends.
## 4. Bring your history along
[Section titled “4. Bring your history along”](#4-bring-your-history-along)
If you used Packs Embedded before, your old history is still in `plugins/Oasis/store`. Oasis reminds you about it at startup. To bring it over, run:
```plaintext
/oasis move
/oasis move confirm
```
Lookups and rollbacks are paused until the move finishes. `/oasis move status` shows how far it has got. If you cancel the move or it fails, the old copy stays untouched, and you’re back where you started.
When the move ends, Oasis renames the old store and does not delete it. With Packs Embedded, the old copy waits in `plugins/Oasis/store-moved-