---
name: ferret-packages
description: Use for Ferret asset loading and the .ferret package format: packing, signing and encrypting packages, catalogs, the persistent cache and its quota, security checks and code policy, streaming levels from a catalog. Read before publishing or loading downloaded content.
---

# Assets and `.ferret` packages

## When to use
Packing a game's levels, loading content from a URL or a file, signing or encrypting it, caching downloads, or reasoning about the security of loaded content.

## What exists
- `FerretPackage`, `packPackage`, `PackageManifest`, `validatePackageManifest`, `validatePackage`: the format and its own checks.
- Signing and keys: `generateSigningKey`, `signManifest`, `verifyManifestSignature`, `generateEncryptionKey`, `createEncryption`.
- Sources: `urlSource`, `httpFolderSource`, `folderSource`, `bytesSource`, `blobSource`.
- Catalogs and streaming: `buildCatalog`, `signCatalog`, `loadCatalog`, `CatalogClient` (in `levels`), travel with a transition.
- Cache: `PersistentCache` with backends (IndexedDB, storage, memory), LRU by package, pins, quota, partials, `downloadedContentItem` for a menu entry.
- `CodePolicy`: a package that carries code runs under it.
- The asset library (`docs/concepts/asset-library.md`): textures, PBR materials, characters and clip sets as `.ferret` packages of kind `assets`, found by id in a catalog (`/lib/ferret-assets/`, or `FERRET_ASSETS`). Take from it instead of copying files out of another project: `AssetLibrary` (in `levels`) with `list`, `material(id, { variant })`, `texture(id)`, `character(id, { tier })`, `preload`; the viewer's `?library` shows every item. Items are built from UE exports by `tools/asset-lib/make.mjs`, never by hand.
- Running code: `code.entry` in `ferret.json` (one bundled ES module under `code/` exporting `install(ctx)`), `installCode` / `CodeLoader.require(id)` (dependencies first, policy, sha256 of the module, `install` once; the engine comes as `ctx.ferret`, the shared `globalThis.Ferret`), commands `pkg.require` and `pkg.loaded`.

## Steps to publish
1. Pack the level folder with `packPackage` (see API reference for options).
2. Sign with a developer key; the owner of the keys signs and encrypts, an agent only prepares unsigned drafts.
3. Build and sign a catalog if levels are fetched remotely.
4. Load with `installPackages`; the loader checks signatures, hashes and paths before anything is used.

## Check afterwards
`validatePackage` is clean; a tampered file is refused; a second load is served from the cache; quota errors are handled (`QuotaError`).

## What usually goes wrong
- Putting private keys in the repo or in a draft; keys are the developer's.
- Paths with `..` or absolute paths in the manifest: refused by the loader by design.
- A package with code and no `CodePolicy` decision.
- Assuming the cache is unlimited: it evicts by package and has a quota.

## Files

- `reference/levels.md` — The level manifest, the level registry and travel, environment, and the .ferret package format.
- `reference/api-assets.md` — every export of `@ferret/assets` with signature and doc comment
- `reference/api-assets-2.md` — every export of `@ferret/assets` with signature and doc comment
- `reference/api-levels.md` — every export of `@ferret/levels` with signature and doc comment
- `reference/api-levels-2.md` — every export of `@ferret/levels` with signature and doc comment
- `reference/commands.md` — 39 commands of these packages with their arguments
