or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdanimation.mdaudio.mdcameras.mddata-management.mdevents.mdgame-objects.mdindex.mdinput.mdloading.mdmath-geometry.mdphysics.mdrendering.mdscenes.mdtweens.mdutilities.md

loading.mddocs/

0

# Asset Loading System

1

2

Phaser's loader system provides comprehensive asset loading capabilities supporting multiple file types, loading strategies, and progress monitoring. The system handles caching, parallel downloads, and various asset formats automatically.

3

4

## Loader Plugin

5

6

### Basic Loading

7

Each scene has its own loader accessible via `this.load`:

8

9

```javascript { .api }

10

class LoadingScene extends Phaser.Scene {

11

preload() {

12

// Basic asset loading

13

this.load.image('logo', 'assets/logo.png');

14

this.load.audio('music', 'assets/music.mp3');

15

this.load.json('gameData', 'assets/data.json');

16

17

// Load with key and URL

18

this.load.image('background', 'assets/images/bg.jpg');

19

20

// Load with configuration

21

this.load.image('sprite', 'assets/sprite.png', {

22

frameConfig: {

23

frameWidth: 32,

24

frameHeight: 32

25

}

26

});

27

28

// Start loading (automatic in preload)

29

this.load.start();

30

}

31

32

create() {

33

// Assets are now available

34

this.add.image(400, 300, 'logo');

35

this.sound.add('music').play();

36

}

37

}

38

```

39

40

### Loader Configuration

41

Configure global loader settings:

42

43

```javascript { .api }

44

class ConfiguredLoadingScene extends Phaser.Scene {

45

init() {

46

// Configure loader settings

47

this.load.setBaseURL('https://cdn.example.com/');

48

this.load.setPath('assets/');

49

this.load.setPrefix('game_');

50

51

// Cross-origin settings

52

this.load.setCORS('anonymous');

53

54

// Parallel loading

55

this.load.maxParallelDownloads = 4; // Default: 32

56

57

// Response type for XHR

58

this.load.setXHRSettings({

59

responseType: 'arraybuffer',

60

timeout: 10000,

61

headers: {

62

'Custom-Header': 'value'

63

}

64

});

65

}

66

67

preload() {

68

// URLs will be: https://cdn.example.com/assets/game_logo.png

69

this.load.image('logo', 'logo.png');

70

71

// Override settings for specific file

72

this.load.image('special', 'special.png', {

73

xhrSettings: {

74

responseType: 'blob',

75

timeout: 5000

76

}

77

});

78

}

79

}

80

```

81

82

## File Types

83

84

### Images

85

Load various image formats and configurations:

86

87

```javascript { .api }

88

class ImageLoadingScene extends Phaser.Scene {

89

preload() {

90

// Basic image

91

this.load.image('logo', 'assets/logo.png');

92

93

// Spritesheet

94

this.load.spritesheet('player', 'assets/player.png', {

95

frameWidth: 32,

96

frameHeight: 48,

97

startFrame: 0,

98

endFrame: 7

99

});

100

101

// Texture atlas (JSON)

102

this.load.atlas('characters', 'assets/characters.png', 'assets/characters.json');

103

104

// Texture atlas (XML)

105

this.load.atlasXML('ui', 'assets/ui.png', 'assets/ui.xml');

106

107

// Multi-atlas (multiple texture sheets)

108

this.load.multiatlas('game', 'assets/game.json');

109

110

// Unity atlas

111

this.load.unityAtlas('unity', 'assets/unity.png', 'assets/unity.txt');

112

113

// SVG images

114

this.load.svg('vector', 'assets/vector.svg', { width: 300, height: 300 });

115

116

// Base64 images

117

this.load.image('base64', 'data:image/png;base64,iVBORw0KGgoAAAANS...');

118

119

// HTML as texture

120

this.load.htmlTexture('htmlText', 'assets/text.html', 512, 256);

121

}

122

}

123

```

124

125

### Audio Files

126

Load audio with various formats and configurations:

127

128

```javascript { .api }

129

class AudioLoadingScene extends Phaser.Scene {

130

preload() {

131

// Basic audio

132

this.load.audio('bgm', 'assets/music.mp3');

133

134

// Multiple formats (browser chooses best)

135

this.load.audio('sfx', [

136

'assets/sound.ogg',

137

'assets/sound.mp3',

138

'assets/sound.wav'

139

]);

140

141

// Audio with instances for overlapping playback

142

this.load.audio('explosion', 'assets/explosion.wav', {

143

instances: 5

144

});

145

146

// Audio sprite

147

this.load.audioSprite('gamesfx', 'assets/gamesfx.json', [

148

'assets/gamesfx.ogg',

149

'assets/gamesfx.mp3'

150

]);

151

152

// Streaming audio (not cached)

153

this.load.audio('stream', 'assets/longtrack.mp3', {

154

stream: true

155

});

156

}

157

}

158

```

159

160

### Data Files

161

Load various data formats:

162

163

```javascript { .api }

164

class DataLoadingScene extends Phaser.Scene {

165

preload() {

166

// JSON data

167

this.load.json('gameConfig', 'assets/config.json');

168

169

// XML data

170

this.load.xml('levelData', 'assets/level.xml');

171

172

// Plain text

173

this.load.text('story', 'assets/story.txt');

174

175

// CSV data

176

this.load.text('scores', 'assets/scores.csv');

177

178

// Binary data

179

this.load.binary('saveFile', 'assets/save.dat');

180

181

// CSS files

182

this.load.css('styles', 'assets/game.css');

183

184

// HTML files

185

this.load.html('template', 'assets/template.html');

186

187

// JavaScript files

188

this.load.script('external', 'assets/external.js');

189

}

190

191

create() {

192

// Access loaded data

193

const config = this.cache.json.get('gameConfig');

194

const levelData = this.cache.xml.get('levelData');

195

const story = this.cache.text.get('story');

196

197

console.log('Game config:', config);

198

console.log('Level data:', levelData);

199

console.log('Story text:', story);

200

}

201

}

202

```

203

204

### Fonts and Textures

205

Load bitmap fonts and special textures:

206

207

```javascript { .api }

208

class FontLoadingScene extends Phaser.Scene {

209

preload() {

210

// Bitmap font

211

this.load.bitmapFont('pixel', 'assets/fonts/pixel.png', 'assets/fonts/pixel.xml');

212

213

// Bitmap font (JSON format)

214

this.load.bitmapFont('arcade', 'assets/fonts/arcade.png', 'assets/fonts/arcade.json');

215

216

// Google Fonts (Web Font Loader required)

217

this.load.script('webfont', 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js');

218

219

// Texture from canvas

220

const canvas = document.createElement('canvas');

221

canvas.width = 64;

222

canvas.height = 64;

223

const ctx = canvas.getContext('2d');

224

ctx.fillStyle = '#ff0000';

225

ctx.fillRect(0, 0, 64, 64);

226

227

this.textures.addCanvas('redSquare', canvas);

228

}

229

230

create() {

231

// Use bitmap font

232

this.add.bitmapText(100, 100, 'pixel', 'Hello World');

233

234

// Use generated texture

235

this.add.image(200, 200, 'redSquare');

236

237

// Load Google Fonts dynamically

238

if (window.WebFont) {

239

WebFont.load({

240

google: {

241

families: ['Orbitron']

242

},

243

active: () => {

244

this.add.text(300, 300, 'Google Font', {

245

fontFamily: 'Orbitron',

246

fontSize: '24px'

247

});

248

}

249

});

250

}

251

}

252

}

253

```

254

255

### 3D and Advanced Assets

256

Load 3D models and shaders:

257

258

```javascript { .api }

259

class Advanced3DLoadingScene extends Phaser.Scene {

260

preload() {

261

// OBJ 3D model

262

this.load.obj('model', 'assets/model.obj', 'assets/model.mtl');

263

264

// GLSL shaders

265

this.load.glsl('vertexShader', 'assets/vertex.glsl');

266

this.load.glsl('fragmentShader', 'assets/fragment.glsl');

267

268

// Video files

269

this.load.video('intro', 'assets/intro.mp4');

270

this.load.video('background', [

271

'assets/bg.webm',

272

'assets/bg.mp4'

273

]);

274

275

// Compressed textures (WebGL)

276

this.load.texture('compressed', {

277

ETC1: 'assets/texture.etc1',

278

PVRTC: 'assets/texture.pvr',

279

S3TC: 'assets/texture.dxt'

280

});

281

}

282

283

create() {

284

// Use loaded assets

285

if (this.renderer.type === Phaser.WEBGL) {

286

// Create shader

287

const shader = this.add.shader('fragmentShader', 100, 100, 200, 200);

288

289

// Play video

290

const video = this.add.video(400, 300, 'intro');

291

video.play();

292

}

293

}

294

}

295

```

296

297

## Loading Progress and Events

298

299

### Progress Monitoring

300

Track loading progress with detailed feedback:

301

302

```javascript { .api }

303

class ProgressLoadingScene extends Phaser.Scene {

304

preload() {

305

// Create progress UI

306

this.createProgressBar();

307

308

// Loading events

309

this.load.on('start', () => {

310

console.log('Loading started');

311

this.progressText.setText('Loading...');

312

});

313

314

this.load.on('progress', (percent) => {

315

console.log('Loading progress:', percent);

316

this.updateProgressBar(percent);

317

this.progressText.setText(`Loading: ${Math.round(percent * 100)}%`);

318

});

319

320

this.load.on('fileprogress', (file, percent) => {

321

console.log(`File ${file.key}: ${Math.round(percent * 100)}%`);

322

this.fileText.setText(`Loading: ${file.key}`);

323

});

324

325

this.load.on('complete', () => {

326

console.log('Loading complete');

327

this.progressText.setText('Complete!');

328

this.time.delayedCall(1000, () => {

329

this.scene.start('GameScene');

330

});

331

});

332

333

// File-specific events

334

this.load.on('filecomplete', (key, type, data) => {

335

console.log(`Loaded ${type}: ${key}`);

336

});

337

338

this.load.on('filecomplete-image-logo', (key, type, data) => {

339

console.log('Logo loaded!');

340

});

341

342

// Error handling

343

this.load.on('loaderror', (file) => {

344

console.error('Failed to load:', file.key);

345

this.errorText.setText(`Error loading: ${file.key}`);

346

});

347

348

// Load assets

349

this.loadGameAssets();

350

}

351

352

createProgressBar() {

353

// Progress bar background

354

this.progressBox = this.add.graphics();

355

this.progressBox.fillStyle(0x222222);

356

this.progressBox.fillRect(240, 270, 320, 50);

357

358

// Progress bar fill

359

this.progressBar = this.add.graphics();

360

361

// Progress text

362

this.progressText = this.add.text(400, 240, 'Loading...', {

363

fontSize: '20px',

364

fill: '#ffffff'

365

}).setOrigin(0.5);

366

367

// Current file text

368

this.fileText = this.add.text(400, 330, '', {

369

fontSize: '16px',

370

fill: '#ffffff'

371

}).setOrigin(0.5);

372

373

// Error text

374

this.errorText = this.add.text(400, 360, '', {

375

fontSize: '16px',

376

fill: '#ff0000'

377

}).setOrigin(0.5);

378

}

379

380

updateProgressBar(percent) {

381

this.progressBar.clear();

382

this.progressBar.fillStyle(0xffffff);

383

this.progressBar.fillRect(250, 280, 300 * percent, 30);

384

}

385

386

loadGameAssets() {

387

// Load multiple assets

388

this.load.image('background', 'assets/bg.jpg');

389

this.load.spritesheet('player', 'assets/player.png', {

390

frameWidth: 32, frameHeight: 48

391

});

392

this.load.atlas('ui', 'assets/ui.png', 'assets/ui.json');

393

this.load.audio('music', ['assets/music.ogg', 'assets/music.mp3']);

394

this.load.audio('sfx', 'assets/sfx.wav');

395

this.load.json('levels', 'assets/levels.json');

396

// Add more assets...

397

}

398

}

399

```

400

401

### Asset Packs

402

Organize assets into reusable packs:

403

404

```javascript { .api }

405

class AssetPackScene extends Phaser.Scene {

406

preload() {

407

// Define asset pack

408

const assetPack = {

409

"section1": {

410

"files": [

411

{

412

"type": "image",

413

"key": "logo",

414

"url": "assets/logo.png"

415

},

416

{

417

"type": "image",

418

"key": "background",

419

"url": "assets/bg.jpg"

420

},

421

{

422

"type": "spritesheet",

423

"key": "player",

424

"url": "assets/player.png",

425

"frameConfig": {

426

"frameWidth": 32,

427

"frameHeight": 48

428

}

429

},

430

{

431

"type": "audio",

432

"key": "music",

433

"urls": ["assets/music.ogg", "assets/music.mp3"],

434

"config": {

435

"loop": true,

436

"volume": 0.8

437

}

438

}

439

]

440

},

441

"section2": {

442

"files": [

443

{

444

"type": "atlas",

445

"key": "sprites",

446

"textureURL": "assets/sprites.png",

447

"atlasURL": "assets/sprites.json"

448

},

449

{

450

"type": "bitmapFont",

451

"key": "font",

452

"textureURL": "assets/font.png",

453

"fontDataURL": "assets/font.xml"

454

}

455

]

456

}

457

};

458

459

// Load from pack object

460

this.load.pack("gameAssets", assetPack);

461

462

// Load from external pack file

463

this.load.pack("uiAssets", "assets/ui-pack.json");

464

465

// Load specific pack section

466

this.load.pack("levelAssets", "assets/levels-pack.json", "level1");

467

}

468

}

469

```

470

471

## Advanced Loading Techniques

472

473

### Dynamic Loading

474

Load assets at runtime based on game state:

475

476

```javascript { .api }

477

class DynamicLoadingScene extends Phaser.Scene {

478

create() {

479

this.currentLevel = 1;

480

this.loadingQueue = [];

481

this.isLoading = false;

482

}

483

484

loadLevel(levelNumber) {

485

if (this.isLoading) {

486

this.loadingQueue.push(levelNumber);

487

return;

488

}

489

490

this.isLoading = true;

491

492

// Create temporary loader

493

const loader = new Phaser.Loader.LoaderPlugin(this);

494

495

// Configure for this level

496

loader.setPath(`assets/levels/${levelNumber}/`);

497

498

// Load level-specific assets

499

loader.image('background', 'bg.jpg');

500

loader.json('data', 'data.json');

501

loader.atlas('enemies', 'enemies.png', 'enemies.json');

502

503

// Progress tracking

504

loader.on('progress', (percent) => {

505

this.showLoadingProgress(percent);

506

});

507

508

loader.once('complete', () => {

509

this.isLoading = false;

510

this.hideLoadingProgress();

511

this.startLevel(levelNumber);

512

513

// Process queue

514

if (this.loadingQueue.length > 0) {

515

const nextLevel = this.loadingQueue.shift();

516

this.loadLevel(nextLevel);

517

}

518

});

519

520

// Start loading

521

loader.start();

522

}

523

524

preloadNextLevel() {

525

// Preload next level assets in background

526

const nextLevel = this.currentLevel + 1;

527

528

// Check if already loaded

529

if (this.textures.exists(`level${nextLevel}_bg`)) {

530

return;

531

}

532

533

// Background loading without blocking current gameplay

534

const backgroundLoader = new Phaser.Loader.LoaderPlugin(this);

535

backgroundLoader.setPath(`assets/levels/${nextLevel}/`);

536

backgroundLoader.image(`level${nextLevel}_bg`, 'bg.jpg');

537

backgroundLoader.json(`level${nextLevel}_data`, 'data.json');

538

539

backgroundLoader.once('complete', () => {

540

console.log(`Level ${nextLevel} preloaded`);

541

});

542

543

backgroundLoader.start();

544

}

545

546

showLoadingProgress(percent) {

547

if (!this.loadingOverlay) {

548

this.loadingOverlay = this.add.graphics();

549

this.loadingText = this.add.text(400, 300, '', {

550

fontSize: '24px',

551

fill: '#ffffff'

552

}).setOrigin(0.5);

553

}

554

555

this.loadingOverlay.clear();

556

this.loadingOverlay.fillStyle(0x000000, 0.8);

557

this.loadingOverlay.fillRect(0, 0, 800, 600);

558

559

this.loadingText.setText(`Loading: ${Math.round(percent * 100)}%`);

560

}

561

562

hideLoadingProgress() {

563

if (this.loadingOverlay) {

564

this.loadingOverlay.destroy();

565

this.loadingText.destroy();

566

this.loadingOverlay = null;

567

this.loadingText = null;

568

}

569

}

570

}

571

```

572

573

### Asset Streaming

574

Stream large assets progressively:

575

576

```javascript { .api }

577

class StreamingScene extends Phaser.Scene {

578

preload() {

579

// Stream large audio files

580

this.load.audio('backgroundMusic', 'assets/long-track.mp3', {

581

stream: true

582

});

583

584

// Progressive texture loading

585

this.loadTexturesProgressively([

586

'texture1', 'texture2', 'texture3', 'texture4'

587

]);

588

}

589

590

loadTexturesProgressively(textureKeys) {

591

let currentIndex = 0;

592

const batchSize = 2; // Load 2 textures at a time

593

594

const loadBatch = () => {

595

if (currentIndex >= textureKeys.length) {

596

return;

597

}

598

599

const batch = textureKeys.slice(currentIndex, currentIndex + batchSize);

600

const batchLoader = new Phaser.Loader.LoaderPlugin(this);

601

602

batch.forEach(key => {

603

batchLoader.image(key, `assets/${key}.png`);

604

});

605

606

batchLoader.once('complete', () => {

607

currentIndex += batchSize;

608

this.time.delayedCall(100, loadBatch); // Small delay between batches

609

});

610

611

batchLoader.start();

612

};

613

614

loadBatch();

615

}

616

}

617

```

618

619

### Memory Management

620

Efficiently manage loaded assets:

621

622

```javascript { .api }

623

class MemoryManagementScene extends Phaser.Scene {

624

create() {

625

this.loadedAssets = new Set();

626

}

627

628

loadAssets(assetList, callback) {

629

const loader = new Phaser.Loader.LoaderPlugin(this);

630

631

assetList.forEach(asset => {

632

if (!this.loadedAssets.has(asset.key)) {

633

loader[asset.type](asset.key, asset.url, asset.config);

634

this.loadedAssets.add(asset.key);

635

}

636

});

637

638

if (loader.list.size > 0) {

639

loader.once('complete', callback);

640

loader.start();

641

} else {

642

callback(); // All assets already loaded

643

}

644

}

645

646

unloadUnusedAssets() {

647

// Remove textures not used in current scene

648

const textureKeys = this.textures.getTextureKeys();

649

650

textureKeys.forEach(key => {

651

if (!this.isAssetInUse(key)) {

652

this.textures.remove(key);

653

this.loadedAssets.delete(key);

654

console.log('Unloaded texture:', key);

655

}

656

});

657

658

// Remove sounds not playing

659

this.sound.sounds.forEach(sound => {

660

if (!sound.isPlaying && sound.key !== 'backgroundMusic') {

661

sound.destroy();

662

}

663

});

664

665

// Clear cache entries

666

this.cache.json.entries.clear();

667

this.cache.xml.entries.clear();

668

}

669

670

isAssetInUse(key) {

671

// Check if any game object is using this asset

672

return this.children.exists((child) => {

673

return child.texture && child.texture.key === key;

674

});

675

}

676

677

getMemoryUsage() {

678

const textureMemory = this.textures.getTextureKeys().length;

679

const audioMemory = this.sound.sounds.length;

680

const cacheMemory = Object.keys(this.cache.json.entries).length +

681

Object.keys(this.cache.xml.entries).length;

682

683

return {

684

textures: textureMemory,

685

audio: audioMemory,

686

cache: cacheMemory,

687

total: textureMemory + audioMemory + cacheMemory

688

};

689

}

690

691

shutdown() {

692

// Clean up when scene shuts down

693

this.unloadUnusedAssets();

694

}

695

}

696

```

697

698

This comprehensive loading system provides all the tools needed to efficiently manage assets throughout a game's lifecycle, from initial loading screens to dynamic runtime asset management.