cog

module
v0.0.0-...-00f6ed4 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: MIT

README

Cog Engine

Cog is a small typed plugin engine for Go. Plugins communicate through events, commands, and locked resources; the kernel owns registration, scheduling, and error handling.

Why Cog

  • Safe parallelism by construction. Ready event subscribers and independent tasks run concurrently whenever their resource access does not conflict. Handlers declare access by binding typed read and write handles; the scheduler acquires the resulting lock set atomically and prevents races over engine-managed state.
  • No lock bookkeeping to keep in sync. The same binding that gives a handler access to a resource declares its lock. When one command uses another, Cog computes the transitive resource set at composition time, so callers stay decoupled from the callee's implementation details.
  • A small, highly decoupled microkernel. Plugins depend on typed commands, events, and resources rather than concrete plugin implementations. Features can be added, removed, or replaced at the composition root without a central application object accumulating subsystem knowledge.
  • Declarative scenes without asset plumbing. Build each frame from UI element values and canvas draw declarations that reference images and fonts by path. Canvas loads and caches assets lazily, packs sprites and glyphs into atlases, and manages their GPU resources; explicit unloading remains available when an application needs tighter residency control.
  • Invalid architectures fail before startup. Cog validates plugin dependencies, unique ownership, required resources, command usage, and event ordering while composing the engine instead of discovering structural mistakes during play.
  • Deterministic lifecycle and event ordering. Explicit dependencies govern startup and shutdown, while event subscribers can declare ordering only where it matters and remain parallel everywhere else.
  • Typed contracts without generated glue. Exact Go types identify commands, events, and resources, preserving compile-time request and response types across plugin boundaries.
  • Low-allocation frame loops. Handler factories run once during registration, synchronous command dispatch avoids per-call allocations, warmed UI processing is allocation-free, and canvas queues retain their backing storage between frames.
  • One operational boundary. Context propagation, asynchronous errors, cancellation, and orderly shutdown converge in the kernel, and the finalized plugin and contract graph is available for runtime introspection.

Packages

  • kernel: plugin lifecycle, typed registry, scheduler, resources, and errors.
  • app: driver-neutral update, render, and quit contracts. No implementation.
  • input: input state, discrete events, and the driver-facing apply command.
  • anim: timelines of eased value tracks and one-tick cues, advanced every fixed step.
  • storage: layered read filesystems and one permanent writable filesystem.
  • m: immutable vectors, rectangles, colors, matrices, quaternions, scalar helpers, and splines. Angles use radians.
  • gfx: driver-neutral rendering queues, resources, viewport, and backend contract.
  • canvas: layered 2D sprites, text, primitives, and custom triangles over gfx.
  • ui: immediate-mode layout, interaction, and canvas-backed visual processing.
  • wgpu: window, input, timing, and WebGPU system driver.

Plugin Layout

Plugin file layout, handler structure, and resource-scope rules are enforced conventions; see .github/instructions/kernel.instructions.md.

Lifecycle

config := map[kernel.PluginName]any{
    storage.Name: storage.DefaultConfig("my-app").WithReadDiskFS("res"),
    wgpu.Name:    wgpu.DefaultConfig().WithTitle("My App"),
}

plugins := []kernel.Plugin{
    storage.New(),
    input.New(),
    gfx.New(),
    wgpu.New(),
    ...
}

kernel.New(config).
    WithPlugins(plugins...).
    Run(ctx)

kernel.New returns an *Engine: the composition root that owns the plugin set, registry, scheduler, and lifetime. WithPlugins validates and topologically orders dependencies, calls every Register, then finalizes ownership and subscription DAGs. Run calls optional PluginStarter implementations in dependency order, calls the optional PluginHost on the calling thread, and invokes optional PluginStopper implementations in reverse order. Unrelated plugins retain caller order.

At runtime plugins receive a kernel.Kernel: a small per-dispatch value carrying the engine, the invocation context, and the locks its caller holds.

Communication At A Glance

Plugins talk through three mechanisms, all identified by exact Go type:

  • Commands are synchronous and return a result. Identity is a distinct defined factory type: type LoadCmd kernel.Command[LoadRequest, LoadResponse].
  • Events are asynchronous and need no registration. Zero or more subscriptions may react: type updateHandler kernel.Subscription[app.UpdateEvent].
  • Resources are shared state whose access the scheduler serializes. A handler binds a Read[T] or Write[T] handle once, and binding is what declares the lock.

A handler is a factory returning a Lock that binds handles and a body that runs per invocation. The factory runs once, at registration.

See kernel/README.md for the full API and .github/instructions/kernel.instructions.md for the rules that keep usage correct — particularly that values read from a handle are valid only while the handler holds its lock.

Errors and Shutdown

All command and subscription handler errors flow through the engine's serialized ErrorHandler. Returning true terminates the engine; returning false allows recovery where possible. The default handler logs and terminates. Context cancellation and the host returning both shut down the runtime.

Directories

Path Synopsis
Package anim provides timelines of eased value tracks and one-tick cues.
Package anim provides timelines of eased value tracks and one-tick cues.
Package app declares the driver-agnostic application lifecycle and real-time loop contract.
Package app declares the driver-agnostic application lifecycle and real-time loop contract.
Package gfx is cog's driver-agnostic high-level renderer (renderer v2).
Package gfx is cog's driver-agnostic high-level renderer (renderer v2).
Package input is the driver-agnostic input contract: a unified Key space (keyboard keys AND mouse buttons), a polled State resource, discrete input events, and the Apply command a driver uses to feed input changes.
Package input is the driver-agnostic input contract: a unified Key space (keyboard keys AND mouse buttons), a polled State resource, discrete input events, and the Apply command a driver uses to feed input changes.
Package kernel is a small microkernel: plugins register resources, commands, and event subscriptions, then communicate through them.
Package kernel is a small microkernel: plugins register resources, commands, and event subscriptions, then communicate through them.
m
Package m provides immutable value-style mathematics for Cog.
Package m provides immutable value-style mathematics for Cog.
Package storage provides one kernel resource, FileSystem: a prioritized read-only overlay over every mounted filesystem, including the single permanent one that writes land in.
Package storage provides one kernel resource, FileSystem: a prioritized read-only overlay over every mounted filesystem, including the single permanent one that writes land in.
Package wgpu is cog's window + input + GPU driver plugin, built on gogpu.
Package wgpu is cog's window + input + GPU driver plugin, built on gogpu.

Jump to

Keyboard shortcuts

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