Skip to main content

Configuring Xtend

Xtend is setupless, meaning all you have to do is add it to your project, and you're good to go. But of course, you can always customize it too!

Upon importing Xtend, you'll see an XGASOFT > Xtend folder added to your asset browser. At the root of this folder is a file called xtend_config. You may freely edit this file to change the default configuration or even add new entries for your own reference.

Xtend's config file uses a struct format similar to JSON. Settings are grouped into categories under the root, which is simply called xtend. Any values changed in this file will be applied at runtime, but they can also be accessed or changed later by chaining categories and properties together:

xtend.scale.enabled = true;

Some properties are optional, and are commented out by default. Simply uncomment any properties you wish to modify, and your custom values will be applied.

debug: {
...
stats_enabled: false, <-- This value is active
//stats_color: c_lime, <-- Remove "//" to activate this value
...
}
caution

Any properties not commented out by default are required and cannot be removed.

For details on each property, see the sections covering each category below. Categories are ordered logically rather than alphabetically.

win#

The window category sets the foundation for scaling behaviors. Of primary importance is the base resolution, which is the unscaled resolution your game design should assume. Scaling will be applied from the base resolution to whatever window it may be displayed on, so choose this value carefully. There is no right or wrong resolution; only the appropriate resolution for your game design and art style.

Many properties here are optional, and will be detected automatically based on room settings. However, getting these right is important, so it is recommended to set them manually rather than rely on Xtend's best guesses. Only you can decide what suits your project!

win: {
...
width_base: 1920,
height_base: 1080,
...
},

Base resolution determines the initial resolution of your game, after which scaling will be applied. If at first scaling isn't working as expected, start here.

tip

Viewports managed by Xtend can still be moved and resized freely. If you resize an active view camera later, the resized dimensions will become the new base resolution.

Of close secondary importance is DPI scaling. For high-resolution displays, DPI scaling will magnify content to present the application at the same physical size as on lower-resolution displays. It is generally recommended to enable DPI scaling, especially on desktop platforms.

How this magnification is applied depends on the base DPI. This value is technically arbitrary, but in general, a base DPI of 96 or 160 is the accepted standard by desktop and mobile operating systems, respectively. (By default, Xtend will use a custom DPI setting for each major platform.)

win: {
...
dpi_enabled: true,
dpi_base: 96,
...
},

DPI scaling will be calculated as a multiplier of base DPI vs actual DPI. Decreasing the base DPI will result in higher magnification. On desktop platforms, this applies to window size only (scaling the window up), while on mobile platforms, this applies to the main view camera (scaling the viewport down).

note

If the magnified window is larger than the physical display, DPI scaling will be disabled automatically. It can be enabled again by running window_set_dpi or setting xtend.win.dpi_enabled to true.

Finally, Xtend allows setting minimum and maximum aspect ratios to prevent extreme window shapes from breaking your design. This is most easily expressed as width/height. If you are familiar with aspect ratios such as 4:3, 16:9, or 21:9, these can be written as 4/3, 16/9, and 21/9, respectively. For portrait orientation, simply reverse the order: 3/4, 9/16, or 9/21, for example. If either aspect ratio is set to 0, no limit will be applied (this is the default behavior).

win: {
...
aspect_min: 4/3,
aspect_max: 21/9,
...
},
note

These values are just examples, and may represent too narrow a range for many users. You should always try to accommodate the broadest range of ratios possible!

scale#

With your window behaviors defined, you can also customize how content is scaled to fit within. Xtend provides 5 unique scaling modes to suit different types of content:

  • linear: Crops or extends both dimensions to match available screen area on a 1:1 basis. Ideal for desktop-style applications.
  • aspect: Preserves the base area of the view (width AND height) and extends the longer axis to fill the screen. Never crops. (Recommended, enabled by default.)
  • axis_x: Preserves height at the cost of either cropping or extending width to fill the screen. Ideal for horizontal splitscreen.
  • axis_y: Preserves width at the cost of either cropping or extending height to fill the screen. Ideal for vertical splitscreen.
  • pixel: For retro art styles with very low resolution. Finds the nearest integer scale on larger resolutions and crops or extends width and height only as necessary to fill aspect ratio. Square pixels are preserved at all costs.
scale: {
...
mode: aspect,
...
},

The chosen scaling mode will be applied to a view camera. GameMaker Studio 2 features a camera system that allows for any number of cameras to exist at the same time, but only 8 can be applied to active views at once (for a maximum of 8-way splitscreen). These views are numbered 0-7, where one must be dedicated exclusively to Xtend as the 'master scaling view'. The chosen view will be configured automatically, but be warned that it will also override any manual settings, so it's best to choose a view not currently occupied for other purposes.

scale: {
...
view: 0,
...
},
tip

Additional views can also be configured in xtend_config. See the view# category for details.

GameMaker Studio also features a separate GUI layer independent of the view camera system. In most cases, it is preferable to allow Xtend to automatically scale this layer as well, but this is not required. Xtend will scale the GUI to match window resolution 1:1 rather than view camera resolution. For other behaviors, you may disable Xtend GUI scaling to take control of the GUI layer yourself.

scale: {
...
gui: true,
...
},

In some cases, scaling may cause visible pixellation which is undesirable for certain art styles. This can be mitigated with texture filtering to smooth out scaling results with linear interpolation. However, it is not universally suitable and is disabled by default.

scale: {
...
filter: true,
...
},

In other cases, certain art styles may actually benefit from additional pixellation, or low-end devices that can't render a project at native resolution. By default, the application surface will render 1:1 with the scaled resolution, but this can be adjusted with the sample multiplier. This will increase or decrease the rendered resolution of the application surface without affecting viewports or the GUI layer. Multiples of 2 will produce best results.

scale: {
...
sample: 0.5,
...
}
tip

Sample size is capped to acceptable minimum and maximum texture resolutions as defined by GameMaker Studio export modules. Multiplier range may vary in real-time depending on scaling. Any invalid inputs will be automatically adjusted.

Finally, Xtend provides a way to disable scaling without having to remove it from your project. This can be useful for testing purposes or even for providing users the option of a fixed aspect ratio if they prefer. However, it's important to note that this setting disables scaling, but it does not disable Xtend! Other features, like Xtend's built-in debug mode, will remain accessible regardless.

scale: {
...
enabled: false,
...
},

By default, disabling scaling in real-time will cause the viewport to reset to its original size, potentially introducing letterboxing/pillarboxing. However, if you'd prefer to simply "freeze" the current scale, it is possible to preserve it instead.

scale: {
...
preserve: true,
...
}

debug#

Xtend features a built-in debug mode for displaying scaling statistics and hint boxes. Hint boxes highlight the area where content has been extended or cropped to provide context for base vs scaled dimensions. Stats and hints can be enabled or disabled independently to avoid cluttering the display with too much information.

debug: {
...
hints_enabled: true,
stats_enabled: true,
...
},
caution

Enabling debug features will incur a significant performance impact and should be disabled when profiling your application.

Because debug information can be difficult to see depending on what's in the background, stats and hints can also be given custom colors, and hints alpha can be customized for more or less contrast with background content. Hints alpha has a range from 0-1, while colors can be provided in any GameMaker format. Note that the chosen hints color will be inverted to show negative space from cropped areas.

debug: {
...
hints_color: c_aqua,
hints_alpha: 0.5,
stats_color: c_lime,
...
},
tip

For hex notation support, see make_color_hex from GML+!

note

Debug stats use a range of font sizes to accommodate different resolutions. Each size is stored as a separate bitmap font asset, named fnt_debug_###, where ### is a multiple of 50 (relating to DPI scale). Included sizes cover the spectrum from 360p to 4K, but additional fonts can be supplied for other resolutions by adding a new font asset with the desired DPI scale value in the name.

If an exact match can't be found for the current resolution, the nearest applicable font size will be used instead.

view##

GameMaker Studio supports up to 8 active views, numbered 0-7, where one must be dedicated exclusively to Xtend as the 'master scaling view'. However, additional views can also be defined in xtend_config for preconfigured splitscreen. This is not required, as additional views must always be scaled later with camera_set_view_scale to reflect any changes in real-time, but some may find xtend_config a more convenient interface for the initial setup.

As soon as any view is scaled by Xtend, configuration entries will be added for it in the running application. (This includes the master scaling view.) Each view has its own category, named view#, where # is the view number (e.g. view1), and requires four properties to be valid:

view1: {
width_base: 1920,
height_base: 1080,
halign: va_left,
valign: va_top,
},

In the case of the master view, width_base and height_base will always equal the values defined in the win category. Any manual changes will be overwritten.

For other views, these values determine the initial size of the view camera--or put differently, the area of the room visible to the camera. Where the camera appears on the screen is determined by the viewport settings defined in camera_set_view_scale. If no configuration exists for the view when it is first scaled, size will be determined automatically. You can also use the GameMaker Studio room editor, or run camera_set_view_size before camera_set_view_scale to have the same effect as defining a size in xtend_config.

Also note that unlike the master view, additional views are not forced visible by default, and must be enabled manually either in the GameMaker Studio room editor or by setting view_visible[#] = true; in code executed within the relevant room itself.

tip

Xtend is compatible with most built-in GameMaker view camera functions. You can freely resize, move, zoom, and even rotate view cameras, and Xtend will automatically update itself to reflect the manual changes.

Additionally, each view managed by Xtend supports horizontal and vertical alignment. These values determine the 'anchor point' or 'attachment' of the view camera when it is resized. When this occurs, the camera position will be offset to whichever side is indicated by halign and valign.

Possible values include:

  • halign
    • va_left
    • va_center
    • va_right
  • valign
    • va_top
    • va_middle
    • va_bottom

While the default va_left, va_top alignment is preferable in the vast majority of cases, some applications may benefit from preserving a particular focal point during rescale operations. This requires thinking about your design from a particular origin point, however, and may not produce the results you expect without the proper design approach.

View alignment can always be determined later with camera_get_view_halign/camera_get_view_valign and camera_set_view_halign/camera_set_view_valign.