# Bootstrap examples (on demand)

Prefer the host template bootstrap. Use these only when starting from zero without a template.

## Minimal 2D bootstrap

```ts
import {
  Game,
  GameObject,
  resource,
  RESOURCE_TYPE,
  LOAD_EVENT,
} from "@combos-fun/engine";
import { RendererSystem } from "@combos-fun/plugin-renderer";
import { Render, RenderSystem } from "@combos-fun/plugin-renderer-render";
import { Img, ImgSystem } from "@combos-fun/plugin-renderer-img";

resource.once(LOAD_EVENT.COMPLETE, () => {
  new Game({
    systems: [
      new RendererSystem({
        canvas: document.querySelector("#canvas")!,
        width: 750,
        height: 1334,
      }),
      new RenderSystem(),
      new ImgSystem(),
    ],
    // Safe place to wire the scene graph: every system has finished init.
    onSystemsBootstrapComplete: (g) => {
      // Transform values go through constructor params — never set them imperatively.
      const logo = new GameObject("logo", {
        position: { x: 100, y: 100 },
        size: { width: 200, height: 200 },
        origin: { x: 0.5, y: 0.5 },
      });
      logo.addComponent(new Img({ resource: "logo" }));
      // Render is only needed when you want to hide / fade / reorder; without it the
      // object is still drawn at alpha 1, zIndex 0. Requires RenderSystem registered.
      logo.addComponent(new Render({ zIndex: 5 }));
      // Use addChild — not addGameObject — so transform parent + scene are both wired.
      g.scene.addChild(logo);
    },
  });
});

resource.loadConfig([
  {
    name: "logo",
    type: RESOURCE_TYPE.IMAGE,
    src: { image: { type: "png", url: "logo.png" } },
    preload: true,
  },
]);
```

## Minimal 3D bootstrap

```ts
import { Game, GameObject } from "@combos-fun/engine";
import { Renderer3DSystem } from "@combos-fun/plugin-renderer-3d";
import {
  Graphics3D,
  Graphics3DSystem,
} from "@combos-fun/plugin-renderer-3d-graphics";

new Game({
  systems: [
    new Renderer3DSystem({
      canvas: document.querySelector("#canvas")!,
      width: 750,
      height: 1000,
    }),
    new Graphics3DSystem(),
  ],
  // Safe place to wire the scene graph: every system has finished init.
  onSystemsBootstrapComplete: (g) => {
    // 3D position / rotation / scale go through the component's own params
    // (positionX/Y/Z, rotationX/Y/Z, scaleX/Y/Z) — GameObject's TransformParams
    // is 2D-only (Vector2 + Size2) and is not read by 3D renderers.
    const box = new GameObject("box");
    box.addComponent(
      new Graphics3D({
        shape: "box",
        width: 1,
        height: 1,
        depth: 1,
        color: 0xff0000,
        positionX: 0,
        positionY: 1,
        positionZ: 0,
      }),
    );
    // Use addChild — not addGameObject — so transform parent + scene are both wired.
    g.scene.addChild(box);
  },
});
```

## Verification

After modifying engine code:

1. `pnpm typecheck`
2. `pnpm run build` (rebuild all packages in dependency order)
3. `pnpm validate-plugin-manifests:strict`
4. Run an example app from `examples/` and verify no console errors

