Skip to content

Run in the browser

Run the scene from the earlier pages in a browser with the WebGPU backend, behind AwakeKt's loading screen.

WebGPU Web (wasmJs)

The app and GameRenderPlan stay in commonMain unchanged. This page adds a wasmJs target, the WebGPU backend, and a page to host it.

Add the WebGPU backend

The WebGPU backend builds on wgpu4k, which only publishes snapshot builds. So the backend is published as a snapshot too, to Maven Central's snapshot repository, and Core releases do not include it. Each Core release publishes a WebGPU snapshot built from it instead.

Add the snapshot repository in settings.gradle.kts:

settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        mavenCentral()
        maven("https://central.sonatype.com/repository/maven-snapshots/") {
            content { excludeGroup("io.ygdrasil") }
        }
        // The wgpu4k builds the WebGPU backend was tested with, which Sonatype no longer serves.
        maven("https://awakekt.github.io/awake/") { content { includeGroup("io.ygdrasil") } }
    }
}

Add the backend to the catalog at your Core version with -SNAPSHOT appended, the WebGPU build of that Core release:

gradle/libs.versions.toml
[libraries]
awake-backend-webgpu = { module = "com.awakekt.awake.backend:webgpu", version = "0.19.0-SNAPSHOT" }

Then add a browser target and the dependency:

build.gradle.kts
kotlin {
    @OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
    wasmJs {
        browser()
        binaries.executable()
    }

    sourceSets {
        wasmJsMain.dependencies {
            implementation(libs.awake.backend.webgpu)
        }
    }
}

The snapshot carries the exact wgpu4k builds it was tested with, so Gradle resolves those without more setup.

Keep WebGPU on your Core release

0.19.0-SNAPSHOT depends on every Core module at exactly 0.19.0 and holds them there, so a build that also asks for a newer Core fails to resolve rather than mixing two, and an older Core in the build is moved up to 0.19.0. Do not take the newest -SNAPSHOT in the snapshot repository instead: that one is built from main after the release, and it moves the wasmJs target onto Core snapshots.

Launch the app

In wasmJsMain, hand the same app and plan to launchWebGpuGame:

wasmJsMain/kotlin/Main.kt
import com.awakekt.awake.webgpu.application.WebGpuEngine
import com.awakekt.awake.webgpu.application.launchWebGpuGame

fun main() = launchWebGpuGame {
    WebGpuEngine(appLifecycle = firstScene(), requestedPlan = GameRenderPlan)
}

launchWebGpuGame finds the <canvas> with id awake-canvas, keeps it the size of the window, and draws a frame on every animation frame. Pass canvasId to use a different canvas.

Add the page and the loading screen

Put an index.html in src/wasmJsMain/resources/:

src/wasmJsMain/resources/index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    <title>Hello AwakeKt</title>
    <style>
        html, body { margin: 0; width: 100%; height: 100%; overflow: hidden; }
        canvas { display: block; width: 100vw; height: 100vh; }
    </style>
</head>
<body>
<canvas id="awake-canvas"></canvas>
<script src="awake-loader.js" data-product="Hello"></script>
<script src="hello.js"></script>
</body>
</html>
  • The canvas id matches what launchWebGpuGame looks for.
  • hello.js stands for your app's bundle, which is named after the Gradle module.
  • awake-loader.js is AwakeKt's loading screen. Copy awake-loader.js from the WebGPU backend into src/wasmJsMain/resources/, next to index.html. Load it before the bundle.

The loading screen shows the AwakeKt mark and a progress bar: first the .wasm download, by bytes, then WebGPU and shader startup. The first frame drawn to the canvas dismisses it. If the download fails, the browser has no WebGPU, or the engine fails to start, it shows a message instead of leaving a black canvas. data-product is the name shown after "AwakeKt" on the screen; leave it out to show only "AwakeKt".

Run it

./gradlew :your-module:wasmJsBrowserDevelopmentRun

Open the address it prints in a browser with WebGPU. The loading screen suggests a current Chrome or Edge, or Safari 26 or later.

One plan for both backends

The WebGPU backend runs as much of GameRenderPlan as it supports and reports anything it leaves out, so the plan never needs a browser copy.

No WebGPU, no start

In a browser without WebGPU, launchWebGpuGame stops before the engine starts, with "WebGPU is unavailable in this browser or device", and the loading screen says so.

See also