Skip to content
shr0x edited this page Mar 25, 2026 · 1 revision

Events

This page explains how the event system works in the framework and how different layers communicate with each other.


Overview

The framework is built around an event-driven architecture.

Events are used for communication between:

  • Server ↔ Client
  • Client ↔ Server

The system relies on RAGE:MP’s event system, extended with a consistent naming convention and structure.


Types of Events

There are two main types of events:

1. Server → Client Events

These are triggered from the server and received on the client.

Used for:

  • sending data to players
  • triggering UI updates
  • running client-side logic

2. Client → Server Events

These are triggered from the client and received on the server.

Used for:

  • player actions
  • UI interactions
  • gameplay requests

Naming Convention

Events follow a structured naming format:

layer::category:action

Examples

client::task:taskAchieveHeading
client::ui:openInventory
server::player:spawn

Explanation

  • client:: → event is handled on the client
  • server:: → event is handled on the server
  • category → logical grouping (task, ui, player, etc.)
  • action → what the event does

Server → Client Communication

Sending event from server

player.call("client::ui:openInventory", [data]);

Receiving on client

mp.events.add("client::ui:openInventory", (data) => {
  // handle UI open
});

Client → Server Communication

Sending event from client

mp.events.callRemote("server::inventory:useItem", itemId);

Receiving on server

mp.events.add("server::inventory:useItem", (player, itemId) => {
  // handle item usage
});

Event Flow Example

Example: Using an Item

sequenceDiagram
    participant P as Player
    participant F as Frontend (CEF)
    participant C as Client
    participant S as Server

    P->>F: Clicks "Use Item"
    F->>C: Send UI event
    C->>S: callRemote("server::inventory:useItem")
    S->>S: Validate & process item
    S-->>C: Send result / updated data
    C-->>F: Emit UI update
    F-->>P: Update interface
Loading

Best Practices

1. Always validate on server

Never trust client input.

// BAD
// trusting client blindly

// GOOD
// validate item exists, player owns it, etc.

2. Keep events small and focused

Avoid large multi-purpose events.

// BAD
"server::game:doEverything";

// GOOD
"server::inventory:useItem";
"server::inventory:dropItem";

3. Use consistent naming

Stick to the same pattern across the project. However you are free of will to change it how you would like to, the reason why I went this way was because it made it easier for me to debug or track an error.


4. Avoid heavy logic in client

Client should not:

  • decide game outcomes
  • modify persistent data

That belongs to the server.


5. Use shared types

Whenever possible, define event payloads in the shared layer.

This prevents:

  • mismatched data
  • runtime errors
  • confusion

Common Mistakes

Using wrong event type

  • call is for local events
  • callRemote is for server events

Not checking player validity

Always check player exists and is valid before processing.


Overloading events

One event should do one thing.


Recommended Structure

Organize events by feature:

server/events/inventory/
client/events/inventory/
shared/events/

This keeps the system modular and scalable, easy to understand and track files, as you may have noticed the whole structure is based on Name.whatitis.ts, so if a system you may developer might have a class, a module and events its easy to track what you want to add or edit in that specific system.

Plain English: Let's say you have a vehicle system or on-top layer of what RAGEMP provides related to vehicles and you have your vehicle class and events. My expectations or what I expect you to do is, create a class file in source/server/classes named Vehicle.class.ts and a event file in source/server/events named Vehicle.events.ts, now instead of navigating to those files by clicking and expanding folders you can use your IDE to go directly at that file by their name, and depending what you want to do you can search for, System.whatsProvided (in this case Vehicle.class or Vehicle.events). But also let's say there's a bug coming from a feature related to vehicles, so the first thing you would search for is vehicle related events, which for you if you created those files would be easy as you know where vehicle events are stored, but if you work with a group of developers then they would struggle to find them, therefore file naming becomes important here and easy for other fellow devs to find stuff.


Summary

The event system is the backbone of the framework.

  • Server handles authority
  • Client acts as bridge
  • Events connect everything together

Understanding events is essential for building features in this framework.

🚀 Getting Started

🧠 Architecture

🎮 Features

🛠 Development

❗ Help

Clone this wiki locally