A world

A game is a World. Things in that world are Actors. You do not construct the window yourself. Activerse.start creates the window, the renderer, audio, the camera, and Input, then runs GameLoop until the window closes.

Start

import ActiverseEngine.Activerse;

public class Main {
    public static void main(String[] args) {
        Activerse.start(new MyWorld());
    }
}

Put this file under cgame/, not under src/. Maven compiles cgame as a second source root into target/classes. Sandbox’s entry is the default-package class Main. OptiShoot’s entry is OptiShoot.OptiShootMain.

Activerse.switchWorld replaces the active world without tearing down GLFW, OpenGL, or OpenAL. It is safe to call from a UI callback. The switch is applied on the loop thread.

World

prepare() is abstract and runs once, after the window and camera exist. Spawn actors and turn on chunk streaming there. showBootLoadingOverlay() defaults to true, so a loading card is up during that work. Title screens return false.

worldAct() runs on the gameplay tick, at the fps value in Activerse.toml (default 60). Weapons, menus, and block edits belong there. If you enabled the Rust body step, do not also integrate that body inside worldAct. See the clock.

public class MyWorld extends World {
    @Override
    public void prepare() {
        addObject(new Crate(), 2f, 1f, 2f);
    }

    @Override
    protected void worldAct() {
        // gameplay at the configured fps
    }
}

addObject(actor, x, y, z) places an actor in world metres. onEnter() runs when the world becomes active, including after a switch. The default captures the mouse for look. onEscapePressed() returns true if the world handled Escape. Returning false asks the loop to close the window.

Actor

act() is abstract and runs once per gameplay tick while the actor is in the world and not tick-inert. Static scenery should override isTickInert() and return true so the loop does not call act() on every crate.

An actor owns a Transform, an optional Mesh, and a Material. setColor tints the material. Removing an actor sets it removed. The world skips removed actors on later ticks.

act() is not the 1 ms clock. A long act() delays the next poll. Keep it to gameplay. Movement of the player body is the Rust step, described on the clock page.

What the loop gives you

After prepare, the world can read the objects Activerse.start created:

handlesLookInput() tells the loop to pass cursor deltas to applyFrameLook instead of Camera.turn. OptiShoot does this so the orbit camera and the weapon share one look sample. Sandbox leaves it false and lets the camera turn itself.