Skip to content

Click in the world ​

Goal ​

Show a hover marker at the collider under the pointer, and click to select a target or walk a character to the hit point.

Files you will edit ​

  • src/game.ts — the existing game's pointer system.

Steps ​

  1. Allocate hit and HUD records once, then add this system after your camera system. Keep the existing player and collider setup. The HUD receives the hover position and entity; use the existing HUD's mint marker to highlight it.

    ts
    import { hitUnderCursor, simpleMoveTo, type CursorHit, type GameContext } from 'gameable';
    
    const hit: CursorHit = {
      point: { x: 0, y: 0, z: 0 },
      normal: { x: 0, y: 1, z: 0 },
      entity: 0,
      distance: 0,
    };
    const model = {
      hover: { visible: false, entity: 0, x: 0, y: 0, z: 0 },
      selected: 0,
    };
    
    export function pointerSystem(ctx: GameContext): void {
      const found = hitUnderCursor(ctx, hit);
      model.hover.visible = found;
      model.hover.entity = found ? hit.entity : 0;
      if (found) {
        model.hover.x = hit.point.x;
        model.hover.y = hit.point.y;
        model.hover.z = hit.point.z;
        if (ctx.started && ctx.input.pressed('LMB')) {
          model.selected = hit.entity;
          if (ctx.player !== 0) simpleMoveTo(ctx, ctx.player, hit.point);
        }
      }
      ctx.hud.set(model);
    }
  2. Register pointerSystem and stepMoves in your systems list (merge model into an existing HUD model). For target-only games, drop simpleMoveTo.

The pointer and viewport() are in CSS pixels from the first tick (hosts send an initial resize), relative to the view's top-left. Pick in a system, after this frame's camera is set. hitUnderCursor reaches 500 m by default; query is physics.raycast's layer mask. Third-person picking assumes the full arm length. With no ground collider, use screenRay then rayToGround(ray, 0, destination).

Verify ​

Run npm run dev in your game. With pointer lock disabled, hover over a collider: the HUD hover data contains its entity and world position. Click once: selected changes to that entity and the player walks to the hit point. Hover empty space: visible becomes false and clicking leaves the selection unchanged.

See also ​