Skip to main content

Server Event Hooks

Event hooks allow you to customize the behavior of events on the server side. These hooks are defined in the event property of your server module and apply to all events in your game.

Usage

import { RpgEvent, RpgPlayer, RpgMap, RpgEventHooks, defineModule } from '@rpgjs/server'

const event: RpgEventHooks = {
    onInit(event: RpgEvent) {
        console.log(`Event ${event.id} initialized`)
    },
    onAction(event: RpgEvent, player: RpgPlayer) {
        console.log(`Player ${player.name} interacted with ${event.id}`)
    }
}

export default defineModule({
    event
})

Available Hooks

onInit

Description: Called when an event is initialized on the map. Use onInit for base event setup that does not depend on a change-detection cycle yet: initial graphic, movement route, speed, direction, attached shapes, or default metadata. Parameters:
  • event: RpgEvent - The event instance
Example:
const event: RpgEventHooks = {
    onInit(event: RpgEvent) {
        console.log(`🎯 Event ${event.id} initialized`)
    }
}

onAction

Description: Called when a player interacts with an event (typically by pressing the action key) Parameters:
  • event: RpgEvent - The event instance
  • player: RpgPlayer - The player who interacted with the event
Example:
const event: RpgEventHooks = {
    async onAction(event: RpgEvent, player: RpgPlayer) {
        console.log(`${player.name} interacted with ${event.name}`)

        switch (event.name) {
            case 'treasure-chest':
                if (!event.getVariable('isOpened')) {
                    event.setVariable('isOpened', true)
                    player.addItem('gold', 100)
                    player.showText('You found 100 gold!')
                    event.setGraphic('opened-chest')
                } else {
                    player.showText('The chest is empty.')
                }
                break
                
            case 'save-point':
                player.save()
                await player.showText('Game saved!')
                event.showAnimation('save-effect')
                break
                
            case 'teleporter':
                player.changeMap('other_map', {
                    x: event.x,
                    y: event.y
                })
                break
        }
    }
}

onBeforeCreated

Description: Called before an event is created, allowing you to modify the event object or return a custom event configuration Parameters:
  • object: any - The raw event data from the map, typically { id?, x?, y?, event } for positioned events
  • map: RpgMap - The map instance where the event will be created
Returns:
  • any - Modified event configuration
Example:
const event: RpgEventHooks = {
    onBeforeCreated(object: any, map: RpgMap) {
        console.log(`Creating event ${object.name} on map ${map.id}`)
    }
}

onPlayerTouch

Description: Called when a player touches an event (collision detection) Parameters:
  • event: RpgEvent - The event instance
  • player: RpgPlayer - The player who touched the event
Example:
const event: RpgEventHooks = {
    onPlayerTouch(event: RpgEvent, player: RpgPlayer) {
        console.log(`${player.name} touched ${event.name}`)
    }
}

onDetectInShape / onDetectOutShape

Description: Called when a player enters or leaves an event’s detection shape Parameters:
  • event: RpgEvent - The event instance
  • player: RpgPlayer - The player who entered/left the shape
  • shape: RpgShape - The shape instance
Example:
const event: RpgEventHooks = {
    onDetectInShape(event: RpgEvent, player: RpgPlayer, shape: RpgShape) {

    },
    
    onDetectOutShape(event: RpgEvent, player: RpgPlayer, shape: RpgShape) {
        
    }
}

onInShape / onOutShape

Description: Called when the event itself enters or leaves a shape Parameters:
  • event: RpgEvent - The event instance
  • shape: RpgShape - The shape instance
Example:
const event: RpgEventHooks = {
    onInShape(event: RpgEvent, shape: RpgShape) {
        
    },
    
    onOutShape(event: RpgEvent, shape: RpgShape) {
        
    }
}

onChanges

Description: Called during the change-detection cycle for a player. This hook is the reactive part of event design. When player state changes, especially player variables, RPGJS can re-run the cycle and call onChanges(event, player) so the event can recompute its state for that player. You can also force that cycle with player.syncChanges(). Parameters:
  • event: RpgEvent - The event instance
  • player: RpgPlayer - The player who caused the change (if applicable)
Example:
const event: RpgEventHooks = {
    onChanges(event: RpgEvent, player: RpgPlayer) {
        const isOpened = player.getVariable('chest-opened')
        event.setGraphic(isOpened ? 'chest-opened' : 'chest-closed')
    }
}

Designing onInit and onChanges together

In practice, these two hooks often share similar logic:
  • onInit sets a correct initial state when the event appears
  • onChanges keeps that state synchronized with player data later
Typical example: a chest.
const event: RpgEventHooks = {
    onInit(event: RpgEvent) {
        event.setGraphic('chest-closed')
    },
    onChanges(event: RpgEvent, player: RpgPlayer) {
        const isOpened = player.getVariable('chest-opened')
        event.setGraphic(isOpened ? 'chest-opened' : 'chest-closed')
    }
}
Use player variables for this kind of state, because they persist with the player and travel with the player snapshot across saves and map transfers.