Skip to main content

excaliburjs logoGame Resources

As previously mentioned, your game is not permitted to make network requests. This means that it can't asynchronously load resources such as more code, images, sprites, or fonts.

tip

By the way! Kenney is a great place for finding free assets (sprites, etc) for your games.

Any resources needed by your game must be bundled into the game itself, i.e., into the final build output file, bundle.js.

Images & Sprites

ExcaliburJS uses ImageSource to represent and load images.

To bundle an image resource into your game, you have a couple of options:

Import Images as base64-encoded Data URIs

You can import image resources as base64-encoded data URIs.

To do this, first encode your image as a base64 string. (You can find free base64 encoders online; or, on a Mac or Linux machine, for example, you can use the base64 command; i.e., base64 -i my-image.png).

Once you have the base64-encoded string for your image file, you can then copy it into a TypeScript-importable file — for example, if your image was an SVG file:

my-image.svg.ts
export default 'data:image/svg+xml;base64,<base64 encoded svg>';

Or, for a PNG file (note the image/png MIME type):

my-image.png.ts
export default 'data:image/png;base64,<base64 encoded png>';

Now we can import our image resource into our game and use it as a graphic on an Actor:

main.ts
import { ..., ImageSource, ... } from 'excalibur';
import myImage from './my-image.svg'; // imports the my-image.svg.ts file

const myImageSource = new ImageSource(myImage);

const loadImgResources = () => {
return Promise.all([myImageSource.load()]);
};

export const install: XellyInstallFunction
= (context: XellyContext, engine: Engine) => {

const desiredWidth = 50;

// we still must go through async loading before we use our image:
loadImgResources().then(() => {
const myActor = new Actor({
anchor: Anchor.Zero,
scale: vec(desiredWidth / sprite.width, desiredWidth / sprite.width)
});
myActor.graphics.use(myImageSource.toSprite());
engine.add(myActor);
});

}

Use ImageSource.fromSvgString to load SVGs

You can use ImageSource.fromSvgString to load SVG files directly from a string; no need to base64-encode them!

const arrowImageSource = ImageSource.fromSvgString(`
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
...
</svg>`)

Make sure your <svg/> tag has a width and height attribute.

Spritesheets

We can create SpriteSheets from loaded ImageSources:

import { ..., ImageSource, SpriteSheet, ... } from 'excalibur';
import mySpriteSheet from './my-sprite-sheet.png';

const mySpriteSheetImageSource = new ImageSource(mySpriteSheet);

...

loadImgResources().then(() => {
const sheet = SpriteSheet.fromImageSource(mySpriteSheetImageSource);
// ...
};

...

Fonts

Here's how to bundle and load custom fonts:

import { ..., Font, ... } from 'excalibur';
import myFont from './MyFont.woff';

const myFontFace = new FontFace('MyFont', `url(${myFont})`);

export const install: XellyInstallFunction
= (context: XellyContext, engine: Engine) => {

myFontFace.load().then((loaded) => {
document.fonts.add(loaded);

const myFont = new Font({
color: Color.Purple,
size: 14,
family: 'MyFont',
unit: FontUnit.Px
});

engine.add(new Label({
text: "Hello, world!",
font: myFont,
pos: vec(
(engine.drawWidth - messageDimensions.width) / 2,
(engine.drawHeight - messageDimensions.height) / 2),
}));
});
}

Third-party libraries

You can bundle third-party libraries with your game, as long as your final game file isn't larger than the 500kb limit.

(For example, the example sudoku game uses the @algorithm.ts/sudoku library to generate game puzzles.)

With our rollup config, any third-party libraries besides ExcaliburJS and xelly.js (which are provided by the platform) will automatically get bundled when you run npm run build.