Lua resources loaded by the server
Resource manifests, the client and server runtime split, signing and download, hot reload, and the security model around resources the server hands to connecting players.
The server picks the session's resources, builds their client image, and the game downloads them
before entering Night City — the same model FiveM uses. The local
red4ext/plugins/CyberM/bootstrap folder holds only the trusted bootstrap:
cyberm_shell / cyberm_pause, which draw the server browser, the connection flow, and the loading
screen. Gameplay resources on the player's disk are never auto-discovered.
Use this guide to write a resource, understand what reaches the player, and publish a change to a running session.
Connection flow
- The GNS handshake announces a generation, a SHA-256 digest, an Ed25519 key, and an HTTPS URL.
- The shell shows a full-screen loading WebUI.
- The client verifies the signed set, the CBOR manifests, each chunk, then each file.
- The complete generation is committed under
red4ext/plugins/CyberM/cache/server-resources/sets/<digest>/resources. - Only then does CyberM load the pristine save.
- The local Lua runtime is replaced by the server's client image.
The screen reports manifest, downloading, verifying, ready, or failed, along with the
resource, the byte count, and the number of files. A signature, hash, or path error blocks entry and
disconnects the client.
Writing a resource
The resource lives in the folder configured by the server's resources.root:
resource "garage"
version "1.0.0"
auto_start true
shared_script "shared/config.lua"
server_script "server/main.lua"
client_script "client/main.lua"
web_ui_page "web/index.html"
web_files { "web/**" }
files { "assets/blips/*.png", "assets/audio/*.wav" }
permissions { "network.events" }
The server runs server_script and shared_script. The downloaded package contains cyberm.lua,
the client and shared files, and the declared assets — never the server/ files. The client and
server Lua APIs are documented in the wiki's main reference. The authoritative subsystem for ground
items is covered in loot.md. The reference time/weather package and its protocol are
covered in weather.md.
files / file declare generic client assets. Globs are expanded by the server, included in the
signed resource set, downloaded before Lua starts, and recorded in the client allowlist. Use
web_files only for files served to that resource's WebUI. For example,
CyberM.assets.texture("assets/blips/job-center.png") only succeeds when the exact file matched a
files entry. Empty globs, traversal paths, oversized files, and undeclared texture reads fail the
resource instead of falling back to arbitrary disk access.
A server script can register a command reachable from the CyberM developer terminal or from the dedicated console:
RegisterCommand("garage.list", function(source, args, rawCommand)
-- source = authenticated playerId from the CyberM terminal, 0 from the dedicated console.
print("garages: " .. tostring(#args))
end, false) -- true puts the command behind the `command.garage.list` ACL
In the in-game terminal, CyberM runs local native commands first. If no local handler matches, the
tokenised line is sent reliably to the server under the session's identity. The server never trusts
a source supplied by the client. Commands are removed automatically along with their VM when a
resource stops or reloads.
Commands declared with restricted=true require the ACL permission
command.<lowercase-name>. The * permission and namespace wildcards such as command.garage.*
are accepted. See server-acl.md.
Publishing and reloading
With autoStart=true, the server notices any valid change. It prepares a new server VM, publishes a
new signed set, then sends ResourceSetChanged to the players. The client downloads only the
missing chunks and switches generation once verification completes. An invalid Lua candidate keeps
the previous generation.
Useful server commands:
resources
refresh
ensure <resource>
start <resource>
stop <resource>
restart <resource>
reload <resource>
Client diagnostic commands:
resource.root
resource.distribution
resource.list
resource.status <resource>
resource.root shows source=bootstrap before the session and source=server once active.
resource.distribution exposes phase, generation, progress, digest, and current resource.
Security and operations
- HTTPS is mandatory for a public URL; HTTP is limited to loopback.
- HTTP redirects and absolute or traversal paths are refused.
- The server must keep its signing key file across a migration.
- The private key and the
.cybermcache must never be committed. - A server resource is code chosen by the operator: only grant sensitive permissions to resources you audit.
Minimum configuration:
"resources": {
"enabled": true,
"root": "../resources",
"autoStart": true,
"download": {
"enabled": true,
"listenUrl": "http://0.0.0.0:11779",
"publicBaseUrl": "https://cdn.example.net/",
"cacheDirectory": ".cyberm/resource-cache",
"signingKeyFile": ".cyberm/resource-signing-key.json",
"chunkSizeBytes": 1048576
}
}For agents and LLMs: this page as Markdown · llms.txt · llms-full.txt
