A High-Performance Lua Framework for Terminal Applications
๐ Quick Start โข ๐ฌ Demos โข ๐ Examples โข ๐ API Docs โข ๐ค Contribute
๐ต Music Player | ๐จ Custom Themes | ๐ Plugin System | ๐ฎ 2D Games | ๐ฑ TUI Applications
RMP (Ray Music Player) is a high-performance, extensible framework built in C with Lua scripting for creating sophisticated terminal user interfaces. Originally conceived as a music player, RMP has evolved into a comprehensive platform for terminal-based applications, featuring:
- ๐ต Advanced Music Player - Multi-format audio support with real-time visualization
- ๐ฑ Rich TUI Framework - Create complex terminal interfaces with ease
- ๐ฎ Game Development Platform - Build 2D games directly in the terminal
- ๐ง Extensible Plugin System - Modular architecture for unlimited customization
- ๐จ Dynamic Theming Engine - Hot-swappable themes with Lua scripting
- โก High Performance - Native C engine with Lua binding for optimal speed
Key Statistics:
- ๐ข 140K+ lines of code across C, Lua, and documentation
- ๐๏ธ Modular Architecture with separate engine and scripting layers
- ๐ Cross-Platform support for Linux, macOS, and Windows
- ๐ฆ Self-Contained - Ships with embedded Lua 5.4.4 engine
- Hot-swappable themes - Change entire UI appearance without restart
- Lua-powered templates - Full programmatic control over interface design
- Dynamic content - Real-time updates and interactive elements
- Cross-platform rendering - Consistent appearance across all platforms
- Unicode support - Rich visual elements with box drawing characters
- Event-driven system - React to user input, system events, and custom triggers
- Isolated plugin contexts - Plugins run in separate environments for stability
- Inter-plugin communication - Share data and events between plugins
- Background services - Run plugins independently of UI
- Hot-reload support - Update plugins without restarting application
- Multi-format support - MP3, WAV, FLAC, and more audio formats
- Intelligent file browser - Navigate music libraries with search and filtering
- Advanced playback - Queue management, shuffle, repeat, crossfade
- Real-time controls - Volume, seeking, speed, and equalizer controls
- Audio visualization - Waveform and spectrum analysis displays
- Virtual terminal engine - Advanced text-based graphics rendering
- Input management - Comprehensive keyboard and mouse handling
- Animation framework - Smooth animations with customizable frame rates
- Collision detection - Built-in physics utilities for game development
- State management - Efficient game state and scene management
- Native C core - Optimized performance for complex terminal applications
- Lua integration - Seamless C-Lua binding with minimal overhead
- Memory efficient - Smart resource management and garbage collection
- Asynchronous operations - Non-blocking I/O for responsive interfaces
Experience real-time 3D graphics rendered entirely in terminal characters.
Animated digital clock with customizable themes and timezone support.
RMP follows a layered architecture designed for performance and extensibility:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Lua Application Layer โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Themes โ Plugins โ Templates โ Config โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ RMP Framework (Lua) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ C Engine Core โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Terminal โ Audio โ Input โ VirtualTerm โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Components:
- C Engine Core - High-performance native operations
- RMP Framework - Lua-based application framework
- Plugin System - Modular functionality extensions
- Theme Engine - Dynamic UI and layout management
Required Dependencies:
# Debian/Ubuntu
sudo apt-get install gcc build-essential
# macOS (with Homebrew)
brew install gcc
# Windows (MSYS2/MinGW)
choco install gcc
# Install MinGW-w64 using chocolaty package managerNote: RMP ships with an embedded Lua 5.4.4 engine - no external Lua installation required!
git clone https://github.com/abdorayden/raymp.git
cd raymp/install
./install.sh compile -v && sudo ./install.sh install -v
cd ..
./rmpgit clone https://github.com/abdorayden/raymp.git
cd raymp\install
install.bat compile
install.bat install
cd ..
rmp.exeTest your installation with the built-in demos:
# Start the music player (default)
./rmp
# Check version and help
./rmp --version
./rmp --help./rmpNavigate with arrow keys, press Space to play/pause, Q to quit.
-- hello_world.lua
-- NOTE: rmp framework installed by rmp engine
local api = require("rmp.rmp")
local frame = api.Frame.new()
frame:setFps(60)
local window = api.Window.new(1):createWindow(
"Hello RMP!", 40, 10, 5, 5, nil, nil, nil,
function(x, y, w, h)
return api.Text.new("Welcome to RMP Framework!",
x+2, y+2, api.FGColors.Brights.Green)
end
)
while true do
frame:add(window)
local key = api.Terminal:handleKey()
if key == api.KEY_Q then break end
frame:run(key)
endcat ~/.rmp/init.lua # config file
# this is the place where u configure your rmp audio player
# the (themes/templates) are located in ~/.rmp/themes/ folder
# you can download or create you own template and add it to this path
# and load it in init.lua config filecat ~/.rmp/init.lua # config file
# this is the place where u configure your rmp audio player
# the (plugins) are located in ~/.rmp/plugins/ folder
# you can download or create you own plugin and add it to this path
# and load it in init.lua config fileThe default configuration provides a full-featured music player:
-- Default mode - just run ./rmp
-- Features included:
-- โข File browser with music library scanning
-- โข Playback controls (play, pause, seek, volume)
-- โข Playlist management
-- โข Audio format detection
-- โข Keyboard shortcuts for all functions-- multi_window_app.lua
local api = require("rmp.rmp")
-- Create application frame
local frame = api.Frame.new()
frame:setFps(60)
-- Main window with dynamic content
local mainWindow = api.Window.new(1):createWindow(
"Multi-Window Demo", "w-4", "h-8", 2, 2,
api.BoxDrawing.LightBorder, api.BGColors.NoBrights.Black, nil,
function(x, y, w, h)
local vterm = api.VirtualTerminal.new()
vterm:writeText(x+1, y+1, "Main Content Area", api.FGColors.Brights.White)
vterm:writeText(x+1, y+3, "Press TAB to switch panels", api.FGColors.NoBrights.Yellow)
return vterm
end
)
-- Status bar
local statusWindow = api.Window.new(2):createWindow(
nil, "w-2", 3, 1, "h-3",
api.BoxDrawing.NoBorder, api.BGColors.NoBrights.Blue, nil,
function(x, y, w, h)
local vterm = api.VirtualTerminal.new()
vterm:writeText(x+1, y+1, "Status: Ready", api.FGColors.Brights.White)
return vterm
end
)
-- Event loop
while true do
frame:add(mainWindow)
frame:add(statusWindow)
local key = api.Terminal:handleKey()
if key == api.KEY_Q then break end
frame:run(key)
end-- simple_game.lua
local api = require("rmp.rmp")
local gameState = {
playerX = 10, playerY = 5,
enemies = {{x=20, y=8}, {x=30, y=12}},
score = 0
}
local frame = api.Frame.new()
frame:setFps(30) -- 30 FPS for smooth gameplay
local gameWindow = api.Window.new(1):createWindow(
"RMP Game Engine Demo", 60, 20, 5, 2,
api.BoxDrawing.DoubleBorder, api.BGColors.NoBrights.Black, nil,
function(x, y, w, h)
local vterm = api.VirtualTerminal.new()
-- Draw player
vterm:writeText(x + gameState.playerX, y + gameState.playerY,
"@", api.FGColors.Brights.Green)
-- Draw enemies
for _, enemy in ipairs(gameState.enemies) do
vterm:writeText(x + enemy.x, y + enemy.y,
"X", api.FGColors.Brights.Red)
end
-- Draw HUD
vterm:writeText(x+1, y+1, "Score: " .. gameState.score,
api.FGColors.Brights.Yellow)
return vterm
end
)
-- Game input handling
gameWindow:addEventListener(api.EventType.Keyboard, function(key)
if key == api.KEY_W then
gameState.playerY = math.max(1, gameState.playerY - 1)
elseif key == api.KEY_S then
gameState.playerY = math.min(18, gameState.playerY + 1)
elseif key == api.KEY_A then
gameState.playerX = math.max(1, gameState.playerX - 1)
elseif key == api.KEY_D then
gameState.playerX = math.min(58, gameState.playerX + 1)
end
end)
-- Game loop
while true do
local key = api.Terminal:handleKey()
if key == api.KEY_Q then break end
frame:add(gameWindow)
-- Update game state here (enemy movement, collision detection, etc.)
frame:run(key)
endRMP's (theme/Template) system allows complete customization of the user interface through Lua templates.
-- themes/cyberpunk_theme.lua
-- Cyberpunk-inspired theme with neon colors and futuristic elements
-- the template lua file are returned a table with tables that has a different id's and types
local api = require("rmp.rmp")
return {
-- main window with a children
{
id = 1,
type = "Window",
title = {
type = "Text",
value = "โโโ RMP CYBERPUNK โโโ",
foregroundColor = api.FGColors.Brights.Magenta,
backgroundColor = api.BGColors.NoBrights.Black,
style = api.TextStyle.Bold
},
width = "w",
height = "h",
x = 1,
y = 1,
border = api.BoxDrawing.DoubleBorder,
backgroundColor = api.BGColors.NoBrights.Black,
children = {
-- Header with animated elements
{
id = 2,
type = "Window",
title = {
type = "Text",
value = "",
dynamic = function(ctx)
-- ctx table for the self object
local time = os.date("%H:%M:%S")
return "โก NEURAL INTERFACE ACTIVE โก " .. time
end,
foregroundColor = api.FGColors.Brights.Cyan,
backgroundColor = api.BGColors.NoBrights.Magenta,
style = api.TextStyle.Bold,
},
width = "w - 2",
height = 4,
x = 2,
y = 2,
border = api.BoxDrawing.LightBorder,
backgroundColor = api.BGColors.NoBrights.Magenta
},
-- Main content area
{
id = 3,
type = "Window",
title = {
type = "Text",
value = "โขโโฃ MAIN MATRIX โคโโฅ",
foregroundColor = api.FGColors.Brights.Green,
backgroundColor = api.BGColors.NoBrights.Black,
style = api.TextStyle.Bold
},
width = "w - 4",
height = "h - 12",
x = 3,
y = 7,
border = api.BoxDrawing.HeavyBorder,
backgroundColor = api.BGColors.NoBrights.Black
},
-- Status/info panel
{
id = 4,
type = "Window",
title = {
type = "Text",
value = function()
return "โ SYSTEM STATUS: ONLINE โ "
end,
foregroundColor = api.FGColors.Brights.Yellow,
backgroundColor = api.BGColors.NoBrights.Red,
style = api.TextStyle.Bold,
dynamic = true
},
width = "w - 2",
height = 4,
x = 2,
y = "h - 5",
border = api.BoxDrawing.NoBorder,
backgroundColor = api.BGColors.NoBrights.Red
}
}
}
}RMP's plugin system enables modular functionality through isolated Lua contexts.
-- plugins/system_monitor.lua
-- Real-time system monitoring plugin
-- the plugin lua file are returned function that accept 4 params and return VirtualTerminal object
local api = require("rmp.rmp")
-- params:
-- x,y : left top corner position (x position and y position)
-- xx,yy : right bottom corner position
-- return:
-- VirtualTerminal
local vterm = api.VirtualTerminal.new()
return function(x, y, xx, yy)
local w = xx - x - 1
local h = yy - y - 1
-- Plugin state
local updateInterval = 1.0 -- seconds
local lastUpdate = 0
local systemData = {}
-- Update system information
local function updateSystemInfo()
local currentTime = os.time()
if currentTime - lastUpdate >= updateInterval then
-- Get system info (simplified example)
systemData = {
time = os.date("%Y-%m-%d %H:%M:%S"),
memory = "Memory: 4.2GB / 8.0GB",
cpu = "CPU: 15.3%",
processes = "Processes: 156"
}
lastUpdate = currentTime
end
end
-- Render plugin content
local function render()
vterm:clear()
updateSystemInfo()
-- Header
vterm:writeText(x, y, "โโโ SYSTEM MONITOR โโโ",
api.FGColors.Brights.Cyan)
-- System information
local line = y + 2
for key, value in pairs(systemData) do
vterm:writeText(x, line, value, api.FGColors.NoBrights.White)
line = line + 1
end
-- Instructions
vterm:writeText(x, yy - 2, "Press 'R' to refresh",
api.FGColors.NoBrights.Yellow)
end
-- Event handlers
vterm:onKeyboard(function(key)
if key == api.KEY_R then
lastUpdate = 0 -- Force refresh
render()
end
end)
-- Initial render
render()
return vterm
end-- In your theme or main configuration
-- ~/.rmp/init.lua
return {
-- the default configuration of the sound
settings = {
fps = 60,
volume = 0.5, -- 0 to 1
speed = 1.0, -- 0.25 to 4.0
mode = api.PlaybackMode.ONES, -- playback modes
restart_engine = api.KEY_CTRL_R,
exit = api.KEY_Q,
-- inc or dec
inc_speed = 0.1,
inc_volume = 0.1,
inc_seek = 5
},
soundMap = {
pause_sound = api.KEY_SPACE,
resume_sound = api.KEY_SPACE,
next_sound = api.KEY_N,
prev_sound = api.KEY_P,
vol_up = api.KEY_PLUS,
vol_down = api.KEY_MINUS,
seek_left = api.KEY_LEFT,
seek_right = api.KEY_RIGHT,
speed_up = api.KEY_UP,
speed_down = api.KEY_DOWN,
change_playback_mode = api.KEY_TAB
},
template = "<your template lua file name without extension>",
-- plugins
plugins = {
{
-- if this attr is not nil or exists , the runner ignore activate
themeWindowId = 2, -- the window id that the plugin injected in
isActivated = true,-- isActivated (true activated by default otherwise is not)
activate = api.KEY_E, -- toggle key for activation plugin
switchPluginKey = api.KEY_I, -- switch key for multiple plugins that integrated on the same window id
names = { -- plugins
-- examples
"matrix_digital_rain_effect",
"music_waves",
"text_editor",
"tellme_yourname",
"digital_clock_with_effects",
"3d_cube",
"filebrowser"
}
},
{
themeWindowId = 3,
isActivated = true,
activate = api.KEY_E,
names = {
"center_text"
}
},
{
isActivated = false,
activate = api.KEY_O,
names = {
"other plugins"
}
}
}
}
RMP provides a complete framework for developing 2D games in the terminal.
- Frame-based rendering with customizable FPS (1-120 FPS)
- Event-driven input system supporting all keyboard keys
- Animation systems for smooth character and object movement
- State management for complex game scenes
- Audio integration for sound effects and background music
RMP is designed for maximum compatibility across operating systems and terminal environments.
- โ Linux (Debian, Ubuntu, Arch, CentOS, Fedora)
- โ macOS (Intel and Apple Silicon M1/M2)
- โ Windows (MinGW, MSYS2, WSL, Cygwin)
- โ FreeBSD and other Unix-like systems
- โ Modern terminals (Alacritty, Kitty, iTerm2, Windows Terminal)
- โ Traditional terminals (xterm, GNOME Terminal, Konsole)
// Platform detection in C engine
#ifdef _WIN32
#define PLATFORM_WINDOWS
#define PATH_SEPARATOR "\\"
#elif defined(__APPLE__)
#define PLATFORM_MACOS
#define PATH_SEPARATOR "/"
#elif defined(__linux__)
#define PLATFORM_LINUX
#define PATH_SEPARATOR "/"
#endifMain application frame and event loop management. hight level class for rendering the frame
local frame = api.Frame.new()
frame:setFps(60) -- Set target FPS (1-120)
frame:add(frame) -- Add VirtualTerminal or Frame to it
frame:run(keyEvent) -- Process single frameWindow management and layout system.
local window = api.Window.new(id)
window:createWindow(title, width, height, x, y, border, bgColor, fgColor, contentFunction)
window:setTitle(title) -- Update window title
window:resize(w, h) -- Resize window
window:move(x, y) -- Move window positionLow-level terminal control and input handling.
api.Terminal:clear() -- Clear entire screen
api.Terminal:setCursor(x, y) -- Move cursor position
api.Terminal:hideCursor() -- Hide cursor
api.Terminal:showCursor() -- Show cursor
local key = api.Terminal:handleKey() -- Get pressed key (non-blocking)
api.Terminal:getSize() -- Get terminal dimensionsAdvanced text rendering and virtual screen buffer.
local vterm = api.VirtualTerminal.new()
vterm:writeText(x, y, text, color) -- Write colored text
vterm:drawBox(x, y, w, h, border, color) -- Draw bordered box
vterm:clear() -- Clear virtual buffer
vterm:addEventListener(EventType, callback) -- Add event handlerRich text rendering with styles and colors.
local text = api.Text.new(content, x, y, fgColor, bgColor, style)
text:getText() -- Update text content
text:getPosition() -- Move text position
text:getColor() -- Change text colors
text:getStyle() -- Apply text styleAudio playback and control for music and sound effects.
api.Audio:load(filename) -- Load audio file
api.Audio:play() -- Start playback
api.Audio:pause() -- Pause playback
api.Audio:stop() -- Stop playback
api.Audio:setVolume(level) -- Set volume (0.0-1.0)
api.Audio:seek(position) -- Seek to position in seconds
api.Audio:getPosition() -- Get current playback position
api.Audio:getDuration() -- Get total track duration-- Bright colors
api.FGColors.Brights.Black
api.FGColors.Brights.Red
api.FGColors.Brights.Green
api.FGColors.Brights.Yellow
api.FGColors.Brights.Blue
api.FGColors.Brights.Magenta
api.FGColors.Brights.Cyan
api.FGColors.Brights.White
-- Normal colors
api.FGColors.NoBrights.Black
api.FGColors.NoBrights.Red
-- ... (similar pattern)-- Background colors (similar structure)
api.BGColors.Brights.Black
api.BGColors.NoBrights.Red
-- ... etcapi.colorFromHex("ff0000" , api.FG) -- forground color
api.colorFromHex("ff0000" , api.BG) -- background colorapi.TextStyle.Normal -- Normal text
api.TextStyle.Bold -- Bold text
api.TextStyle.Italic -- Italic text
api.TextStyle.Underline -- Underlined text
api.TextStyle.Strikethrough -- Strikethrough textapi.BoxDrawing.NoBorder -- No border
api.BoxDrawing.LightBorder -- Light single line border
api.BoxDrawing.HeavyBorder -- Heavy single line border
api.BoxDrawing.RoundedBorder -- Rounded corner border-- Letter keys
api.KEY_A, api.KEY_B, ..., api.KEY_Z
-- Number keys
api.KEY_0, api.KEY_1, ..., api.KEY_9
-- Special keys
api.KEY_SPACE -- Space bar
api.KEY_ENTER -- Enter/Return
api.KEY_TAB -- Tab
api.KEY_ESC -- Escape
api.KEY_BACKSPACE -- Backspace
api.KEY_DELETE -- Delete
-- Arrow keys
api.KEY_UP -- Up arrow
api.KEY_DOWN -- Down arrow
api.KEY_LEFT -- Left arrow
api.KEY_RIGHT -- Right arrow
-- Modifier keys
api.KEY_CTRL_A, api.KEY_CTRL_B, ... -- Ctrl combinationscheck the docs from RMP Framework
# Error: Permission denied during install
# Solution: Use sudo for system installation
sudo ./install.sh install -v
# Error: gcc not found
# Solution: Install build tools
sudo apt-get install build-essential gccWe welcome contributions from developers of all skill levels! Here's how to get involved:
- C Code: Follow Linux kernel coding style
- Lua Code: Use 4-space indentation, descriptive variable names
- Comments: Document complex algorithms and public APIs
- Testing: Add tests for new features when possible
- ๐จ Theme Development - Create new visual themes
- ๐ Plugin Development - Build plugins for new functionality
- ๐ฎ Game Development - Create example games and demos
- ๐ Documentation - Improve guides and API documentation
- ๐ Bug Fixes - Fix issues and improve stability
- โก Performance - Optimize engine and framework code
-
Create descriptive commits
git commit -m "feat: add cyberpunk theme with animations" git commit -m "fix: resolve memory leak in audio engine" git commit -m "docs: improve plugin development guide"
-
Test thoroughly
# Run existing tests ./rmp --run-tests # Test on multiple platforms if possible # Test with different terminal emulators
-
Submit pull request
- Describe changes clearly
- Link to related issues
- Include screenshots/videos for visual changes
Please use GitHub Issues for bug reports and feature requests:
- Bug reports: Include system info, steps to reproduce, expected vs actual behavior
- Feature requests: Describe use case, proposed solution, and alternatives considered
For more details, see our Contributing Guide.
see the LICENCE file for details.
RMP is built on the shoulders of amazing open-source projects:
- Lua 5.4.4 - Embedded scripting language
- Miniaudio - Cross-platform audio library
- GCC/Clang - C compiler toolchains
- Terminal emulator developers - For advancing terminal capabilities
Special thanks to the terminal application community for inspiration and feedback.
- ๐ฑ๏ธ Mouse Support - Full mouse interaction support
- ๐ Network Support - TCP/UDP networking for multiplayer games
- ๐จ Advanced Graphics - Improved rendering with better Unicode support
- ๐ Plugin Marketplace - Online repository for themes and plugins
- ๐ Performance Profiler - Built-in performance analysis tools
- โญ Star the repository to show support
- ๐ Report bugs to help improve stability
- ๐ก Suggest features for future development
- ๐ค Contribute code to help build the future of terminal applications
๐ต Start creating amazing terminal applications with RMP today! ๐ต
๐ Quick Start โข ๐ Examples โข ๐ API Docs โข ๐ค Contribute โข โญ GitHub
