Loading Assets
Use this skill when loading assets in Phaser 4. Covers the Loader plugin, loading images, spritesheets, atlases, audio, JSON, tilemaps, bitmap fonts, and tracking load progress. Triggers on: preload, this.load, asset loading, spritesheet, atlas, load progress.
- Skill ID
- phaserjs/phaser/loading-assets
- Publisher
- phaserjs
- Repository
- phaser
- Installs
- 0
- Files
- 2
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
phaserjs/phaser/loading-assetsInstalls these files- SKILL.md
- references/REFERENCE.md
What this skill tells the agent
Loading Assets
The Phaser Loader (this.load) handles fetching all external content: images, audio, JSON, tilemaps, atlases, fonts, scripts, and more. Assets are queued inpreload(), loaded in parallel, and placed into global caches accessible by every Scene.
Key source paths: src/loader/LoaderPlugin.js, src/loader/File.js, src/loader/filetypes/, src/loader/events/ Related skills: ../game-setup-and-config/SKILL.md, ../scenes/SKILL.md, ../sprites-and-images/SKILL.md
Quick Start
class GameScene extends Phaser.Scene {
preload() {
this.load.image('logo', 'assets/logo.png');
}
create() {
this.add.image(400, 300, 'logo');
}
}Assets loaded in preload() are guaranteed to be ready when create() runs. The Loader starts automatically during the preload phase.
Core Concepts
The Preload Pattern
Every Scene can define a preload() method. The Loader automatically starts when preload() completes and waits for all queued files to finish before calling create().
preload() {
// Queue files - they don't load immediately
this.load.image('sky', 'assets/sky.png');
this.load.spritesheet('dude', 'assets/dude.png', { frameWidth: 32, frameHeight: 48 });
this.load.audio('jump', 'assets/jump.mp3');
}
create() {
// All assets above are now available
this.add.image(400, 300, 'sky');
this.add.sprite(100, 450, 'dude');
this.sound.play('jump');
}Loading Outside of Preload
If you call this.load methods outside of preload() (for example, in create() or in response to a user action), you must manually start the Loader:
create() {
this.load.image('extra', 'assets/extra.png');
this.load.once('complete', () => {
this.add.image(400, 300, 'extra');
});
this.load.start();
}URL Resolution: baseURL, path, and prefix
The final URL for a file is resolved as: baseURL + path + filename. These can be set via the game config or at runtime.
preload() {
// Set base URL (prepended to all relative paths)
this.load.setBaseURL('https://cdn.example.com/');
// Set path (prepended after baseURL, before filename)
this.load.setPath('assets/images/');
// Set key prefix (prepended to the cache key, not the URL)
this.load.setPrefix('LEVEL1.');
// Loads from: https://cdn.example.com/assets/images/hero.png
// Cached with key: LEVEL1.hero
this.load.image('hero', 'hero.png');
// Absolute URLs bypass the path/baseURL
this.load.image('cloud', 'https://other-server.com/cloud.png');
}These can also be set in the game config:
const config = {
loader: {
baseURL: 'https://cdn.example.com/',
path: 'assets/',
prefix: '',
maxParallelDownloads: 32,
crossOrigin: 'anonymous',
responseType: '',
async: true,
timeout: 0,
maxRetries: 2,
imageLoadType: 'XHR' // or 'HTMLImageElement'
}
};Global Caches
Assets are stored in global game-level caches, not per-Scene. An image loaded in one Scene is available in every other Scene. Textures go into game.textures (the Texture Manager). Other data goes into game.cache sub-caches (e.g., game.cache.json, game.cache.audio, game.cache.xml).
Load Events
The Loader emits events throughout the loading lifecycle. Use these for progress bars and loading screens.
preload() {
this.load.on('progress', (value) => {
// value is 0 to 1
console.log(`Loading: ${Math.round(value * 100)}%`);
});
this.load.on('complete', () => {
console.log('All assets loaded');
});
this.load.on('loaderror', (file) => {
console.warn('Failed to load:', file.key);
});
this.load.image('bg', 'assets/bg.png');
}Common Patterns
Loading Images and Sprite Sheets
preload() {
// Single image
this.load.image('star', 'assets/star.png');
// Image with normal map (pass URL array: [texture, normalMap])
this.load.image('brick', ['assets/brick.png', 'assets/brick_n.png']);
// Sprite sheet (fixed frame sizes)
this.load.spritesheet('explosion', 'assets/explosion.png', {
frameWidth: 64,
frameHeight: 64,
startFrame: 0,
endFrame: 23,
margin: 0,
spacing: 0
});
// SVG (optionally rasterize at a specific size)
this.load.svg('logo', 'assets/logo.svg', { width: 400, height: 400 });
}Loading Audio
preload() {
// Single file
this.load.audio('bgm', 'assets/music.mp3');
// Multiple formats for cross-browser support
this.load.audio('bgm', ['assets/music.ogg', 'assets/music.mp3']);
// Audio sprite (JSON defines named regions within a single audio file)
this.load.audioSprite('sfx', 'assets/sfx.json', [
'assets/sfx.ogg',
'assets/sfx.mp3'
]);
}Loading JSON and Tilemaps
preload() {
// JSON data (stored in this.cache.json)
this.load.json('levelData', 'assets/level1.json');
// JSON with a dataKey to extract a sub-object
this.load.json('enemies', 'assets/data.json', 'enemies');
// Tiled tilemap (JSON format exported from Tiled)
this.load.tilemapTiledJSON('map', 'assets/map.json');
// CSV tilemap
this.load.tilemapCSV('csvmap', 'assets/level.csv');
// Impact tilemap
this.load.tilemapImpact('impactmap', 'assets/level.js');
}
create() {
const data = this.cache.json.get('levelData');
const map = this.make.tilemap({ key: 'map' });
}Loading Atlases
preload() {
// JSON atlas (e.g., TexturePacker JSON Hash/Array)
this.load.atlas('sprites', 'assets/sprites.png', 'assets/sprites.json');
// XML atlas (e.g., Starling/Sparrow format)
this.load.atlasXML('ui', 'assets/ui.png', 'assets/ui.xml');
// Multi-atlas (atlas split across multiple textures)
this.load.multiatlas('world', 'assets/world.json', 'assets/');
// Unity texture atlas format
this.load.unityAtlas('chars', 'assets/chars.png', 'assets/chars.txt');
// Aseprite atlas
this.load.aseprite('knight', 'assets/knight.png', 'assets/knight.json');
}
create() {
this.add.sprite(400, 300, 'sprites', 'walk_01');
}Loading Bitmap Fonts
preload() {
// Requires both a texture and XML/JSON font data file
this.load.bitmapFont('pixels', 'assets/font.png', 'assets/font.xml');
}
create() {
this.add.bitmapText(100, 100, 'pixels', 'Hello World', 32);
}Loading Video
preload() {
// Load a video file. Third arg: noAudio flag (default false)
this.load.video('intro', 'assets/intro.mp4');
// Load without audio track
this.load.video('bg_loop', 'assets/loop.mp4', true);
}Loading Web Fonts
preload() {
// Load a font file (ttf, otf, woff, woff2)
this.load.font('myFont', 'assets/myfont.ttf', 'truetype');
// With optional font face descriptors
this.load.font('boldFont', 'assets/bold.woff2', 'woff2', {
weight: 'bold',
style: 'normal'
});
}Loading a Pack File
A pack file is a JSON file that describes multiple assets to load at once. Useful for organizing asset manifests.
preload() {
this.load.pack('pack1', 'assets/pack.json');
}Pack file format:
{
"section1": {
"baseURL": "assets/",
"files": [
{ "type": "image", "key": "bg", "url": "bg.png" },
{ "type": "atlas", "key": "chars", "textureURL": "chars.png", "atlasURL": "chars.json" }
]
}
}Loading with a Progress Bar
preload() {
const progressBar = this.add.graphics();
const progressBox = this.add.graphics();
progressBox.fillStyle(0x222222, 0.8);
progressBox.fillRect(240, 270, 320, 50);
this.load.on('progress', (value) => {
progressBar.clear();
progressBar.fillStyle(0xffffff, 1);More from phaserjs
Use this skill in a project
Open any RiverX project, search the Skills panel for phaserjs/phaser/loading-assets, and install it in one click.
