Axel Meyer 72801957cd chore: add Tier-1 LICENSE file
Adds the proprietary all-rights-reserved license that applies to this
library. The text is identical to the engine LICENSE — this lib is
Tier-1 official platform content, distributed under the same terms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:04:37 +02:00
2026-05-16 18:04:37 +02:00

lib-core.player_control

Single-player movement lib. Top-left position + size + speed, reads input-direction via lib-core.input, applies 4-corner-AABB collision against lib-core.maps.is_walkable. All-or-nothing block (no wall-sliding in v0.1.0).

Version: 0.1.0
Lib-ID: lib-core.player_control
Requires: lib-core.maps v>=0.1.1, lib-core.input v>=0.4.0
Tags: player, movement, aabb, collision

Topology

graph LR
  this["lib-core.player_control"]
  lib_core_maps["lib-core.maps"]
  this --> lib_core_maps
  lib_core_input["lib-core.input"]
  this --> lib_core_input
  engine["engine.*"]
  this --> engine

API

player.set_position(x, y)

Syntax: player.set_position(x: number, y: number) -> void

Example:

player.set_position(244, 244)

Description: Sets the player's top-left position in pixel-coords. Lua error(...) on non-number args.

player.position()

Syntax: player.position() -> {x: number, y: number}

Description: Returns the current top-left position. Compute center as p.x + size.w/2, p.y + size.h/2.

player.set_size(w, h)

Syntax: player.set_size(w: number, h: number) -> void

Description: Sets the AABB bounding-box size in pixels. Default 24x24.

player.size()

Syntax: player.size() -> {w: number, h: number}

Description: Returns current bounding-box size.

player.set_speed(s)

Syntax: player.set_speed(s: number) -> void

Description: Sets move-speed in px/sec. Default 200.

player.speed()

Syntax: player.speed() -> number

Description: Returns current speed.

player.bind_movement(left, right, up, down)

Syntax: player.bind_movement(left: string, right: string, up: string, down: string) -> void

Example:

input.bind("move_left",  { "a", "left" })
input.bind("move_right", { "d", "right" })
input.bind("move_up",    { "w", "up" })
input.bind("move_down",  { "s", "down" })
player.bind_movement("move_left", "move_right", "move_up", "move_down")

Description: Registers 4 input-action names for the player's WASD-style direction. Until called, update(dt) is a silent no-op.

player.update(dt)

Syntax: player.update(dt: number) -> void

Example:

function update(ctx, dt)
    player.update(dt)
end

Description: Reads bound actions, computes direction-vector via lib-core.input.direction, predicts next position, runs 4-corner-AABB walkability check against the current map, and mutates position only if all corners walkable (all-or-nothing block; no wall-sliding in v0.1.0). Silent no-op until bind_movement is called.

Conventions

  • Position is top-left of the AABB (matches engine.render.draw_rect origin).
  • Center calculation lives in caller: cx = position.x + size.w/2.
  • All-or-nothing block on collision (no wall-sliding in v0.1.0).
  • Module owns rendering (lib has no draw fn). Module composes camera-follow.
  • Silent no-op for update() before bind_movement (debug-friendly).
  • Lua error(...) for setter misuse (caller-bug fast-fail).
  • Y-down-positive per ADR-0031.

Consumer pattern

local player = require("lib-core.player_control")
local input  = require("lib-core.input")
local camera = require("lib-core.camera")

input.bind("move_left",  { "a", "left" })
input.bind("move_right", { "d", "right" })
input.bind("move_up",    { "w", "up" })
input.bind("move_down",  { "s", "down" })

player.set_position(244, 244)
player.bind_movement("move_left", "move_right", "move_up", "move_down")

function update(ctx, dt)
    player.update(dt)
    local p = player.position()
    local s = player.size()
    camera.set_target(p.x + s.w/2, p.y + s.h/2)
end

function render(ctx)
    local p = player.position()
    local s = player.size()
    engine.render.draw_rect(p.x, p.y, s.w, s.h, engine.render.rgb(200, 60, 80))
end

CHANGELOG

v0.1.0 (P.0)

  • Initial release: position/size/speed + bind_movement + per-frame update with 4-corner-AABB collision.

References

  • Spec v0.1.0 (P.0): meta/docs/superpowers/specs/2026-05-09-p0-lib-player_control-design.md
  • ADR-0001 (engine knows verbs, libs bring nouns)
  • ADR-0031 (pixel-convention: Y-down-positive)
  • ADR-0038 (API-Doc-Convention)
Description
P.0.lib.player_control � player movement + AABB-wall-collision
Readme 43 KiB
Languages
Lua 89.5%
Shell 10.5%