-
Notifications
You must be signed in to change notification settings - Fork 14
Utilities
Codex ships a set of static helper classes, conventionally suffixed UT. They live in
studio.magemonkey.codex.util and are available from the codex-api artifact — see
Developer Getting Started.
The one you will use most.
String colored = StringUT.color("&aHello &#ff0088World"); // & codes + hex
List<String> lore = StringUT.color(rawLore); // works on lists and sets
StringUT.colorOff(text); // strip colour
StringUT.colorRaw(text); // raw colour handling
StringUT.colorFix(text); // repair broken colour sequences
StringUT.colorSensitiveStrip(s); // strip while preserving colour stateHex colours use &#RRGGBB (matching StringUT.HEX_PATTERN).
Safe parsing with fallbacks — no exception handling needed:
double d = StringUT.getDouble(input, 0.0);
double positive = StringUT.getDouble(input, 0.0, false); // reject negatives
int i = StringUT.getInteger(input, 1);
int[] arr = StringUT.getIntArray("1,2,3");Formatting and tab completion:
StringUT.capitalizeFully("iron sword"); // "Iron Sword"
StringUT.capitalizeFirstLetter("iron sword"); // "Iron sword"
StringUT.oneSpace(messy); // collapse repeated spaces
StringUT.noSpace(text); // remove spaces
// Filter completions by what the user has typed so far
List<String> matches = StringUT.getByFirstLetters(arg, allOptions);getByFirstLetters is exactly what you want in a TabCompleter.
Placeholder replacement across lists, including multi-line expansion. These return a new list and do not mutate the input — assign the result:
lore = StringUT.replace(lore, "%description%", descriptionLines);
lore = StringUT.replace(lore, "%name%", name);Two traps. An empty replacement list is substituted as the literal
["[]"]. And a third overload,replace(String placeholder, List<String> r, String... orig), takes its arguments in a different order — check which one you are calling.
MsgUT.sendActionBar(player, "&eStatus text");
MsgUT.sendTitles(player, title, subtitle, fadeIn, stay, fadeOut);
MsgUT.sound(player, Sound.ENTITY_PLAYER_LEVELUP);
MsgUT.sound(location, "entity.player.levelup");
MsgUT.sendWithJSON(sender, jsonOrPlainText);
boolean isJson = MsgUT.isJSON(text);
isJSONdoes not detect a serialized chat component — it literally checks whether the string containsjson:. Both methods deal with Codex's own inline markup,{json:~hint:…;~url:…;}text{end-json}, whichsendWithJSONexpands into a clickable/hoverable component for players and strips to plain text for console. Raw chat-component JSON is not parsed.
Title timings are in ticks. Note sendTitles is marked @Deprecated in source.
For the string-name sound overloads, prefer the enum form (ENTITY_PLAYER_LEVELUP) — the name is
upper-cased before lookup, and an unknown sound is swallowed silently.
Action bar rendering respects the action-bar-legacy setting — see Configuration.
NumberUT.format(1234.5678); // default formatting
NumberUT.format(value, "#.##"); // custom pattern
NumberUT.round(value);
NumberUT.round(value, "#.##");
NumberUT.toRoman(4); // "IV"toRoman is handy for enchantment-style level display.
PlayerUT.execCmd(player, "spawn");
List<String> names = PlayerUT.getPlayerNames();
String ip = PlayerUT.getIP(player);
PlayerUT.setExp(player, 5000L); // ADDS 5000 XP to the current total
PlayerUT.setTotalExperience(player, 5000); // sets the total to exactly 5000
⚠️ Despite the name,setExpadds rather than sets — it reads the current total, adds your amount, and writes the result back. Negative amounts subtract. UsesetTotalExperiencefor an absolute value; it throwsIllegalArgumentExceptionon negatives.
Both work in total experience rather than levels, which is the calculation Bukkit does not give you.
String raw = LocUT.serialize(location);
Location loc = LocUT.deserialize(raw);
List<String> rawList = LocUT.serialize(locations);
List<Location> locs = LocUT.deserialize(rawList);
Location ground = LocUT.getFirstGroundBlock(loc);Use these for storing locations in config — the round trip is stable, preserving yaw and pitch. The
serialized format is x,y,z,pitch,yaw,world.
Both
serializeanddeserializeare@Nullable— a null world, or a string without exactly six fields, yieldsnull. Check the result.
getFirstGroundBlock(loc) walks downward until it finds a solid block and returns the position above
it. Note this is not what /unstuck uses — that replays recently-recorded standing positions
(see Commands).
double max = EntityUT.getAttribute(entity, Attribute.GENERIC_MAX_HEALTH);
double base = EntityUT.getAttributeBase(entity, Attribute.GENERIC_MAX_HEALTH);
ItemStack[] gear = EntityUT.getEquipment(entity);The distinction between total and base attribute values matters when displaying "how much of this comes from gear" — see also Compat and NMS.
FileUT.copy(inputStream, targetFile);
FileUT.mkdir(folder);
FileUT.create(file);
List<File> files = FileUT.getFiles(path, true); // true = recurse
List<File> folders = FileUT.getFolders(path);Debugger.setDebug(true);
Debugger.log("Loaded 42 items");
Debugger.warn("Config key missing, using default");
Debugger.err("Failed to parse item definition");
⚠️ All three are gated, not justlog—warnanderrare equally invisible unlessdebugis enabled in Configuration. They also write toSystem.outwith a[RiseDebugger]prefix rather than to the plugin logger.
Use these for diagnostics a server owner should be able to switch on. For anything that must always
reach console, use plugin.warn(...) / plugin.error(...) instead.
| Class | Purpose |
|---|---|
SoundUT |
Resolve sounds by name across versions |
EnumUT |
Version-safe enum name resolution |
EffectUT |
Particle spawning and line drawing |
ItemUT |
Item stack helpers (in codex-plugin, not codex-api) |
CollectionsUT |
Collection utilities, plus getEnum/getEnums name resolution |
DataUT |
Persistent data container helpers, incl. types Bukkit lacks (UUID, BOOLEAN, array types) |
RangeUtil |
Random value from a DoubleRange, and percentage chance rolls |
ClickText |
Build clickable chat components |
Reflex |
Reflection helpers |
Zipper |
A single createBackupZip(dir) helper |
SerializationBuilder / DeserializationWorker
|
Config serialisation |
SoundUT.getSound(name) and EnumUT.getName(value) exist because several Bukkit types stopped
being enums and became registry-backed Keyed values — not because constants were renamed.
getSound reflects valueOf and falls back to Enum.valueOf, returning Keyed; EnumUT.getName
reflectively reads name() off a value whose type may or may not still be an enum. Use them instead
of a direct Sound.valueOf(...) or .name() call, which breaks across versions.
Codex bundles a small expression evaluator under util.eval, used for formula-driven values in
configs — attribute scaling, damage formulas, and similar. Plugins built on Codex expose it wherever
they accept a formula string rather than a fixed number.
codex-core provides shared registries for cross-plugin data:
| Registry | Holds |
|---|---|
AttributeRegistry |
Custom attributes |
BuffRegistry |
Buff definitions |
DamageRegistry |
Damage types |
Plus NamespaceResolver, which resolves PotionEffectTypes and Enchantments from a list of
candidate names so they survive Mojang's renames, and MigrationUtil for config and data-folder
migration.
The expression evaluator's entry point is Evaluator.eval(String expression, int method) — method
0 uses the internal parser, 1 or 2 use the bundled javaluator (falling back to the internal one
on failure). It lives in codex-api.
Source · Issues · Discord · Maven repo
Server Owners
- Installation
- Configuration
- Commands
- Permissions
- Join and Interact Commands
- Localization
- Version Support
Deprecated
-
Chat Module
⚠️ -
Scoreboard Module
⚠️
Developers