keyhold

package
v2.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 17, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package keyhold derives "key held" state from terminal auto-repeat — the closest a terminal game can get to press/release semantics.

Terminals (and SSH) deliver only discrete key events: there is NO key-up, and holding a key produces an initial press, a delay (~250–600ms depending on the user's OS settings), then repeats (~15–35Hz). A Tracker treats a key as held from its first press until Linger elapses with no further events, which bridges both the initial-delay gap and the inter-repeat gaps.

Usage (asteroids-style thrust):

tracker := keyhold.New(0) // default linger

func (rm *room) OnInput(r kit.Room, p kit.Player, in kit.Input) {
    rm.tracker.Observe(in, r.Now())
}
func (rm *room) OnWake(r kit.Room) {
    if rm.tracker.Held(kit.KeyUp, r.Now()) {
        rm.thrust(dt) // integrate while held — do NOT count events
    }
}

Honest physics: integrate against elapsed time while Held reports true, never per-event (event rate is the user's terminal repeat rate). The cost of the trick is release latency: a key reads held for up to Linger after the user lets go. Tune Linger per feel — lower is snappier release but risks flicker on slow repeat rates; the default rides above common initial-delay settings.

Index

Constants

View Source
const DefaultLinger = 550 * time.Millisecond

DefaultLinger comfortably exceeds common terminal initial-repeat delays.

Variables

This section is empty.

Functions

This section is empty.

Types

type Tracker

type Tracker struct {
	// contains filtered or unexported fields
}

Tracker derives held state for named keys and printable runes.

func New

func New(linger time.Duration) *Tracker

New returns a Tracker. linger <= 0 selects DefaultLinger.

func (*Tracker) Held

func (t *Tracker) Held(k kit.Key, now time.Time) bool

Held reports whether a named key is currently held at room time now.

func (*Tracker) HeldRune

func (t *Tracker) HeldRune(r rune, now time.Time) bool

HeldRune reports whether a printable rune is currently held at room time now.

func (*Tracker) Observe

func (t *Tracker) Observe(in kit.Input, now time.Time)

Observe records one input event at the room time it arrived. Call it from OnInput with r.Now().

func (*Tracker) Release

func (t *Tracker) Release(k kit.Key)

Release forgets a key immediately (e.g. consume a one-shot trigger).

func (*Tracker) ReleaseRune

func (t *Tracker) ReleaseRune(r rune)

ReleaseRune forgets a rune immediately.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL