GGCode Scripting System
Welcome to GGCode's scripting documentation! This system lets you create custom client and server plugins for MU Online using LuaJIT.
Whether you're building a simple reward window or a complex gameplay mechanic, everything you need is here.
This documentation is actively maintained and updated. Found an issue or something unclear?
Contact GGCode Support - we'll fix it quickly and improve the docs for everyone.
What's Covered
Client Side
Build user interfaces, handle input, communicate with the server.
Topics:
- UI Windows - create and position windows
- UI Rendering - draw colors, text, images, items
- UI Components - buttons, text inputs, slots
- Input System - mouse and keyboard
- Network Events - server communication
- Utilities - HTTP, JSON, sounds, logs
Server Side
Manage players, control game logic, work with databases.
Topics:
- Player Functions - stats, positions, currency
- Items & Monsters - inventory, spawning
- Database & Events - SQL and game events
- Utilities - commands, effects, party/guild
Working Examples
Complete, ready-to-use plugins you can learn from.
- Daily Reward System - basic plugin with database
- Teleport System - advanced UI with scrolling lists
The Essential Rules
1. Packet IDs Must Match
Client and server must use identical packet IDs:
// Client
PluginPacket.MyPlugin = 15100
// Server
PluginPacket.MyPlugin = 15100 -- Same ID!
Always use IDs >= 15000 to avoid game conflicts.
2. Validate in SQL Callbacks
Players can disconnect while SQL runs. Always check:
SQLQuery(query, function(q)
-- Is player still online?
if GetObjectConnected(aIndex) ~= OBJECT_ONLINE then
return
end
-- Name still matches?
if GetObjectName(aIndex) ~= playerName then
return
end
-- Safe to proceed
end)
3. Connection States
OBJECT_OFFLINE = 0 -- Disconnected
OBJECT_CONNECTED = 1 -- Connected
OBJECT_LOGGED = 2 -- Logged in
OBJECT_ONLINE = 3 -- In game ← Use this!
Always check for OBJECT_ONLINE.
4. UI Groups
UI_GROUP_SERVER = 0 -- Server select
UI_GROUP_SELECT = 1 -- Character select
UI_GROUP_INGAME = 2 -- In game ← Most common
Quick Tips
Client:
packet:free() -- Always free packets!
LogPrint("[MyPlugin] Debug info")
if not InputCheckChatOpen() then
-- Process hotkeys
end
Server:
LogColor(2, "[MyPlugin] Success!") -- Colored logs
SetObjectStrength(aIndex, 5000)
UserCalcAttribute(aIndex) -- Recalculate!
UserInfoSend(aIndex) -- Update client!
Basic Plugin Structure
-- CLIENT
MyPlugin = {
index = GetWindowIndex(),
group = UI_GROUP_INGAME,
}
PluginPacket.MyPlugin = 15100
BridgeFunction:push("OnLoad", function()
-- Create UI
end)
MagicWorld:pushRecv(PluginPacket.MyPlugin, function(packet)
-- Handle server data
packet:free()
end)
-- SERVER
MyPlugin = {}
MyPlugin.ScriptVersion = "1.0.0"
PluginPacket.MyPlugin = 15100
BridgeFunction:push("OnLoadScript", function()
-- Initialize
end)
MagicWorld:pushRecv(PluginPacket.MyPlugin, function(aIndex, packet)
-- Handle client request
end)
How to Learn
New to this?
- Start with UI Windows guide
- Try the Daily Reward example
- Read Player Functions guide
- Build your own plugin
Already know Lua? Jump to the examples and use the guides as reference.
Debugging
Client:
LogPrint("Debug: " .. tostring(value))
NoticeSend(1, "Debug message")
Server:
LogColor(3, "Debug info")
NoticeSend(aIndex, 1, "Message")
LuaJIT Limits
- No goto statements
- Watch upvalues in large loops
- Limit closures in SQL callbacks
- Prefer local tables
Where to Start?
Pick what you need:
- Creating UI? → Client Side guides
- Game logic? → Server Side guides
- Learn by doing? → Examples section
All guides have working code you can use right away.
Maintained by GGCode | Updated regularly with community feedback