New mythical creature forms are added by implementingDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ikeepcalm/coi-client/llms.txt
Use this file to discover all available pages before exploring further.
MythicalCreatureForm and calling MythicalFormManager.register() inside the manager’s static initializer block. The server triggers player transformations by sending a MythicalFormPayload containing the pathway name; the client looks up the registered form and replaces the player’s vanilla model with fully procedural, translucent 3D geometry for as long as the transformation is active.
The MythicalCreatureForm Interface
All forms implementdev.ua.ikeepcalm.coi.client.mcf.MythicalCreatureForm. The interface is intentionally lean — two abstract methods plus two default geometry helpers:
Method Reference
| Method | Details |
|---|---|
getPathwayName() | Returns the human-readable pathway name (e.g. "Sun", "My New Form"). MythicalFormManager.register() uses this string — lowercased — as the primary registry key, and also inserts several normalized variants automatically. |
render(state, pose, consumer) | The main render callback. Use drawBox and addVertex to submit geometry. Access animation state via state.ageInTicks and per-player lighting via state.lightCoords. |
drawBox(...) | Convenience helper that emits all 6 faces (24 vertices) of an axis-aligned box in local player space. Colors and alpha are per-call, in the 0.0f–1.0f range. |
addVertex(...) | Low-level helper for custom shapes. Internally calls consumer.addVertex(...).setColor(...).setUv(...).setOverlay(NO_OVERLAY).setLight(...).setNormal(...) — matching the Minecraft 1.21.2+ buffer API. |
Coordinate System
All geometry passed todrawBox and addVertex is in local player space:
- Origin is at the player’s feet (ground level).
- Y+ is up — a typical full-height humanoid body reaches
Y = 2.0, and a head sits aroundY = 2.0–2.6. - X is lateral (right = positive), Z is depth (forward = negative in standard orientation).
- All geometry is rendered in translucent mode using
coi-client:textures/entity/white.png— ther,g,b,avalues you supply per vertex are the actual visible color. - The
PoseStackis pre-rotated around Y by180° − state.bodyRotbefore yourrender()is called, so shapes you define facing +Z will automatically face the same direction the player is looking.
Because the pose stack is already aligned with
state.bodyRot, you do not need to apply any rotation yourself for a standard upright humanoid form. The existing forms — FoolForm, SunForm, TyrantForm, etc. — rely entirely on this pre-rotation.Step-by-Step Guide
Implement getPathwayName()
Return the pathway display name exactly as it appears in the server’s
mythical_creatures.json. Letter case does not matter for matching — MythicalFormManager normalizes everything to lowercase — but the string you return here is what the debug screen and getRegisteredPathwayNames() will display:Build the creature shape in render()
Use
drawBox() for solid regions and addVertex() for custom polygons. All coordinates are in the local player space described above:Animate with state.ageInTicks
state.ageInTicks increments every client tick (20 Hz) and is the standard driver for all form animations. Combine multiple sine/cosine frequencies to avoid repetitive motion:state.lightCoords directly to every drawBox or addVertex call — this ensures your form inherits in-world lighting rather than appearing uniformly lit.Register in MythicalFormManager's static block
Open
MythicalFormManager.java and add your form to the static initializer, alongside the 20 existing registrations:Boilerplate Example
The following complete class is taken directly from theMYTHICAL_FORMS.md reference:
SunForm or FoolForm), expand render() with multiple drawBox calls at different offsets driven by Math.sin(time * ...) and use a for loop with a seeded Random for orbital particles or trailing effects.
Registration
Add your form to thestatic initializer in MythicalFormManager.java:
register() stores the form under multiple normalized keys so the server does not need to match the pathway name character-for-character (see Key Name Normalization below).
Aesthetics Guide
When designing the look of a new form, follow the visual language established by the existing 20 forms:- Colors — keep them vibrant and thematically aligned with the pathway. The established palette is: Fool = purple/indigo (
0.72, 0.5, 0.92), Tyrant = lightning cyan, Sun = blazing gold (1.0, 0.62, 0.0), Death = green gas / bone white. Avoid muddy mid-tones. - Opacity — use
0.2falpha for glassmorphic ghost-body silhouettes (as inFoolForm’s translucent humanoid base), and0.85f–0.95ffor dense core structures. Layering multiple semi-transparent boxes at the same position creates natural depth and glow. - Animation — combine at least two different sine/cosine frequencies in
time(e.g.time * 0.12ffor slow pulse andtime * 0.38ffor fast shimmer) to break up rhythmic repetition. Per-particle phases seeded with a fixedRandom(i * SEED)prevent all orbiting elements from moving in lockstep. - Performance — keep loop iteration counts reasonable. The existing forms use between 16 and 24 particles per loop. Each
drawBoxcall emits 24 vertices; 20 particles × 24 vertices = 480 vertices per frame per transformed player in view. Avoid allocatingnew Random(...)or any other heap objects that aren’t strictly necessary insiderender().
Key Name Normalization
MythicalFormManager.register() automatically inserts the form under five key variants derived from getPathwayName(), all lowercased:
| Variant | Example for "My New Form" |
|---|---|
| Exact lowercase | "my new form" |
| Spaces removed | "mynewform" |
| Underscores removed | "my new form" (same if no underscores) |
| Spaces → underscores | "my_new_form" |
| Underscores → spaces | "my new form" |