The media library and the creator asset editors.
Asset Studio
Beyond maps and content, the Studio ships a suite of asset editors for making the art, audio, and effects your game uses. Everything they produce lands in the shared media library and becomes selectable from every content form — items, mobs, NPCs, tilesets, and more.
There are two things people mean by "the Asset Manager", and it helps to keep them straight:
| Surface | What it is | How you open it |
|---|---|---|
| Asset Manager (workspace) | A full-screen studio with a sidebar of asset editors — Library, Animations, Pixel Editor, VFX, Sound Studio, Fonts, Shaders, Atlas Packer | Editor Tools → Asset Manager, or Ctrl+Shift+A |
| Media Manager (file library) | The actual file library — upload, folders, search, tag, delete, AI-generate. It's what pops up when you click any media field in a form | Automatically, from any media field in a content form; the manager's Library tab also links to it |
This page covers both: how to get media in (the Media Manager), and how the editors around it are organized. Each editor has its own page in this section.
Opening the Asset Manager#
From the zone editor, open Tools → Asset Manager or press Ctrl+Shift+A. The Tools submenu lets you jump straight to a specific tab (Library, Animations, Pixel Editor, VFX Editor, Sound Studio, Fonts, Shaders, Atlas Packer). The window has a vertical tab sidebar on desktop and a horizontal strip on mobile.
The Library tab is a read-mostly grid across every asset kind (images, animations, tilesets, audio, video, VFX, fonts, shaders, atlases) with a search box and type chips — a good place to see everything at a glance. The other tabs are the editors documented on the following pages.
The Media Manager — getting files in#
You'll spend most of your asset time here. It opens by itself whenever you click a media field in any form (an item icon, an ability icon, a tileset, an NPC portrait…), and it also runs as a standalone browser. In a form it shows a Select Mode badge and hides the folder stats to stay compact; standalone it shows folders, storage stats, and a sync footer.
Uploading#
You have several ways to add files:
- Upload button — opens a file picker; select one or many files at once.
- Drag and drop — drop files anywhere on the grid. You can even drop an OS folder and its subfolder structure is recreated inside the library.
- Drop onto a field — a media field in a form accepts a single dropped file directly.
- Link — the Link button adds a remote asset by URL (with an optional name) instead of uploading bytes.
Size limits: up to 50 MB per file on hosted projects (raised only by lifting your Supabase project's global upload limit first), and up to 64 MB on local projects. Oversized files are rejected before upload with a clear message.
Supported types: images (png, jpg, jpeg, gif, webp, svg, bmp), audio (mp3, wav, ogg, webm, flac, aac, m4a), video (mp4, webm, ogv), and fonts (ttf, otf, woff, woff2).
Large files just work. On hosted projects, big uploads go straight to cloud storage via a signed URL, bypassing the ~4.5 MB server-action body cap. You never have to think about it — just drop the file.
Duplicate detection#
Every upload is fingerprinted (SHA-256). If an identical file already exists, a resolver dialog appears:
- Same filename → Skip or Upload anyway
- Different filename → Use existing (default) or Keep both
- A "Apply to all remaining files in this batch" checkbox handles bulk drops in one decision.
This is why re-importing the same art twice doesn't quietly bloat your library.
Folders#
The left sidebar lists folders. The root is called Home.
- Create a folder with the folder-plus button, type a name, press Enter. Folders nest — a new folder is created inside whichever folder you're viewing.
- Navigate with the folder list or the breadcrumb trail (Home → … ).
- Scoping: browsing shows only the files in the current folder (not everything underneath it). This keeps large libraries manageable.
- Searching escapes the scope — a search spans every folder, so you can always find a file regardless of where it lives.
Good to know: there is currently no rename or delete for folders. A folder effectively goes away once it's empty. Plan your folder names up front.
Finding assets#
- Search — matches both the display name and the original filename, across all folders.
- Sort — Newest/Oldest updated, Newest/Oldest added, Name A→Z / Z→A, Largest, Smallest, or by Type.
- View — toggle Grid or List.
- Type filters (sidebar) — All, Images, Audio, Video, Links, each with a live count.
- Top tabs (standalone) — All Assets, Images, Tilesets, Animations, Audio, Video, plus two smart buckets: Generated (AI-made assets) and, on hosted projects only, Unsynced (assets not yet in cloud storage).
- Load more — the grid pages in as you scroll (200 at a time), with a manual Load more button as a fallback.
Working with a single asset#
Hover or click an asset for its actions:
- Click — docks the details panel on the right for that asset.
- Preview / magnify — the expand button on the tile, or a double-click, opens the asset full size in a centred viewer: wheel to zoom, drag to pan, double-click to reset, ←/→ to flip through the rest of the folder without closing, Esc to drop back to the docked panel.
- Edit — the only single-item editor: change the Name and edit Tags (comma-separated).
- Details — the preview panel lists name, type, MIME, pixel size, file size, duration, sample rate/channels (audio), filename, tags, and created date.
- Used By — for any asset, see every place it's referenced (table · field · label), or "Not referenced anywhere — safe to delete." Check this before removing anything.
- Regenerate (AI images only) — the panel shows the original prompt, provider and model, with a one-click Regenerate.
What isn't here (by design, today): there is no per-item Delete, Download, Copy URL, Copy ID, Move, or Replace on a single asset. Deleting and moving are bulk operations (below). To "replace" an asset in a form, clear the field and pick/upload a new one.
Bulk actions#
Selecting works like a file browser:
| Gesture | Selection |
|---|---|
| Click | Selects just that asset (and docks its details) |
| Click the tile's checkbox | Adds or removes that one, leaving the rest of the selection alone |
| Ctrl-click (Cmd on Mac) | Same as the checkbox — add or remove one |
| Shift-click | Takes everything between the last click and this one |
| Select all | Selects every asset currently listed — respects your folder, search and type filter, so it never grabs more than you can see |
Once anything is selected a bulk toolbar appears (Clear empties the selection again):
| Action | What it does |
|---|---|
| Move (N) | Move the selection into another folder |
| Delete (N) | Delete the selection (with confirmation) |
| Rename (N) | Add a prefix and/or suffix to every selected name |
| Tag (N) | Add and/or remove tags across the selection |
This is the intended path for cleaning up, reorganizing, and removing media.
Cleaning up unused files#
On hosted projects, deleting a media item removes it from your library but leaves the file behind it in cloud storage — several items can share one file, so it is never pulled out from under another. Over time those leftover files add up against your storage allowance. Local projects can collect them too (an interrupted upload or import). Clean up unused files finds them and deletes them safely.
Where: open the Media Manager on its own (not from a form field) and click Clean up unused files in the footer, bottom right.
How to clean up#
- Click Clean up unused files. The dialog runs a dry run straight away — nothing is deleted yet.
- Read the summary: how many files are stored, how many are in use, and how many nothing uses.
- Adjust Only files older than and Delete at most if you want to (the list refreshes).
- Click Delete N unused files, then Delete permanently to confirm.
- The dialog reports how many files were deleted and how much space was freed. Run it again if it says more are left.
What the dialog shows#
| Field | What it means |
|---|---|
| Stored files | Every file in your project's storage, with the total size |
| In use | Files a media item or any of your content points at — these are never deleted |
| Unused files | Files nothing points at — the only thing this tool deletes |
| Newer than the cut-off | Unused files still inside the grace period — kept for now |
| Only files older than | The grace period (1 to 90 days, default 7). A file younger than this is never deleted, so an upload that is still finishing is safe |
| Delete at most | A per-run cap (default 500). Run it again for the rest |
| Media items nothing uses | Library items no map, event, item, ability, sprite, tileset, UI screen or setting uses. Listed for you to review only — never deleted here. Remove any you don't want with the bulk Delete action |
What counts as "in use"#
The check reads all of your project's content — every table, including map events, sprite and avatar settings, tilesets, UI and login screens, item and ability icons, and settings — and looks for each file's ID or address. If anything mentions a file, it stays. Just before deleting, each file is checked once more against your library, so a file you re-uploaded while the scan ran is kept.
Gotchas#
- Publish before you clean up. The check looks at your editor content. If you deleted something since your last publish, your live game server may still be showing its file until you publish again.
- Deleting is permanent. There is no undo and no recycle bin. Every run is recorded in the Audit log.
- Media items are never deleted by this tool — only the leftover files behind items that are already gone.
- Projects that keep media inside the database (a remote database without cloud storage) have no stored files, so the dialog only lists unused media items.
- Large projects take a while. If the check cannot finish in time, the dialog says so and deletes nothing — try again when the project is quiet.
- Works the same on local projects (files in your project's asset folder) and hosted projects (cloud storage).
- AI tools can run the same check:
GET /api/ai/media/gcreturns the dry run, andPOST /api/ai/media/gcwithconfirm: truedeletes, with the same rules.
Recolor an image as a new asset#
Make a recoloured copy of any image, sprite sheet or tileset — team colours, seasonal variants, armour tiers — without touching the original.
Where to find it: Asset Manager → Media, select an image, sprite sheet or tileset, then Recolor… in the details panel. It is there while the Sprite Recolor feature is on.
- Select the image and click Recolor….
- Swap colours in the Palette: click a colour, then pick what it becomes. A swapped swatch shows its new colour in the corner; Keep original undoes one swap.
- Add Steps for broader changes. Steps apply top to bottom — the eye bypasses a step, the arrows reorder it. + Add a step → Presets adds a ready-made recolor (Red Team, Frost, …) or one of Your presets as steps you can still tweak.
- Check the result with Result / Original and Zoom; the line above the image says how many pixels changed and how many colours are left.
- Name it under Save as and click Save as new asset. The new asset opens; the original is unchanged.
| Step | What it does |
|---|---|
| Palette swap | Every swatch you changed becomes its new colour. Tolerance also catches near-identical shades, such as anti-aliased edges. |
| Hue / saturation / lightness | Rotates the hue (degrees) and shifts saturation and lightness. |
| Replace a colour | Swaps one colour (From — pick it, or Pick from image) for another (To). Tolerance widens the match. |
| Brightness / contrast | Lightens or darkens, and adds or removes contrast. |
| Tint toward a colour | Gives the pixels the tint's colour while keeping their own shading — light stays light, shadow stays shadow. Amount mixes from untouched (0) to fully tinted (100). |
Sprite sheets: frames and areas#
Every step can be limited to part of the image — a cloak, a banner, a shield — instead of the whole sheet.
- Set Frames (above the image) to the size of one frame, for example 32 × 32. It is filled in for you when the asset already knows its frame size. A grid shows the frames, and a small preview under the steps plays them in order (Pause / Play).
- Select a step and click Draw area, then drag boxes on the image. Click Done when finished.
- With Same area in every frame ticked (the default once frames are set), a box drawn in one frame applies at the same spot in every frame, so the cloak changes in every pose at once. Untick it to recolor only where you drew.
- Whole image removes the area so the step applies everywhere again.
| What you see | What it means |
|---|---|
| Area: whole image | The step changes the whole image |
| Area: 2 boxes | The step only changes what its boxes cover |
| Dashed boxes on the image | The selected step's area — in every frame when it repeats |
Gotchas:
- A box stays inside the frame you start dragging in. Drag again in the frame you want.
- Areas need the image itself. A recolor set on a character, mob, pet or mount's look (rather than saved as a new image) skips any step that has an area.
Saving a recolor as a preset#
Type a name under the steps and click Save as preset to keep the steps (the ones with their eye open) for reuse on any other image. Your presets lists them; × then Delete removes one. Saving under a name you already used replaces that preset. Presets belong to the project and come along when you export it; they are never sent to the game, because a recolor is baked into a new image when you save it.
Gotchas:
- Transparent pixels are never touched, and the image keeps its exact size — pixel art stays crisp, and a recoloured sprite sheet lines up frame for frame with the original.
- A grey image has no hue to rotate. Use a palette swap or Replace a colour instead.
- Very large images update the preview when you let go of a slider rather than while you drag.
- Undo / Redo at the top of the editor step back through your changes.
- Saving a result identical to an asset you already have asks whether to reuse that one.
Recolor with the AI copilot#
The media-recolor AI action does the same job without opening the editor. Ask the copilot for something like "make a red-team copy of the goblin sprite sheet" and it saves a new recoloured asset; the original is unchanged.
| Field | What it does |
|---|---|
| Source | One media item, or up to 20 to recolour a whole set the same way. Each source gets its own new asset. |
| Colour | A preset (red-team, blue-team, green-team, gold, frost, shadow, undead, or one of your saved presets by name), a hue / saturation / lightness shift, or a full list of steps like the editor's. |
| Name | The new asset's name, for one source only. Without one, the asset is named after its source and preset, such as goblin (Red Team). |
| Folder / tags | Where the new asset goes (default: the source's own folder) and the tags it gets. |
Gotchas:
- A preview saves nothing. When the copilot previews the step, it reports for each source how much of the image would change, how many colours are left and the new file's size.
- A set keeps going past a bad source. The result lists each one it skipped and why.
- The copilot can manage presets too. recolor-preset-list shows the built-in and saved presets; recolor-preset-save saves one under a name (replacing a preset of the same name).
- Images over 16 megapixels are refused here. Recolour those in the editor.
- SVG and GIF files can't be recoloured. Convert them to PNG first.
Used By, inline media and cooked assets#
Three more storage tools live next to the cleanup: a Used By list on every media item, a way to move pictures that were saved inside your content out into files, and cooked assets — small previews and size checks made when you publish.
Where to find them#
- Used By — Asset Manager → Media, select any item; the details panel ends with Used By.
- Inline media and Cooked assets — Asset Manager → Media → Clean up unused files, at the bottom of the dialog.
- Cooking also runs automatically as the Cook assets step of Publish.
Used By#
Lists every map, event, NPC, item, sprite, tileset, UI screen, setting or other media item that points at the selected file — by its ID or by the file itself (so a copy pasted as a web address still counts). Each line shows the thing's name and where it is (the table and the field).
| What you see | What it means |
|---|---|
| N references | How many things use this file |
| Not referenced anywhere — safe to delete | The whole project was checked and nothing uses it |
| The search stopped before checking everything | A very large project ran out of time; the list may be missing entries — don't delete on this basis |
It uses exactly the same rules as Clean up unused files, so the two never disagree.
Moving inline media to files#
Older imports and some editors saved pictures straight into your content as long text ("base64"). That makes every save, publish and reload carry the whole picture again.
- Open Clean up unused files and click Check under Media stored inside the database.
- Review the list: how many media items and which content fields still hold pictures, and roughly how much space they take.
- Click Move to files. Each picture is stored once (identical copies share one file, placed in the /harvested folder) and every place that used it now points at that file.
- If the result says More left, click it again until it says All done.
Everything keeps showing the same picture — only where the bytes live changes. New uploads, imports and harvested event sprites go straight to files already.
Cooked assets#
| Field | What it means |
|---|---|
| Cooked | Media that already has its preview and size check |
| Waiting | New or changed media the next publish (or Cook now) will handle |
| Object cards without a preview | Objects-palette cards that will get the cooked preview of their image |
| Over budget | Images wider or taller than 4096 px (many phones cannot load them), image files over 16 MB, audio over 25 MB |
A file is only cooked again when its contents change. Each publish cooks up to 240 files, so a first publish of a very large library finishes over a few publishes — the game works the whole time. Cooking also makes smaller copies, low-memory previews and levelled sounds for players — see Media Cooking.
Media whose bytes are still stored inside the project database (rather than inside your content) is moved out from Project Health — see Moving Stored Media to Files.
Gotchas#
- Projects whose database is shared with other machines (a remote database without cloud storage) keep media inside the database; Move to files is not offered there.
- Very small icons (a few KB) are left inline on purpose — a separate file would cost more than it saves.
- Stored previews are never moved; they are meant to be small and inline.
- Over-budget images are reported, not changed — split or re-export them yourself.
- Moving and cooking are recorded in the Audit log.
- AI tools:
GET /api/ai/media/graph?mediaId=…(what uses a file) or?table=…&id=…(what a record uses),GET/POST /api/ai/media/inlineandGET/POST /api/ai/media/cook— both POSTs are dry runs unless you sendconfirm: true.
Importing existing content#
- URL / Link import — the Link button (above) references a remote file without copying it.
- Library "Import" funnel — on the Asset Manager's Library tab, the Import button opens a per-file table where each file gets a name and an "Import as" choice: Image, Tileset, Sprite sheet → Animation (with frame width × height), Audio, or Video. Sprite sheets become configurable animation assets; everything else lands in the library.
- Whole-project imports (RPG Maker / RPG Tools) are separate importers — see Data Management.
Editing an image you already have#
Select an image in the Library tab and press Edit pixels. It opens in the Pixel Editor at its own size, as a normal editable layer — every tool works on it.
When you save, you are asked which you meant:
| Choice | What happens |
|---|---|
| Replace original | The same asset now holds the new art. Everything already using it — items, tiles, NPCs, abilities — shows the change, because they all point at the asset rather than at a copy of its pixels. The prompt tells you how many things that is first. |
| Cancel | Saves a separate copy named "… (edited)" in the same folder and leaves the original exactly as it was. |
Only images open this way. VFX, shaders, fonts and atlases have no picture behind them, so their actions just take you to the right editor.
Replacing is not undoable. The old pixels are gone once you save over them. If an image is used in many places and you only want it different in one, save a copy and point that one thing at the copy.
Deleting several assets at once#
The Library tab tidies up as well as it imports. Hover any card and a checkbox appears in its corner; Select all (to the right of the filter chips) ticks everything the current search and filter chips are showing — never the rows hidden behind them. A bar then appears along the bottom with the count and a Delete button.
One selection can mix kinds freely — images, animations, VFX, fonts, shaders and atlases go together, and each is removed the way its own editor would remove it. That means the usual protections still apply: a font still assigned to a UI role refuses to go, and says which roles to reassign first. Anything that can't be deleted stays ticked with the reason shown, so a partial result is never silent.
Generating assets with AI#
- Generate (the ⚡ button) opens the image generator: Prompt, Negative prompt, Asset type (Icon, Tileset, Sprite, Texture, VFX, UI, Concept), Style preset (Pixel Art, Isometric, Stylized, Realistic, Hand-drawn, Photoreal), Model & Quality, Size, and a Transparent background toggle. It shows credits available and the per-generation cost, and offers Generate variation afterward.
- Audio generation — media fields for audio open a Sound Effect or Voice Line generator (prompt or line, voice selection, duration).
- AI Settings — manage per-asset-type style reference images that steer future generations toward your game's look.
Generated assets are tagged so the Generated bucket collects them automatically.
How an asset gets referenced#
When you pick an asset, the form receives both a media id and a resolved src (URL or data URI). Which one is stored depends on the field — some editors store the id, others store the URL directly (for example, an ability's icon stores the resolved URL). You don't manage this yourself; just pick the asset and the field records the right thing.
On hosted projects, files are content-addressed in cloud storage (identical bytes dedupe to one file). Local projects work the same way on disk: every upload is stored once, by its fingerprint, under your project's assets/.ed5-media/ folder, and the library keeps only a small reference — the project database stays lean no matter how much art you add. Files you drop directly into the assets/ folder are picked up in place (see the sync footer below); they keep their names and locations. Older projects that still carry images inside the database are moved to the file store automatically the next time you Publish (the "Optimizing media" step) — a one-time cleanup that can shrink a big project's database dramatically.
The engine's own built-in art — the 600 object sprites and the 20 ground terrains — is stored the same way from the moment a project is created, which keeps roughly 120 MB out of every new project's database. A project made before this change picks the saving up the next time its starter content is refreshed.
Leave
.ed5-mediaalone. It's the engine's content store — deleting files from it breaks the assets that reference them. Deleting an asset in the Media Manager cleans up its file automatically once nothing else uses it.
Syncing (standalone footer)#
On a hosted project the footer shows local/remote status, pending upload/download counts, and any conflicts. Sync Now processes the queue; Sync Activity opens a log where you can resolve conflicts. Sync is what keeps a project's media consistent between your machine and the hosted copy in cloud storage.
Desktop projects never use cloud storage for media. If you run Studio on your own computer — with the embedded database, Docker, your own Postgres or Supabase database, or your own game server — your media lives in the project folder (
assets/.ed5-media) and reaches players through Publish: publishing sends every image, sheet and sound to the game server you are connected to, bytes included when that server is on another machine, and the server serves them to players itself. Nothing is written to a Supabase Storage bucket, so an empty bucket in your own Supabase project is expected. The footer reads Remote: sent on Publish, and the Unsynced tab, Sync Now and Sync Activity do not appear.
The editors at a glance#
Each of these is a tab in the Asset Manager, documented on its own page:
| Editor | What it makes | Page |
|---|---|---|
| Avatar & Sprite Editor | Sprite sheets mapped to named animations (used by players, mobs, NPCs) | Avatar & Sprite Editor |
| Sound Studio | A full in-browser DAW plus the data-driven game-audio engine | Sound Studio & Audio |
| Shader Editor | Post-processing and sprite effects (presets or raw GLSL) | Shader Editor |
| Atlas Packer | Packs a zone's images into efficient texture atlases | Atlas Packer & Fonts |
| Font Manager | Uploaded / Google fonts assigned per UI role, with baked bitmap atlases | Atlas Packer & Fonts |
| Pixel Editor | A built-in pixel-art paint tool | Pixel Editor |
| VFX Editor | Death effects, hit sparks, AOE visuals, telegraphs, lights | Visual Effects |