Adding Scripts
Adding scripts to your server is the primary way to customize and extend gameplay. This guide will walk you through everything you need to know.
If you're just getting started, consider downloading the official default scripts! They include freeroam, menus, player management and a few gamemodes, and serve as great examples for learning how scripts work. See the Server Setup guide for installation instructions.
How Scripts Work
Scripts in JC4MP are organized into resources - collections of related scripts that work together. Each resource is a folder containing scripts and assets that provide specific functionality to your server. There is no manifest or meta file: the folder layout is all there is. The full rules are on the Resources page.
Basic File Structure
Scripts are placed in your server's resources folder. Here's the basic structure:
your-server/
└── resources/
├── my-first-script/
├── vehicle-spawner/
└── chat-system/
Each resource folder can contain three special directories:
client/- Scripts that run on players' computersserver/- Scripts that run on your server (players can't see these)shared/- Scripts that run on both client and server
File Types
Resources can contain various file types:
.lua- Main script files (most common).html,.css,.js- For creating webviews (all UI is made of web pages - put these files in theclientfolder).json,.txt- Configuration and data files- Images, sounds, models - Other assets
Download Behavior
When players connect to your server:
- They download everything from
client/andshared/folders - They cannot access anything in
server/folders - Server scripts remain private on your server
Script Execution
- Client scripts run on each player's computer
- Server scripts run only on your server
- Shared scripts run on both client and server
- Client and server scripts can both load shared modules with
require - Scripts run on LuaJIT (Lua 5.1 syntax). See the Sandbox for which libraries each side can use
Example Directory Structure
Here's a realistic example with multiple resources:
resources/
├── vehicle-spawner/
│ ├── client/
│ │ ├── spawner_ui.lua
│ │ └── webview/
│ │ ├── index.html
│ │ ├── style.css
│ │ └── script.js
│ ├── server/
│ │ ├── vehicle_manager.lua
│ │ └── permissions.lua
│ └── shared/
│ ├── vehicle_data.lua
│ └── config.lua
├── chat-system/
│ ├── client/
│ │ └── chat_client.lua
│ ├── server/
│ │ ├── chat_server.lua
│ │ └── moderation.lua
│ └── shared/
│ └── chat_utils.lua
└── my-gamemode/
├── client/
│ ├── hud.lua
│ └── player_input.lua
├── server/
│ ├── gamemode.lua
│ ├── player_data.lua
│ └── database/
│ └── connection.lua
└── shared/
├── constants.lua
└── math_utils.lua
Nested Resources
You can group resources in subfolders. Any folder, at any depth inside resources, that contains a client, server or shared folder is a resource, and its name is the folder name. In the example below, racing, weapons and utilities are three separate resources. Resource names must be unique across the whole resources folder.
resources/
└── my-script-pack/
├── racing/
│ ├── client/
│ │ └── race_ui.lua
│ ├── server/
│ │ └── race_logic.lua
│ └── shared/
│ └── race_data.lua
├── weapons/
│ ├── client/
│ │ └── weapon_effects.lua
│ └── server/
│ └── weapon_spawner.lua
└── utilities/
└── shared/
└── common_functions.lua
Files That Aren't Scripts
Only the client, server and shared folders of a resource are used. Files directly in the resource folder, or in any other folder next to them, are neither run nor sent to players, so you can keep notes, sources and build files there:
resources/
└── my-webview-script/
├── client/
│ ├── webview_client.lua
│ └── ui/ # built web UI, sent to players
│ └── index.html
├── src/ # UI sources, never sent to players
├── package.json
└── README.md
Don't create folders named client, server or shared deeper inside a resource: such a folder makes its parent look like another resource. This includes dependencies, such as a node_modules package with its own client folder, so keep node_modules outside of resources. The __ folder prefix that hid folders in 1.x no longer exists in 2.0.0.
Sharing Code Between Scripts
Every .lua file is a separate script with its own globals (see Script Context).
Static Data and Methods
Use require to share static data and functions between different scripts.
Dynamic Runtime Data
Use events to communicate and share dynamic data between scripts while your server is running, and Net to send data between the server and players.
Getting Started
- Create a new folder in your
resourcesdirectory - Add
client,server, orsharedfolders as needed - Place your
.luascripts in the appropriate folders - Type
start <resource_name>in the server console (or add it tostartup_resourcesand restart the server)
The server runs the server and shared scripts, and players download and run the client and shared scripts when they join. For a complete walkthrough, see Your First Resource.
Lua Standard Library Availability
Scripts run in a sandbox. Only os.time and os.date are available from the os library, io and debug are not available, and precompiled bytecode is refused. Client scripts also can't use package, loadfile or dofile. Use the provided game APIs (e.g., SQL, Timer, Net) to perform needed tasks. See the Sandbox page for the full list per side.