Skip to main content

Rendering Visual Content

Now that you know how to create windows, let's make them actually show something! This guide covers drawing colors, text, images, and game items.

Colors - The RGBA Function​

Everything visual needs a color. Here's how you make one:

RGBA(r, g, b, a)

Parameters:

  • r - Red (0-255)
  • g - Green (0-255)
  • b - Blue (0-255)
  • a - Alpha/Transparency (0=invisible, 255=solid)

Returns: Encoded color value

Common Colors​

local white = RGBA(255, 255, 255, 255)
local black = RGBA(0, 0, 0, 255)
local red = RGBA(255, 0, 0, 255)
local green = RGBA(0, 255, 0, 255)
local blue = RGBA(0, 0, 255, 255)
local yellow = RGBA(255, 255, 0, 255)
local purple = RGBA(128, 0, 128, 255)
local orange = RGBA(255, 165, 0, 255)
local gray = RGBA(192, 192, 192, 255)

-- Transparency examples
local transparent = RGBA(255, 255, 255, 0)
local semiTransparent = RGBA(255, 255, 255, 128)

Rendering Window Borders​

UIRenderWindow(window, x, y, w, h, type)

Parameters:

  • window - Window object
  • x, y - Relative position
  • w, h - Width and height
  • type - Border type (0=default)

This renders the game's default window border/background style.

function MyPlugin.renderWindow(window)
-- Render window border
UIRenderWindow(window, 0, 0, window.w, window.h, 0)
end

Rendering Colored Rectangles​

UIRenderColor(x, y, w, h, color, convert)

Parameters:

  • x, y - Position on screen
  • w, h - Width and height
  • color - Color (use RGBA())
  • convert - Color conversion (optional)

Examples​

-- Render a red rectangle
UIRenderColor(100, 100, 200, 50, RGBA(255, 0, 0, 255))

-- Render a semi-transparent background
UIRenderColor(0, 0, 800, 600, RGBA(0, 0, 0, 180))

-- Inside a window (using relative coordinates):
function MyPlugin.renderWindow(window)
-- Dark background
window:renderColor(10, 10, window.w-20, window.h-20, RGBA(0, 0, 0, 200))

-- Green bar
window:renderColor(10, 50, 280, 30, RGBA(0, 255, 0, 255))
end

Rendering Text​

UIRenderText(text, x, y, w, h, sort, color, font, convert)

Parameters:

  • text - Text to render
  • x, y - Position
  • w, h - Area size
  • sort - Alignment (1=left, 2=right, 4=center)
  • color - Text color (use RGBA())
  • font - Font object (FontS, FontM, FontL, FontLB)
  • convert - Color conversion (optional)

Text Alignment​

1 = Left
2 = Right
4 = Center

Available Fonts​

These fonts are created in Main.lua:

FontS  = Small font
FontM = Medium font
FontL = Large font
FontLB = Large bold font

Text Examples​

-- Centered white text
UIRenderText("Welcome!", 100, 100, 200, 30, 4, RGBA(255,255,255,255), FontL)

-- Left-aligned green text
UIRenderText("HP: 100", 50, 200, 150, 20, 1, RGBA(0,255,0,255), FontM)

-- Right-aligned red text
UIRenderText("Mana: 50", 50, 220, 150, 20, 2, RGBA(255,0,0,255), FontM)

-- Inside a window:
function MyPlugin.renderWindow(window)
-- Centered title
window:renderText(
"My Plugin",
0, 10,
window.w, 30,
4, -- Center
RGBA(255, 255, 0, 255), -- Yellow
FontL
)

-- Left-aligned text
window:renderText(
"Level: 400",
20, 50,
window.w-40, 20,
1, -- Left
RGBA(255, 255, 255, 255),
FontM
)

-- Right-aligned text
window:renderText(
"Reset: 10",
20, 70,
window.w-40, 20,
2, -- Right
RGBA(192, 192, 192, 255),
FontM
)
end

Custom Fonts​

Want to use a different font?

-- UIFontCreate(name, size, bold)
-- Creates a custom font
local MyFont = UIFontCreate("Arial", 16, 1) -- Arial 16pt bold

-- Use the font
UIRenderText("My text", 100, 100, 200, 30, 4, RGBA(255,255,255,255), MyFont)

-- UIFontDelete(font)
-- Removes a font from memory
UIFontDelete(MyFont)

Loading and Rendering Images​

Texture Filter Constants​

GL_NEAREST = 0x2600  -- No smoothing (pixelated)
GL_LINEAR = 0x2601 -- Smoothing (blurred)

Texture Wrap Constants​

GL_CLAMP = 0x2900
GL_REPEAT = 0x2901
GL_CLAMP_TO_EDGE = 0x812F

Loading Images​

UILoadImage(path, index, filter, wrapMode)

Parameters:

  • path - Image path (e.g., "Data/MyImage.jpg")
  • index - Unique ID for the image
  • filter - Filter mode (GL_NEAREST or GL_LINEAR)
  • wrapMode - Wrap mode (optional)
local IMG_MY_LOGO = 10001  -- Unique ID
UILoadImage("Data/Custom/logo.png", IMG_MY_LOGO, GL_LINEAR)

Rendering Images​

UIRenderImage(index, x, y, w, h, sw, sh, ow, oh, convert)

Parameters:

  • index - Image ID (from UILoadImage)
  • x, y - Position
  • w, h - Render size
  • sw, sh - Source width/height (optional, for sprite sheets)
  • ow, oh - Offset in source image (optional, for sprite sheets)
  • convert - Color conversion (optional)

Image Examples​

-- Render entire image
UIRenderImage(IMG_MY_LOGO, 100, 100, 200, 150)

-- Render part of an image (sprite sheet)
-- sw, sh = size of the part
-- ow, oh = offset in the original image
UIRenderImage(IMG_MY_LOGO, 100, 100, 32, 32, 32, 32, 64, 0)

-- Inside a window:
function MyPlugin.renderWindow(window)
-- Render logo at the top
window:renderImage(IMG_MY_LOGO, 10, 10, 280, 100)
end

Rendering Animated GIFs​

UIRenderImageGif(index, x, y, w, h, convert, reflect)
local IMG_MY_GIF = 10002
UILoadImage("Data/Custom/animation.gif", IMG_MY_GIF)
UIRenderImageGif(IMG_MY_GIF, 100, 100, 64, 64)

Rendering Game Items​

Want to show an item sprite from the game?

UIRenderItem(x, y, w, h, itemIndex, level, newOption, setOption, scale)

Parameters:

  • x, y - Position
  • w, h - Size
  • itemIndex - Item index
  • level - Item level (0-15)
  • newOption - Excellent/Ancient options
  • setOption - Set option
  • scale - Render scale (optional)

Calculating Item Index​

itemIndex = (Section * 512) + Index

Examples:

  • Kris = Section 0, Index 0 = (0*512)+0 = 0
  • Short Sword = Section 0, Index 1 = (0*512)+1 = 1

Item Rendering Examples​

-- Render Kris +0
UIRenderItem(100, 100, 32, 32, 0, 0, 0, 0)

-- Render Kris +15
UIRenderItem(100, 150, 32, 32, 0, 15, 0, 0)

-- Render item with excellent (newOption=63 = all exc options)
UIRenderItem(100, 200, 32, 32, 0, 15, 63, 0)

-- Inside a window (render inventory):
function MyPlugin.renderWindow(window)
local startX = 20
local startY = 50
local slotSize = 36
local itemsPerRow = 8

for i = 0, 31 do
local row = math.floor(i / itemsPerRow)
local col = i % itemsPerRow
local x = startX + (col * slotSize)
local y = startY + (row * slotSize)

-- Render empty slot
window:renderColor(x, y, 32, 32, RGBA(50, 50, 50, 200))

-- If there's an item, render it
-- (static example, normally would come from server data)
if i == 0 then
window:renderItem(x+2, y+2, 28, 28, 0, 15, 0, 0)
end
end
end

Window Render Methods​

All these methods use coordinates relative to the window:

-- Render text (relative to window)
window:renderText("Text", 10, 10, 200, 30, 4, RGBA(255,255,255,255), FontM)

-- Render colored rectangle (relative to window)
window:renderColor(10, 10, 280, 50, RGBA(100, 100, 100, 255))

-- Render image (relative to window)
window:renderImage(IMG_MY_LOGO, 10, 10, 100, 100)

-- Render GIF (relative to window)
window:renderImageGif(IMG_MY_GIF, 10, 10, 64, 64)

-- Render item (relative to window)
window:renderItem(10, 10, 32, 32, 0, 15, 0, 0)

-- Render asset (pre-defined system image)
window:renderAsset(GlobalAsset.buttonN, 10, 10, 100, 30)

Complete Example - Advanced Rendering​

Here's a window that shows off different rendering techniques:

MyRenderDemo = {
index = GetWindowIndex(),
group = UI_GROUP_INGAME,
}

-- Load images
local IMG_DEMO_BG = 20001
local IMG_DEMO_ICON = 20002

BridgeFunction:push("OnLoad", function()
-- Load images
UILoadImage("Data/Custom/background.jpg", IMG_DEMO_BG, GL_LINEAR)
UILoadImage("Data/Custom/icon.png", IMG_DEMO_ICON, GL_LINEAR)
end)

function MyRenderDemo.renderWindow(window)
-- 1. Render window border
UIRenderWindow(window, 0, 0, window.w, window.h, 0)

-- 2. Render background image
window:renderImage(IMG_DEMO_BG, 10, 40, window.w-20, window.h-50)

-- 3. Render title with background
window:renderColor(0, 0, window.w, 35, RGBA(0, 0, 0, 200))
window:renderText(
"Rendering Demo",
0, 10, window.w, 30,
4, -- Center
RGBA(255, 215, 0, 255), -- Gold
FontL
)

-- 4. Render icon
window:renderImage(IMG_DEMO_ICON, window.w-40, 5, 32, 32)

-- 5. Render progress bar
local barX = 20
local barY = 50
local barW = window.w - 40
local barH = 20
local progress = 0.75 -- 75%

-- Bar background
window:renderColor(barX, barY, barW, barH, RGBA(50, 50, 50, 255))
-- Progress bar
window:renderColor(barX, barY, barW * progress, barH, RGBA(0, 255, 0, 255))
-- Bar text
window:renderText(
"75%",
barX, barY, barW, barH,
4, -- Center
RGBA(255, 255, 255, 255),
FontM
)

-- 6. Render item list
local itemsY = 80
for i = 1, 5 do
local itemY = itemsY + ((i-1) * 40)

-- Item background
local bgColor = (i % 2 == 0) and RGBA(40,40,40,200) or RGBA(30,30,30,200)
window:renderColor(20, itemY, window.w-40, 35, bgColor)

-- Item icon
window:renderItem(25, itemY+2, 32, 32, i-1, 15, 0, 0)

-- Item name
window:renderText(
"Item " .. i,
65, itemY+5, 150, 25,
1, -- Left
RGBA(255, 255, 255, 255),
FontM
)

-- Quantity
window:renderText(
"x" .. (i * 10),
window.w-100, itemY+5, 80, 25,
2, -- Right
RGBA(200, 200, 200, 255),
FontM
)
end

-- 7. Render player info
local infoY = window.h - 35
window:renderColor(10, infoY, window.w-20, 25, RGBA(0, 0, 100, 180))
window:renderText(
"Player: John | Level: 400 | Reset: 10",
15, infoY+3, window.w-30, 20,
1,
RGBA(255, 255, 255, 255),
FontM
)
end

function MyRenderDemo.updateWindow(window)
return window.state == 1
end

Quick Tips​

  1. Load images in OnLoad - Not every frame!
  2. Use window:render methods - They handle relative coordinates automatically
  3. Semi-transparent backgrounds look professional - Use alpha values around 180-220
  4. Cache RGBA values - Don't create them every frame
  5. Text rendering is expensive - Avoid rendering huge amounts of text
  6. Use appropriate fonts - FontS for small text, FontL for titles

That's rendering covered! Next up: adding interactive components like buttons and text inputs.