Skip to main content

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.

New to Scripting?

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' computers
  • server/ - 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 the client folder)
  • .json, .txt - Configuration and data files
  • Images, sounds, models - Other assets

Download Behavior​

When players connect to your server:

  • They download everything from client/ and shared/ 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
warning

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​

  1. Create a new folder in your resources directory
  2. Add client, server, or shared folders as needed
  3. Place your .lua scripts in the appropriate folders
  4. Type start <resource_name> in the server console (or add it to startup_resources and 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.