Content generated with AI — it may contain mistakes.

Modules

Replays

The last minute around any player, saved on a death, a report, a freeze or on request, and watched from any server with ping and server lag on the board.

The server keeps the last minute of everything around every player in memory. Nothing is written anywhere until something worth keeping happens: a death, a report, a freeze, a staff member or a player asking for it. Then that window is cut, stored in the database, and any staff member on any server can step into it as a flying camera, with the controls on their hotbar and a board that says how the server and both players' connections were doing at every moment.

That board is the answer to "I died to lag": a ping of 900 or a server at 12 TPS is either on it or it is not.

Module id replay, switch modules.replays, files under modules/replay/. Watching needs PacketEvents.

Commands

CommandPermissionWhat it does
/staffreplay <player>exyliastaff.replayOpens that player's saved replays. /sreplay is an alias.
/staffreplay capture <player>exyliastaff.replay.captureSaves the last minute around a player on this server, now.
/staffreplay debug <id>exyliastaff.replayLists what a saved replay holds, in chat.
/staffreplay leaveexyliastaff.replayStops watching.
/savereplayexyliastaff.savereplayA player saves their own last minute. /saveclip and /clip are aliases.

The bare /staffreplay answers with its usage lines. The player argument is anybody the network knows, online or not; capture needs them on this server, because the minute is only in this server's memory.

The command is not /replay on purpose: a practice server already has one, for its duels.

Grant /savereplay to everyone

exyliastaff.savereplay is meant for the default group, like /report and /helpop. A player who wants to report somebody and cannot record their own screen saves the minute instead, and the staff member reading the report watches it. It costs one database row and a cooldown.

When a replay is saved

CauseSaved whenSwitch
DeathSomebody dies. The replay carries on after-death seconds past the death, so the fall is in it.capture.death
ReportSomebody is reported, if they are on the reporter's server.capture.report
FreezeA freeze starts.capture.freeze
Staff save/staffreplay capture, or Save now in the list.Always on
Player save/savereplay, every player-saves.cooldown-seconds.player-saves.enabled

The anticheat module saves one too when a player sets off a burst of alerts; see Exylia Staff Web.

Everybody is recorded, staff in vanish included: only staff watch these, and a staff member reviewing their own fight, or a report against somebody who was spectating in vanish, needs them in it. A save of somebody who was not recorded on this server in that window is "Nothing of them was recorded".

Watching

/staffreplay <player> lists their replays, newest first, each drawn with the icon of its cause and its length, how many players and things are in it, the date, the server and the coordinates. Left click watches; shift and right click deletes, with exyliastaff.replay.delete. Save now keeps the last minute around that player, with exyliastaff.replay.capture.

The replay is staged on a temporary world before anybody moves, so one that cannot be shown never takes the viewer anywhere. They are put into it as a flying camera; leaving puts them back where they were. Opening another replay while watching goes straight to the next one.

SlotItemLeft clickRight click
0Spectral arrow5 seconds backOne frame back
1ClockPlay or pause; at the end it starts again
2Arrow5 seconds onOne frame on
3Recovery compassPrevious hit, death, teleport or disconnection
4SugarSlowerFaster
5CompassNext hit, death, teleport or disconnection
6Ender eyeFirst person, through each player in turnThe list of who is on screen
7RepeaterBack to the first second
8BarrierLeave

The controls are drawn on the client, never put in the inventory: the viewer's own items stay underneath and come back when they leave. The layout is lang/<language>/modules/replay/hotbar.yml.

The players list shows everybody on screen at that moment with their ping: left click flies to them, right click watches through their eyes. As the replay passes them, chat lines, deaths, teleports, disconnections and totems are written into the viewer's chat, and the action bar shows the time, the speed and whose eyes the camera is in. With reveal-invisible on, invisible players are drawn glowing, so nobody hides in a replay.

From reports and restores

A replay is one click from where staff need it:

  • The report alert ends with ▶ Replay, which runs /reports replay <id>.
  • In /reports, shift and left click a report; in one player's reports, press Q on a report, or open Replays for their whole list.
  • In the inventory restore screen, a death backup has Watch what happened: the death replay nearest to that backup.

All of them need exyliastaff.replay. When the replay saved with a report is missing, because the player was not recorded or it is still being written, the click opens that player's list instead.

Across servers

Replays are rows in the shared database, so a death on one server is watched from any other. With terrain on, the ground the replay happened on is stored with it, from vertical-margin blocks above and below where people went, up to max-chunks chunks, so it can be watched anywhere and after the place has changed. Without it, a replay can only be watched on the server it was recorded on, over whatever is there now.

Configuration

plugins/ExyliaStaff/modules/replay/config.yml
seconds: 60
radius: 32.0
after-death: 3
terrain: true
vertical-margin: 24
max-chunks: 400
max-entities: 1500
capture:
  death: true
  report: true
  freeze: true
player-saves:
  enabled: true
  cooldown-seconds: 120
keep-days: 14
keep-per-player: 30
reveal-invisible: true
board:
  enabled: true
  title:
    - '{primary}&lREPLAY'
  lines:
    - ''
    - '{secondary}Playback:'
    - ' {letters_black}▎ {letters}Time {letters_black}» {info}%staff_replay_time%{letters_black}/{info}%staff_replay_length% ⌚'
    - ' {letters_black}▎ {letters}Speed {letters_black}» {info}%staff_replay_speed% {letters_black}%staff_replay_state%'
    - ''
    - '{secondary}Players:'
    - ' {letters_black}▎ {highlight}%staff_replay_player% {letters_black}» {info}%staff_replay_player_ping%'
    - ' {letters_black}▎ {letters}%staff_replay_opponent% {letters_black}» {info}%staff_replay_opponent_ping%'
    - ''
    - '{secondary}Server:'
    - ' {letters_black}▎ {letters}TPS {letters_black}» {info}%staff_replay_tps%'
    - ' {letters_black}▎ {letters}MSPT {letters_black}» {info}%staff_replay_mspt%'
    - ' {letters_black}▎ {letters}On {letters_black}» {info}%staff_replay_server%'
    - ''
  update:
    interval: 5
    smart: true
icons:
  death: SKELETON_SKULL
  report: WRITABLE_BOOK
  freeze: PACKED_ICE
  manual: SPYGLASS
  player: PLAYER_HEAD
KeyDefaultWhat it does
seconds60How far back a replay reaches. The server keeps this much around every player in memory at all times.
radius32Blocks around a player that are recorded. Whoever was this close to anywhere they went is in their replay.
after-death3Seconds a death replay carries on after the death.
terraintrueKeep the ground, so a replay can be watched on any server.
vertical-margin24Blocks above and below where people went that the ground is kept.
max-chunks400Chunks one replay keeps. A long chase keeps its end.
max-entities1500Things that are not players followed at once, server-wide.
player-saves.cooldown-seconds120Between two /savereplay by the same player.
keep-days14Days a replay is kept. The ground goes with the last replay that needed it.
keep-per-player30Replays kept per player; the oldest go first.
reveal-invisibletrueDraw invisible players glowing while watching.
boardThe sidebar shown while watching.
iconsThe icon of each cause in the list.

Expired replays are purged when the module starts and every hour after that.

Messages

lang/<language>/modules/replay/messages.yml: saved with %target%, %seconds% and %id%; player-saved with %seconds% and %id%; player-cooldown with %time%; player-disabled; nothing-recorded, no-replays, no-replay-for-backup; loading, load-failed, unsupported, deleted, not-watching; following with %player%, following-none, nobody-on-screen, no-more-events; the chat lines line-chat, line-death, line-teleport, line-quit and line-totem; hud with %time%, %length%, %speed%, %state%, %bar% and %following%, and its pieces state-playing, state-paused, bar-done, bar-left, hud-following; unknown, no-opponent; usage; and causes, the name of each cause.

Placeholders

Read by the viewer, while watching; empty otherwise.

PlaceholderValue
%staff_replay_time%Time on screen.
%staff_replay_length%Length of the replay.
%staff_replay_speed%Playback speed.
%staff_replay_state%state-playing or state-paused.
%staff_replay_following%Whose eyes the camera is in, empty for none.
%staff_replay_player%The player the replay is about.
%staff_replay_player_ping%Their ping on the tick on screen.
%staff_replay_opponent%Who they were last fighting on that tick, or no-opponent.
%staff_replay_opponent_ping%That player's ping.
%staff_replay_tps%The server's TPS on that tick.
%staff_replay_mspt%The server's MSPT on that tick.
%staff_replay_cause%Why it was saved.
%staff_replay_server%The server it was recorded on.

A figure that was not recorded reads as unknown.

Storage

staff_replays for what was saved, staff_replay_data for the recordings and staff_replay_chunks for the ground.

Something missing on this page? Tell us on Discord