Getting Started Download Markdown

Make menus and a pause screen

Use KartUI for menus, HUDs, and overlays in 2D, first-person, or isometric games.

Keep screen state in Go and screen structure in .kui files. The CLI discovers components under ui/, shared layouts under ui/layouts/, and a theme at ui/theme.toml.

Save this shared frame as ui/layouts/screen-frame.kui:

<template>
  <panel modal="true" class="screen">
    <panel class="card"><slot/></panel>
  </panel>
</template>

<style>
.screen
  height: 100%
  flex-grow: 1
  align: center
  justify: center
  background: theme.colors.surface
.card
  padding: 24
  gap: 12
  max-width: 420
  flex-grow: 1
</style>

Save the menu as ui/views/menu.kui. The filename gives it the generated name ui.Menu:

<template>
  <ScreenFrame>
    <label>My game</label>
    <button onClick={ onPlay }>Play</button>
  </ScreenFrame>
</template>

<script setup lang="go">
func setup(onPlay func()) {}
</script>

Save a second screen as ui/views/pause.kui:

<template>
  <ScreenFrame>
    <label>Paused</label>
    <button onClick={ onResume }>Resume</button>
  </ScreenFrame>
</template>

<script setup lang="go">
func setup(onResume func()) {}
</script>

Add a screen *engine.UI field and the import example.com/my-game/.karty/ui. Open one screen at a time:

func (game *Game) showMenu() {
    if game.screen != nil { game.screen.Close() }
    game.screen = ui.Menu(func() {
        game.screen.Close()
        game.screen = nil
        // Start or resume your game here.
    })
}

Call game.showMenu() from OnStart. Open ui.Pause the same way from your existing input hook, for example when OnKeyDown receives engine.KeyEscape. Set a playing flag to false when pausing and skip game movement in OnUpdate until Resume sets it true. A modal panel captures input; your Go code decides whether the game simulation pauses.

Layouts share structure and styles. Component callbacks change game state. Packages can also export .kui components/layouts, images, fonts and theme defaults through karty-package.toml. Import a folder or .kpkg with karty package import; compose its exported components with the same typed props and callbacks. The consuming game retains its own root, state and theme overrides. Use prefixed component/props names to avoid shared Go-scope collisions. Call Invalidate() after changing data used by dynamic UI bindings. Test your layout at a narrow viewport before adding more screens. Orbital flight deck shows menus, loading, inventory, gameplay, and pause screens.

Orbital flight deck uses a left menu over its game artwork.
Orbital flight deck uses a left menu over its game artwork.