Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sanchedev/fraxel/llms.txt

Use this file to discover all available pages before exploring further.

All asset loading functions in Fraxel return symbol IDs. These symbols are opaque handles — you store them in constants and pass them to JSX props like textureId or soundId on nodes. The engine maps symbols back to their underlying ImageBitmap or AudioBuffer at render/playback time. For a full guide on preloading strategies and per-scene loading patterns, see the Assets guide.
import { loadTexture, loadSound, loadBatch, loadBatchAsset, unloadTexture, unloadSound } from 'fraxel/assets'

loadTexture(url)

Loads an image from url, decodes it into a Texture, and returns a symbol ID. If the same URL has already been loaded, the existing symbol is returned immediately (automatic deduplication — no double-fetching).
import { loadTexture } from 'fraxel/assets'

const PLAYER = await loadTexture('/assets/sprites/player.png')
const BG     = await loadTexture('/assets/background.png')

// Use the symbol in JSX
return <sprite textureId={PLAYER} />
url
string
required
Absolute or root-relative URL of the image file. Any format the browser’s <img> element accepts works (PNG, WebP, JPEG, SVG, etc.).
Returns Promise<symbol> — resolves to a symbol ID once the image has fully loaded and decoded. Rejects if the network request fails or the image cannot be decoded.

loadSound(url)

Fetches an audio file from url, decodes the raw bytes using the Web Audio API (AudioContext.decodeAudioData()), and returns a symbol ID referencing the in-memory AudioBuffer.
import { loadSound } from 'fraxel/assets'

const SHOOT = await loadSound('/assets/sounds/shoot.mp3')
const HIT   = await loadSound('/assets/sounds/hit.ogg')

// Use the symbol on an audio-player node
return <audio-player soundId={SHOOT} />
url
string
required
Absolute or root-relative URL of the audio file. Any format supported by the browser’s AudioContext works (MP3, OGG, WAV, etc.).
Returns Promise<symbol> — resolves to a symbol ID once the file has been fetched and the audio buffer has been decoded. Rejects on network errors or decode failures.
Unlike loadTexture, loadSound does not deduplicate by URL — each call returns a new symbol. Load sounds once at module scope or in a preload step.

loadBatch(loaders, options?)

Loads multiple assets in parallel with optional progress tracking. Each loader is a zero-argument function that returns Promise<T> — wrap your loadTexture / loadSound calls in arrow functions. Results are returned in the same order as the input array, regardless of which asset resolves first.
import { loadBatch, loadTexture, loadSound } from 'fraxel/assets'

const [BG, PLAYER, SHOOT] = await loadBatch(
  [
    () => loadTexture('/assets/bg.png'),
    () => loadTexture('/assets/player.png'),
    () => loadSound('/assets/shoot.ogg'),
  ],
  {
    onProgress: (loaded, total) => {
      const bar = document.querySelector('#loading-bar') as HTMLElement
      if (bar) bar.style.width = `${(loaded / total) * 100}%`
    },
  },
)
loaders
Array<() => Promise<T>>
required
An array of loader functions. All are invoked immediately and run concurrently via Promise.all. Each function should return a Promise that resolves to the asset handle.
options
LoaderOptions
Optional configuration object.
options.onProgress
(loaded: number, total: number) => void
Called each time an individual asset finishes loading. loaded is the count of assets resolved so far; total is the length of the loaders array. Use this to drive loading-screen progress bars.
Returns Promise<T[]> — resolves to an array of results in the same order as the input loaders. The generic T matches whatever your loader functions return (typically symbol).

loadBatchAsset(type, urls, options?)

A typed convenience wrapper around loadBatch for loading multiple assets of the same type from a URL list. Internally calls loadTexture or loadSound for each URL depending on type.
import { loadBatchAsset } from 'fraxel/assets'

// Load all level textures at once
const [BG, TILESET, ENEMIES] = await loadBatchAsset('texture', [
  '/assets/level1-bg.png',
  '/assets/tileset.png',
  '/assets/enemies.png',
])

// Load all sound effects
const [SHOOT, HIT, EXPLODE] = await loadBatchAsset('sound', [
  '/assets/sfx/shoot.ogg',
  '/assets/sfx/hit.ogg',
  '/assets/sfx/explode.ogg',
])
type
'texture' | 'sound'
required
Asset type. Determines whether each URL is loaded with loadTexture or loadSound.
urls
string[]
required
Array of URLs to load. All are fetched concurrently.
options
LoaderOptions
Optional configuration object.
options.onProgress
(loaded: number, total: number) => void
Called each time an individual URL finishes loading.
Returns Promise<symbol[]> — array of symbol IDs in the same order as the input urls.

unloadTexture(id)

Frees a previously loaded texture from memory by removing it from the internal texture store. After calling this, any node still referencing the symbol will render nothing (or fall back to a default).
import { unloadTexture } from 'fraxel/assets'

unloadTexture(PLAYER)
id
symbol
required
The symbol ID returned by loadTexture. Passing an unknown symbol is a no-op.
Returns void.

unloadSound(id)

Frees a previously loaded AudioBuffer from memory. After calling this, any <audio-player> node referencing the symbol will no longer be able to play that sound.
import { unloadSound } from 'fraxel/assets'

unloadSound(SHOOT)
id
symbol
required
The symbol ID returned by loadSound. Passing an unknown symbol is a no-op.
Returns void.

Usage patterns

Individual loading at module scope

The simplest approach — await each asset at the top level of your scene module. Works well for small scenes:
import { loadTexture, loadSound } from 'fraxel/assets'

export const PLAYER = await loadTexture('/assets/player.png')
export const ENEMY  = await loadTexture('/assets/enemy.png')
export const SHOOT  = await loadSound('/assets/shoot.ogg')

Preload screen with progress bar

Load everything before starting the game loop. Drive a loading bar with onProgress:
import { loadBatch, loadTexture, loadSound } from 'fraxel/assets'

let PLAYER: symbol, ENEMY: symbol, BG: symbol, SHOOT: symbol

async function preload() {
  [BG, PLAYER, ENEMY, SHOOT] = await loadBatch(
    [
      () => loadTexture('/assets/bg.png'),
      () => loadTexture('/assets/player.png'),
      () => loadTexture('/assets/enemy.png'),
      () => loadSound('/assets/shoot.ogg'),
    ],
    {
      onProgress: (loaded, total) => {
        const pct = Math.round((loaded / total) * 100)
        document.querySelector('#progress')!.textContent = `${pct}%`
      },
    },
  )
}

await preload()
// Start the game

Per-scene loading with loadBatchAsset

Load only what a specific level needs, then unload when the player leaves:
import { loadBatchAsset, unloadTexture } from 'fraxel/assets'

let level2Textures: symbol[]

async function enterLevel2() {
  level2Textures = await loadBatchAsset('texture', [
    '/assets/level2-bg.png',
    '/assets/level2-tileset.png',
    '/assets/boss.png',
  ])
}

function exitLevel2() {
  for (const id of level2Textures) {
    unloadTexture(id)
  }
}

LoaderOptions reference

import type { LoaderOptions } from 'fraxel/assets'
PropertyTypeDescription
onProgress(loaded: number, total: number) => voidCalled after each asset resolves. loaded increments from 1 to total.

Related guides

Build docs developers (and LLMs) love