Basalt is a component-based UI framework for ComputerCraft that provides a comprehensive terminal-based UI system with reactive properties, event-driven architecture, and an extensible plugin system. It enables developers to build complex user interfaces for Minecraft computers and turtles using a declarative component model similar to modern UI frameworks.
For installation instructions, see Installation. For detailed architecture explanations, see Core Architecture. For component usage, see UI Components.
This document provides a high-level overview of Basalt's architecture, including:
This overview is intended for developers who need to understand Basalt's overall structure before diving into specific subsystems.
Basalt is structured in four major layers: Build Time (code generation and bundling), Core Runtime (framework orchestration), Element Hierarchy (UI component classes), and Plugin System (extensibility):
The main.lua basalt object and elementManager are the two most critical components, serving as the central hub that connects all other systems. The element hierarchy flows from abstract to concrete (BaseElement → VisualElement → Container → specific elements), while plugins extend functionality through the elementManager's hook system.
Sources: src/main.lua1-604 src/elementManager.lua src/propertySystem.lua src/elements/BaseElement.lua src/elements/VisualElement.lua src/elements/Container.lua config.lua1-510
The basalt object in src/main.lua serves as the primary entry point and runtime coordinator. It maintains:
| Component | Type | Purpose |
|---|---|---|
basalt._events | table | Global event callback registry |
basalt._schedule | table | User-scheduled coroutines with filters |
basalt._eventQueue | table | Internal async event processing queue |
activeFrames | table | Per-terminal frame mapping |
focusedFrame | BaseFrame | Single frame receiving keyboard input |
main | string | Reference to main terminal |
Key functions:
basalt.create(type, properties) - Creates UI elements via ElementManagerbasalt.run() - Starts the event loop at src/main.lua336-359basalt.update(...) - Single-step event processing at src/main.lua311-323basalt.schedule(func) - Registers user coroutines at src/main.lua183-195Sources: src/main.lua1-435
The elementManager module src/elementManager.lua acts as a component registry and plugin coordinator:
loadElement(name) - Loads element classes and applies pluginsgetElement(name) - Returns loaded element classesgetAPI(name) - Returns plugin API objectsElement classes are organized in config.lua164-442 with metadata including dependencies (requires), file size, and default inclusion status.
Sources: src/elementManager.lua config.lua1-448
The propertySystem module src/propertySystem.lua implements reactive properties for all UI elements:
defineProperty(class, name, config) - Class-level property definitionsProperty configurations support:
type="string", type="number", etc.)default=true)canTriggerRender=true)Sources: src/propertySystem.lua BasaltLS.lua357-426
All UI components inherit from a progressive enhancement pattern where each layer adds specific capabilities:
| Class | File | Size | Key Responsibilities |
|---|---|---|---|
| BaseElement | elements/BaseElement.lua | 13,870 bytes | Property system integration, event callbacks, lifecycle |
| VisualElement | elements/VisualElement.lua | 43,389 bytes | Positioning, colors, constraints, mouse/keyboard events, rendering |
| Container | elements/Container.lua | 26,063 bytes | Child management, z-index sorting, event propagation, focus management |
| BaseFrame | elements/BaseFrame.lua | 9,017 bytes | Terminal binding, root rendering, monitor support, peripheral events |
The hierarchy follows a progressive enhancement pattern: BaseElement provides the property and event foundation, VisualElement adds rendering and positioning, Container introduces child management, and specialized containers implement specific layout patterns. Complex elements like TextBox and Tree demonstrate deep feature sets built on this foundation.
Sources: config.lua105-444 src/elements/BaseElement.lua src/elements/VisualElement.lua src/elements/Container.lua src/elements/BaseFrame.lua
The framework includes 40+ UI elements organized by category in config.lua105-444:
| Category | Count | Components | Default Loaded |
|---|---|---|---|
| Layout | 8 | Frame, BaseFrame, ScrollFrame, TabControl, SideNav, Accordion, FlexBox, Dialog | All except Dialog |
| Input | 6 | Input, TextBox, CheckBox, Switch, Slider, ComboBox | All except TextBox, ComboBox |
| Display | 7 | Label, ProgressBar, Image, BigFont, Display, Toast, Breadcrumb | All except Image, BigFont, Display |
| Data | 7 | Collection, List, Menu, Table, Tree, DropDown, ContextMenu | All except DropDown |
| Specialized | 5 | Button, Timer, Program, Graph, BarChart | All |
| Charts | 2 | LineChart, BarChart | LineChart not default |
Elements marked as not default-loaded can be loaded on-demand via elementManager.loadElement(name) or auto-loaded through remote sources.
Sources: config.lua105-444
Basalt implements a sophisticated event-driven architecture with clear separation between event dispatch and rendering:
Event routing logic at src/main.lua225-299:
| Event Type | Routing Target | Processing |
|---|---|---|
mouse_click, mouse_up, mouse_scroll, mouse_drag | activeFrames[main] | Spatial routing to active frame |
key, key_up, char | focusedFrame | Focus-based routing |
| All other events | All activeFrames | Broadcast to all frames |
The runtime implements three-tier event handling:
_schedule with event filters_events tableThe rendering phase is separate and optimized through dirty rectangle tracking, ensuring UI updates only when necessary.
Sources: src/main.lua225-299 src/main.lua212-224 src/main.lua336-359 src/main.lua301-306
The rendering pipeline uses dirty rectangle tracking for optimized terminal output:
The Render class src/render.lua1-190 maintains three parallel buffers:
buffer.text[y] - Character data per linebuffer.fg[y] - Foreground color per linebuffer.bg[y] - Background color per linebuffer.dirtyRects - List of changed regionsOnly modified screen regions are sent to term.blit() at src/render.lua153-169
Sources: src/render.lua1-190 src/main.lua301-306 src/elements/BaseFrame.lua245-247
Basalt implements a three-stage build pipeline supporting multiple installation modes:
| Stage | Tool | Purpose | Output |
|---|---|---|---|
| Configuration Generation | generate-config.lua | Scans source files for annotations, builds component registry | config.lua |
| Code Bundling | bundler.lua | Minifies and packages everything into single file with custom module loader | release/basalt.lua |
| Type Definition Generation | generate-annotations.lua | Creates LSP support files from annotations | BasaltLS.lua |
Release Mode (release/basalt.lua1-52):
require() override intercepts module loading at release/basalt.lua6-7project tableminified_elementDirectory and minified_pluginDirectory at release/basalt.lua2-52Development Mode (src/ directory):
src/ ├── main.lua (runtime coordinator) ├── elementManager.lua (component registry) ├── propertySystem.lua (reactive properties) ├── render.lua (rendering engine) ├── errorManager.lua (error handling) ├── elements/ (40+ component files) │ ├── BaseElement.lua │ ├── VisualElement.lua │ ├── Container.lua │ └── ... ├── plugins/ (7 extension modules) │ ├── xml.lua │ ├── animation.lua │ ├── theme.lua │ └── reactive.lua └── libraries/ (utilities) ├── colorHex.lua ├── utils.lua └── expect.lua Custom Mode:
The config.lua file serves as the single source of truth for component metadata, driving both Dev and Custom installers. The annotation-driven approach (@configDescription, @requires, @class) enables automated dependency tracking and documentation generation.
Sources: config.lua1-510 release/basalt.lua1-52 src/init.lua1-14
The bootstrap process differs between development and production:
Development Mode (src/init.lua1-14):
Production Mode (release/basalt.lua6-7):
In production, all modules are embedded in the project table, allowing the single-file distribution to function identically to the development version while maintaining zero external dependencies.
Sources: src/init.lua1-14 release/basalt.lua1-7
Basalt's plugin system implements a non-invasive extension architecture where plugins extend element classes without modifying them:
The elementManager discovers plugins via directory scanning and applies them through four extension mechanisms:
| Extension Mechanism | Purpose | Example Usage |
|---|---|---|
| Element lifecycle hooks | Intercept postInit, destroy, handleEvent | theme.lua applies themes on postInit |
| Property setter hooks | Intercept all property assignments | reactive.lua parses expressions like "{parent.x + 12}" |
| Event handler hooks | Augment event processing | animation.lua listens to timer events |
| Exposed APIs | Global plugin interfaces | basalt.getAPI("theme") returns ThemeAPI |
Core plugins demonstrate different patterns:
Sources: config.lua447-507 src/elementManager.lua src/plugins/theme.lua src/plugins/reactive.lua src/plugins/animation.lua src/plugins/xml.lua
The property system implements a sophisticated reactive programming model enabling declarative, data-driven UIs:
Properties are defined with rich metadata at the class level. The reactive plugin extends this by intercepting property sets and transforming string expressions like "{parent.x + 12}" into observed, dynamically-evaluated functions.
When a property changes:
canTriggerRender=true)This creates a declarative, data-driven UI where element properties automatically update when their dependencies change. The system supports state-specific values for UI states like hover/pressed/disabled.
Sources: src/propertySystem.lua src/plugins/reactive.lua config.lua467-473
| Pattern | Implementation | Location |
|---|---|---|
| Progressive Enhancement | Four-tier class hierarchy with incremental capability addition | elements/*.lua |
| Reactive Properties | Observer pattern with expression parsing and automatic updates | propertySystem.lua, plugins/reactive.lua |
| Plugin Mixin System | Non-invasive extension via lifecycle hooks and property interceptors | elementManager.lua |
| Event Delegation | Parent-to-child event propagation with coordinate transformation | Container.lua |
| Dirty Rectangle Rendering | Accumulate and merge changed regions before blitting | render.lua |
| Triple-Tier Event Processing | Parallel coroutine systems with event filters | main.lua |
| Deferred Element Loading | Blueprint pattern for lazy element instantiation | propertySystem.lua |
Sources: src/main.lua225-299 src/propertySystem.lua src/elementManager.lua src/elements/Container.lua src/render.lua153-177
Basalt provides a complete UI framework for ComputerCraft with:
The framework is coordinated by the basalt object in src/main.lua which manages the event loop, frame lifecycle, and provides the primary API for application developers.
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.