ARefinery / Accelerated Accelerated · 12 modules

AshForge Refinery · the whole tool, one course

It tells you what is wrong.
It does not stop you.

Refinery builds the asset index the rest of the suite reads. Almost nothing in it is a gate — it warns, records and carries on, and knowing exactly which one switch does refuse is the difference between a clean ship and a surprise at signing.

Application  AshForge Refinery Prerequisites  none Format  one course, 12 modules Time  ~75 min

What it is

An indexer. It walks your mod's assets, records what it finds, and writes the index Motion and Echo both depend on.

Modules 1–4 are the index, 5–8 are what it will and will not stop, 9–12 are the ledger underneath.

The thing to internalise

It is a ledger, not a mirror. It records what happened rather than reflecting what is there now.

That one distinction explains most of its surprising behaviour.

Why this is one course

Refinery is a focused tool. Its content is 12 things worth knowing, not three escalating tiers — the old split implied the later material needed the earlier, and it does not. Read straight through, or jump to the module that matches your problem.

01

Classification

Type is the extension

Read nine of them

An asset's type is decided by its file extension and nothing else — not by inspecting the file, not by what the importer managed to do with it. The whole map is nine entries long.

TypeExtensions
Model.glb .gltf
Texture.png .jpg .jpeg .tga .exr
Audio.wav .ogg
Unknowneverything else — including .fbx and .obj

Case does not matter, so .PNG is a texture. What does matter is the gap in the last row: the file dialog offers .fbx and .obj under "Models", and the model importer accepts both — both verified — but the type detector has no case for either.

So those two import successfully, appear in the index, and are labelled unknown. Nothing is broken and nothing warns; they simply will not be found by anything looking for a model. Convert them to glTF before importing and the problem disappears.

Key
Type is a label written at import time, not a property of the file. Rename an asset's extension and you change its type; import the same content twice under two extensions and you get two different types.
02

The contract

What an entry carries

Read seven fields

Every successful import adds one entry. It is worth knowing each field, because between them they are everything the rest of the suite knows about your asset.

FieldHoldsWhy a consumer wants it
nameThe logical name, no extension.How a mod refers to the asset.
typeLowercased: model, texture, audio, unknown.Filtering — Motion looks for animations here.
outputRelative to the assets folder.Finding the file wherever the mod is.
sourceWhere it came from.Audit only.
hashA real SHA256 of the emitted file.Telling whether it changed since last look.
sizeBytes · presetSize, and which preset produced it.Provenance.

The two doing the most work are output and hash. A relative output path means the index survives the mod being moved or shared; a real content hash means a consumer can tell a changed asset from an unchanged one without opening it. That pairing is how Vault does change detection.

Naming matters more than it looks
The name is what other tools show and what a mod refers to. It is taken at import, so name your source files the way you want them referred to — renaming later means re-importing.
03

Omissions

What never reaches it

Diagnose done only

The index lists what exists, not what you attempted. An asset only earns a line by finishing.

In the queueIn the index?
Status done, with an output pathYes
Status errorNo
Still pending or validatingNo
Finished but with no output pathNo

Verified with a queue of four, of which two finished: the index held exactly two entries. The other two left no trace in it at all — not an entry marked failed, simply nothing.

Which means a queue that looks mostly successful can produce a much shorter index, and the queue is the only place the failures are visible. If a consumer cannot see an asset you are sure you imported, the index is the place to look first and the queue is the place to look second.

Also refused outright
Writing an index needs a real mod folder. An empty or non-existent mod root is refused rather than guessed at — both verified — so there is no chance of an index appearing somewhere nothing will look for it.
04

Consumers

Who reads it

Know five tools

The index sits at <mod>/assets/assets.index.json, and it is read by more of the suite than any other file Refinery produces.

ToolUses the index to
MotionList a clip for every animation asset — see Two Sources, One Name.
EchoFind audio to build banks and sounds from.
AtlasOffer props to place.
VaultBrowse assets and detect what changed, via the hash.
StudioReport what a mod contains.

All of them go through the same shared reader, and so does Refinery when it merges — deliberately, so that what the writer sees is exactly what the consumers see rather than two parsers that could disagree.

It also means an asset's absence from the index is felt across five tools at once, which is why the failure modes on this page are worth recognising early.

SymptomWhat it meansFix
A model does not appear in Motion or AtlasIt was a .fbx or .obj and is typed unknown. Convert to .glb and re-import.
An asset is missing from every toolIt is not in the index — it never finished. Check the queue for its error.
A tool shows a stale versionThe hash tells it nothing changed. Re-import so a new hash is written.
Nothing was written at allNo valid mod root. Open a mod folder first.
05

Permissiveness

Nothing here is a gate

Read warnings only

The word validation suggests a check that can stop something. Here it cannot. A texture that trips every check imports successfully, is emitted into the mod, and appears in the index like any other — verified.

What the checks produce is warnings on a successful import. They are advice attached to a result, not conditions on it, which makes them easy to miss precisely because nothing went visibly wrong.

That is a reasonable design for an asset pipeline — refusing an artist's file because it is 100 pixels wide would be worse. But it means the warnings column is the only place problems appear, and a run of thirty assets that all say "done" can still be carrying thirty warnings.

Key
Treat the import list's status column as "did it finish", never as "is it right". The two are separate questions and only the first is answered there.
06

Power of two

One switch works

Compare on vs off

Import a 100×100 texture with Validate power-of-two textures on, then off, and compare the warnings.

TextureSwitch onSwitch off
100×100Warns about power-of-twoSilent
128×128SilentSilent

So this one is real: the switch genuinely governs whether the check runs, and the check genuinely notices. Both imports succeeded either way — the switch controls the advice, not the outcome.

There is a second size check that is always on: a texture larger than Max texture size warns at import regardless. Note that the warning and the resizing are different steps — the importer notices the size, and the optimisation processor is what actually changes the pixels. You can get the warning without the resize if resizing is switched off.

07

The other one

One switch does not

Diagnose inert

Run the same comparison for Validate meshes have UVs and there is nothing to compare. On and off produce identical results: same success, same warnings, same everything.

The setting is read and the code does enter its branch — and the branch is empty, its one line commented out with a note that a full UV probe is expensive. So the toggle survives in the interface and in every saved preset, and has no effect on any run.

This matters more than a dead switch usually would, because an unwrapped model is a real problem and this is the control that appears to guard against it. It does not. Canvas's own ladder covers what an unwrapped model does once you try to paint it — and that is where you will find out, not here.

How this is knowable
Searching the code for the setting's name finds it and shows it being used, which reads like a working feature. Only running the import with it on and with it off shows that nothing changes. A reference is not an effect — the same reason this whole set is verified by running things rather than reading them.
08

Failure

What actually stops an asset

Know three things

Exactly three things mark an asset as failed, and none of them is a validation check.

CauseMeaning
The source file is not thereMoved, renamed or deleted since queuing. Verified.
The importer failedThe file could not be opened or parsed as its type.
A processor failedOptimisation, LOD generation or emit could not complete.

All three produce an error status, and — from tier one — an errored asset gets no line in the index at all. So the queue is the only record that it was ever attempted.

SymptomWhat it meansFix
Everything says done, but assets look wrongValidation warns and never refuses. Read the warnings; status only means "finished".
An unwrapped model imported cleanlyThe UV switch does nothing. Check UVs in your modelling tool or in Canvas.
A texture warned about size but was not resizedWarning and resize are separate steps. Turn on texture resizing.
An asset vanished from the runIt errored, so it is not in the index. Check the queue — source missing, import or processor failed.
09

History

The bug this shape exists for

Read two sittings

The index used to be rebuilt from the current run's queue alone and written over whatever was there. That sounds harmless until you notice when the queue is empty.

Within one sitting the queue survives, so a second run still held the first run's assets and nothing looked wrong. But the queue starts empty on launch. So importing on Monday and again on Tuesday meant Tuesday's run wrote an index containing only Tuesday's assets — and Monday's files sat untouched on disk, unlisted.

Because five tools read this file, those assets simply stopped existing for all of them at once, and only came back by being imported again. The most ordinary workflow there is triggered it, and nothing failed while it happened.

Now
A second run keeps the first — verified with two runs from separate queues, ending with both assets listed. That single change is what makes the index usable across days.
10

Merging

How the merge works

Derive keyed on output

Two rules, and both matter when you re-import something you have imported before.

RuleEffect
Prior entries are carried forward in their original order, and this run appends after them The file diffs cleanly rather than reshuffling every line.
Duplicates are resolved by output path, and this run wins Re-importing replaces the entry — hash, size and preset with it.

The key is the output path, not the name. Re-emit the same path and the old entry is superseded rather than duplicated — verified, including that the recorded hash changed to match the new file. That is precisely what a consumer's change detection is watching, so the replacement is the mechanism by which "this asset was updated" travels.

It also means two different sources emitting to the same output path are one entry, with the most recent run's version winning. And the same source emitted to two different paths is two entries.

Read back the way consumers do
The merge reads the existing index through the same reader every consumer uses, deliberately — so the merge sees exactly what Vault, Studio, Atlas, Motion and Echo see, rather than through a second parser that could disagree with them.
11

The consequence

Ledger, not mirror

Know never pruned

If entries are only ever added or replaced, then nothing removes them — and nothing does.

Delete an emitted file by hand and run another import: the deleted asset is still listed, verified, alongside the newly imported one. No step walks the assets folder to confirm that listed files still exist.

This is deliberate rather than an oversight, and it is a genuine design question — is the index a mirror of the folder, or a record of everything that was ever produced? The tool takes the second view, consistently: it also tolerates a file it cannot hash rather than failing.

What it means for you is simple. The index is a record of imports, not an inventory of files. If you remove an asset, remove its entry too, or the tools that read it will keep offering something that is not there.

The symptom to recognise
An asset that appears in Vault, Atlas or Motion and then fails to load is the classic sign: the ledger still lists it and the file has gone. Look in the assets folder before assuming the consuming tool is at fault.
12

Damage

When the index is unreadable

Diagnose recoverable

A corrupt index is the one case where the merge cannot do its job, and the behaviour is a deliberate compromise.

What happensWhy
The run does not failA corrupt index must not brick every future import.
A fresh index is written with this run's assetsYou keep working.
It says so in the log, naming what is being droppedSilence would be worse than the loss.
The entries it could not read are goneThey could not be recovered to carry forward.

All four verified: after deliberately corrupting an index, the next run succeeded, the new asset was listed, and the previously-listed one was not. Nothing failed and something was lost — which is exactly why the log line exists.

Recovery is straightforward and manual: re-import the assets that vanished. Their files are still on disk; only the ledger forgot them.

SymptomWhat it meansFix
Assets from an earlier session are missingA corrupt index was rewritten fresh. Check the log, then re-import them.
A listed asset fails to loadIts file was deleted; the entry was not pruned. Remove the entry or re-import.
Re-importing added a duplicateIt emitted to a different output path. Dedupe is by path, not name — match the path.
A consumer shows a stale versionThe hash did not change, so nothing looked updated. Re-import so a new hash is written.

Course complete

What you now know

Check yourself

  • Refinery's real output is assets/assets.index.json — the record five other tools read.
  • Type is decided by extension alone: two model, five texture, two audio extensions, and everything else is unknown.
  • .fbx and .obj import but are typed unknown, so consumers filtering by type will not see them.
  • An entry carries name, type, relative output, source, a real SHA256, size and preset.
  • Relative output plus a content hash is what lets a consumer find an asset and tell whether it changed.
  • Only assets that finished appear. Errors leave no trace in the index at all.
  • A missing or invalid mod root is refused rather than guessed.
  • Validation warns and never refuses. A texture failing every check still imports, emits and indexes.
  • Warnings appear on successful imports, so "done" answers "did it finish", not "is it right".
  • Validate power-of-two textures works — verified on and off, against both a power-of-two and a non-power-of-two texture.
  • Validate meshes have UVs does nothing at all. Its branch body is commented out; the switch is live in the UI and in presets and affects no run.
  • The Max texture size warning and the actual resize are separate steps.
  • Defaults: both validation switches on, resizing on at 2048, and mipmaps, compression, ORM packing, glb re-export and LODs all off.
  • Only three things fail an asset: a missing source file, a failed import, a failed processor.
  • Each run merges into the index rather than replacing it — which is what makes work across several days add up.
  • It used to replace, so importing in two sittings lost the first sitting from the index while the files stayed on disk.
  • Carried entries keep their order and this run appends, so the file diffs cleanly.
  • Dedupe is by output path and this run wins, replacing hash, size and preset — which is how "this changed" reaches a consumer.
  • Entries are never pruned. A deleted file stays listed; the index is a ledger of imports, not an inventory of files.
  • A missing index is just a first run; an unreadable one is survivable but loses what it listed, with a log line saying so.
  • The merge reads the existing index through the same reader every consumer uses.

That is Refinery. It underpins Motion's and Echo's asset resolution, so a problem in either of those is worth checking here first.