Skip to content

Repository files navigation

Gloss Editor

Visual web editor for Gloss menu and display configurations. Build holographic menus on a calibrated canvas, edit every field the plugin actually parses, and export documents and images that drop straight into plugins/Gloss/.

Version 4.0.0 — a from-scratch rewrite in arcane_jaspr (Dart, compiled to a fully static site). Replaces the retired Next.js editor.

Features

  • Visual canvas in block space: zoom/pan, grid + snapping, drag components, selection, keyboard nudge. Uses the runtime's documented text-line scale, uiScale semantics and hitbox geometry while clearly separating approximations that depend on the Minecraft client.
  • Linked button hitboxes: text and image click planes follow the visible render, while an optional custom width and height can replace automatic icon-derived sizing without creating an independent position that can drift away.
  • Runtime 3D preview: simulates the open pose, followPlayer position and yaw, fixed / vertical / horizontal / center icon billboards, click planes, hover push and nearest-click behavior. Client text wrapping, culling, brightness, entity models, effects, obstruction and competition between personal menus and boards still require in-game validation. PlaceholderAPI tokens remain literal because the browser has no server context; the preview reports their refreshTicks cadence instead.
  • Full format coverage as the plugin's Gson actually reads it — all three component types (button / decoration / toggle), all eight authorable icon types (text / textImage / animatedTextImage / item / block / customItem / entity / playerHead), all six actions (command / sound / message / teleport / connect / navigate), toggle conditions, maxDistance, closeOnDeath, closeOnTeleport, customModelValue (the real key — the customModelData older files carry is migrated on import).
  • Kind modes: top-bar tabs — All plus one per document kind — scope the shell to a single kind, narrowing the library rail and its heading count, defaulting creation to that kind and naming the kind in empty states. The mode persists and follows the documents you open. Workspace-bundle import/export and erase-all live in a labelled Workspace actions menu on the rail instead of the creation row.
  • Four views, every kind: Visual (the kind's own editing surface), Preview (that surface framed in a Minecraft game screen — sidebar against the client's right edge, tablist overlay, server-list MOTD, bubbles over a player, emoji in chat, holograms and animations in-world), Code (two-way JSON sync) and Split. The choice is remembered per kind, and a kind that cannot use a view says why rather than hiding the button. Validated menu handoffs retain their exact source formatting and extension keys through storage and export until the first visual edit or explicit Format action.
  • Drop stage: dropped stacks are thrown forward, tumble, bounce and settle under the settings document, through a port of the plugin's own RealDropModel — displays per stack from the stack size, the offset table, the scale family a material belongs to, the configured tumble rates with their variance and bounce re-rolls, the settled landing pose, the authored ground clearances, and the &7{count}x {type} label with its real background, shadow and see-through depth. Pose changes are handed to the client's own interpolation windows, so a coarse updateIntervalTicks reads as coarse here too. Left alone the stage cycles one stack per model family — a cube, a flat item and a slab — changing on every completed drop; the shuffle button steps out of that rotation and through the whole themed sample table.
  • Scripted and physical drops: the two optional document blocks both run on the stage, and the stage keeps them apart the way the format does. physics moves the item — gravityMultiplier, bounce, waterBuoyancy and waterDrag are applied to the stage's trajectory with the plugin's own constants, so gravity 0 really does hang the stack and bounce 0 really does land and stick. script moves only the picture: expressions are compiled with the same engine the container previews use, vars run first in declaration order, and the result composes onto what the document already computed — offset adds blocks, rotation composes onto the pose before the resting-height clearance is recomputed, scale multiplies the family per axis, glow traces an outline and visible stops drawing a display without removing the drop. A broken expression is refused with the server's own sentence, field and character position included, whether or not the script is switched on — because that is when the server refuses it. The inspector edits expressions in a monospace field that shows the parse error under the character that caused it, and the vars list adds, removes and reorders without ever sorting, because declaration order decides what each entry can read.
  • What the drop stage approximates, all four named in its readout: the ballistics (Minecraft's Item entity owns the real ones; the throw keeps the shape of Player.drop but at a distance the stage can frame, and the physics block bends that arc rather than the server's); a cube's side texture, because the sprite catalog ships one rendered image per material rather than six face textures; the four script variables a browser has no world to read — inWater is a water button that floods the stage so a buoyancy script has something to act on, inLava is always false, and both light levels are 15; and the glow outline, which is a pair of drop-shadow filters at the sprite's alpha edge rather than the client's own silhouette pass.
  • Drop stage camera: the editor stage is a free camera — drag to orbit, WASD to walk, space and shift for height, wheel to dolly, and a Reset view control that puts the default framing back. Pitch is clamped above the ground and short of straight down, and every offset is bounded, so the stack cannot be lost off screen. The stage takes the keyboard only while it is focused and drops held keys on blur, so typing elsewhere is never stolen. The same stage inside the game screen keeps a fixed camera: that frame stands in for the client's own view.
  • Themed sample content: every generated document, mock tablist and canned chat line comes from one themed pool in config/showcase_flavor.dart, so a screenshot reads as somebody's server rather than as lorem ipsum. Randomizing picks a mood and derives the whole document's colour, glyphs and motion from it, over an effect library — breathing and sweeping gradients, stepped palettes, strobes, tickers, a scanline, a typewriter and a per-character wave — all written as pipeline text a person could have typed. Tablist randomization chooses among compact, welcome, status, event, community and staff structures, then independently composes bounded header/footer rows, animation recipes and group-name formats instead of repainting one preset.
  • Inspector help: every field carries a note — generated from the plugin's JSON schemas, hand-written where a schema is silent or hides a runtime trap, each hand-written body citing the Gloss source line that proves it. Defaults show with one-click reset, sections collapse and remember it, colours get a picker, and tick/millisecond fields show a live seconds readout.
  • Validation engine aligned with the plugin's authoring contract (lowercase registry keys, action source spellings, silent-zero pitfalls like volume: 0, legacy and MiniMessage formatting, hitbox overlap warnings).
  • Image library: upload validated PNG pixel art, preview with the plugin's rasterization rules, export images.zip laid out for plugins/Gloss/images/. Player heads import either from a skin PNG you pick or from a typed username, fetched from a public skin CDN and composited through the same face-plus-hat path so both routes produce the identical 8x8 asset. Server sync preserves captured PNG, JPEG, GIF, WebP and BMP bytes losslessly.
  • Workspace: folders, multiple menus and menu flow maps, atomic IndexedDB autosave with previous-transaction recovery and cross-tab conflict protection, undo/redo, templates, and searchable catalogs. Renaming a runtime id updates navigation, linked world-panel roots and sync scope as one checked save; dropped JSON opens as a uniquely named document instead of replacing the active one. Existing holoui.workspace.v1 / v2 localStorage data migrates once without deleting the rollback copy.
  • Optional server sync: capability links opened from /gloss menu edit import an exact menu or persistent panel graph through the configured relay. Linked panels expose typed root-menu, transform, follow, audience, permission and range controls, with strict JSON under Advanced. Panel publication retains the bound no-delete baseline and adds only menus reachable from the panel root, leaving unrelated folder documents local. A labelled Publish to Server action appears in the connection bar during a live capability session; it durably saves a panel project and hot-reloads the running panel, while revision conflicts never overwrite local work. Links use the configured HTTPS relay (the plugin defaults to https://sync.gloss.volmitsoftware.com/v2) or a localhost HTTP development relay; an unreachable provider is reported without implying that a deployment is available.

The editor itself remains a static client with no accounts, and it makes outbound requests in exactly two situations. Asking the image manager for a head by username sends that username, and nothing else, to https://minotar.net/skin/<name>.png — or to https://mc-heads.net/skin/<name> when minotar does not answer; no request is made until you type a name and press Fetch head. Opening a server-issued capability link enables bounded HTTPS requests to that link's relay until the tab disconnects. Everything else — authoring, autosave, import, export and the whole document workspace — stays local to the browser. Capability tokens stay in the URL fragment and tab sessionStorage, never in workspace documents or exported bundles. If tab storage is blocked, the capability stays in the fragment and the sync bar tells you to copy the link before reloading.

Sync v2 does not delete captured server resources. A panel can add menus only under the displayed newMenuPrefix; menus and panels can add images only under newImagePrefix. The editor validates exact runtime ids, the whole bound graph, typed panel JSON, image bytes, immutable constraints and content revisions before publishing. Synced raster assets are limited to 64×64 pixels each and 262,144 stored pixels per project; every repeated text-image component and animated frame is counted again against a 262,144-pixel / 4,096-row runtime-render budget. The protocol safety ceiling is 32 MiB per project; a relay deployment may enforce a lower configured limit and return 413.

Workspace bundles and server projects span IndexedDB documents and localStorage images. Import and refresh use checked compensation when either write fails, but browsers provide no atomic transaction across those two storage systems; force-closing the browser between their writes can leave a partial import.

Development

Requires Dart ≥ 3.10 and a checkout of arcane_jaspr at .deps/arcane_jaspr (a symlink to a local clone works):

git clone https://github.com/ArcaneArts/arcane_jaspr .deps/arcane_jaspr   # or: ln -s /path/to/arcane_jaspr .deps/arcane_jaspr
dart pub get
dart run jaspr_cli:jaspr serve      # dev server on :8080
dart test                           # core-logic test suite
dart run jaspr_cli:jaspr build      # static output in build/jaspr/

Releasing

The hosted editor is deployed to gloss.volmitsoftware.com through the existing Firebase holoui-editor project and Hosting site by .github/workflows/firebase-hosting.yml after every push to master. The workflow checks the paired Gloss runtime contract, analyzes and tests the project, then builds, deploys, and verifies the custom-domain bundle. It requires the FIREBASE_SERVICE_ACCOUNT_HOLOUI_EDITOR repository secret. There are no editor releases: /gloss menu builder links players to the hosted editor.

Architecture

lib/model/        Gloss menu JSON data model + codec (runtime semantics, unknown-key preserving)
lib/doctype/      per-kind DocumentTypeAdapter registry (codec, views, capabilities, templates, inspector)
lib/logic/        validation rules, Minecraft text parser, viewport math, hitbox geometry
lib/services/     browser storage, image library, catalogs, file transfer, clipboard
lib/state/        EditorStore, IndexedDB persistence, multi-doc workspace and menu flow maps
lib/components/   shell (top bar, shortcuts, palette), canvas, inspector, panels, dialogs
web/assets/       fonts (Geist, lucide, Minecraft), item/sound catalogs, backdrop, brand
tool/             asset extraction scripts

Editor Tandem

This editor is developed in tandem with the merged Gloss plugin (VolmitSoftware/Gloss, checked out beside this repo at ../Gloss), and Gloss is the truth repo: every format contract is derived from its Java parsing code (art.arcane.gloss.* via VolmLib's Gson setup), never from schemas or documentation — where prose and code disagree, this editor follows the code. The concrete anchors of that contract — shipped defaults, baselines, preview cards, golden snapshots, generated catalogs, and the cross-repo vector tables — are inventoried in FIXTURES.md; the test suite compares the editor's copies against the live Gloss checkout, so a change to any shared contract must land editor-side and plugin-side in the same workstream, with both suites green against the paired checkouts. Editor copies are never edited in place: the Gloss resource changes first, then the copy (and its embedded Dart constant) is refreshed or regenerated here.

About

Web builder for creating and previewing HUI configs.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages