Community listing page, reviews here may not be monitored by the author.
High Level Peripherals
No reviews yet
This is a fork of the mod Tom's Peripherals with minor additions and fixes
Community voices
Reviews
No reviews yet. Be the first to review this project!
Get it on
Available Platforms
Compatibility
Supported Environments
Must be installed on both the client and the server.
About
Project Details
For authors
Embed Badge
If you're the author of this project, you can embed a live badge anywhere that supports HTML or Markdown. It updates automatically whenever ratings change.
Use HTML for any page that supports it, or Markdown for README files and Markdown-based descriptions.
Identifiers
Platform IDs
Resources
External Links
About
Description
High Level Peripherals
A CC:Tweaked monitor peripheral that actually keeps up with what you want to build.
A fork of Tom's Peripherals, rebuilt to be far more usable, stable, and complete — bigger screens, real GPU-rendered shaders, full mouse/touch input, and a cleaner API that doesn't fight you.
✨ Features
🖥️ Big, sharp monitors
Build arrays up to 32x32 blocks (admin-adjustable up to 64x64), with per-block resolution up to 4096x4096. Draw with a full 2D API — filled shapes, gradients, text with custom fonts, image loading, double buffering — all running server-side, synced to every client automatically.
⚡ Real GPU shaders, not Lua math
Write a small GLSL-like shader once and it renders live on every viewer's own graphics card, at their own framerate, completely decoupled from the server tick. No more choking the game with per-pixel Lua raymarching — the shader engine handles that with zero Lua involved per pixel. Includes first-class raytracing primitives (sphere/plane/box intersection) so you're not hand-rolling ray math from scratch.
gpu.compileShader([[
color = vec3(uv.x, uv.y, sin(time));
]])
That's it — it's already rendering.
🖱️ Full mouse input
Click, right-click, drag, and scroll directly on a monitor's screen face, with pixel-accurate coordinates delivered straight to your script. Respects whatever controls the player has configured — no hardcoded key assumptions. Perfect for building actual interactive UIs, not just static displays.
🎮 3D immediate-mode rendering
An OpenGL-1-style API (glBegin/glVertex/glTranslate/glRotate/lighting) for
building real 3D scenes on a monitor without writing a shader — great for models,
diagrams, or simple games.
🔆 Brightness control
Scale a monitor's output brightness in nits, from dim ambient displays to eye-searingly bright — applies to both drawn pixels and live shaders.
🧠 Room to build big
Generous default VRAM budget (~2 GiB per screen) shared across framebuffers, images, and shader textures, with server-configurable limits for bigger builds.
Why this fork?
Tom's Peripherals gave monitors and a GPU peripheral, but hit real ceilings fast —
low resolution limits, no shader rendering, no mouse input, and a handful of
long-standing multiblock/sync bugs. High Level Peripherals keeps the same familiar
peripheral.find("tm_monitor") API you already know, and pushes every one of those
ceilings out — so your builds stop being limited by the peripheral and start being
limited by your imagination.
Getting started
local gpu = peripheral.find("tm_monitor")
gpu.fill(0x000000)
gpu.drawText(10, 10, "Hello, HLPS!", 0xFFFFFF)
Full API reference below.
Docs
tm_monitor Lua API Reference
Complete reference for the monitor peripheral: 2D drawing, text, images, the 3D immediate-mode API, mouse/scroll input, and the shader engine.
1. Limits
| Limit | Value |
|---|---|
| Grid size | Up to 32x32 blocks by default (maxScreenSize, 1-64). Over limit → every call throws. |
gpu.setSize(n) |
64–4096 px/axis, default 1024. |
gpu.setGpuResolution(w, h) |
64–4096 px/axis, or (0,0) for auto. |
| VRAM budget | ~2 GiB default (maxVRAMSize), shared across framebuffer/images/buffers/textures. |
2. Color format
Packed 0xRRGGBB ints, or (r,g,b[,a]) 0-255 each.
- Alpha
0or255→ opaque. - Alpha
1..254→ source-over blend:out = (src*a + dst*(255-a)) / 255. getPixel/getpxreturn0xRRGGBB(alpha stripped).
3. Sizing
| Call | Effect |
|---|---|
gpu.setSize(n) |
Per-block resolution, one axis. Total canvas is (blocksWide*n) x (blocksTall*n). |
gpu.getSize() |
→ width, height, cols, rows, blockSize. |
gpu.getResolution() |
→ width, height. |
gpu.refreshSize() |
Forces a re-scan of the array's grid layout. |
gpu.debugTiling() |
→ string dump of live server-side tiling state, for diagnosing a wrong-looking array. |
Keep setSize low (64-256) if drawing per-pixel in Lua — use the shader engine
(section 8) instead for anything procedural.
4. Basic 2D drawing
All coordinates are 1-based.
| Call | Notes |
|---|---|
gpu.fill([color]) |
Fills the canvas. Default black. |
gpu.clear([color]) |
Alias of fill. |
gpu.setPixel(x, y, color) |
Out-of-bounds writes ignored. |
gpu.getPixel(x, y) |
→ int, 0 if out of bounds. |
gpu.filledRectangle(x, y, w, h, [color]) |
Throws if out of bounds. |
gpu.rectangle(x, y, w, h, [color]) |
Outline only. |
gpu.line(x1, y1, x2, y2, [color]) |
Bresenham. |
gpu.lineS(x1, y1, x2, y2, [color]) |
Alternate algorithm. |
gpu.circle(cx, cy, r, [color]) |
Outline. |
gpu.fillCircle(cx, cy, r, [color]) |
Filled. |
gpu.triangle(x1,y1, x2,y2, x3,y3, [color]) |
Outline. |
gpu.fillTriangle(x1,y1, x2,y2, x3,y3, [color]) |
Filled. |
gpu.gradientRectangle(x, y, w, h, c1, c2, [vertical]) |
Linear interpolation between two colors. |
gpu.copy(srcX, srcY, w, h, dstX, dstY) |
Overlap-safe. Capped at 64M px. |
gpu.scroll(dx, dy, [fillColor]) |
Shifts canvas; exposed area filled. Same cap. |
gpu.drawBuffer(x, y, w, scale, ...pixels) |
Row-major pixels as vararg numbers, not a table. |
5. Double buffering
gpu.setDoubleBuffered(true)
-- ... draw calls ...
gpu.flush() -- presents + syncs
gpu.sync() pushes the framebuffer directly (throttled internally) — not usually
needed outside double-buffering/shader flows.
6. Text
| Call | Notes |
|---|---|
gpu.drawText(x, y, text, [fg=-1], [bg=-1], [size=1], [pad=1]) |
-1 skips that layer. |
gpu.drawTextSmart(x, y, text, [fg], [bg], [forceUnicode=false], [size=1], [pad=1]) |
Auto ASCII/unicode fonts (ASCII draws at 2x size). |
gpu.getTextLength(text, [size=1], [pad=1]) |
→ pixel width. |
gpu.getFont() |
→ name, editable. |
gpu.setFont(name) |
No-op if font doesn't exist. |
gpu.drawChar(x, y, charIndex, [fg], [bg], [size=1]) |
Draws one glyph, 1-based index. |
gpu.addNewChar(char, width, ...16 numbers) |
→ int. Font must be editable. |
gpu.delChar(char) / gpu.freeChars() / gpu.clearChars() |
Glyph management. |
gpu.setFontDefaultCharID(id) / gpu.getFontDefaultCharID() |
Fallback glyph. |
7. Images and buffers
| Call | Returns |
|---|---|
gpu.newImage(w, h) |
Blank LuaImage. |
gpu.imageFromBuffer(w, ...pixels) |
LuaImage from raw pixel data. |
gpu.decodeImage(bufferRef) / gpu.decodeImage(...bytes) |
Decodes PNG/etc. |
gpu.newBuffer([initialCapacity=32]) |
Growable LuaByteBuffer. |
gpu.drawImage(x, y, image) |
Draws, clipped to canvas. |
All charge VRAM (w*h*4 bytes) up front and throw if over budget.
8. The shader engine
Write a small GLSL-like program once; it runs per-pixel on the real GPU, no Lua involved.
gpu.compileShader([[
float sdSphere(vec3 p, float r) { return length(p) - r; }
uniform float speed;
color = vec3(uv.x, uv.y, sin(time * speed));
]])
gpu.setUniform("speed", 2.0)
There's no main — code after the function defs runs top-to-bottom; color is the
pixel output. gpu.clearShader() returns to normal 2D drawing.
gpu.isGpuMode()→truewhile a shader is live.gpu.setUniform(name, value)/gpu.setUniform3(name, x, y, z)— live-update, no recompile.gpu.setGpuResolution(w, h)— resolution the shader renders at (independent ofsetSize). Match your array'scols:rowsshape or don't call it.
A live shader has no ongoing tie to the computer that started it — it stops only if
the last attached computer disconnects, or you call gpu.clearShader().
texture() isn't GPU-accelerated yet — a texture-sampling shader compiles fine
but won't auto-render. Drive it yourself:
gpu.compileShader(src)
gpu.uploadTexture(0, w, h, pixels)
while true do
gpu.runShader(os.clock())
gpu.sync()
sleep(0)
end
Shader language
- Two types:
float,vec3. - Predefined:
color(write this),uv(.x/.y0..1,.y=0at top),res,time. uniform <float|vec3> name;- Functions:
<float|vec3> name(params) { ...; return expr; }. No recursion. Must appear before any other top-level statement, includinguniformdeclarations. - Control flow:
if/else,for (init; cond; update) {},break;,return expr;. - Operators:
+ - * /, unary- !, comparisons,&& ||,.x .y .zswizzle.vec3 * floatworks;float * vec3does not. - Built-ins:
vec3(f,f,f),sin cos tan sqrt abs floor fract exp pow mod min max step clamp mix smoothstep length dot cross normalize reflect,texture(slot, u, v). - Raytracing builtins (return nearest positive hit distance, or
-1.0for a miss):intersectSphere(ro, rd, center, radius),intersectPlane(ro, rd, planeY),intersectBox(ro, rd, center, halfSize).
9. Memory
| Call | Returns |
|---|---|
gpu.getUsedMemory() |
Bytes currently used. |
gpu.getMaxMemory() |
VRAM budget for this peripheral. |
10. Mouse & scroll input
Fires only while looking at the screen face with no GUI open. Sneaking has no effect. Keyboard input isn't captured here — that's a separate keyboard peripheral.
| Event | Args | Trigger |
|---|---|---|
tm_monitor_touch |
side, x, y, soft |
Whichever button is bound to "use" (right-click by default). soft is always false. |
tm_monitor_mouse |
side, x, y, button, action |
Mouse button press/release. |
tm_monitor_scroll |
side, x, y, dir |
dir is 1 (up) or -1 (down). |
tm_monitor_drag |
side, x, y, button |
Cursor moved this tick while held. Once per client tick. |
x, y are screen-absolute (1-based) across the whole array.
while true do
local ev, side, x, y, button, action = os.pullEvent("tm_monitor_mouse")
gpu.setPixel(x, y, 0xFF0000)
gpu.sync()
end
11. 3D immediate-mode API
gpu3d = gpu.createWindow3D(...)
gpu3d.glFrustum(70, 0.1, 100)
gpu3d.glLoadIdentity()
gpu3d.glTranslate(0, 0, -5)
gpu3d.glDirLight(0, -1, 0)
gpu3d.glBegin(4) -- triangles
gpu3d.glColor(0xFF0000)
gpu3d.glVertex(-1, -1, 0)
gpu3d.glVertex( 1, -1, 0)
gpu3d.glVertex( 0, 1, 0)
gpu3d.glEnd()
gpu3d.render()
gpu3d.sync()
| Call | Notes |
|---|---|
glFrustum(fov, near, far) |
Perspective projection. |
glDirLight(x, y, z) |
Directional light. |
glLoadIdentity() / glPushMatrix() / glPopMatrix() |
Model matrix stack. |
glTranslate / glScale / glRotate(angleDeg, x,y,z) |
|
glBegin([mode=4]) / glEnd() |
Start/finish a primitive. |
glVertex(x,y,z) |
Appends a vertex with current color/UV. |
glTexCoord(u,v) |
UV for the next vertex. |
glColor(color) |
Packed int or (r,g,b[,a]). |
glEnable(3553) / glDisable(3553) |
Only GL_TEXTURE_2D supported. |
glGenTextures() / glDeleteTextures / glBindTexture / glTexImage |
Texture management. |
getConstants() |
GL constant name→value table. |
render() |
Culls, lights, clips, projects, sorts, blits since last clear(). |
clear() |
Wipes canvas + triangles + resets matrix/depth buffer. |
12. Performance
All drawing is server-side Java, always — singleplayer, LAN, or dedicated. Pushing pixels to the client is the one real client cost, done via a bulk memory copy.
Per-pixel Lua drawing (raymarching, plasma, etc.) will choke a client — use the shader engine instead, which runs on the GPU with zero Lua per pixel.
13. Brightness (nits)
gpu.setBrightness(200) -- 2x normal
print(gpu.getBrightness())
nits / 100 scales final pixel output — 100 is default (1.0x). Applies to both CPU
drawing and GPU shaders. Values that would exceed 255 clip instead of wrapping. Range
is server-configurable (minBrightnessNits/maxBrightnessNits, default 10–400).
Screenshots
Gallery
Versions
Files
Relations
Project Relations
More like this
Similar Mods
Suggestions use data such as tags, dependencies, dependents, descriptions, titles, and more to rank how much they overlap with this mod.
On ModDex
Community snapshot
By the numbers
Statistics
Want to reach Minecraft players?
We're looking for a server hosting partner to feature here and other parts of the site. Interested? Send us a message!
Get in touchGet it on
Available Platforms
On ModDex
Community snapshot
By the numbers
Statistics
Resources