One resource, two runtimes
A resource is a folder with a package.json manifest. Server scripts run in Node.js and own gameplay decisions. Client scripts run in a sandboxed V8 runtime for presentation, local input, and supported game interfaces. CEF panels provide HTML/CSS/JavaScript UI.
The public event bus is Events, not Core.Events. Use the current generated declarations for your build; API changes accompany releases. Replicated entity state is not durable database storage. The old key/value storage API was removed in 1.3.0.
Create a minimal welcome resource
Create resources/my-welcome/package.json with the manifest below. Server script paths are relative to that resource folder.
{
"name": "my-welcome",
"version": "1.0.0",
"mafiahub": {
"serverScripts": [
"server/main.js"
],
"priority": 10
}
}
Respond when a player connects
Create resources/my-welcome/server/main.js. This small example uses the documented playerConnect event and sendChat method, without taking over character creation, inventory, or another gameplay system. Restart a distributed server build to load the resource.
Events.on("playerConnect", (player) => {
console.log(`${player.nickname} joined`);
player.sendChat("Welcome to Hogwarts!");
});
Choose what reaches the client
Keep secrets and database credentials in server-only configuration. The runtime discovers resources with manifests; a descriptive category such as “dev” does not prevent loading. Do not deploy the mod’s internal resource tree as a public pack.
| Manifest key | Role |
|---|
| serverScripts | Node.js scripts. These are not sent to clients. |
| clientScripts | Client V8 scripts, delivered during connection. |
| sharedScripts | Runs on both sides and is delivered to clients. |
| files | Additional client files such as web views, styles, and images. Supports globs. |
| resourceDependencies | Resources that must load first; declare the systems you depend on. |
| priority | Higher values load later. It controls order, not whether other resources run. |
| errorBehavior | stop (default), restart, or continue when a resource throws. |
Build around server-owned rules
Use server APIs for player appearance, health, visibility, inventories, doors, world conditions, NPCs, PvP rules, loot, and House Cup standings. Client requests should express an intention; the server decides whether it is allowed.
Recent releases moved more of the game under server control. 1.6.0 added house standings, held door states, character scale, and held props, and changed appearance APIs to JSON looks. 1.8.0 added server-owned loot and respawns. 1.9.0 added PvP rules, camps and world events, Room of Requirement rooms, beast catching, and NPC kill rewards, and replaced Broom setMaxSpeed with a server-set speed multiplier. 1.10.0 shut the game’s own enemy spawners, added scripted movement, custom spells, animal forms, gates, and spawn points, and made LocalPlayer.stopPlayerInput hold input per resource. Check release notes before porting a resource from an older build.
Use client scripts for supported presentation and input, and CEF for interfaces. Client and shared scripts are delivered to players; they cannot keep an authority rule or secret hidden.
Extend Foundation, rather than duplicating it
Foundation is the supported base for public servers and uses MySQL/MariaDB for durable gameplay data. Declare resource dependencies and coordinate ownership of character, inventory, money, and administration systems. Two resources trying to own the same commands or state can conflict.
Replicated state bags share values while a session runs. They do not replace a persistence layer. Read Foundation’s resource contracts before wiring custom jobs, shops, or roleplay systems into its data.
Test with the build you deploy
Release builds require a restart for resource changes. The debug-only file watcher is not part of the distributed server experience.
Test connection, disconnect, repeated requests, and resource startup failures with matching client and server builds. Use the generated hogwartsmp-server.d.ts and hogwartsmp-client.d.ts declarations for editor help. Internal QA resources may mutate game state and belong in controlled development sessions.