DraxGUI operator guide

Updated 28 October 2026

For server owners and administrators. It explains how to install DraxGUI, reach the editor, build and apply menus, give players the resource pack, and run the plugin safely.

What "tested" means in this guide. Where it says something was tested, verified or seen, it ran on a real server with a real client, and the versions are named. Everything else describes what the plugin does, with its limits.

What the tests covered. One Windows 11 machine with vanilla Java clients, Paper servers with PacketEvents 2.14.0, and the Shader-Safe renderer unless stated otherwise. Nothing was run on Linux or macOS, behind a proxy such as Velocity or BungeeCord, with a permission plugin or with an anti-cheat plugin. Bedrock was tested on Windows only (Bedrock players).

Other guides: Advanced code runtimes (scripts and their trust policy), Bedrock players (Geyser/Floodgate), MCP adapter (AI clients), Expressions and templates (the expression language), Webhooks and Tebex checkout and the compatibility matrix.


1. What DraxGUI does to your server

  • It draws menus, HUDs and popups for players with no client mod and no chest inventory. Pictures and text come from a resource pack that DraxGUI builds. Text shaders in that pack (vanilla core-shader overrides for the GUI text) position the glyphs.
  • It adds a browser editor served by the plugin itself (no Node.js, no cloud account, no AI account needed).
  • It never sends or hosts a resource pack itself, never edits server.properties, and never touches another plugin's pack configuration. With ItemsAdder, CraftEngine, Nexo or Oraxen installed, applying a build puts it into that plugin's pack and runs its rebuild, which delivers the pack as you set it up (pack.auto-export); otherwise you publish the pack yourself (section 8).
  • A change made in the editor reaches players only after a person runs /draxgui applyedit <id>. The editor and AI clients cannot apply a build (section 7).
  • While a screen is open the player's camera is redirected client-side (packet-only display entity, the player is seated on it on the client), mouse movement becomes a cursor, clicks go to a packet-only Interaction entity and the wheel is read from hotbar changes. The server-side player is not teleported, frozen or made invulnerable. Some of the player's packets are cancelled while the screen is open (rotation, hotbar slot changes, arm swings, digging, block placement, item use). Anti-cheat plugins were not tested.
  • HUDs, popups and screens are composed into the player's action bar. While DraxGUI composes a player's action bar, action-bar messages other plugins send to that player are captured and shown inside the DraxGUI composite for about three seconds instead of replacing it.
  • An open Shader-Safe screen draws its pointer on the player's title line. Titles and subtitles other plugins send while it is open are held back (they would hide the pointer) and shown when the screen closes, for the display time they have left; a title that was already showing when the screen opened comes back the same way. Titles whose time ran out while the screen was open are not shown. Standard screens and HUDs do not use the title line.

2. Requirements and tested combinations

Item Requirement Tested
Server software Paper (the plugin uses Paper API such as getPluginMeta() and AnvilView; plugin.yml has api-version: '1.21.4') Spigot, Folia, Purpur and other forks: not tested, not advertised. The plugin uses the global Bukkit scheduler and does not declare Folia support.
Required plugin PacketEvents, plugin name packetevents (depend in plugin.yml), 2.14.0 or newer per the start-up message Only 2.14.0 was tested.
Java for the server The JDK your Paper version requires. The DraxGUI JAR is Java 21 bytecode Ran on JDK 21 (Paper 1.21.4, 1.21.11) and JDK 25 (Paper 26.3). Java 21 bytecode does not imply that a Java 25 server runs on Java 21; use the JDK Paper asks for.
Optional plugins Floodgate (Bedrock detection and forms), Geyser, Vault (Money node), PlaceholderAPI, ItemsAdder, CraftEngine, Nexo, Oraxen are softdepend entries Floodgate and Vault have code (reflection, loaded only when present); ItemsAdder and CraftEngine have the operator-run /draxgui export adapter (found by plugin name, never linked; section 9). PlaceholderAPI is read through placeholder() in expressions; Nexo and Oraxen have the same export adapter, built from their documentation. Run on a server: Vault + EssentialsX (Money), Geyser + Floodgate with a Windows Bedrock client, ItemsAdder 4.0.18 and CraftEngine 26.9.2 (export); PlaceholderAPI, LuckPerms, Nexo and Oraxen not run yet.
Player clients Java Edition, vanilla, with the DraxGUI resource pack loaded See the table below.
Bedrock players Geyser + Floodgate on the backend (Bedrock players) Custom Bedrock screens (with the build's .mcpack in Geyser) or plain forms: tested on Bedrock 26.52 for Windows with mouse and keyboard; phones, touch and controllers not tested.
Browser for the editor A current Chromium-based browser Exercised in a Chromium pane only; Firefox and Edge untested.

Tested server/client combinations (real clients)

Paper build Server JDK Vanilla client Shader family Verified there (Shader-Safe)
1.21.4 build 232 JDK 21 1.21.4 f1 menus, HUDs, popups, scrolling, tabs, sliders, toggles, anvil text input, tooltips, applyedit, editor round trip, Player HUD demo, MCP-authored demo
1.21.8 build 60 JDK 21 1.21.8 f2 Control Panel demo: HUD, hover, click, wheel scroll with clipping, tooltip, popup, tabs, Shift close
1.21.11 build 132 JDK 21 1.21.11 f3 Control Panel demo: panel, click, wheel, settings, tooltip, popup, close
26.1.2 build 74 JDK 25 26.1.2 f4 same as 1.21.8
26.2 build 134 JDK 25 26.2 f5 same as 1.21.8
26.3 build 209 JDK 25 26.3 f6 same as 1.21.11, plus the Candy Cascade demo with JavaScript/Python/Java bonus rules (scripts trusted on the test server only)
1.21.4 build 232 JDK 21 1.21.4 Fabric 0.19.5 + Iris 1.8.8 + Sodium 0.6.13 f1 Control Panel demo with Complementary Reimagined r5.9, BSL v10.1.5 and shaders off; Standard world panel under BSL

All of this is tested only within that scope. Details:

  • Every shader family ran in a real client with one representative version each. Other versions that share a family with a tested one (1.21.5, 1.21.6, 1.21.7, 1.21.9, 1.21.10, 26.1, 26.1.1) were not run; an untested version stays untested.
  • Standard renderer (world-space panels, Move / scale): verified on 1.21.4 only (Paper 1.21.4-232 with a 1.21.4 client; other versions are still to come). When a Standard screen opens, the player's view is turned to the panel (panels are axis aligned; players rarely face exactly north, east, south or west).
  • Games: the Redstone Run template (/redstone) is the showcase: a Shader-Safe screen drawn over the view like the store, sprites moved with Move / scale twenty times a second, movement keys through the screen's key event (Java 1.21.2+) and one Java project script, so it needs scripts.trust: trusted-admin (a restart) and a JDK with javac (tested on Paper 1.21.4-232 with a 1.21.4 client; Bedrock players get a plain form instead).
  • Iris shader packs: the product runtime works with Iris 1.8.8 on 1.21.4 with Complementary Reimagined r5.9, BSL v10.1.5 and shaders off. Standard world panels take the shader pack's lighting and bloom. Iris on 26.x and OptiFine were not tested; name the packs you tested rather than saying "works with all shader packs".
  • Pointer feel: the cursor is driven by client rotation packets, i.e. about 20 updates per second. Per-frame smoothness applies to shader animations, not to the pointer. Latency under added network delay and 60 FPS animation were not measured.
  • Crosshair: the vanilla crosshair stays visible on Shader-Safe screens unless a panel covers the centre (custom crosshairs draw over the vanilla one).
  • GUI scale / ultrawide: anchor accuracy was proven with an early prototype at 16:9, 21:9, 32:9, 4:3 and GUI scale 2; the product HUD was only seen at 16:9; GUI scales 3-4, FOV and fullscreen are untested.

3. Install

  1. Get the JAR. The download on DraxGUI's BuiltByBit page is a zip with DraxGUI-<version>.jar, MCP Bridge Setup.txt (for AI clients, see the MCP adapter) and Thanks For Purchasing.txt. The JAR from BuiltByBit carries your licence key.
  2. Install PacketEvents (the plugin build packetevents, 2.14.0 or newer) into plugins/. Without it DraxGUI logs PacketEvents is required (install packetevents 2.14.0 or newer in plugins/). DraxGUI is disabled. and disables itself.
  3. Put the DraxGUI JAR in plugins/ and start the server on the JDK your Paper version needs. Do not use /reload: /reload breaks PacketEvents.
  4. Optional: install Floodgate (and Geyser) for Bedrock players, Vault plus an economy plugin for the Money node.

First start

On first start DraxGUI creates plugins/DraxGUI/config.yml from the bundled default and the data folders (section 16). The console shows, in order, lines such as:

DraxGUI <version> READY (PacketEvents 2.14.0, <Paper version string>)
Editor listening on 127.0.0.1:8765 (local mode: this machine only)

READY means everything started. DEGRADED means an optional part failed (for example the editor port is taken) and the reason is listed; menus keep working. If startup throws, DraxGUI logs DraxGUI failed to start; resources are released and the plugin is disabled. Run /draxgui status to see the state, Java and PacketEvents versions, the active generation, editor state, Bedrock bridge, ffmpeg and script runtimes.

First-run checklist (about ten minutes)

  1. Console or an operator: /draxgui editor, open the printed link on the server machine (section 6).
  2. In the editor create a project from the Control Panel template (templates: blank, control_panel, player_hud, candy_cascade).
  3. Press Build & Deploy at the top right, choose the Java versions, Build, then Deploy. The panel shows /draxgui applyedit <id>.
  4. Run that command in game or in the console. Expect Applied <id> (<project> r<revision>).
  5. Download the pack from the same panel (Downloads), host it and point the server at it (section 8); rejoin so the pack loads.
  6. /draxgui open <project>:<screen> [player] (the Control Panel template's screen is home, so for a project named demo: /draxgui open demo:home). Move the mouse to move the cursor, click to press, Shift closes (closeOnSneak is a screen option).

4. Configuration reference (plugins/DraxGUI/config.yml)

/draxgui reload re-reads config.yml and re-applies only the keys marked "reload". Everything marked "restart" is read once at startup. The shipped config.yml marks each key the same way.

Key Default Applies Meaning
license.key "" reload Your licence key. Leave it empty for a copy downloaded from BuiltByBit (it carries the key). A changed key is checked right after /draxgui reload. Your licences and the servers using them are listed in the licence panel.
editor.enabled true restart false disables the editor, the REST API and the MCP endpoint; /draxgui editor then reports "The editor is not running".
editor.bind-address 127.0.0.1 restart Interface for the editor listener. Keep loopback.
editor.port 8765 restart TCP port. If it cannot be bound the plugin runs DEGRADED without an editor.
editor.public-url "" restart Public HTTPS base address when the editor is reached through a reverse proxy or tunnel, e.g. https://editor.example.com. Empty = local mode. Sets the browser origin DraxGUI accepts and the host in /draxgui editor links. See section 6.
editor.trusted-proxies [] restart Read but currently unused. X-Forwarded-For is never read anywhere in the web module, so listing proxies has no effect. DraxGUI sees every proxied request as coming from the proxy's address.
pack.name server restart Names the outputs: draxgui_<name>_pack.zip and draxgui_<name>_bedrock.mcpack, and the font/texture namespace inside the pack. Must match [a-z0-9_]{1,32}; anything else silently becomes server. Changing it creates a different pack: players need the new one.
pack.resolution 2 reload Texels per GUI pixel (whole number 1-4) for builds that do not choose one; the editor's Build panel does not send its own value, so this setting applies. Invalid values fall back to 2 with a warning.
security.console-commands [] reload Command roots that the Run command node may run as console (compared lower-case with the first word, no leading /). Empty disables console mode, and a console-mode Run command then fails. Player-mode commands always use the player's own permissions. Treat every entry as a permission you hand to everyone who can edit projects. (From main: the node now has a failed exit, so a refused or failed command can be handled in the graph; without a failed connection the flow stops and is logged, see section 15.)
input.chat-max-length 50 reload Character limit for chat prompts (clamped to 1-256). The anvil is always capped at 50; live typing uses the box's own maxLength (up to 256). The shipped comment mentions Bedrock forms too, but only chat prompts use this value; a Bedrock input uses the element's maxLength (default 50).
input.prompt-timeout-seconds 60 reload Seconds before an unanswered chat/anvil text prompt expires (minimum 1). Players type cancel to abort a chat prompt.
media.ffmpeg-path "" restart Optional ffmpeg executable for MP4/WebM import. PNG, APNG, JPEG, GIF, WebP (still and animated) and SVG decode without it. DraxGUI never downloads it.
bedrock.layouts auto restart Custom Bedrock screens, HUDs and popups. auto: used when Geyser's packs folder (plugins/Geyser*/packs/) holds exactly the deployed build's .mcpack (checked off the main thread after every deployment and every 30 seconds while missing; the console and /draxgui status say which applies and why); otherwise plain forms and no Bedrock HUDs. Unquoted YAML true/false count as on/off. on: always (Geyser on a proxy, where DraxGUI cannot see the folder; keep the proxy's pack current). off: always plain forms. DraxGUI never copies packs. See Bedrock players.
media.video-frame-cache-mb 1024 restart Disk space for decoded MP4/WebM frames (plugins/DraxGUI/cache/video-frames). A video is decoded with ffmpeg once per frame step and renderer budget; later builds reuse those frames, so they still work (and give the same frames) after ffmpeg is removed or upgraded. Least recently used entries are removed first; deleting the folder is safe (the next build decodes again, which then needs ffmpeg).
scripts.trust disabled restart disabled or trusted-admin. Any other value makes startup fail. See section 13.
scripts.syncWaitMs 0 restart 0..20 ms the server thread waits for a script's result so its effects apply in the same tick (real-time games such as Redstone Run: 8); slower calls fall back to the next tick.
scripts.languages.<lang>.executable / memoryMb auto / 128, 256, 256 restart Per-language runtime for javascript, python, java. The full option list is in Advanced code runtimes.
aliases {} reload Each entry maps a root command name to a /draxgui subcommand prefix, e.g. popup: "popup" makes /popup show ... the same as /draxgui popup show ..., with the same permission checks. See Dynamic commands. The built-in alias /dgui for /draxgui comes from plugin.yml.
web all off reload (worker/queue sizes: restart) Outbound Webhook endpoints and the optional Tebex adapter. Projects name endpoint ids only; URLs, secrets and tokens stay here or in environment variables. Egress to private, loopback, link-local and cloud-metadata addresses is refused unless you allowlist it. See Webhooks and Tebex checkout.
models.skin-lookup true reload Players without a skin in their profile (offline mode, or a proxy that does not forward skins) get Mojang's skin for their name on heads and 3D player models. DraxGUI sends the names of players online to api.mojang.com and sessionserver.mojang.com, off the main thread, and keeps answers 6 h (unknown name 1 h; failures retried after 30 s, 2 min, then 10 min). false: default skins, nothing is sent.
debug false reload Extra [debug] console lines (for example a failing graph step). Tokens and player inputs are not logged.

A screen's own Open command field (for example the templates' panel, candy) is validated for duplicates and registered as a real command (see Dynamic commands). /draxgui open <project:screen> always works too.

5. Commands and permissions

/draxgui (alias /dgui). With no arguments, or an unknown subcommand (including help), it prints the commands you may use. Every DraxGUI chat line starts with a purple DraxGUI » and is coloured by kind (information, done, warning, error); names and numbers stand out in white, /draxgui … commands in a line are clickable and fill in the chat box, and a missing permission shows its node on hover. Player-typed text is never read as formatting. The text stays readable from the console and RCON.

Permissions (plugin.yml)

Permission Default Grants
draxgui.open op /draxgui open for yourself
draxgui.open.others op open / close aimed at another player
draxgui.close everyone (true) /draxgui close for yourself
draxgui.hud op parent of draxgui.switch and draxgui.hud.element; also hud who
draxgui.switch op /draxgui hud show|hide|reset
draxgui.hud.element op /draxgui hud item ...
draxgui.popup op /draxgui popup show|hide
draxgui.var op /draxgui var ...
draxgui.admin op children: open, open.others, close, hud (and so its children), popup, var. Needed itself for list, editor, applyedit, rollback, reload, status, license, mcp

Permissions were tested with Bukkit permission attachments on a non-operator, not with a permission plugin such as LuckPerms. Give normal players draxgui.close implicitly and delegate everything else deliberately. A screen may also declare its own open permission and open when condition; /draxgui open honours both in addition to draxgui.open (the screen check applies to the target player even when an administrator opens it for them).

Subcommands

Command Permission Behaviour
open <project:screen> [player] draxgui.open (+ draxgui.open.others for another player) Opens a screen. Refused in spectator mode, while the player is in a vehicle, when the screen's permission or open when fails, or when no deployment is active. Bedrock players (Floodgate) get a form. Console must name a player.
close [player] draxgui.close (+ draxgui.open.others for another player) Closes the open DraxGUI screen; safe when none is open.
list [page] draxgui.admin Lists the active generation's screens, HUDs and popups (10 per page) with click-to-prepare commands.
editor draxgui.admin Issues a single-use editor link (section 6).
applyedit <id> [--allow-older] draxgui.admin Applies a pending edit (section 7).
rollback draxgui.admin Switches to the last-known-good generation.
reload draxgui.admin Reloads config.yml (reload-marked keys) and re-activates the generation stored on disk. Open screens close with "Menus were updated (reload)". It does not rebuild projects. (From main: it also re-registers the dynamic open commands and aliases.)
hud show|hide|reset <project:hud> draxgui.switch Self only (console gets an error). Forces that HUD, forces no HUD for its selector, or returns to rules.
hud item show|hide|reset <project:hud> <element> [player] draxgui.hud.element Overrides one element's visibility; console must name a player.
hud who [player] draxgui.hud Explains the HUD chosen per selector, the winning rule or override, HUDs not shown, element overrides, and the player's resource-pack status. Another player needs draxgui.hud.
popup show <project:popup> <player|*> [key=value ...] draxgui.popup Shows a popup with typed values. * is a snapshot of online players (max 500).
popup hide [project:popup|all] [player] draxgui.popup Ends one or all popups; omitted player = yourself. An unknown popup id is rejected with "Unknown popup ...".
var set|add|toggle|reset|get <project:variable> [value] [player] and var list [player] draxgui.var Typed variable access (section 11).
pointer [0.25..4] draxgui.pointer (default: everyone) Shows or sets the player's own pointer sensitivity in Shader-Safe menus (a multiplier on the screen's pointer speed; 1 = default). Saved in data/player-prefs.json.
status draxgui.admin Diagnostics (section 15), including Key to draw: the server-side time from a key press arriving to the redraw being sent on screens with a key event (network and client time excluded), and Script calls: how many script results were applied in the same tick (scripts.syncWaitMs).
license [recheck] draxgui.admin The licence state (active, offline grace, first-start grace, refused, grace over, or not enforced in a development build), where the key came from, whether this copy came from BuiltByBit, the last answer, how long it covers offline use, the next check and a link to the client panel. recheck checks now (at most every 30 s). A refused or long-unreachable licence turns off editor, applyedit, deploys and new AI tokens; live menus keep working.
mcp token create <name> <projects|all> [--caps a,b] [--ttl 30d], mcp token list, mcp token revoke <name> draxgui.admin MCP credentials (section 14). --ttl takes <n>m, <n>h or <n>d.
export <itemsadder|craftengine|nexo|oraxen> [dry-run|remove|check [file]] draxgui.admin Writes the active build into that plugin's content folder for its own rebuild (section 9); never runs its commands or sends packs.

Tested live on Paper 1.21.4 with a vanilla client: editor and applyedit, popup show, var, open for yourself and for another player from the console, the HUD commands, denials and grants for a non-operator, the parent draxgui.hud grant, close, list, popup hide, rollback and reload (both audited), console target errors and mistyped ids. The tests used Bukkit permission attachments, not a permission plugin.

Tab completion offers subcommands you may use and ids from the active generation.

Dynamic commands

Verified on Paper 1.21.4 with a vanilla client.

  • Screen open commands. Each screen's open.command (set in the editor, e.g. panel for the Control Panel template) is registered as a real server command whenever a generation activates (applyedit, rollback, reload, server start). The command is gated by the screen's own open.permission (everyone when none is set). /<command> <player> additionally needs draxgui.open.others. The runtime still checks the target player's screen permission and the screen's open.when. /draxgui open keeps requiring draxgui.open as well.
  • Aliases. Entries under aliases: in config.yml map a command name to a /draxgui subcommand prefix. popup: "popup" makes /popup show example_hud:reward Steve amount=250 equivalent to /draxgui popup show ...; the same permission checks apply. Command and alias names must match [a-z0-9_-]{1,32}.
  • Collisions. A name already owned by the server or another plugin is never replaced: DraxGUI skips it, logs a WARNING, and lists it under "Dynamic commands" in /draxgui status.
  • Lifecycle. Every activation or reload first unregisters DraxGUI's previous dynamic commands and resyncs the client command tree. Commands that have a permission are hidden from players who lack it (they see "Unknown or incomplete command").
  • Aliases and open commands are (re)created at every activation and on /draxgui reload, so a changed aliases: section or a renamed open command applies without a restart (reload also closes open screens).

6. Editor access

New authors get help inside the editor: Wisp, a small helper with a wand, flies them through a ten-stop tour on the first visit (and again from the ? menu) and runs three step-by-step lessons that tick themselves off as the project changes, with "Show me" buttons that send Wisp to the right spot and "Try it" buttons that open a practice project named after the lesson (earlier steps already done) where Wisp walks the author through each step live (steps an author completes stay ticked in the guide across projects, kept in that browser for each player); the Guide (the ? key and the ? menu in a project; a full page on the home screen, from the sidebar or the Guide button) has a guide home with the lessons and every topic as cards, live try-it boxes, short quizzes, and covers a first menu, themes, HUDs and popups, logic, scripts, building a game (Redstone Run, step by step), shipping and Bedrock, and the project tree keeps scripts and graphs under Advanced until they are used (Show advanced tools in the same menu). The editor's home page lists the projects with thumbnails, search and sorting, and offers a blank project, a Control panel and a Player HUD (each with its own setup dialog and a live sketch of the result) and an Import dialog that shows what a file contains before importing it.

Control panel. The Control panel card opens the same live dialog as the templates (a clickable preview; the settings can be opened again from the project). A panel is built from sections the owner picks, none forced: Profile (the player's head and name with up to five lines; values take ${expressions}, %placeholders% from PlaceholderAPI and {player}), Buttons (up to twelve, each with a Lucide icon and one action: run a command as the player, run it as the console when security.console-commands allows it, send to a server through BungeeCord or Velocity, or post a clickable link in chat), Settings (switches each player sets, saved as persistent player variables cp_<section>_<setting>, optionally running a command as the player when switched on or off) and Text page. Up to six sections show as tabs, a sidebar or one page that scrolls, at compact (300 × 200) or large (420 × 236), with a greeting beside the heading. Buttons lift (or grow) on hover and press in (or bounce) on click on Java, or stay still. Starting points: Player menu (profile, menu buttons, links, rules), Server info, Player settings and Blank. The old fixed panel (volume slider, notifications, nickname, a list that only set a variable) is gone; the server's own control_panel starter project is unchanged.

Inspector. The Design tab folds into sections (Position & size, the element's own settings, Style with the fields that matter for its type and the rest under More style, Hover & click, Animation, Bindings & conditions, Tooltip & label, Bedrock) and remembers which are open; Find a setting shows only the sections and fields that match. A screen's preferences fold the same way. Hover & click holds the four ways a control reacts: the hover look and click look (style overrides, shown on Java and Bedrock), and the hover animation and click animation (Java). The canvas toolbar's Animations button plays animated pictures (GIF, APNG, WebP) and always-on effects in the design view.

Hover and click animations (Java). hoverAnimation moves a control while the pointer is on it: lift (up 0.5–8 GUI px, eased over three ticks), grow (scale 1.01–1.25), float (up and down 0.25–8 px every period s) and wiggle (side to side 0.25–4 px). clickAnimation plays once when it is clicked, over ms (50–1000): press (scale 0.8–0.99), pop (scale 1.01–1.3), bounce (up 0.5–12 px and back) and shake (side to side 0.5–8 px, settling). Everything inside the control moves with it. Lift, float, wiggle, bounce and shake are offsets the server applies each tick (20 steps a second), and the pointer keeps aiming at the control's resting place, so a lifted button does not flicker. Grow, press and pop draw the control and its children from pictures the pack holds at that scale (keys <element>~h and ~c; text keeps its size and moves with the box), so each such control adds its pictures once more to the pack. Standard (in-the-world) screens map grow and lift to the display's own scale and lift; Bedrock shows the hover and pressed looks without motion. Nested animated controls: the nearest one decides.

Click and type (input boxes, Java). An Input box's method is popup by default: a click opens a vanilla anvil whose title is DraxGUI's typing popup (TypingPopup in every pack: a card at the top of the anvil window with the prompt, the text field and a ✔ button over the result slot), so the player types straight away with no /. Minecraft sends the anvil field's text on every keystroke; DraxGUI puts it into the box at once and runs its change handler (no result item is ever made). ✔, Esc or anything closing the anvil keeps what was typed and submits it. The prompt item has no tooltip and a flat model (draxgui:typing_cover) that covers the anvil's "Inventory" label; the player's inventory is hidden from the popup by sending its slots empty (packets only) and sent again when it closes. Up to 50 characters (Minecraft's anvil limit; anvil_limit warns above). While it is open the menu behind shows the text but Minecraft dims it, and the mouse cursor shows. A build from before the popup gets a plain anvil titled with the prompt. The picture is four 176 × 166-texel tiles (Minecraft draws nothing for a font glyph over 256 texels). A window can't be smaller than the anvil, so below the card it is painted #131314, the colour of a dark menu under Minecraft's dimming: the menu behind is hidden there while typing, and over a light menu it shows as a dark area. Seen on a 1.21.4 client.

See-through typing popup (opt-in, experimental). input.see-through-anvil names the anvil texture your players see (a copy of textures/gui/container/anvil.png from your server's pack, or Minecraft's own), saved in the DraxGUI folder. Builds then cut that texture below the popup's card, so the menu shows through while typing. DraxGUI draws the cut part back in the title of every other anvil, for players who loaded a pack, so those look as before, except one thing: Minecraft's hover highlight on their inventory slots no longer shows (tooltips do). The popup's card reaches over the first inventory row, where Minecraft puts the mouse on open, so no highlight shows there; moved lower, the mouse still lights up the popup's invisible inventory slots. Anvils that other plugins open without Bukkit's open event show the cut texture. Needs a build and /draxgui applyedit. Seen on a 1.21.4 client.

Live typing (input boxes, Java). With method: live (anvil and chat remain too). A click on the box sends the player a command list with a single node, a greedy text argument whose suggestions the client asks the server for; the box shows Press / and type. When the player presses / and types, the client sends the chat line on every keystroke as a suggestion request: DraxGUI takes it (it never reaches the server's own completion), puts the text into the box at once (up to maxLength, at most 256) and runs the box's change handler, so a search can filter live. Enter sends the line as a command: it is cancelled and becomes the box's answer (submit); a plain chat message (T) is taken as the answer too and never broadcast. A click anywhere else, the screen closing, applyedit, a death, a teleport or leaving ends typing and sends the player's real command list again; while typing, the server's own updates of the command list are replaced, so the player cannot run commands from chat until they finish. Bedrock players type in the form's text field as before. Enter is taken from the command packet before the server handles it, so the typed text is neither run nor written to the server log as a command. While the chat line is open, vanilla shows the recent chat lines over the lower part of the screen. Seen on a 1.21.4 client.

UI templates. The home page's Templates tab offers three templates in three categories, with chips to show one category: Shops (Item shop), Games (Redstone Run) and Lobby (Server selector). The Daily rewards, Game modes, Settings, Leaderboard and Quests templates were removed on 2026-10-24; projects made from them stay ordinary projects (their template settings button no longer shows). The Server selector is a full-screen hub menu (640 × 360, scaled to the window, over a generated hub picture or your own): up to six servers with banners (six generated ones, or your own 2:1 picture), colour, badge, tagline, description and capacity; the selected server fills a big panel with a Play button; Join sends the player through the proxy (player.connect, so the server must be behind BungeeCord or Velocity) or runs a command. Player counts are hidden, read from PlaceholderAPI (%bungee_<server>%, %bungee_total% from the BungeeCord expansion) or from global variables (players_<id>, players_total); each server's status is the global variable status_<id> (online, maintenance, soon), so /draxgui var set <project>:status_creative maintenance closes it live. Each has a setup dialog (colour as a preset or any #RRGGBB) and a live preview, and creates a normal project with its own pixel-art sprites. Redstone Run creates the full arcade game (the same document as examples/redstone_run) with its game settings ready to change: a difficulty preset (Easy, Normal, Hard or Custom), lives (1-9), starting pulse charges (0-3), player and mob speed (50-200 %), golden apple time (25-300 %) and the names of the three caves. They are global variables (cfg_lives, cfg_charges, cfg_hero_speed, cfg_mob_speed, cfg_apple_time, cfg_name_1..3) that the rules read every tick, so /draxgui var set <project>:cfg_lives 5 changes a running server without a rebuild; its rules need scripts.trust: trusted-admin and a JDK, like the example. The item shop covers the whole game: it is drawn at 640 × 360 and scaled to each player's window at any GUI scale (screen setting Scale to fit the player's window); DraxGUI's HUDs are hidden while it is open. It shows a blurred picture behind everything (screen setting Background picture), and its preview and item cards show the viewer as a real 3D player wearing the item (see 3D player models below); the setup dialog takes ItemsAdder ids for what each item puts on the player. What your server must provide: for coins, Vault and an economy plugin, the template's coins variable, or PlaceholderAPI with a balance placeholder (e.g. %playerpoints_points%) plus take/give console commands ({player} and {amount} filled in); console commands used for ranks and placeholder currencies must be on security.console-commands; the server selector's counts come from PlaceholderAPI or variables your proxy plugin sets with /draxgui var set or the API; Send to server needs this server behind BungeeCord or Velocity (bungeecord in spigot.yml, or Velocity forwarding in paper-global.yml). Expressions can read player.balance (Vault), placeholder('%…%') (PlaceholderAPI; numbers come back as numbers, cached 1 s per player) and server.day / server.next_day_in (the server's calendar day in its time zone). See the in-editor guide page "UI templates" for the commands.

3D player models. A Player Model element set to View: 3D on a Shader-Safe screen with Scale to fit the player's window shows a real player in its box instead of a flat picture. While the screen is open the viewer's camera moves to a private stage 12 to 60 blocks above them, where player entities stand in front of a full-bright backdrop block, and the screen is cut open over each model's box (up to 16 boxes per screen). Everything is sent to that viewer only: other players see nothing, and the real player does not move. The models wear the viewer's own skin. On an offline-mode server (or behind a proxy that does not forward skins) players have none, so DraxGUI asks Mojang (api.mojang.com, sessionserver.mojang.com) for the skin of the player's name, off the main thread, and keeps it 6 hours (an unknown name 1 hour; after a failure it asks again in 30 seconds, then 2 and 10 minutes); only names of players online are sent, and a name owned by someone else on Mojang shows that account's skin, as on any offline-mode server. models.skin-lookup: false in config.yml turns it off (default skins). Head, Chest, Legs, Feet, Mainhand and Offhand take minecraft:<id>, leather_<piece>#RRGGBB (dyed) or an ItemsAdder id such as summercosmeticset:summerhat (ItemsAdder's pack must be the one players have). Players turn a Rotatable model by holding the left mouse button on it and moving the mouse (it stops when they let go), with the mouse wheel (30° per notch), or with buttons that change a variable bound to its Yaw. While a stage is open, clicks land on the invisible barrier ahead of its camera: holding the left button on a block makes the client report the press and the release (an entity click reports only the press), and adventure-mode clients are told they are in survival meanwhile (they report no block clicks otherwise; their real mode never changes, and flight is put back on close). Creative clients repeat the press while it is held, so their release is taken 0.45 s after the last repeat. Sliders on such screens also stop dragging on release; turns play smoothly (up to 60° per tick) and keep worn elytra and capes steady. A rotatable model takes the clicks on it, so models inside clickable cards should not be Rotatable (the item shop turns only its preview). While the stage is open the viewer's own weather is clear (rain would fall in front of the models) and light blocks are shown to them at the models; both are put back when the screen closes (the weather only if no other plugin changed it meanwhile).

Third person (F5). F5 moves the client's camera up to four blocks back from what it views through, which would shrink the models and open the windows onto the sky. The stage puts invisible barrier blocks (shown to that viewer only, in air only) right behind and one block in front of its camera: in the back view (F5 once) the camera then stays about 0.14 blocks back, so the models stand where they belong, a few percent smaller; the front view (F5 twice) looks backwards at a dark wall that says "Press F5" in every model window. Clicks are aimed from the stage camera, not the view, so they work in all three views. The barriers go with the rest of the stage when the screen closes.

Fitting the models to a player's window. The world behind the menu scales with the window's height, a menu scaled to the window fits a window narrower than its canvas (split screen, 4:3, 16:10) by its width, and the size of everything depends on the player's field of view: none of which a server can see. The server places the models for a field of view of 70 and a window at least as wide as the canvas; the pack's entity shaders, which do see the window and the FOV, recognise the stage camera's view and scale what it shows so the models, their gear and their backdrops land in their windows at the player's real FOV and window shape. Nothing is measured, saved or clicked: a player can resize the window or change their FOV with the menu open and the models follow. Pictures that lie wholly inside a model's window under the model (the template's pixel figures for the editor and for players without a stage) are not drawn while a stage is open, so a shut window shows its plain panel. When there are not 13 × 9 × 7 blocks of air above the player the screen shows those pictures instead (Flat fallback). Limits: the vanilla hand and crosshair still draw (the crosshair shows through a model window at the screen centre); at fields of view under about 45 the outermost models of a window narrower than the canvas can drop out (the client culls them with its real view before the shader moves them); a build with more than 40 scale-to-window canvases that hold 3D models shows the models of the later ones flat; 1.21.4, 1.21.8 and 1.21.11 clients seen, 26.x clients, Iris shaders and Bedrock (flat pictures) not tested with the stage.

The item shop's settings. The item shop starts with twenty example products named Example 1 to Example 20, each a 3D player wearing a vanilla item and sold by no command (buying only marks it owned) until you set one. Its settings have five tabs, the same when you create the shop and later, from the Shop settings button in the project's top bar:

  • Products: one list of everything the shop sells, each with a name, price, rarity, the item its 3D player wears (an ItemsAdder id such as draxcosmetics:little_hat, or minecraft:elytra; the arrow opens the slot it is worn in, the badge, the description, what the card shows and the command). Add product adds the next Example N. The pages below name products from this list, so a product changed once changes everywhere and owning it counts everywhere. A product can show a name colour ("Hello!" in it, and the buyer's name over the preview) or a rank (its label, or an ItemsAdder texture). Their colour is typed the way ItemsAdder, MiniMessage and chat plugins write it: #FF4D6D, &#FF4D6D, <#FF4D6D>, &c, red, or a gradient <gradient:#FF4D6D:#3FA9FF> / #FF4D6D-#3FA9FF (2 to 8 colours); a swatch shows the result. A rank's ItemsAdder texture (namespace:path under its textures folder, picked from the list the server offers) replaces the label on the card and shows above the name; the server copies the PNG from plugins/ItemsAdder/contents into the project when you save (IA 4 contents/<ns>/textures and older contents/<folder>/resourcepack/assets/<ns>/textures; PNG only, up to 2 MiB; DraxGUI's own export folder is skipped). Owned when (bottom of the tab): by default the shop remembers what each player bought here (a player variable own_<id> per product, set by a purchase); set to A placeholder says so, it asks PlaceholderAPI per product instead ({id} in the placeholder is the product id, e.g. %cosmetics_has_{id}%; the answers that mean owned are a list such as true, yes, 1), so items granted by ranks, crates or that plugin count, the bundle is owned when every product in it is, and the shop keeps no record of its own (a purchase still runs the product's command, which must grant the item in that plugin). Each product's placeholder is asked at most once a second per player.
  • Home page: ask before buying, the two featured products, the bundle (name, prices, what its player wears, its command, and the products it includes, as chips), and the background: the template's beach picture, your image (PNG or JPEG up to 8 MiB, picked with Choose image, shown as a thumbnail, uploaded as the asset img_shop_background_custom when you save and shown cover-cropped to 16:9 at 960 × 540), a plain colour (#RRGGBB or #RRGGBBAA, a shape under everything that reaches the window's sides), or just the game, dimmed.
  • Banner: a picture across the top of one page, which may move. Off (default), Example (a pixel-art crate-keys banner that ships with the editor: the words slide in, a chest opens and throws out three keys; 80 frames of 50 ms) or Your picture (GIF, PNG, JPEG or WebP up to 8 MiB, uploaded as the asset img_shop_banner_custom; animated GIF, APNG and WebP play in game, at most 20 frames a second because frames change on the server tick). The box is 388 × 110 GUI px, so a picture of 776 × 220 (2 texels per GUI px) fits exactly; other shapes are cover-cropped. Shown on: the home page, where it takes the place of the bundle and the featured products, or one category page, where it takes the upper row so that page shows six products (a category with more is reported until you choose fewer). A click shows: optionally a product the banner selects in the preview, ready to buy (it can be bought even without a card of its own). Every frame is a picture in the pack: the example adds about 0.7 MB. The editor's canvas and previews play animated GIF, APNG and WebP pictures as they move in game.

Changing products after the shop is made. Click a product card on the canvas: the inspector names the product it shows and Edit <product> opens Shop settings with that product open (the bundle opens the Home page; with nothing selected the screen's inspector offers Shop settings). In Shop settings, a click on a product in the live preview jumps to it, and with more than six products a search finds one by name, id, badge or item. An open product lists where it shows (featured, days) with switches for the category pages and the bundle, Duplicate (a copy with a new id, so nobody owns it yet) and its id; a product with no card of its own (on no featured slot, day or shown category page) is outlined in amber. Edit products there, not on the canvas: a card's text is not what is charged or given, and saving Shop settings rebuilds the shop's screen, logic and variables (the inspector says so on every element the template made; earlier versions stay in Revision history).

  • Daily: the rotation, from 1 to 7 days of six products each. Server day d shows day d mod days (the server's calendar day, changing at its midnight); one day shows the same six every day. The current day is marked today.
  • Categories: an on/off switch for category pages and up to 4 categories, each a tab in the shop's top bar with a page of up to 12 products (two rows of six) picked as chips. Home stays the first tab. With categories off, the top bar shows the tagline instead.

A screen has 16 windows for 3D models; the shop uses 10 on its home page, and a category page's lower row shares the daily row's windows, so four categories still fit. On the small cards (daily and category pages) a name has two lines of about 10 letters; a longer word is shortened with ".." (the dialog says which). Saving the settings rebuilds the shop, so changes made to it by hand in the editor are replaced (the inspector says so on elements the template made); the version before stays in Revision history. A shop made by an earlier editor has no Shop settings button.

Quick settings (any other project). The top bar's Quick settings collects the values an owner changes most often: select an element and pin its text, colours, picture or other plain values under Quick settings in the inspector, or pin a variable's starting value with the sparkle button in the Variables table; Arrange renames, reorders and removes them, and Save applies every change as one undoable edit. The list is stored in the project (meta.quickSettings, written with the set_project op's new meta field, at most 256 KiB), so every editor of the project sees it; an entry whose element or variable was deleted says so. Projects made from a template show their template's settings instead.

Selling items through commands. A product's command runs as the console when it is bought (typing an ItemsAdder id suggests iagive {player} <id> 1; {player} is the buyer; several commands are separated by ;). The bundle runs its own command if you give one, else every included product's command. Buying takes the price, runs the command, and refunds the price if the command fails. Add each command's name (for example iagive) to security.console-commands in DraxGUI's config.yml, or every purchase is refunded.

Getting in

/draxgui editor (permission draxgui.admin, or the console) prints a link of the form <base>/login#t=<token>. Players get a clickable [Open the DraxGUI editor]; the console prints the URL. Rules (console-issued links were tested, the in-game click path was not):

Rule Value
Link validity 10 minutes, single use. The token is in the URL fragment, never sent in a request line; opening the page with GET spends nothing; the page posts it once. Only a SHA-256 of it is stored.
Browser session exactly 1 hour after redemption, not extended by activity. Cookie dg_session: HttpOnly; SameSite=Strict; Path=/, plus Secure when the base URL is https://.
New link Revokes that issuer's earlier unredeemed links. At most 256 outstanding links and 256 sessions (oldest session dropped).
Redeem rate 10 attempts per minute per remote address.
Authority Re-checked on every request. Console sessions stay valid. A player session needs draxgui.admin or operator status, sampled once per second on the server thread; non-operator sessions also end when the player is no longer online.
Mutations Need the CSRF header and an Origin equal to the editor's configured origin, else 403 csrf_or_origin.
Restart All links and sessions are in memory and die with the server process.
Headers Strict CSP (default-src 'self', no third-party scripts), X-Frame-Options: DENY, no-store on the API and login.

Every editor session holds all of project.read, project.write, asset.write, preview, build, deploy.prepare and script.write. There are no separate editor roles yet. Anyone who can open the editor can author logic that gives items, XP, money (through Vault) and potion effects to players who click it, and can spend your console-command allowlist. Treat draxgui.admin accordingly.

Local mode (default)

Bind 127.0.0.1:8765, no public-url. The link works only in a browser on the machine running the server, and you must open it exactly as printed: the browser origin must equal http://127.0.0.1:8765, so rewriting the host to localhost makes the redeem call fail with 403 csrf_or_origin. Console output may be kept by your host's logging; the link is short-lived and single use, but do not paste it into shared channels.

Remote access

DraxGUI does not terminate TLS and has no firewall, allow-list or SSO of its own. For remote use:

  1. Put an HTTPS reverse proxy in front of 127.0.0.1:8765 (or use a private tunnel such as an SSH port forward that keeps the same local port; the forward follows from the origin rule above and was not tested).
  2. Set editor.public-url: "https://editor.example.com" and restart. The origin check and the links now use that address.
  3. The proxy must preserve the Host header and the browser's Origin header, must not buffer /api/events (server-sent events; the server sends X-Accel-Buffering: no), must allow request bodies up to 256 MiB on /api/uploads (base-pack upload; other uploads are limited to 32 MiB, JSON to 4 MiB), and should not time out long builds' event stream.
  4. Restrict who can reach it (VPN, IP allow-list or proxy-level authentication). The 10-minute link is the only credential and the proxy address appears to DraxGUI as the client address (trusted-proxies is unused).
  5. Do not set bind-address: 0.0.0.0 without a proxy: links would still print http://127.0.0.1:<port>, browsers on other machines fail the origin check, and a plain-HTTP listener would expose cookies and links.
  6. Do not use an http:// public-url on a public network: sessions would travel unencrypted and the cookie would lack Secure.

Illustration only, untested by the project (any HTTPS proxy that meets point 3 works):

server {
    listen 443 ssl;
    server_name editor.example.com;
    # ssl_certificate / ssl_certificate_key: your certificates
    client_max_body_size 256m;
    location / {
        proxy_pass http://127.0.0.1:8765;
        proxy_set_header Host $host;          # keep Host and Origin intact
        proxy_buffering off;                  # /api/events is a live stream
        proxy_read_timeout 1h;
    }
}

What is audited

plugins/DraxGUI/audit.jsonl receives one JSON line per event (time, actor such as player:Name, console:Console, mcp:<token name>, action, project, revision, result): editor.link, editor.redeem (including refusals), project create/replace/ops/archive/import, asset.upload, build.start, deploy.prepare, deploy.apply, mcp.token.create, mcp.token.revoke, deploy.rollback (including refusals), config.reload, pack.export and pack.export.remove (including refusals). There is no IP address. The file rotates at 5 MiB (audit.1.jsonl ... audit.3.jsonl; the oldest is dropped); archive older files yourself if you need longer retention. Tokens are never logged.

7. Build, deploy, apply, rollback

editor "Build"  ->  builds/<buildId>/        (immutable, validated)
editor "Deploy" ->  runtime/pending/<id>.json (pending edit, 24 h)
/draxgui applyedit <id>   ->  new generation active, previous generation kept as last-known-good
/draxgui rollback         ->  swap back
  1. Build (needs build): the editor snapshots every project (the edited project at the requested revision, all others at their current head), compiles one resource pack for the whole server and writes the output atomically to plugins/DraxGUI/builds/<buildId>/. One build runs at a time and at most four wait (429 busy beyond that). A project with validation errors produces no pack. Cancel is available. Outputs: draxgui_<pack.name>_pack.zip, runtime.json (the runtime bundle), report.json, and optionally <base>-draxgui.zip (merge, section 9) and draxgui_<pack.name>_bedrock.mcpack plus draxgui_<pack.name>_bedrock_forms.json (section 14). Every artifact has SHA-1 and SHA-256 in the report. Identical inputs give identical pack bytes on one JDK (identical bytes across different JDKs was not tested). The default Java target is every release in the registry (1.21.4 through 26.3); you can pick a subset. A "universal" pack holds the oldest selected shader family in the pack root and newer families in draxgui_f2 ... draxgui_f6 overlay folders selected by pack format.
  2. Deploy (needs deploy.prepare): creates a pending edit for a finished build and shows /draxgui applyedit <id>. The id is an opaque 8-character handle, not a credential. A pending edit expires after 24 hours. requiresPack tells you whether the build changed the artwork/fonts/shaders (different visual fingerprint) compared with the active generation.
  3. Apply (/draxgui applyedit <id>, needs draxgui.admin, from game or console): refuses an unknown id, an expired id, a build whose runtime.json changed on disk (hash check), and an edit that would roll a project back to an older revision than the one already active (--allow-older overrides; rollback is the intended way). Applying an already applied edit answers "already live" or "applied earlier and has since been replaced". On success the runtime generation switches without a restart, all open screens close ("Menus were updated ... reopen to see the changes"), popups end, and the previous generation becomes last-known-good. The command reports whether players need a new pack. Behaviour tested live on 1.21.4, 1.21.11 and 26.3.
  4. Rollback (/draxgui rollback): re-activates the last-known-good generation and makes the generation you left the new last-known-good, so running it twice returns you. It does not change project sources. If the old generation used different artwork, it tells you which pack file and SHA-1 to serve again. Apply, replay, expiry and unknown ids were tested; rollback was run live (twice, returning to the original generation) and is audited.
  5. Start-up: the active generation is reloaded from runtime/active.json; if it cannot be loaded the previous one in runtime/last-good.json is used and a warning is logged.

Metadata/logic-only builds (requiresPack: false) change nothing on clients and are safe to apply while players are online. A build that adds or changes artwork, fonts or shaders is "runtime applied, pack publication required": until players load the new pack they see missing or wrong graphics, so publish the pack before or right after applying. The command and the editor both say this.

/draxgui applyedit, /draxgui rollback, /draxgui status and the editor name the file players must receive: the merged <base>-draxgui.zip after a Merge build, otherwise draxgui_<pack>_pack.zip, each with its own SHA-1 for resource-pack-sha1 (report.json lists it under distribution).

8. Giving players the resource pack

With a pack plugin (automatic). When ItemsAdder, CraftEngine, Nexo or Oraxen is installed and enabled, /draxgui applyedit and /draxgui rollback put the now-live build into that plugin's pack folder (the same plan, ownership and safety checks as /draxgui export, section 9) and then run the plugin's own rebuild command as the console (/iazip, /ce reload all, /nexo reload pack, /oraxen reload pack), which rebuilds and delivers its pack however you set that plugin up. The reply is one line per plugin ("ItemsAdder pack updated with this build. Rebuilding it now (/iazip).", "already has this artwork", or "not updated: <reason>" with the dry-run command). A blocked export (for example ItemsAdder's text_effects on) changes nothing. Settings in config.yml:

Key Default Meaning
pack.auto-export auto auto: every pack plugin installed; off: never (use /draxgui export yourself); or a list such as [itemsadder].
pack.auto-rebuild true Run the plugin's rebuild command after the export. ItemsAdder's /iazip can pause the server for a few seconds.

This is an exception to "DraxGUI never sends packs" that the owner asked for on 2026-10-24: DraxGUI still does not send or host anything itself and never edits the other plugin's settings; it writes its own folder and runs that plugin's documented rebuild command, and that plugin sends its pack as configured. The editor's Build & Deploy panel names the plugins that will be updated next to the applyedit command.

Without a pack plugin:

Everything DraxGUI draws comes from its pack. DraxGUI will not host or send it; use your existing mechanism.

  1. Download draxgui_<pack.name>_pack.zip (or the merged zip) from Build & Deploy -> Downloads, or copy it from plugins/DraxGUI/builds/<buildId>/. Note the SHA-1 shown next to it.
  2. Host it at an HTTPS URL players can reach, or hand it to the pack plugin you already use.
  3. With plain vanilla delivery set, in server.properties:
    resource-pack=<direct download URL>
    resource-pack-sha1=<the 40-character SHA-1 of that exact file>
    require-resource-pack=true    # optional: kicks players who decline
    
    server.properties is read when the server starts, so this normally needs a restart; with a pack plugin, use its own update procedure. DraxGUI does not read or change these keys.
  4. After every build that changes artwork, publish the new file and update the SHA-1. The SHA-1 of the DraxGUI pack changes with its content.
  5. If you already serve another pack, vanilla offers one server pack, so you normally want Merge or an administrator-managed merge in your pack plugin.

What the DraxGUI pack contains (from PackCompiler): assets/draxgui/textures/<pack>/g/*.png, assets/draxgui/font/<pack>/*.json, the GUI text core shaders under assets/minecraft/shaders/core/ (per shader family: rendertype_text and rendertype_text_intensity files for 1.21.4 through 26.1.2, text.vsh/text.fsh for 26.2 and 26.3), and pack.mcmeta with overlays. The shaders change only DraxGUI's own glyphs under the GUI projection; other text renders like vanilla. It does not install or merge Iris/OptiFine shader packs.

Players without the matching pack see missing-glyph boxes where HUDs or screens appear: DraxGUI does not hide HUDs from players who lack the pack (it records the pack status only for diagnostics). hud who prints unknown (no status reported; DraxGUI does not send packs) when no answer was seen. Otherwise it prints the client's answer and the pack id, including answers given while joining (before join, for packs sent before the player is in the world, such as ItemsAdder's before_join). When the id is ItemsAdder's pack and a DraxGUI export is in it, the line says so and names the exported build (and asks you to export again when that is not the active build); for any other id it prints the expected file and SHA-1 and says it cannot tell whether that id is that file. Make the pack required, or only deploy HUDs that default to hidden until your pack is live.

9. Merging into an existing pack

In Build & Deploy, tick Merge into a pack, upload your pack ZIP (up to 256 MiB), and build. The result is <your zip name>-draxgui.zip. Status: retention, determinism, no nesting and refusal are covered by automated tests; a live merge build was loaded by a 1.21.4 client. Shader composition with a real third-party pack that edits the GUI text shader has not been client-tested: check such merges in a real client.

What it does:

  • Reads your ZIP read-only and rejects unsafe archives: path traversal, absolute or backslash paths, duplicate or case-colliding names, more than 50,000 entries, an entry above 64 MiB, more than 768 MiB expanded, ratio above 200. pack.mcmeta must exist at the root.
  • Every merge starts from your original upload (stored by SHA-256 under uploads/), so repeated merges never nest. If you upload a pack that DraxGUI merged earlier (it contains draxgui-merge.json), the originals are restored first. A pack containing assets/draxgui/ without that manifest is refused: upload your original.
  • Copies all your files byte for byte, adds DraxGUI's files, and de-duplicates identical files. If a path exists in both with different bytes, the merge is blocked with a conflict report; nothing is overwritten.
  • Your pack's declared pack-format range stays authoritative; DraxGUI overlays are added only for formats your pack declares. pack.mcmeta is rewritten (your original is saved as draxgui-originals/pack.mcmeta).
  • Core text shaders: if your pack ships its own rendertype_text, rendertype_text_intensity or text shader in the same family, DraxGUI wraps your main() with its transform (recipe wrap-main-v1). It composes only when the structure matches (one main(), a Position input, ProjMat); otherwise the merge is blocked. Different shaders for different formats inside one family also block. The report marks each composed shader "client check required for this exact base pack".
  • Your ItemsAdder, CraftEngine, Nexo or Oraxen content is not rewritten. DraxGUI writes only its own folder inside their content or pack folder, and only when you run /draxgui export (below; Nexo and Oraxen built from their documentation only). Namespaces do not collide by design (no collision test with those plugins was run). If those plugins generate your pack, merge DraxGUI into the generated file after each regeneration, or use their own documented merge workflow.
  • The output name and SHA-1 differ from the unmerged pack; every DraxGUI message names the merged file and its SHA-1 (section 7).

ItemsAdder and CraftEngine

Status: run on live servers with ItemsAdder 4.0.18 and CraftEngine 26.9.2 (what was seen with ItemsAdder is described below). The folder layouts and behaviour below come from those plugins' official wikis, ItemsAdder's official issue tracker and CraftEngine's source code (project version 26.9.2), read on 2026-10-21.

Use this when players receive the pack that ItemsAdder or CraftEngine generates. Instead of merging DraxGUI into that generated zip after every regeneration (Merge), DraxGUI places its files in the plugin's own content folder, so the plugin includes them each time it builds its pack. ItemsAdder and CraftEngine stay optional: DraxGUI finds them by plugin name, never links against them and works without them.

What DraxGUI does, only when you run the command: writes the active generation's own pack (draxgui_<pack>_pack.zip, checked against its SHA-1) into exactly one folder it owns, plus a manifest draxgui-export.json listing every file it wrote and its SHA-256:

Plugin Folder DraxGUI owns What goes in it You run next check reads (read-only)
ItemsAdder plugins/ItemsAdder/contents/draxgui/ resourcepack/ (assets, overlay folders, pack.mcmeta, and a copy at resourcepack/assets/minecraft/pack.mcmeta where the wiki example puts it), manifest /iazip plugins/ItemsAdder/output/generated.zip
CraftEngine plugins/CraftEngine/resources/draxgui/ pack.yml (namespace draxgui, enable: true), resourcepack/, manifest /ce reload all plugins/CraftEngine/generated/resource_pack.zip (the default workflow's zip path)

What DraxGUI never does: run /iazip, /ce reload or any other command of those plugins; write their generated output (output/, generated/); edit their config.yml or any file outside its own folder; create their content folder (start the plugin once first); send or host a pack. It only reads their config.yml for the few settings listed below.

Steps (ItemsAdder; CraftEngine is the same with its own command):

  1. Build, Deploy and /draxgui applyedit <id> as usual (section 7). The export always uses the active generation.
  2. /draxgui export itemsadder dry-run (permission draxgui.admin, also from the console). It lists what would be written, replaced and deleted, the shader families with their client versions, warnings and blocking problems. Nothing is written.
  3. /draxgui export itemsadder writes the folder. The reply ends with the next command.
  4. Run /iazip yourself (CraftEngine: /ce reload all; its default reload_pack workflow builds, uploads and sends the pack to online players, which is CraftEngine's own delivery that you configured, not DraxGUI's).
  5. /draxgui export itemsadder check reads the generated zip and prints, per client version, whether the DraxGUI shader files that version loads (root, then the overlays whose formats include that version, later entries winning) are DraxGUI's own bytes, and whether all DraxGUI asset files arrived with the same content. It proves file placement, not rendering. If your workflow writes the zip elsewhere, name it relative to the plugin folder: /draxgui export craftengine check generated/production.zip. ItemsAdder's resource-pack protection (resource-pack.zip.protect-file-from-unzip) makes the zip unreadable to this check: while any of its protection_1/2/3 switches is on, the check says so and how to turn it off, and that this is not recommended outside a safe server such as a private test server. DraxGUI still goes into the pack either way.
  6. Publish the plugin's generated pack the way you already do. Players need that pack: the file name and SHA-1 printed by applyedit, rollback and status describe DraxGUI's own zip, which you do not serve while you use this export.
  7. After every build that changes artwork (requiresPack: true), repeat steps 1, 3, 4, 5 and 6. A re-export replaces and deletes only files its manifest lists with unchanged bytes (or, for PNG pictures, unchanged pixels: ItemsAdder recompresses the images in its content folder); files you add to the folder stay untouched.

Removal: /draxgui export itemsadder remove deletes exactly the files the manifest lists (and folders that become empty), then run /iazip (or /ce reload all) so the rebuilt pack no longer contains DraxGUI. It also works after the plugin was uninstalled.

Nexo and Oraxen

Status: built from the plugins' public documentation only (docs.nexomc.com and docs.oraxen.com, read on 2026-10-24). Nothing here has run against either plugin yet; automated tests use stand-in plugin folders. Both plugins are optional (softdepend), found by name and never linked against.

The export works like the ItemsAdder one above, with the same dry run, check, removal, manifest and ownership rules. Both plugins merge a whole pack folder into the pack they generate, so DraxGUI's folder is a pack (assets/, its draxgui_* overlay folders and pack.mcmeta with their overlay entries):

Plugin Folder DraxGUI owns Documented as You run next check reads (read-only)
Nexo plugins/Nexo/pack/external_packs/draxgui/ "put my_pack.zip or a folder inside Nexo/pack/external_packs" (ResourcePack, Vendors) /nexo reload pack pack/pack.zip, which Nexo does not document: name the real zip with /draxgui export nexo check <file>
Oraxen plugins/Oraxen/pack/uploads/draxgui/ "only assets/, overlay assets/, pack.mcmeta and pack.png are considered; overlays.entries are merged" (Pack Merging) /oraxen reload pack pack/pack.zip (Oraxen FAQ), or the readable copy below

Settings DraxGUI reads (never writes) from their settings.yml, and what they do to the export:

  • Nexo Pack.obfuscation.type SIMPLE or FULL blocks: Nexo renames files (and with FULL namespaces), including DraxGUI's fonts, which the server refers to by name. Set it to NONE if you want DraxGUI in Nexo's pack. Pack.generation.packsquash.enabled warns: PackSquash re-encodes files; exclude assets/draxgui and the draxgui_* overlays in packsquash.toml if menus look wrong. Nexo's docs do not say how it merges pack.mcmeta overlay entries from external packs, and DraxGUI's 1.21.6+ shaders live in overlays: run the check after every rebuild. Nexo removes core shaders only from the ModelEngine pack it imports itself, not from external_packs (where its docs also put core-shader add-ons).
  • Oraxen Pack.import.remove_core_shaders_from_imported_packs: true blocks (it would delete DraxGUI's shaders), and so does Pack.generation.disable_mcmeta_generation: true (Oraxen then adds no overlay entries). Pack.generation.obfuscation.type SIMPLE/FULL warns. Pack.generation.protection is on by default and makes pack/pack.zip unreadable to the check: set Pack.generation.unprotected-location to a readable copy inside the plugin folder, for example plugins/Oraxen/draxgui-check/pack.zip; /draxgui export oraxen check then reads that copy by itself. multi_version_packs warns: only the 1.21.4+ pack matters for DraxGUI.

Another merged folder that ships a GUI text shader (rendertype_text* or text.*) blocks the export, as for ItemsAdder; the check after the rebuild also catches text shaders the plugins add themselves.

Pictures and 3D models. The editor's texture picker (rank pictures in the item shop) also lists PNGs from Nexo's pack/assets/*/textures/ and pack/external_packs/*/assets/*/textures/, and Oraxen's pack/assets/*/textures/, pack/textures/ (the minecraft namespace) and pack/uploads/*/assets/*/textures/; zips are not opened. 3D player models wear Nexo items written as nexo:<item id> and Oraxen items as oraxen:<item id> (through NexoItems.itemFromId and OraxenItems.getItemById, called by reflection), and the item shop suggests nexo give <id> 1 {player} or oraxen give {player} <id> 1 as the purchase command. Add nexo or oraxen to security.console-commands so the shop may run it.

Seen with ItemsAdder 4.0.18. On Paper 1.21.11 and on Paper 1.21.4 with a 1.21.4 client, the item shop's 3D models wore ItemsAdder hats from ItemsAdder's merged pack. Things to know from those runs: /iazip with a large export (4,455 files) held the server thread for about 40 seconds, so rebuild ItemsAdder's pack when few players are online; on Paper 1.21.4, ItemsAdder 4.0.18 needs a ProtocolLib release that supports 1.21.4 (5.4.0 worked; 5.5 snapshots declare a newer API and are refused), and its FastNbt 1.4.22 library contains one class compiled for Java 25 that Paper 1.21.4 cannot remap (ItemsAdder fails to enable until that is resolved; ask ItemsAdder's author for a build).

How the shader families are carried. Both plugins copy a content folder's resourcepack/ tree into their pack as-is and merge pack.mcmeta overlay entries (ItemsAdder: wiki page Pack Overlays and its maintainer in issue #4946; CraftEngine: merge_pack_mcmeta in its source and default config). DraxGUI therefore keeps every shader family in its own overlay: draxgui_f2 ... draxgui_f6 as in DraxGUI's own pack, and the 1.21.4/1.21.5 family, which DraxGUI's own pack keeps in its root, is moved to overlay draxgui_f1 (formats 46-62) for the export. The host plugin writes the pack's declared format range itself, and that range can include clients older than 1.21.4; those clients must not load DraxGUI shaders. No family is dropped. Which client versions can use DraxGUI is still limited to the families in your build and to the formats the host pack declares; check lists versions outside that range as NOT IN PACK RANGE.

It refuses (nothing is written) when:

  • another folder of that plugin ships the GUI text core shaders DraxGUI replaces (assets/minecraft/shaders/core/rendertype_text*, rendertype_text_intensity* or text.*, in any layout or overlay). ItemsAdder and CraftEngine keep one of two conflicting files (CraftEngine's conflict resolver does not merge shaders), so DraxGUI or the other pack would break silently. Remove or disable that pack, or merge both into one pack with Merge into a pack, which composes compatible text shaders;
  • DraxGUI files exist elsewhere in the content folder (an older manual copy);
  • a file in draxgui/ changed since DraxGUI wrote it, a file DraxGUI did not write is where it needs to write, the folder exists without a manifest, the manifest is unreadable or lists an unsafe path, or a symbolic link or junction is inside draxgui/ (or the content folder itself is one);
  • ItemsAdder is older than 4.0.4 (it skipped overlay entries before then, issue #3969), or CraftEngine's resource-pack.exclude-core-shaders is true (CraftEngine then deletes every core shader). Change that setting yourself if you want DraxGUI in that pack;
  • ItemsAdder's text_effects.enabled is true (the value in its generated config). At /iazip ItemsAdder then keeps its own text shaders and drops every content-folder file that overlaps them, which is all of DraxGUI's text shaders, on every client version (it logs "Found shader overlapping an ItemsAdder Texts shader"). Set it to false yourself (this turns off ItemsAdder's text effects), run /iareload, then export again. When the setting cannot be read the export warns instead, and check repeats the hint when it finds broken versions;
  • the plugin is not installed (export only), its content folder is missing, or the content folder has more than 200,000 files.

It warns when: ItemsAdder is older than 4.0.16 (overlays of merged packs were reported lost, issue #4836) or its version cannot be read; ItemsAdder's pre_1_21_2_shaders_fix is enabled (it rewrites shader .json files); CraftEngine has no merge_pack_mcmeta rule for pack.mcmeta; a CraftEngine workflow has an optimize step (it re-encodes PNG and JSON; check compares JSON values and PNG pixels, so a lossless re-encode passes); another pack overrides a shader include (assets/minecraft/shaders/include/*); a link or junction elsewhere in the content folder was not followed. Every ItemsAdder export also warns that ItemsAdder's wiki does not say where overlay folders go and that ItemsAdder generates core shaders of its own at /iazip (for example text.vsh in ia_overlay_26_3_plus, issue #5531) that can replace DraxGUI's for some versions: run check after every /iazip. ItemsAdder's shader-armour entity shaders (entity.vsh in ia_overlay_1_21_5, ia_overlay_1_21_6_plus and ia_overlay_26_1_plus, generated while custom_armors_shaders_legacy.vanilla.generate_shader.1_21_5_plus is on) take precedence over DraxGUI's on 1.21.5 and newer clients: menus render, but 3D player models there stay placed for a field of view of 70 and a wide window instead of following the player's window (the check reports 3D MODELS UNFITTED for those versions). 1.21.4 clients keep DraxGUI's. Turn that setting off if you do not use ItemsAdder's shader armours.

Supported versions: ItemsAdder 4.x targets Minecraft 1.20.5 and newer (wiki ItemsAdder v4); DraxGUI requires ItemsAdder 4.0.4 or newer for overlays. Tested here: ItemsAdder 4.0.18 with ProtocolLib 5.5.0-SNAPSHOT on Paper 1.21.11: with text_effects off, check reported every DraxGUI family OK, DraxGUI menus rendered in a 1.21.11 client both from the generated zip and from ItemsAdder's own server-delivered, protected and shader-compressed pack, and the pack compiled on 1.21.4-26.2. Seen with that ItemsAdder version, independent of DraxGUI: clients before 1.21.9 log declared support for versions [32, 64] but declared main format is 75 for its pack and list it as incompatible when a player picks it locally (it loads when accepted anyway); and on 26.3 its own ia_overlay_26_1_plus entity shaders use #moj_import, which 26.3 rejects, so 26.3 clients drop the whole pack (DraxGUI menus included) until ItemsAdder updates them. check cannot read a pack with ItemsAdder's unzip protection on (as above); check once with protection off, then rely on clients. CraftEngine runs on Paper-based servers 1.20+ with JDK 21+ (wiki Installation). DraxGUI's own client range (1.21.4 to 26.3) applies inside either pack.

Output goes to the sender and, prefixed [export], to the server log (RCON replies arrive in the log only, because the work runs off the main thread). export and remove write pack.export / pack.export.remove lines to audit.jsonl, including refusals; dry-run and check change nothing and are not audited. One export runs at a time.

10. Using DraxGUI from other plugins and the console

Everything below is also reachable from DraxGUI's Java API, which is safer than building command strings.

Popups (tested on Paper 1.21.4 with a vanilla 1.21.4 client):

/draxgui popup show <project:popup> <player|*> [key=value ...]
# examples assume a project named "hud" created from the Player HUD template (popups kill, quest, reward):
/draxgui popup show hud:reward Steve amount=250
/draxgui popup show hud:quest Steve "title=Quest complete" reward=250
/draxgui popup hide [project:popup|all] [player]

Grammar: separate values with spaces; wrap a token (or just the value) in double quotes to include spaces; \" is a literal quote; at most 16 values; keys are [a-z][a-z0-9_]{0,47}; every value starts as text and is coerced to the popup's declared parameter type (unknown keys and bad values are refused, e.g. Popup hud:reward has no value 'x'). * takes a snapshot of online players (max 500) and stops at the first player for whom it fails; players already shown are not undone. The reply is Popup <id>: shown N, queued M[, dropped K (queue full)]. From another plugin: Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "draxgui popup show hud:reward " + player.getName() + " amount=250"). Never put untrusted text into the command string. (From main: with aliases: { popup: "popup" } in config.yml, /popup show hud:reward Steve amount=250 does the same through the alias, with the same draxgui.popup check; see Dynamic commands.)

Variables (tested: get from the command, set/add/toggle/reset through menu logic):

# examples assume projects named "candy" (Candy Cascade template) and "control_panel" (Control Panel template)
/draxgui var get   candy:score Steve
/draxgui var set   candy:score 120 Steve        # value is ONE word; text with spaces cannot be set from the command
/draxgui var add   candy:score 30 Steve
/draxgui var toggle control_panel:notifications Steve
/draxgui var reset control_panel:notifications Steve
/draxgui var list [player]

Variables are project:variable. global variables take no player; player variables take a player (omit it only when a player runs the command); session variables live in open screens and are refused. add needs a finite number. Types are checked against the declaration. Whether a variable is reachable at all is the declaring project's external flag: the default is readwrite, so unless the project author set read or none, anyone with draxgui.var (and any plugin using the API) can change it. Review external on variables that hold currency, ranks or progress.

HUD control (tested on 1.21.4):

/draxgui hud who [player]                         # why this HUD? which rule? which overrides? pack status?
/draxgui hud show|hide|reset <project:hud>        # self only; scoped to the HUD's selector
/draxgui hud item show|hide|reset <project:hud> <element> [player]    # console-friendly

HUD selection re-evaluates rules every 20 ticks per player and on variable changes, so a health-based rule can take up to a second to switch. Overrides are per player and in memory: they are lost on logout and restart.

11. Variables

Declared per project: global (shared), player (per UUID), session (per open screen). Persistent global and player variables are written to plugins/DraxGUI/variables/global.json and variables/players/<uuid>.json by a background thread with coalescing; a failed write is logged and retried on the next change, never reported as success. Values of variables that no longer exist are ignored on load. Declared names, types and constraints come from the project; /draxgui var list shows only externally visible ones (max 50).

12. Safe handling of what the editor can do

  • Console commands from menus: only roots in security.console-commands. Keep it empty unless you need it, and never list op, lp, lpb, perms, minecraft:* roots or anything that grants permissions.
  • Items, XP, potions, Vault money and commands as the player run from any button an editor user places. Gives are capped (6,400 items per node, 1,000,000 XP) and refuse a full inventory.
  • Webhooks and Tebex checkout nodes: only endpoints you configure under web: can be called; projects name endpoint ids, never URLs or secrets. Private, loopback, link-local and cloud-metadata destinations are refused unless allowlisted; bodies are size-capped and HMAC-signed when you set a secret. A webhook was delivered live to a loopback receiver; Tebex was tested against mocks only. See Webhooks and Tebex checkout.
  • The show/hide, set text ... nodes only change the open menu of the player who clicked.
  • Imported fonts: editor users (asset.write) and MCP tokens can upload TTF/OTF fonts. DraxGUI ships no fonts. A build rasterises the used characters of each imported font into bitmap glyphs inside the resource pack every player downloads, so the font's licence must allow embedding/redistribution in that form; the uploader is responsible. Record it in the asset's License field (validation shows font_license while it is empty) and watch for the "restricted embedding (fsType 2)" warning. Limits: 8 MiB per font file, at most 20,000 glyphs, TTF or OTF only (TTC/WOFF/WOFF2 are refused), the font must draw ASCII letters or digits; per element size 4-32 GUI px; printable ASCII, Latin-1 and up to 256 further characters from the element's literal text are rasterised, everything else (and all Bedrock forms) uses the Minecraft font. Nothing in a font file is executed by DraxGUI; it is parsed by the JDK's font engine on the build thread under the media time limit.

13. Advanced code (scripts)

Menus, HUDs, packs and visual logic never need this. The Call script node runs Java, JavaScript or Python in separate worker processes under the server's OS account. scripts.trust is disabled by default; trusted-admin means "everyone who can edit scripts is as trusted as a server administrator". A worker process is not a sandbox; DraxGUI states it enforces argument-list start, a private working directory, a minimal environment, time/memory/queue/effect limits and a declared-capability check on the server, nothing more. An OS sandbox (container, bwrap, a separate low-privilege user) is yours to configure through sandboxPrefix, and DraxGUI does not verify what it enforces. Prerequisites when enabled: Node.js 18+, CPython 3.9+, a JDK 21+ with javac (a JRE is reported unavailable). Status: tested with trusted-admin on Windows 11 (Linux/macOS runs not done, memory limits not enforced on macOS). Full policy, limits and options: Advanced code runtimes. /draxgui status shows each runtime's availability and call counters.

14. Bedrock and MCP status

  • Bedrock (Bedrock players): Bedrock players (detected only through Floodgate, never by name prefix) get custom Bedrock screens that redraw the Java design when they have the build's .mcpack, otherwise native forms. Geyser without Floodgate means everyone is treated as Java and Bedrock players cannot use DraxGUI screens (logged as a warning). Tick Bedrock in the build panel to produce draxgui_<pack>_bedrock.mcpack, copy it to plugins/Geyser-Spigot/packs/ and restart Geyser (or /geyser reload); players reconnect to get it. HUDs and popups are drawn by the same .mcpack (texts travel as boss bars the pack hides; other plugins' titles and boss bars still show); without the pack Bedrock players get no DraxGUI HUD. Verified on Bedrock 26.52 for Windows (mouse and keyboard) for screens, HUDs, popups and plain forms; phones, touch and controllers are untested.
  • MCP (MCP adapter): AI clients edit projects through the editor's own services at <editor base URL>/mcp with named, expiring, revocable bearer tokens; they cannot apply, roll back, run commands, read files or fetch URLs. Create a token with /draxgui mcp token create <name> <projects|all> [--caps a,b] [--ttl 30d] (read-only unless --caps adds more). Without --caps a token can only read (project.read); it lasts 30 days unless --ttl says otherwise. Ask for exactly what you need, e.g. --caps project.read for review-only. The secret is shown once; console output may be retained by your host. Tokens are stored hashed in plugins/DraxGUI/mcp-tokens.json. Status: the discovery and read tools and the token scopes are tested, and a demo authored through MCP (with the official Python SDK client) was built and applied on 1.21.4; a real Claude Code or Codex client has not been connected yet.

15. Troubleshooting

Start with /draxgui status (needs draxgui.admin; works in the console). It prints: plugin state and degraded reasons; server version, Java and PacketEvents versions; the active generation (id, pack name, pack SHA-1, project count); editor address and number of sessions; the Bedrock bridge state; ffmpeg; per client family, how many features of each Java renderer are verified / limited / unverified in the capability registry (details in the compatibility matrix; the editor's Build & Deploy panel lists the ones your project uses); script trust and per-language counters; and one line per player with an open screen or popups. It also lists "Dynamic commands" (registered open commands/aliases and skipped collisions) and Logic: N flow(s) stopped ... when logic failures were logged. Then /draxgui hud who <player> for HUD questions.

Symptom Likely cause and action
Plugin disabled at start, "PacketEvents is required" Install packetevents 2.14.0+; check the console order of plugin load.
DEGRADED, "Editor could not start on ..." editor.port already used. Change it, restart. Menus keep working.
A menu or HUD briefly dims or vanishes now and then The client fades the action-bar line DraxGUI draws on when no new one arrives for 2 s. DraxGUI resends it every second and its shader ignores the fade, so the UI only disappears when the server stalls for about 3 s or more (Can't keep up! in the console; ItemsAdder's /iazip with a large DraxGUI export can do that).
3D player models stand off their windows, or vanish when the window is resized The client runs an older DraxGUI pack: build and apply again, and have the player reload the pack (F3 + T) or rejoin. With Iris or another shader mod the pack's shaders do not run and the menu shows its flat pictures instead.
Start-up fails after editing scripts.trust Only disabled and trusted-admin are accepted.
"This editor link was already used / expired / not valid" Run /draxgui editor again (links last 10 minutes and work once).
"Your editor session has ended" The hour is over, the server restarted, or you lost draxgui.admin. Request a new link.
403 csrf_or_origin in the browser Open the link with the exact host printed, or fix the proxy so Origin/Host pass and editor.public-url matches the address in the browser.
The editor message says "Local mode: true" Expected without public-url: the link only opens on the server machine (hover it for details); see section 6.
Build fails or is refused Open the Diagnostics list in the Build panel (blocking errors, warnings). 429 busy: more than four queued builds. Merge conflicts are listed with paths.
"Unknown edit id" / "expired" / "already live" / "would roll ... back" Deploy again; for an intended downgrade use rollback or applyedit <id> --allow-older.
"No DraxGUI deployment is active yet" No applyedit has run (and none could be restored at start).
Unknown screen '...' Use /draxgui list for ids; ids are project:screen, lower case.
Screen does not open Spectator mode, in a vehicle, the screen's permission/open when failed, or a Bedrock player without the form bridge.
Screen closes by itself Death, a real teleport, a world change, logout, applyedit/rollback/reload, or a replacement screen.
Boxes/garbled glyphs, wrong images The player lacks the current pack: compare the SHA-1 in /draxgui status with the one you serve (remember the merge gap), and check hud who.
Clicks do nothing A graph's event node is not routed from the element: run validation in the editor and read unbound_event / missing_entry (see the developer guide). debug: true prints failing steps.
Console shows Logic flow stopped at <project|kind|container|event> <graph node>: <reason> A logic action failed on a node that has no failed exit, so the flow ended. The server logs this as a WARNING at most once a minute per node, and /draxgui status shows Logic: N flow(s) stopped .... Fix the reason (e.g. a refused console command, a full inventory, a missing economy) or connect the node's failed exit. The Run command node now has a failed exit.
A screen's open command or an alias does nothing / is "Unknown or incomplete command" Look under "Dynamic commands" in /draxgui status and the console WARNINGs: a name owned by the server or another plugin is skipped, never replaced. Players without the command's permission do not see it at all. Names must match [a-z0-9_-]{1,32}.
"Scripts are disabled on this server" Expected with scripts.trust: disabled.
The pointer moves too far or too little The screen's pointer.speed (editor Preferences; default 2.5 GUI px per degree) sets the pace for everyone; each player can scale it with /draxgui pointer 0.5 .. 4. Minecraft's own mouse sensitivity and GUI scale change the feel too: at GUI scale 4 the cursor covers twice the screen pixels per mouse movement as at scale 2.
A game or menu feels laggy Run /draxgui status: UI cost per tick shows the server-thread time DraxGUI spends per open screen (a few ms is normal), Key to draw the server-side key latency, and Script calls whether script results land in the same tick (scripts.syncWaitMs). Compare with the server's own /mspt: if the whole tick is slow, the lag is not the key path. Players who see scattered symbols instead of the menu have an old pack loaded: reload with F3+T or re-enable the pack.
"console command '<x>' is not in security.console-commands" Add that root if you intend it (/draxgui reload applies it).
"no economy: install Vault and an economy plugin" The Money node needs Vault with a registered economy.
"Bedrock menus need Floodgate" Install Floodgate on the Paper server.
Text prompt never ends Anvil: close it; chat: type cancel; prompts expire after input.prompt-timeout-seconds.
Another plugin's action bar flickers While a player has DraxGUI HUD/screen content, other action bars are merged into DraxGUI's output for about 3 s.
Another plugin's title appears late It was sent while a Shader-Safe screen was open; DraxGUI shows it when the screen closes (section 1).

16. Data files and backups

Everything lives under plugins/DraxGUI/. Writes use temp-file-then-move.

Path Contents Back up?
config.yml operator settings yes
projects/<id>/head.json, revisions/<n>.json, log.jsonl, snapshots/<name>.json project sources; the last 200 revisions are kept, named snapshots (editor: Revision history → Snapshots; at most 50 per project) until deleted; archived (deleted) projects move to projects/.archive/ yes, essential
assets/ content-addressed uploaded media yes (projects reference it)
variables/global.json, variables/players/<uuid>.json persistent variable values yes
builds/<buildId>/ pack zips, runtime.json, report.json, Bedrock outputs keep at least the builds named in runtime/active.json, runtime/last-good.json and runtime/pending/*.json; nothing prunes old builds, so clean up by hand
runtime/active.json, last-good.json, pending/<id>.json which build is live, the fallback, and pending edits yes
uploads/<sha256>.zip (+ .name) uploaded base packs for Merge optional
mcp-tokens.json hashed MCP tokens (owner-only permissions where supported) yes, protect it
audit.jsonl audit trail archive/rotate yourself

Stop the server for a consistent copy; a copy of a running server was not tested. Deleting a build that active.json or last-good.json names makes the plugin fail to load that generation at the next start.

17. Upgrading

  1. Stop the server. Back up plugins/DraxGUI/.
  2. Replace the DraxGUI JAR (remove the old file), keep PacketEvents at a tested version, start.
  3. The old generation keeps running as built. Rebuild and re-apply after upgrading: the compiler is part of the pack's identity (the report carries a compiler build hash), so a new version may produce a different pack, in which case republish it and update the SHA-1.
  4. Project files are versioned (schema 2); older schema-1 documents are migrated on import. A runtime bundle with an unknown format or version is refused, and the plugin falls back to the last-known-good generation. Downgrading was not tested.

18. Uninstalling, and what is restored

Stop the server, delete plugins/DraxGUI.jar (and plugins/DraxGUI/ if you do not want to keep projects). DraxGUI never changed server.properties, other plugins' files, world data or player data files. What it did to players is client-side or in memory:

  • Pointer capture is packets only (camera, seat, held slot, view rotation). On a close, death, teleport, world change, applyedit/rollback/reload, or a clean shutdown the plugin sends the packets that restore the camera, release the seat, resync the held slot, restore the original view rotation and clear titles. On logout or a server crash the client-side state disappears with the connection and nothing persistent was stored.
  • On shutdown it clears the action bar it was composing.
  • Persistent variables remain only in plugins/DraxGUI/variables/.
  • The resource pack: remove it from your pack host or server.properties yourself (DraxGUI did not add it). Bedrock .mcpack files you copied into plugins/Geyser-Spigot/packs/ stay until you remove them, followed by /geyser reload.

19. Known limitations at a glance

Area Status
Shader-Safe menus/HUD/popups on 1.21.4, 1.21.8, 1.21.11, 26.1.2, 26.2, 26.3 Tested in the scope above
Standard (world-space) renderer 1.21.4 (vanilla and Iris + BSL); 26.x not run
Iris with the product renderer 1.21.4: Complementary r5.9, BSL v10.1.5, shaders off
Per-frame animate effects (pulse, bob) client game time; measured on 1.21.4
Latency under delay, GUI scale 3-4, fullscreen, FOV not measured
Animated pictures play on Shader-Safe screens, swapped by the server up to 20 fps (asset delays honoured); no 60 fps path for pictures
Custom fonts TTF/OTF import, bitmap glyphs for Shader-Safe and Standard, covered by automated tests; not yet checked in a client
Player Model Tested: 3D on Standard, a flat front view on Shader-Safe; real skins not seen (offline test server)
3D player models on Shader-Safe (View: 3D) Seen on 1.21.8 and 1.21.11 at 1920 × 1080 (GUI 4): the item shop with ItemsAdder cosmetics (SummerCosmeticSet) worn by the viewer's model, turned by drag, wheel, buttons and a variable; camera, weather and light put back on close. An elytra kept steady while spinning, on 1.21.11 and 1.21.4. The models follow the window and the FOV by themselves through the pack's entity shaders: on 1.21.11 and 1.21.4 at 1920 × 1061, resized live to 1100 × 1000, 956 × 1048, 800 × 600 and 1900 × 500, and reopened at 800 × 600, at FOV 70, 90 and 110 every model stays in its window; at FOV 30 the outermost models drop out (culled by the client's own view). With ItemsAdder's shader-armour entity shaders in the merged pack, 1.21.5+ clients keep their wide-window placement. Not run: 26.x clients in game (shaders compile on F1–F6), Iris, online-mode skins
Screen Scale to fit the player's window (fit) Shader-Safe: the text shader scales the screen about its anchor so the canvas fits the window (16:9 canvases stay pixel-sharp on 16:9 windows); pointer, hover and clicks scale with it. Seen on 1.21.8 at 1280 × 720 (GUI 3) and 1920 × 1080 (GUI 2, 4) and on 1.21.4 at 1920 × 1080 (GUI 4); shaders compile on F1–F6. Shapes can stretch to the window's edges. DraxGUI HUDs are hidden while such a screen is open
Screen Background dim Shader-Safe: darkens the whole window for the viewer only (one glyph the shader stretches; HUDs under it, the screen, tooltips and popups above); seen on 1.21.4 at 1920 × 1080 (0.35 and 0.6 measured exactly), shaders compile on F1–F6. Values under 0.1 show as 0.1. Standard (world-space) screens: no dim. Bedrock: JSON UI layer
Image import (PNG/JPEG/GIF/WebP/APNG/SVG/MP4/WebM), QR, icon library Built and covered by automated tests; not shown in a client except one icon and some shapes
Chat text entry, popup queue/replace/priority not exercised live
Merge into a pack Tested (automated tests, a live merge, client load); third-party shader composition not client-tested
Webhook / Tebex nodes webhook live against a loopback receiver; Tebex mocks only
Screen "Open command" and aliases Tested on Paper 1.21.4 + vanilla 1.21.4
Bedrock custom screens, HUDs, popups and forms tested on Bedrock 26.52 for Windows (mouse and keyboard); phones, touch and controllers not tested
Linux/macOS, proxies, permission plugins, anti-cheat not tested