KorGE Resolutions

Table of contents:




In KorGE you don’t have to deal with different resolutions. That’s something handled by the engine.

When initializing your game, you define a virtualWidth and a virtualHeight (and a width and height). In windowed platforms, the width and height will be the size of the window, while on full screen platforms or the browser where javascript can’t resize the window, those values would be ignored.

The virtualWidth and virtualHeight define your in-game dimensions. So for example, if the size of the window is 1920x1080 but you defined a virtual size of 1280x720, and you place an object at 1279x719, the object will be placed at the 1918x1078 screen dimensions.

Setting the resolution using DSL

suspend fun main() = Korge(width = 1280, height = 720, virtualWidth = 640, virtualHeight = 480) {
    // ...

Setting the resolution using the Module System

suspend fun main() = Korge(Korge.Config(module = MyModule)) {
    // ...
object MyModule : Module() {
	override val size = SizeInt(640, 480) // Virtual Size
	override val windowSize = SizeInt(1280, 720) // Window Size

Aspect Ratio

So, if you are defining a virtualWidth and a virtualHeight that by itself defines a fixed aspect ratio, how do you handle different aspect ratios or windows resizes gracefully?

Black bars

With the default configuration KorGE will place “black bars” (clip your content) to a container that is centered, filling the window keeping the aspect ratio.

This behaviour is defined by the scaleAnchor, scaleMode and clipBorders parameters in the game initialization:

suspend fun main() = Korge(scaleAnchor = Anchor.MIDDLE_CENTER, scaleMode = ScaleMode.SHOW_ALL, clipBorders = true) {

clipBorders = false & Dealing with the extra space & dockedTo

With the default scaleMode = ScaleMode.SHOW_ALL but setting clipBorders = false, your get your content centered keeping the aspect ratio, and filling all the available space. But now, pixels that would go in the border are being displayed.

You can use the dockedTo component / view decorator to automatically update the view position when a resize or rotation happens.

val container = container {
    solidRect(32, 32, Colors.RED).xy(0, 0).anchor(1.0, 0.0)
    solidRect(32, 32, Colors.BLUE).xy(-32, 0).anchor(1.0, 0.0)

// This will keep your container 0,0 coordinate at the top-right of the window independently to the virtual aspect ratio
container.dockedTo(anchor = Anchor.TOP_RIGHT, scaleMode = ScaleMode.NO_SCALE)

Dealing with resize events

Whenever the window is moved or resized, a ReshapeEvent is triggered to the stage.

stage.addEventListener<ReshapeEvent> { e -> // e.x, e.y, e.width, e.height

But normally you would want to attach it to a view, so when the view is not attached to the stage and not referenced, you won’t have leaks.

view.addComponent(object : ResizeComponent {
    override fun resized(views: Views, width: Int, height: Int) {
        // ...

Note, that if you use the dockedTo component, you might not need this at all.

Actual/Extended Virtual Size

// The Window Size
val Views.nativeWidth: Int
val Views.nativeHeight: Int

// Your defined Virtual Size
val Views.virtualWidth: Int
val Views.virtualHeight: Int

// When scaleAnchor != Anchro.TOP_LEFT, the left and top values here will contain the "border" gap between the top-left of the window and your actual content in the virtual space
val Views.actualVirtualLeft: Int
val Views.actualVirtualTop: Int

// Greater or equal that the virtual size. This pair will have the aspect ratio of the window (not the virtual size aspect ratio)
val Views.actualVirtualWidth: Int
val Views.actualVirtualHeight: Int

val Views.virtualLeft: Int
val Views.virtualTop: Int
val Views.virtualRight: Int
val Views.virtualBottom: Int