.esk bundle format¶
The canonical reference for what's inside a .esk folder.
Folder layout¶
myskin.esk/
manifest.json required
document.json required
hooks.json optional; auto-generated
textures/ optional; baked PNG textures
<placement_id>_albedo.png
<placement_id>_normal.png
assets/ optional; any other resources
studio.hdr
masks/<placement>.png
animations/ optional; exported animation tracks
wing_flap.json
shaders/ optional; custom WGSL
variants/ optional; per-theme / per-platform overrides
dark/document.json
designer_layout.json ignored by runtime (Designer's UI state)
manifest.json¶
{
"schema_version": "1.0",
"id": "dev.example.myskin",
"name": "My Skin",
"version": "0.1.0",
"color_space": "srgb",
"window": {
"shape": { "kind": "path", "path_d": "M …" },
"default_size": [720, 480]
},
"code_file": "myapp.py"
}
Fields¶
| Field | Required | Notes |
|---|---|---|
schema_version |
Yes | "1.0" today |
id |
Yes | Reverse-DNS identifier |
name |
Yes | Human-readable |
version |
Yes | Semver |
color_space |
Yes | "srgb" / "linear" / "aces" / "rec709" |
window.shape.kind |
No | "rect" / "ellipse" / "path" |
window.shape.path_d |
No | SVG path (when kind="path") |
window.default_size |
No | [w, h] pixels |
code_file |
No | Paired Python file (Code Link) |
document.json¶
{
"placements": [
{ "id": "background", "kind": "ellipse", "x": 0, "y": 0, "width": 360, "height": 360, "fill": "#0f0d1eff" },
{ "id": "time", "kind": "label", "x": 80, "y": 168, "width": 200, "height": 24, "text": "00:00:00", "font_size": 18 }
]
}
Each placement is a typed dict with at least id and kind. The
kind field dictates which other fields are valid.
Placement kinds¶
| Kind | Common fields |
|---|---|
ellipse / rectangle / rounded_rect |
x, y, width, height, fill, stroke, stroke_width, radius |
path |
path_d, fill, stroke, stroke_width |
arc |
cx, cy, radius, start_angle, end_angle, stroke, cap |
ticks |
cx, cy, inner_radius, outer_radius, count, stroke |
label / heading |
x, y, width, height, text, font_family, font_size, fill, align |
button / icon_button / orb_button |
x, y, width, height, label, fill, text_fill, radius |
card / panel |
x, y, width, height, radius, material, background_image |
image |
x, y, width, height, image_path |
mesh3d |
translate, rotate, scale, texture_path, material, mesh_dist |
light |
kind (directional/point/spot), color, intensity, direction/position |
canvas |
x, y, width, height (Python-driven via publish_display_list) |
The full type catalog lives in the framework source at
python/elysium/skin/schema.py.
hooks.json¶
{
"hooks": [
{ "id": "save", "events": ["click", "press"] },
{ "id": "name_input", "events": ["change", "focus", "blur"] }
]
}
Auto-generated by the Designer on save. Lists every hook exposed
by the skin so the framework's @window.on(...) decorator can
validate names. Code Link uses this for handler scaffolding.
Token references¶
Skin field values can reference theme tokens:
Resolved on load_skin and on set_theme.
Variants¶
The framework picks the matching variant based on the active
theme + accessibility prefs, falling back to the root
document.json otherwise.
On disk¶
Bundles are folders, not zips. Drag the folder between machines; the runtime resolves relative paths against the folder root.
See also¶
- Skins (framework guide)
- Project files