Skip to content

Screenshotting ​

Overview ​

The methods listed on this page allow you to take screenshots of any room in the project without ever visiting it. Screenshots can be baked as Sprites, Surfaces or Buffers.

Screenshots can be used in a variety of ways, like displaying previews in a level selection menu, capturing layouts for notes or level design, or previewing rooms in the world before loading them in.

❗ PERFORMANCE NOTE

If room data hasn't been initialized before screenshotting, GMRoomLoader will initialize it automatically. This is fine for quick tests or small rooms, but it significantly slows down the first screenshotting call for each room. See the Initialization page for best practices.

SCREENSHOTTING ROOM PARTS

Similar to drawing parts of sprites with draw_sprite_part(), you can use the .Part() State method to define which part of the room to capture.

WORKING AT SCALE

When you need to capture screenshots for many rooms, it's a good idea to use .ScreenshotSurface() or .ScreenshotBuffer() to build a dynamic texture page, or a custom sprite atlas to avoid creating a new page group for every new .ScreenshotSprite() you create. See the Atlasing section below for more detail.

Methods ​

.ScreenshotSprite() ​

RoomLoader.ScreenshotSprite(room, [xOrigin], [yOrigin], [flags], [xScale], [yScale]) ➜ Asset.GMSprite

Takes a screenshot of the given room and returns it as a sprite. If specified, assigns the optional Origin to the created sprite, filters captured asset types by the given Flags, and applies the optional Scale.

WARNING

This method returns a Asset.GMSprite created by sprite_create_from_surface(). Make sure to keep track of it and delete it using sprite_delete() when it's no longer needed.

ParameterTypeDescription
roomAsset.GMRoomThe room to take a screenshot of
[xOrigin]RealThe x screenshot Origin [Default: State.XOrigin if set, or ROOMLOADER_DEFAULT_XORIGIN]
[yOrigin]RealThe y screenshot Origin [Default: State.YOrigin if set, or ROOMLOADER_DEFAULT_YORIGIN]
[flags]RealThe Flags used to filter which asset types are captured [Default: State.Flags if set, or ROOMLOADER_DEFAULT_FLAGS]
[xScale]RealThe horizontal screenshot scale [Default: State.XScale if set, or 1]
[yScale]RealThe vertical screenshot scale [Default: State.YScale if set, or 1]
js
// Takes a centered sprite screenshot of rmExample with only Tilemaps and Sprites
var _flags = ROOMLOADER_FLAG_TILEMAPS | ROOMLOADER_FLAG_SPRITES;
screenshot = RoomLoader.ScreenshotSprite(rmExample, 0.5, 0.5, _flags); 

// Takes a scaled down sprite screenshot of rmExample
screenshot = RoomLoader.ScreenshotSprite(rmExample, 0, 0, ROOMLOADER_FLAG_ALL, 0.5, 0.5); 
js
// Takes a centered sprite screenshot of rmExample with only Tilemaps and Sprites
screenshot = RoomLoader.MiddleCenter().Tilemaps().Sprites().ScreenshotSprite(rmExample); 

// Takes a scaled down sprite screenshot of rmExample
screenshot = RoomLoader.Scale(0.5).ScreenshotSprite(rmExample); 

.ScreenshotSurface() ​

RoomLoader.ScreenshotSurface(room, [flags], [xScale], [yScale]) ➜ Id.Surface

Takes a screenshot of the given room and returns it as a surface. If specified, filters captured asset types by the given Flags and scales the output surface.

WARNING

This method returns a Id.Surface created by surface_create(). Make sure to keep track of them and free them using surface_free() when they're no longer needed.

Also keep in mind that surfaces are volatile and don't persist in memory forever - see the Surface Rules section in the docs.

TIP

This is especially useful when building your own dynamic texture pages at runtime, see the Atlasing section below.

ParameterTypeDescription
roomAsset.GMRoomThe room to take a screenshot of
[flags]RealThe Flags used to filter which asset types are captured [Default: State.Flags if set, or ROOMLOADER_DEFAULT_FLAGS]
[xScale]RealThe horizontal screenshot scale [Default: State.XScale if set, or 1]
[yScale]RealThe vertical screenshot scale [Default: State.YScale if set, or 1]
js
// Takes a surface screenshot of rmExample with only Tilemaps and Sprites
var _flags = ROOMLOADER_FLAG_TILEMAPS | ROOMLOADER_FLAG_SPRITES;
screenshot = RoomLoader.ScreenshotSurface(rmExample, _flags); 

// Takes a scaled down surface screenshot of rmExample
screenshot = RoomLoader.ScreenshotSurface(rmExample, ROOMLOADER_FLAG_ALL, 0.5, 0.5); 
js
// Takes a surface screenshot of rmExample with only Tilemaps and Sprites
screenshot = RoomLoader.Tilemaps().Sprites().ScreenshotSurface(rmExample); 

// Takes a scaled down surface screenshot of rmExample
screenshot = RoomLoader.Scale(0.5).ScreenshotSurface(rmExample); 

.ScreenshotBuffer() ​

RoomLoader.ScreenshotBuffer(room, [flags], [xScale], [yScale]) ➜ Struct

Takes a screenshot of the given room and returns a { buffer, width, height } struct, where buffer is the buffer ID filled with image data, width is the width of the image, and height is the height of the image.

If specified, filters captured asset types by the given Flags and scales the output buffer.

WARNING

This method includes a Id.Buffer in the returned struct, created by buffer_create(). Make sure to keep track of it and delete it using buffer_delete() when it's no longer needed.

TIP

This is especially useful when building your own dynamic texture pages at runtime using texturegroup_add(), see the Atlasing section below.

ParameterTypeDescription
roomAsset.GMRoomThe room to take a screenshot of
[flags]RealThe Flags used to filter which asset types are captured [Default: State.Flags if set, or ROOMLOADER_DEFAULT_FLAGS]
[xScale]RealThe horizontal screenshot scale [Default: State.XScale if set, or 1]
[yScale]RealThe vertical screenshot scale [Default: State.YScale if set, or 1]
js
// Takes a buffer screenshot of rmExample with only Tilemaps and Sprites
var _flags = ROOMLOADER_FLAG_TILEMAPS | ROOMLOADER_FLAG_SPRITES;
screenshot = RoomLoader.ScreenshotBuffer(rmExample, _flags); 

// Takes a scaled down buffer screenshot of rmExample
screenshot = RoomLoader.ScreenshotBuffer(rmExample, ROOMLOADER_FLAG_ALL, 0.5, 0.5); 
js
// Takes a buffer screenshot of rmExample with only Tilemaps and Sprites
screenshot = RoomLoader.Tilemaps().Sprites().ScreenshotBuffer(rmExample); 

// Takes a scaled down buffer screenshot of rmExample
screenshot = RoomLoader.Scale(0.5).ScreenshotBuffer(rmExample); 

Atlasing ​

The Problem ​

When capturing screenshots for many rooms, it's worth thinking about texture memory. Each call to sprite_create_from_surface() from .ScreenshotSprite() creates a brand new texture page for the created sprite.

A handful of these is fine, but at scale this adds up fast: each additional screenshot means another separate texture page, which is significant and unnecessary overhead - especially on lower-end devices with limited VRAM.

Runtime Texture Pages ​

A more efficient approach is to build a dynamic texture page at runtime using texturegroup_add(), which accepts buffers directly. .ScreenshotBuffer() pairs naturally with this: capture each room as a buffer and pass them together in an array.

The catch is that you still need to supply the sprite data struct yourself, including frame coordinates - which means bringing your own bin packing logic. That's a non-trivial algorithm to write well.

Collage Integration ​

Most of this work is already handled by TabularElf's Collage - a runtime texture page builder and packer for GameMaker that handles the bin packing algorithm internally, mimics GameMaker's own texture page packing, handles power-of-two constraints, and supports all major platforms.

Collage pairs naturally with .ScreenshotSurface(): capture a room as a surface and hand it straight to Collage via .AddSurface(), and it handles the packing and texture page management for you.