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.