Menu

Overview

Relevant source files

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.


Purpose and Scope

This document provides a high-level overview of Basalt's architecture, including:

  • The core runtime system and its major subsystems
  • The component hierarchy and how UI elements are structured
  • The event-driven execution model
  • Distribution formats and module organization
  • Key code entities and their relationships

This overview is intended for developers who need to understand Basalt's overall structure before diving into specific subsystems.


System Architecture

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


Core Subsystems

Runtime Coordinator (main.lua)

The basalt object in src/main.lua serves as the primary entry point and runtime coordinator. It maintains:

ComponentTypePurpose
basalt._eventstableGlobal event callback registry
basalt._scheduletableUser-scheduled coroutines with filters
basalt._eventQueuetableInternal async event processing queue
activeFramestablePer-terminal frame mapping
focusedFrameBaseFrameSingle frame receiving keyboard input
mainstringReference to main terminal

Key functions:

Sources: src/main.lua1-435

Element Manager

The elementManager module src/elementManager.lua acts as a component registry and plugin coordinator:

  • loadElement(name) - Loads element classes and applies plugins
  • getElement(name) - Returns loaded element classes
  • getAPI(name) - Returns plugin API objects

Element 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

Property System

The propertySystem module src/propertySystem.lua implements reactive properties for all UI elements:

  • defineProperty(class, name, config) - Class-level property definitions
  • Property observers with automatic render triggering
  • Setter hooks for global property interception
  • Blueprint system for deferred element instantiation

Property configurations support:

  • Type validation (type="string", type="number", etc.)
  • Default values (default=true)
  • Render triggers (canTriggerRender=true)
  • Custom getters/setters

Sources: src/propertySystem.lua BasaltLS.lua357-426


Component Model

Element Class Hierarchy

All UI components inherit from a progressive enhancement pattern where each layer adds specific capabilities:

ClassFileSizeKey Responsibilities
BaseElementelements/BaseElement.lua13,870 bytesProperty system integration, event callbacks, lifecycle
VisualElementelements/VisualElement.lua43,389 bytesPositioning, colors, constraints, mouse/keyboard events, rendering
Containerelements/Container.lua26,063 bytesChild management, z-index sorting, event propagation, focus management
BaseFrameelements/BaseFrame.lua9,017 bytesTerminal 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

Component Categories

The framework includes 40+ UI elements organized by category in config.lua105-444:

CategoryCountComponentsDefault Loaded
Layout8Frame, BaseFrame, ScrollFrame, TabControl, SideNav, Accordion, FlexBox, DialogAll except Dialog
Input6Input, TextBox, CheckBox, Switch, Slider, ComboBoxAll except TextBox, ComboBox
Display7Label, ProgressBar, Image, BigFont, Display, Toast, BreadcrumbAll except Image, BigFont, Display
Data7Collection, List, Menu, Table, Tree, DropDown, ContextMenuAll except DropDown
Specialized5Button, Timer, Program, Graph, BarChartAll
Charts2LineChart, BarChartLineChart 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


Runtime Model

Event Processing Pipeline

Basalt implements a sophisticated event-driven architecture with clear separation between event dispatch and rendering:

Event routing logic at src/main.lua225-299:

Event TypeRouting TargetProcessing
mouse_click, mouse_up, mouse_scroll, mouse_dragactiveFrames[main]Spatial routing to active frame
key, key_up, charfocusedFrameFocus-based routing
All other eventsAll activeFramesBroadcast to all frames

The runtime implements three-tier event handling:

  1. Immediate frame dispatch - Events sent directly to frames based on type
  2. Coroutine-based async processing - User coroutines in _schedule with event filters
  3. Callback invocation - Direct callbacks in _events table

The 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

Rendering System

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 line
  • buffer.fg[y] - Foreground color per line
  • buffer.bg[y] - Background color per line
  • buffer.dirtyRects - List of changed regions

Only 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


Distribution Format and Build Pipeline

Basalt implements a three-stage build pipeline supporting multiple installation modes:

Build Stages

StageToolPurposeOutput
Configuration Generationgenerate-config.luaScans source files for annotations, builds component registryconfig.lua
Code Bundlingbundler.luaMinifies and packages everything into single file with custom module loaderrelease/basalt.lua
Type Definition Generationgenerate-annotations.luaCreates LSP support files from annotationsBasaltLS.lua

Installation Modes

Release Mode (release/basalt.lua1-52):

  • Single minified file (~500KB)
  • Custom require() override intercepts module loading at release/basalt.lua6-7
  • All modules embedded in project table
  • Element directories: minified_elementDirectory and minified_pluginDirectory at release/basalt.lua2-52

Development 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:

  • User-selectable components
  • Optional minification
  • Configured via config.lua metadata

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

Module Loading

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


Plugin System and Extension Points

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 MechanismPurposeExample Usage
Element lifecycle hooksIntercept postInit, destroy, handleEventtheme.lua applies themes on postInit
Property setter hooksIntercept all property assignmentsreactive.lua parses expressions like "{parent.x + 12}"
Event handler hooksAugment event processinganimation.lua listens to timer events
Exposed APIsGlobal plugin interfacesbasalt.getAPI("theme") returns ThemeAPI

Core plugins demonstrate different patterns:

  • theme uses lifecycle hooks + mixins
  • reactive uses property hooks + observers
  • animation uses event hooks + timers
  • xml uses mixins + custom parsers

Sources: config.lua447-507 src/elementManager.lua src/plugins/theme.lua src/plugins/reactive.lua src/plugins/animation.lua src/plugins/xml.lua


Property System and Reactive Evaluation

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:

  1. Setter hooks run (including reactive expression parsing)
  2. _values storage is updated
  3. Observers are notified (triggering re-renders if canTriggerRender=true)
  4. Cascades to dependents (reactive expressions referencing this property)

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


Key Design Patterns

PatternImplementationLocation
Progressive EnhancementFour-tier class hierarchy with incremental capability additionelements/*.lua
Reactive PropertiesObserver pattern with expression parsing and automatic updatespropertySystem.lua, plugins/reactive.lua
Plugin Mixin SystemNon-invasive extension via lifecycle hooks and property interceptorselementManager.lua
Event DelegationParent-to-child event propagation with coordinate transformationContainer.lua
Dirty Rectangle RenderingAccumulate and merge changed regions before blittingrender.lua
Triple-Tier Event ProcessingParallel coroutine systems with event filtersmain.lua
Deferred Element LoadingBlueprint pattern for lazy element instantiationpropertySystem.lua

Sources: src/main.lua225-299 src/propertySystem.lua src/elementManager.lua src/elements/Container.lua src/render.lua153-177


Summary

Basalt provides a complete UI framework for ComputerCraft with:

  • 40+ pre-built components organized in a clear inheritance hierarchy
  • Reactive property system with automatic UI updates
  • Event-driven architecture with three parallel processing tiers
  • Optimized rendering using dirty rectangle tracking
  • Extensible plugin system for animations, themes, XML layouts, and state management
  • Flexible distribution supporting both development (multi-file) and production (single-file) formats

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.