Configuration
EmbersTextAPI splits config into two files: one that lives on the client and controls rendering, and one that lives on the server and controls who can use markup and what API messages are allowed. Neither file needs to exist for the mod to work; defaults are applied whenever a key is absent.
Where the config lives
Section titled “Where the config lives”NeoForge uses TOML, managed by the FML config system.
| Side | File |
|---|---|
| Client | config/emberstextapi-client.toml |
| Server | config/emberstextapi-server.toml (world-specific: saves/<world>/serverconfig/emberstextapi-server.toml) |
Forge uses TOML, managed by the Forge config system. Same file names as NeoForge.
| Side | File |
|---|---|
| Client | config/emberstextapi-client.toml |
| Server | config/emberstextapi-server.toml (world-specific: saves/<world>/serverconfig/emberstextapi-server.toml) |
Fabric uses JSON, read and written by ETA directly.
| Side | File |
|---|---|
| Client | config/emberstextapi-client.json |
| Server | config/emberstextapi-server.json |
The client file is written by the client instance; the server file is distributed to all players from the server. On a dedicated server the client file does not exist.
Client config
Section titled “Client config”| Section | Key | Type | Default | Description |
|---|---|---|---|---|
messages | immersiveMessagesEnabled | boolean | true | Master toggle for immersive messages sent via commands or the API. Disabling this drops all incoming messages silently. |
messages | maxMessageDuration | integer | 0 | Client cap on immersive message duration in ticks. 0 means no limit. |
messages | maxActiveMessages | integer | 0 | Client cap on simultaneous active messages. 0 means no limit. |
messages | maxQueueSize | integer | 50 | Client cap on pending steps per queue channel. 0 means no limit. |
effects | reduceMotion | boolean | false | Disables all motion-category effects (wave, bounce, shake, etc.). Accessibility setting. |
effects | perEffect | string list | [] | Per-effect render overrides. Entries are "<name>=false" to disable one effect. Overrides perCategory. |
effects | perCategory | string list | [] | Per-category render overrides. Entries are "<CATEGORY>=false" to disable all effects in a category. |
effects | maxNeonQuality | integer | 3 | Caps neon/glow quality. 1 = fast, 2 = balanced, 3 = quality. |
rendering | sdfEnabled | boolean | true | Master toggle for SDF font rendering. |
rendering | textLayoutCacheSize | integer | 256 | Max entries in the text layout LRU cache. Valid range: 64-2048. |
internal | schemaVersion | integer | 1 | Config schema version. Do not edit this by hand. |
Server config
Section titled “Server config”| Section | Key | Type | Default | Description |
|---|---|---|---|---|
playerMarkup | mode | string | "ALL" | Controls who can use markup in player-authored text. ALL, PERMISSION, or NONE. See Player markup permissions. |
playerMarkup | requiredOpLevel | integer | 0 | Fallback OP level required when no permission mod is installed and mode is PERMISSION. Range: 0-4. |
playerMarkup | surfaceChat | boolean | true | Allow markup in chat messages. |
playerMarkup | surfaceAnvil | boolean | true | Allow markup in anvil item names. |
playerMarkup | surfaceSign | boolean | true | Allow markup on signs. |
playerMarkup | surfaceBook | boolean | true | Allow markup in written books. |
playerMarkup | perEffect | string list | [] | Per-effect player rules. Entries are "<name>=false" to disallow one effect for players. Overrides perCategory. |
playerMarkup | perCategory | string list | [] | Per-category player rules. Entries are "<CATEGORY>=false" to disallow all effects in a category for players. |
playerMarkup | notifyOnStrip | boolean | true | Sends the player a chat message when their markup was stripped because they lack permission. |
apiMessages | maxDuration | integer | 1200 | Server cap on API/command message duration in ticks. 0 means no limit. |
apiMessages | maxActiveMessages | integer | 10 | Server cap on simultaneous API messages per player. 0 means no limit. |
apiMessages | maxQueueSize | integer | 50 | Max pending steps per queue channel. 0 means no limit. |
apiMessages | allowedEffects | string list | [] | If non-empty, only these named effects survive in API/command messages. An empty list means all effects are allowed. |
anvil | nameMaxLength | integer | 50 | Max characters when renaming an item in an anvil. Vanilla default is 50. |
internal | schemaVersion | integer | 1 | Config schema version. Do not edit this by hand. |
Player markup permissions
Section titled “Player markup permissions”The mode key in the playerMarkup section controls whether players can use ETA tags in chat, anvil names, signs, and written books.
| Mode | Behavior |
|---|---|
ALL | Every player can use markup on every allowed surface. The requiredOpLevel and permission nodes are ignored. |
PERMISSION | Markup is node-gated. Players need emberstextapi.markup.use (or the bypass node) to use markup at all, then individual effect or category nodes to use specific effects. |
NONE | Markup is disabled for all players regardless of permissions. |
requiredOpLevel fallback
Section titled “requiredOpLevel fallback”When mode is PERMISSION and no permission mod is installed, ETA falls back to checking whether the player has the vanilla OP level set in requiredOpLevel. Set it to 0 to grant access to everyone (same effect as ALL), or 2-4 to restrict to operators.
On Fabric, if the fabric-permissions-api library is present (me.lucko.fabric.api.permissions.v0.Permissions), ETA delegates node checks to it instead of the OP-level fallback. This means LuckPerms and any other mod that implements the Fabric Permissions API will handle the nodes automatically.
On Forge and NeoForge, ETA only uses the vanilla OP-level fallback; there is no built-in integration with a specific permission library.
Permission nodes
Section titled “Permission nodes”| Node | What it gates |
|---|---|
emberstextapi.markup.use | Basic markup access. Required before any effect node is checked. |
emberstextapi.markup.bypass | Bypasses all per-effect and per-category restrictions. A player with this node can use any effect regardless of perEffect or perCategory. |
emberstextapi.markup.effect.<name> | Access to one specific effect, e.g. emberstextapi.markup.effect.glitch. |
emberstextapi.markup.category.<CATEGORY> | Access to all effects in a category, e.g. emberstextapi.markup.category.distortion. Category names are lowercase in the node. |
Per-effect and per-category gating
Section titled “Per-effect and per-category gating”Both the client config and the server playerMarkup section have perEffect and perCategory string-list keys. They work the same way in both places, just in different contexts.
Format: each entry is a string in the form "name=false" (only false is meaningful; omitting an entry leaves the default as enabled).
perEffect examples:
perEffect = ["glitch=false", "shake=false"]This disables the glitch and shake effects. Other effects are unaffected.
perCategory examples:
perCategory = ["DISTORTION=false", "SOUND=false"]This disables every effect in the DISTORTION and SOUND categories.
Precedence: perEffect overrides perCategory. If you have DISTORTION=false in perCategory but glitch=true in… well, there is no =true syntax; only =false suppresses. A key absent from the list means the effect is allowed. So if you want to allow only glitch from a blocked category, you’d need to block the category and then note that glitch is absent from perEffect, but the category block wins unless the effect key explicitly overrides it. In practice, block at category level and add individual effect overrides via perEffect as needed.
On the client, these settings only affect rendering; effects are stripped from display even if the server sent them.
On the server, playerMarkup.perEffect and playerMarkup.perCategory gate whether players are allowed to write a given tag in chat, anvil names, signs, or books at parse time.
Reloading config
Section titled “Reloading config”/emberstextapi reloadRequires OP level 2. Rereads both config files from disk and pushes the updated markup policy to every online player. The server responds with [EmbersTextAPI] Config reloaded. in the game log.