prowlengine/prowl/prowl-assets
- community
Checking that the SKILL.md file is still in the repository.
How Prowl assets work for scripts. Use when a script references textures, materials, meshes, prefabs, clips, scenes or other assets, chooses between a plain field and AssetRef, loads assets by path at runtime, creates assets in code, or when assets unload, go missing, or are not in a build.
Install
npx vskill@latest install prowlengine/prowl/prowl-assetsSKILL.md
Prowl assets
The model
- Every asset derives from
Asset(anEngineObject). A database asset has a GUID (AssetID), a path (AssetPath) and aNametaken from its file name, or the part after#for a sub asset. - One object per GUID for the whole session. Unloading frees the data but keeps the object, and loading, reimporting or reverting refills that same object. So a reference you hold never goes stale or gets swapped for another object.
asset.Stateis anAssetState(a top level enum inProwl.Runtime):Loaded,Unloaded,Loading,MissingorFailed. An unloaded or missing asset is stillIsValid(). CheckIsLoadedorIsMissingwhen the content matters.- Reading an asset's data loads it on demand, blocking. A missing or failed asset reads as empty and logs one warning.
- A runtime asset made with
new Material(shader),new Mesh()orClone()has no GUID. It is always loaded, never unloaded by the engine, and belongs to whoever made it. Dispose it when done. - Never call
Dispose()orDestroy()on a database asset, it throws. UseAssetDatabase.Unloadif you really must.
Referencing assets from a script
Plain field: public Material Mat; | public AssetRef<Material> Mat; | ||
|---|---|---|---|
| Saved as | the GUID | the GUID | |
| Keeps the asset loaded | yes, while the object holding it is reachable | no | |
| Loaded with the scene | yes | no, call Load() or LoadAsync() | |
| Shipped in builds | yes | yes |
Use a plain field for almost everything. Use AssetRef<T> only for things needed maybe later, such as a list of levels or an optional high resolution texture.
AssetRef<T>: Get() never loads, Load() blocks, LoadAsync() is async, IsEmpty, AssetID, and it converts implicitly from T. Wrapping a runtime asset (no GUID) gives an empty ref and a warning.
What keeps an asset loaded
A background walk starts from every live scene, DontDestroyOnLoad objects, held assets, roots added with AssetDatabase.AddRoot, and statics marked [HeldStatic]. It follows instance fields (collections too). Anything it reaches stays loaded. An asset it does not reach for two walks and longer than the grace period (10 seconds by default) is unloaded.
The walk does not see static fields (unless [HeldStatic]), lambda captures, delegates or locals in async methods. An asset kept only there will unload. Put it in a field, mark the static [HeldStatic], or call AssetDatabase.Hold(asset, owner), which holds it until owner is garbage collected or you call Release.
If a field points at an asset that was unloaded, the next read reloads it (blocking) and logs a warning telling you to keep it in a field or hold it.
AssetDatabase
| Call | Loads? | |
|---|---|---|
AssetDatabase.Get(guid), Get<T>(guid) | never | |
AssetDatabase.Load<T>(guid) | blocks | |
await AssetDatabase.LoadAsync<T>(guid) | async | |
AssetDatabase.FindResource<T>("Textures/Paint") | blocks | |
await AssetDatabase.FindResourceAsync<T>("Sfx/Hit") | async | |
AssetDatabase.FindAllResources<T>("Folder") | blocks, and the results are not held afterwards | |
AssetDatabase.LoadGroup(assets), Preload(sceneAsset) | returns an awaitable AssetGroup with Progress | |
AssetDatabase.Explain(asset) | reports state, size and what holds it, for debugging |
Loading by path at runtime
A load path is the path below the nearest Resources folder, without the extension: Assets/Enemies/Resources/Textures/Paint.png loads as Textures/Paint. Sub assets add #Name.
Builds only ship the scenes in the build, everything they reference (plain fields and AssetRef), everything inside Resources folders, and what those reference. Assets under Editor folders are left out. An asset you only load by path or GUID must be in a `Resources` folder, or a player build reports it is not in the asset manifest.
Sub assets, prefabs and scenes
- A model file imports as a
PrefabAssetwith sub assets: meshes, materials, the avatar and animation clips. Address one asModels/Hero.fbx#Run.Library/prowl command asset info --path Models/Hero.fbxlists them. - Spawn a prefab with
GameObject.Instantiate(prefab), with overloads for position, rotation, parent and scene. - Prefabs do not nest. A prefab instance inside another prefab is flattened into plain objects when the outer prefab is saved.
- The prefab a model imports as is read only. To change it, instantiate it, edit the instance, and save a new prefab with
prefab create. SceneAssetis the saved data of a scene.Sceneis the live scene.Scene.Load(sceneAsset)blocks while it loads everything the scene uses.Scene.LoadAsync(sceneAsset)returns an awaitableSceneLoadwithProgressand swaps the scene in at the end of a frame.
Creating and saving assets (editor code only)
EditorAssetBackend.Instance.CreateAsset(asset, "Materials/New.mat") writes the file, imports it and turns that same object into the database asset. SaveAsset(asset) writes changes back. Files like .fbx and .png are imported, not saved, so they can not be written this way. From the CLI use asset create, set, material and importer instead.
Gotchas
- Never use
?.,??,??=,== null,!= null,is nulloris not nullon an asset or anyEngineObject. They are compile errors (PROWLEO001, PROWLEO002, PROWLEO003). Usex.IsValid()andx.IsNotValid(). - Never block on a task in a script with
.Result,.Wait()orGetAwaiter().GetResult()(PROWLTH001). Loads finish on the main thread, so the wait never returns.awaitinstead, or call the blockingLoad(). - Blocking loads hitch the frame. Use the async calls or
LoadGroupfor large content. Material.LoadDefault(...)returns a new copy you own. The other built inLoadDefaultcalls return a shared asset.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingProwl.Editor/Resources/Agent/Skills/prowl-assets/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/prowlengine/prowl/prowl-assets)