MeowMC

Components

Beta

State

Beta. Reference for the component model the runtime implements.

A scene is assembled from components, not hand-written entity spawns. Each component type is registered with an id, a property schema and a spawn routine — the same schema drives the server's validation and the web editor's property panel.

The built-in components

| Component | Renders as | Properties | | --- | --- | --- | | text | TextDisplay | text, alignment, line width, background, opacity, shadow, see-through | | stat-text | TextDisplay with a bound statistic | everything text has, plus stat, format ({value}) and a refresh cadence — see placeholders | | item | ItemDisplay | one vanilla item id, a display transform (ground, gui, head, fixed, …), scale | | block | BlockDisplay | one vanilla block state | | hitbox | Interaction — invisible | float width, height, and an action list |

Every component carries offset — blocks, relative to the scene anchor — plus shared display options: billboard mode, view range, a brightness override, and interpolation settings for entrance and exit. No component escapes the vanilla ceiling: no custom fonts, no custom textures, no hover, only box hitboxes.

Templates and presets

A template is a scene shipped as .meowui with template: true — pre-assembled component sets (a leaderboard, a server-info panel, a warp board with hitbox rows) that an author duplicates and customises. A preset is the same idea at component granularity: a saved property set reused inside a scene. Both are .meowui documents; there is no second format.

Anchors

  • Coordinate anchor — {type: "coordinate", world, position: [x, y, z]}. Static.
  • Entity anchor — {type: "entity", uuid, alias}. The scene follows the entity. Any entity qualifies, including any NPC plugin's entity, because the anchor is resolved by UUID in the world; the alias is documentation only.

Follow strategies: passenger mount — one packet puts the scene's virtual entities on the anchor's passenger list and the client interpolates them from the anchor's own movement — or position teleport at a bounded cadence as the fallback when a mount cannot be used. An anchor that is missing at poll time (the NPC unloaded) parks the scene at its last known position and re-syncs on recovery, rather than following a dead reference.

Pages

A scene is an ordered list of pages; each page is a list of components. Page state is per-viewer — next-page, prev-page, open-page are actions — so a scene with pagination is inherently personal mode.

A page may declare a repeat: the same component row generated over a list, with repeat-index-aware offsets. A leaderboard over N entries and a warp board of N clickable rows are repeats, not hand-copied components — and because the vanilla client offers only box hitboxes, the repeat is what makes N clickable rows affordable.

Per-viewer state — current page, last-seen click timestamps, the viewer's virtual entity ids, the last rendered placeholder values — is in memory only. It dies with the viewer's session and is rebuilt on rejoin; a restart returns every viewer to page 1.

Action lists — a closed set, not a scripting language

A hitbox's behaviour is an action list: a closed, fixed set, validated at load.

| Action | Fields | Notes | | --- | --- | --- | | run-command | command, as: player | console | as: player dispatches through the clicker's own permission set — no scene-author privilege is ever attached. as: console needs the gate below. | | teleport | world, position | Entity-safe teleport of the clicker. | | open-page | page | Per-viewer state flip. | | next-page / prev-page | — | Wraps at the page list ends. | | message | text | A placeholder-resolved chat message to the clicker. | | play-sound | sound, volume, pitch | Vanilla sound names. | | function | name | Runs a named list from the scene's functions block — still from the closed set. |

Functions are not scripts. No variables, no conditionals, no arithmetic, no loops, no per-viewer data read beyond the stat placeholders. A scene that needs logic composes it out of pages and the closed set — or waits for a plugin.

The console-command gate

as: console executes with the server console's authority. A scene author who can write a holograms/*.meowui file and place a console command behind a clickbox has handed a console command to anyone who clicks. So:

  1. as: console is refused at load unless the config gate is on (default off) and the scene file carries an explicit, load-validated marker acknowledging it.
  2. When enabled, command permission is the server's own command permission system — no extra layer is invented.
  3. as: player needs no gate: the clicker's permissions are checked exactly as if they typed it.

Clicks, and the rate bound

The vanilla interaction entity records a click by writing a field, not by firing an event: the runtime polls the entity's timestamp pair once per tick, matches the player UUID, and runs the bound action list.

The right-click path carries no vanilla cooldown — a scripted client can flood interact packets — so there is a per-viewer token bucket per scene (default 8 per second, burst 2×). Over-budget clicks are dropped silently: a dropped click is a graceful miss, a kicked player is not. Left-click already carries the vanilla attack cooldown.

Entity budgets

Budgets are enforced at scene validation time — a scene that would exceed them is refused with a reason — and at runtime a viewer who would exceed the total is served the earliest-loaded scenes only, with a one-line console warning.

| Budget | Default | Cap | | --- | --- | --- | | Personal-scene display entities, per viewer | 56 | 256 | | Total entities, per scene | 40 | 256 | | Personal scenes, per world | 8 | 32 | | Shared (global) entities, per world | 64 | 256 |

Shared scenes are real entities in a real world, so they ride every world's entity accounting — which is why the last row is a separate, world-scoped budget rather than another viewer-side number.

Every budget is a bound, not a tuning promise: no default above has been measured.

  • Placeholders — what {kills} and {tps} resolve against, and why a stat line forces personal mode.
  • The .meowui format — how a scene like this is written down.
  • The web editor — the no-syntax authoring surface.
  • Holograms — the vanilla ceiling and the two render modes.