Overview
The Scripting API allows you to define custom behavior for objects and NPCs in GRPG. Scripts are written in Go and registered during server initialization.
Registration Functions
These functions register callbacks that execute when players interact with game elements.
OnObjInteract
func OnObjInteract(objId ObjConstant, fnc ObjInteractFunc)
Registers a callback function that runs when a player interacts with an object.
The object ID to attach this script to (e.g., BERRY_BUSH)
Callback function with signature: func(ctx *ObjInteractCtx)
Example:
OnObjInteract(BERRY_BUSH, func(ctx *ObjInteractCtx) {
if ctx.GetObjState() == 0 {
// Bush is empty
return
}
// Give player berries
ctx.PlayerInvAdd(BERRIES)
ctx.PlayerAddXp(shared.Foraging, 5)
// Set bush to empty state
ctx.SetObjState(0)
// Respawn berries after 100 ticks
ctx.AddTimer(100, func() {
ctx.SetObjState(1)
})
})
OnTalkNpc
func OnTalkNpc(npcId NpcConstant, fnc NpcTalkFunc)
Registers a callback function that runs when a player talks to an NPC.
The NPC ID to attach this script to (e.g., TEST)
Callback function with signature: func(ctx *NpcTalkCtx)
Example:
OnTalkNpc(TEST, func(ctx *NpcTalkCtx) {
ctx.TalkNpc("Hello, adventurer!")
ctx.TalkPlayer("Hi there!")
ctx.TalkNpc("Welcome to GRPG.")
ctx.StartDialogue()
})
SpawnNpc
func SpawnNpc(npcId NpcConstant, x uint32, y uint32, wanderRange uint8)
Spawns an NPC at the specified position during server initialization.
The NPC type to spawn (e.g., TEST)
How many tiles the NPC can wander from spawn point (0 = stationary)
Example:
// Spawn a test NPC at (100, 100) that doesn't wander
SpawnNpc(TEST, 100, 100, 0)
ObjInteractCtx
Context object passed to object interaction callbacks.
GetObjState
func (o *ObjInteractCtx) GetObjState() uint8
Returns the current state value of the object.
Returns: Current state (0-255)
SetObjState
func (o *ObjInteractCtx) SetObjState(new uint8)
Sets the object’s state and automatically sends update packets to nearby players.
Example:
ctx.SetObjState(1) // Set object to state 1
PlayerInvAdd
func (o *ObjInteractCtx) PlayerInvAdd(itemId ItemConstant)
Adds an item to the player’s inventory and sends an inventory update packet.
The item to add (e.g., BERRIES)
Example:
ctx.PlayerInvAdd(BERRIES) // Give player berries
PlayerAddXp
func (o *ObjInteractCtx) PlayerAddXp(skill shared.Skill, xpAmount uint32)
Adds experience points to a player’s skill and sends a skill update packet.
The skill to add XP to (e.g., shared.Foraging)
Example:
ctx.PlayerAddXp(shared.Foraging, 10) // Give 10 foraging XP
AddTimer
func (o *ObjInteractCtx) AddTimer(ticks uint32, fn TimerFunc)
Schedules a function to execute after a specified number of game ticks.
Number of ticks to wait before execution (600 ticks = 1 minute at 10 TPS)
Function to execute: func()
Example:
// Respawn berries after 100 ticks
ctx.AddTimer(100, func() {
ctx.SetObjState(1)
})
NpcTalkCtx
Context object passed to NPC talk callbacks.
TalkNpc
func (n *NpcTalkCtx) TalkNpc(msg string)
Adds an NPC dialogue line to the conversation queue.
Example:
ctx.TalkNpc("Welcome to my shop!")
TalkPlayer
func (n *NpcTalkCtx) TalkPlayer(msg string)
Adds a player dialogue line to the conversation queue.
The message the player says
Example:
ctx.TalkPlayer("What do you sell?")
StartDialogue
func (n *NpcTalkCtx) StartDialogue()
Begins the dialogue sequence, sending the first message to the player.
Must be called after adding dialogue lines to display them.
Example:
ctx.TalkNpc("Hello!")
ctx.TalkPlayer("Hi!")
ctx.StartDialogue() // Required to show the dialogue
ClearDialogueQueue
func (n *NpcTalkCtx) ClearDialogueQueue()
Clears all dialogue and closes the dialogue box.
Constants
These type-safe constants identify game elements.
Object Constants
type ObjConstant uint16
const (
BERRY_BUSH ObjConstant = 1
)
NPC Constants
type NpcConstant uint16
const (
TEST NpcConstant = 1
)
Item Constants
type ItemConstant uint16
const (
BERRIES ItemConstant = 1
)
These constants are currently manually defined but will be auto-generated from .gcfg files in the future.
Complete Example
Here’s a complete script that creates a harvestable berry bush:
package main
import (
"server/scripts"
"server/shared"
)
func init() {
// Register berry bush interaction
scripts.OnObjInteract(scripts.BERRY_BUSH, func(ctx *scripts.ObjInteractCtx) {
// Check if bush has berries (state 1)
if ctx.GetObjState() == 0 {
// Bush is empty, do nothing
return
}
// Give player rewards
ctx.PlayerInvAdd(scripts.BERRIES)
ctx.PlayerAddXp(shared.Foraging, 5)
// Set bush to depleted state
ctx.SetObjState(0)
// Respawn berries after 100 ticks (~10 seconds at 10 TPS)
ctx.AddTimer(100, func() {
ctx.SetObjState(1)
})
})
// Register NPC conversation
scripts.OnTalkNpc(scripts.TEST, func(ctx *scripts.NpcTalkCtx) {
ctx.TalkNpc("Hello, adventurer!")
ctx.TalkPlayer("What can you tell me about foraging?")
ctx.TalkNpc("Try interacting with berry bushes to gather berries!")
ctx.StartDialogue()
})
// Spawn the NPC at position (100, 100)
scripts.SpawnNpc(scripts.TEST, 100, 100, 5)
}
ScriptManager
The ScriptManager is created automatically by the server and manages all registered scripts.
type ScriptManager struct {
InteractScripts map[ObjConstant]ObjInteractFunc
NpcTalkScripts map[NpcConstant]NpcTalkFunc
}
You don’t need to interact with this directly - use the registration functions instead.