cc-libs/CLAUDE.md
2026-05-31 00:39:30 +02:00

5.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

A collection of ComputerCraft (CC:Tweaked) Lua APIs, servers, and programs for in-game networked computers. Targets CC:Tweaked for Minecraft 1.21 (latest). Runtime is the ComputerCraft Lua sandbox (fs, peripheral, os.pullEvent, shell, parallel, modem.transmit, etc.), not standard Lua.

Tooling constraints

  • There is no way to run, build, or test this code yet. It only executes inside ComputerCraft (in-game or under CraftOS-PC). Do not attempt to run Lua locally or add a test harness unless asked.
  • Linting: just check runs luacheck over all Lua source. Always run just check after editing a Lua file, and fix any warnings before considering the change done. Config lives in .luacheckrc (a custom lua51+cc std that knows the ComputerCraft sandbox globals and the os/table extensions). If a new genuine global is needed, add it there rather than suppressing the warning inline.
  • Match the existing style (2-space indent, semicolons, local function).
  • require paths are ComputerCraft-resolved and absolute from the computer root, e.g. require('/apis/net'). Most modules return a factory function — call it once to get the API: local net = require('/apis/net')().

Architecture

Three layers, bottom-up:

  1. apis/eventloop.lua — the foundation. A single-threaded event loop wrapping os.pullEventRaw. register(eventName, handler) returns a disposer; handlers returning api.STOP auto-unregister. Also provides setTimeout/clearTimeout, onStart/onStop, and runLoop. The loop auto-stops when no handlers/timeouts remain (unless runLoop(true)). Mutations during dispatch are queued (unregisterQueue, removeTimeoutQueue, timeoutFactories) and flushed after, so handlers can safely (un)register.

  2. apis/net.lua — messaging built on the event loop. Sends typed packets over modems. Key concepts:

    • Packet = { sourceId, sourceLabel, routerId, destId, message }. destId may be a numeric computer ID, a string label, or nil (broadcast).
    • Routing: messages go out on DEFAULT_ROUTING_CHANNEL (10) to be picked up by a router, unless the sender is itself a router (_G.isRouterEnabled). A router must be running somewhere on the network for net-based programs to reach other machines.
    • Request/response: sendRequest/listenRequest implement RPC — the responder replies on eventType .. "_response". sendRequest spins up a private event loop + net instance, waits up to timeoutInSec (default 0.5s), and returns ok, result, packet. sendMultipleRequests collects replies from many machines until timeout.
    • Higher-level helpers: createRequest(channel, eventType) and createEvent(channel, eventType).
  3. servers/ and programs/ — concrete uses of net. Servers listenRequest and call net.startLoop(); programs (clients) fire sendRequest/sendMultipleRequests and exit.

Channels (well-known ports)

  • 9 — ping
  • 10 — router / default routing channel
  • 64 — cube (deployment/control)

These are duplicated as local constants across files; keep them in sync when changing.

The cube deployment system

cube (client programs/cube.lua, server servers/cube-server.lua) manages a cluster of "cube" machines over channel 64:

  • cube ls — list reachable cubes (broadcast ping; each replies with its boot command). * marks the local machine.
  • cube deploy — walk the local filesystem (skipping IGNORED_PATHS: /rom, /.cubeboot, /.git, /.gitignore, /startup.lua), send every file to each remote cube via deploy-file, then reboot it.
  • cube set-boot <machineId> [command] — write/clear the remote's /.cubeboot, then reboot. Empty command deletes the boot hook.
  • cube reboot <machineId> — remote reboot.
  • .cubeboot holds a per-machine startup shell command, run by servers/cube-boot.lua at boot.

Boot flow

startup/servers.lua is the entry point on each machine: it adds /programs to shell.path, then parallel.waitForAll runs an interactive shell alongside every server in SERVERS. When all stop, it reboots.

CraftOS-PC emulation

startup/servers.lua detects the periphemu global and, when present, creates an emulated modem plus (on computer 0) a few emulated peer/router computers. Code guards CraftOS-PC quirks with if periphemu then ... end (e.g. os.sleep(0.5) after reboots in cube.lua to avoid crashes). Preserve these guards.

Installation / distribution

install.lua is fetched and run on a machine via wget run <raw-github-url>/install.lua. It deletes old paths, re-downloads every file in LIST_FILES from the master branch raw GitHub URL, and runs startup/servers.lua. When adding a new file that ships to machines, add it to LIST_FILES in install.lua (and to SERVERS in startup/servers.lua if it's a server).

Conventions

  • Each module starts with local _VERSION = '...'; bump it when changing that module's behavior.
  • Programs accept -version/--version and -help/--help (and -silent/--silent for the router) via vararg ....
  • French comments appear throughout — fine to add either language, match the surrounding file.