kagura

    2D-first game engine for MoonBit inspired by Ebiten

    game-engine
    wgpu
    webgl
    moonbit
    Download zip
    Author
    Version
    0.6.0
    License
    Apache-2.0
    Last updated
    15 days ago
    Downloads
    75

    #kagura

    A 2D-first (with future 3D) game engine for MoonBit, inspired by Ebiten.

    Playground · Play ASHEN REALMS — a low-poly action RPG with hunter, mage, archer and summoner builds.

    #Features

    • Contract-first architecture -- API contracts are defined before implementations, keeping the codebase modular and replaceable
    • Ebiten-inspired design -- Fixed timestep updates, draw command batching, offscreen compositing, and backend abstraction
    • Cross-platform -- Desktop via wgpu-native, browser via WebGPU
    • Pure MoonBit -- No CGo, no FFI beyond the graphics backend boundary

    #Architecture

    moon.work |-- core/ Calculations: geometry, physics, terrain, input state |-- platform/ Shared window/input/surface contracts |-- platform_web/ Browser adapters and runtime_hooks/ |-- platform_native/ Native hooks, gfx_wgpu_native/, capture/ |-- engine/ Rendering, assets, application/runtime, scene, HUD |-- game/ Rules, progression, ECS, inventory, input bindings `-- editor/ Authoring and inspection tools

    #Platform Support

    TargetBackendStatus
    Web (all OS)WebGPUSupported
    Native macOSwgpu-native + Metal + GLFWSupported
    Native Linuxwgpu-native + Vulkan + GLFWSupported (CI: check + test + build)
    Native Windowswgpu-native + D3D12/Vulkan + GLFWPartial (CI: check + build workaround; runtime validation pending)
    WASM GuestShared-memory binary protocolSupported (MoonBit / Rust / Zig)

    JS builds (browser) work on any OS. Native builds support macOS and Linux. Windows native build uses a repo-side workaround for the upstream -lm issue, but runtime validation is still limited.

    #Quick Start

    #Prerequisites

    #Run in Browser

    pnpm install just dev flappy_bird

    Builds and serves at http://localhost:8080. Browser demos currently require WebGPU (Chrome 113+, Edge 113+).

    #Development CLI

    Install the CLI from this checkout, then scaffold a standalone Web game:

    moon install ./cmd/kagura kagura new my-game --web cd my-game pnpm install kagura dev kagura build

    kagura new --web uses the current empty directory. The template includes the browser runtime and Vite setup and depends on the published Kagura packages, without local path dependencies.

    Starting with 0.6.0, the CLI shares the root mizchi/kagura module and release version. Install it with moon install mizchi/kagura/cmd/kagura@0.6.0.

    For examples and Studio in this checkout:

    pnpm kagura dev hacknslash_3d --port 8080 pnpm kagura build hacknslash_3d --out-dir output/game pnpm kagura studio

    Run just studio-install once before launching Studio. just kagura ... also works; inside a game directory the project argument can be omitted. Builds are self-contained static sites. See Kagura CLI for options.

    kagura capture [url] --output game.png captures the game surface, and kagura profile [url] --out-dir output/profile writes frame statistics and a Chrome CPU profile. Both work with external Kagura projects; install @playwright/test in the calling project. See browser tool setup.

    #Publish the playground

    Run just studio-install once to install the Studio build dependencies. just pages builds release bundles, Studio, and relative assets into _site/. Pushing main publishes them to GitHub Pages through .github/workflows/deploy.yml. The repository's Pages source must be GitHub Actions.

    After deployment, just pages-test https://mizchi.github.io/kagura/ checks the public gallery, Studio modeling, save selection and summoner gameplay with Playwright. It also accepts a locally served _site/ URL, including a project subdirectory.

    Open kawaiko in Studio initializes the modeling workspace directly from a shareable URL.

    #Native

    bash scripts/setup-wgpu-native.sh # Run with just (recommended -- sets CPATH/LIBRARY_PATH automatically) just run-native flappy_bird # Non-visual smoke test (window can appear black) (cd examples/smoke/runtime_smoke_native && moon run src --target native) # Visual sanity check just run-native native_triangle

    runtime_smoke_native is intended for internal verification. A black window is expected; success is runtime_smoke_native: ok (real).

    #Examples

    ExampleDescription
    runtime_smokeMinimal JS smoke test
    runtime_smoke_nativeMinimal native smoke test (non-visual)
    native_triangleNative backend triangle demo
    flappy_bird2D game loop with input handling
    survivorMulti-entity game with weapons/UI
    arena3d3D arena prototype (experimental)

    Each example is an independent MoonBit module. Run with:

    (cd examples/<name> && moon run src --target <js|native>)

    #Documentation

    #For Users

    #For Contributors

    #Verification

    just fmt just check target=js just test target=js just check target=native just test target=native just check-release pnpm e2e:smoke

    #Updating release versions

    just version 0.6.0 --dry-run # Preview affected modules and manifests just version 0.6.0 # Update versions and regenerate Web runtime / CLI just version 0.6.0 --check # Fail if any manifest version/reference differs just check-release just publish-status # Inspect packaged modules without uploading

    The publication catalog in scripts/release-policy.mjs is shared with just publish. It includes the reusable libraries, platform runtime hooks and CLI. The updater changes their versions and internal dependency references in source manifests, examples, editors and Web scaffolding, preserving external dependencies and consumer project versions. Both moon.mod and moon.mod.json are supported. Use a stable X.Y.Z version; downgrades are rejected.

    Version updates regenerate the browser distribution before embedding it in the CLI. If a build fails, fix the error and repeat the same command to finish regeneration. The updater does not commit, tag, push or publish. Review the diff and validation results before running just publish.

    Publication stages every module outside the checkout, checks the staged workspace and verifies each archive has its manifest, MoonBit sources and prebuild support. Modules are published in dependency order; an upload failure stops the release. just publish-status performs the same packaging checks.

    #Dependencies

    #License

    Apache-2.0

    FixedStepConfig

    Fixed-step simulation contract. Ebiten refs:
    • internal/clock/clock.go
    • internal/ui/context.go (updateFrameImpl / update count handling)

    FixedStepState

    Scheduler state carried between frames. Ebiten refs:
    • internal/ui/context.go (tick progression and frame accumulator semantics)

    RenderPassDesc

    What GraphicsDriver.begin does before any draw calls of a pass.

    clear_enabled=false keeps the previous framebuffer contents (useful for additive overlays). present=true swaps buffers at end; set false for offscreen render-to-texture passes.

    StepResult

    Planned updates for one rendered frame. Ebiten refs:
    • run.go (Update / Draw separation)
    • internal/ui/context.go (skip / interpolation flow)

    WindowOptions

    default_fixed_step_config

    fn default_fixed_step_config() ->
    FixedStepConfig

    initial_fixed_step_state

    fn initial_fixed_step_state() ->
    FixedStepState

    new_fixed_step_config

    fn new_fixed_step_config(tps : Int, max_updates_per_frame : Int) ->
    FixedStepConfig

    step_result_alpha

    fn step_result_alpha(result :
    StepResult
    ) -> Double

    step_result_next_state

    step_result_updates

    fn step_result_updates(result :
    StepResult
    ) -> Int

    Source Files