Running a server
Restarting the server when a plugin asks
A plugin can ask the server to restart, for example a gamemode with wipes at the end of a season. The
server cannot start itself again. What it does is stop exactly as /stop does, with every plugin told
the server is stopping and then stopped, and the world and everybody in it saved, and then end with
exit code 75 instead of 0. Whatever started the server reads that code and starts it again.
| Exit code | Meaning | What to do |
|---|---|---|
0 | Stopped (/stop, Ctrl+C, the management API). | Stay stopped. |
75 | A plugin asked for a restart; everything was saved. | Start it again. |
1, 2 | Refused to start: a bad rustmc.yml, an unknown generator, a world that could not be made. | Read the log; starting again will fail the same way. |
| anything else | It crashed. | Your choice; a loop that restarts on everything hides crashes. |
When a plugin asks, the console logs RESTART: plugin <name> asked for the server to restart (...)
with the plugin's reason. Everybody online is disconnected with that reason ("the server is
restarting" if it gave none), each saved as they leave. The stop waits up to five seconds for them to
go, then saves whoever is still there. A second request while a restart is under way is ignored.
A start script
Two start scripts in the tools folder of the rustmc repository, run-with-restarts.sh (Linux,
macOS, Git Bash) and run-with-restarts.ps1 (Windows), run the server and start it again,
after a two-second pause for the port to be let go of, whenever it ends with 75, and only then:
tools/run-with-restarts.sh ./rustmc-server --survival
powershell -File tools\run-with-restarts.ps1 .\rustmc-server.exe --survival
Both pass their arguments to the server unchanged, and end with the server's own exit code when it ends with anything other than 75.
Under systemd
No script is needed. RestartForceExitStatus restarts on exactly that code, and a normal stop
(code 0) stays stopped:
[Service]
ExecStart=/opt/rustmc/rustmc-server --survival
WorkingDirectory=/opt/rustmc
Restart=no
RestartForceExitStatus=75
SuccessExitStatus=75
In Docker
restart: unless-stopped restarts after any exit, including a deliberate /stop. To restart only
when a plugin asked, run the start script as the container's command instead.
A world reset on the next start
A plugin can also ask for the world to be made fresh on the next start. That is off by default, and
refused unless you allow it in rustmc.yml:
world-reset:
allow-plugins: true
The default is false. With it off, a plugin's request is refused, and a reset asked for earlier is
left undone, with the console saying so at every start.
A request is the file rustmc-reset-requested.json in the world's folder, and the console says when
one is made. Delete the file to take the reset back; the plugin can also take it back itself.
On the next start, before the world opens, the world's folder is renamed to
<world>-reset-<yyyymmdd>-<hhmmss> beside it (with -2, -3 and so on if that name is taken).
Nothing is deleted. A fresh world is then made from server.properties with the seed the plugin
named, or a random one, never level-seed, which would make the same world again. The generator is
whichever rustmc.yml chooses. The console prints where the old world is kept and the new seed.
The renamed folder keeps everything that was in the world: builds, player files, the Nether and the
End, and the request itself, renamed with .done on the end. Delete it when you are sure. On a server
started with a world path, the server's own files and plugin data are kept in the world's folder, so
they move aside with it.
If the folder cannot be renamed, the world opens as it is and the reset is tried again at the next
start. A server started with --no-generate does not reset.
From docs/restarting.md in the RustMC repository at bbd81209ad.