CityRP Documentation Repository

cityrp.plugin

Plugin registration and utilities library.

Functions

Availability

Sharedcityrp.plugin.GetDependencyStatus(key) → PluginDependencyStatus?Source ☍

Why a plugin is or is not available, for diagnostics. Not a guard - use cityrp.plugin.IsAvailable for that. Returns copies, and may gain fields.

Parameters

  • keystringThe plugin's key.

Returns

  1. PluginDependencyStatus?Nil when no plugin with that key was discovered here.
Sharedcityrp.plugin.IsAvailable(key) → booleanSource ☍

Whether a plugin is loaded and running on this realm. The guard to put around a call into another plugin. Every reason one might be absent reads the same false; cityrp.plugin.GetDependencyStatus tells them apart. Not the same test as cityrp.plugin.get(key) ~= nil, which misses the ~27 plugins that never call register. scope prefix. Not PLUGIN.name.

Parameters

  • keystringThe plugin's key - the folder name, or a file plugin's name without its

Returns

  1. booleanWhether the plugin is loaded on this realm.
Sharedcityrp.plugin.SendsSubResourcesToClient(entry) → booleanSource ☍

Whether any of one plugin's sub-resources will be sent to the client.

The loader AddCSLuaFiles sub-resources after the plugin loop in sh_init.lua has already decided whether to send the plugin's .meta.lua, so a plugin with no cl_init.lua/sh_init.lua of its own can still materialise its folder clientside through them - breathalyser is exactly that shape. Left alone, the client discovers such a plugin with no metadata at all and resolves it with its dependencies and availability conditions never evaluated.

This deliberately mirrors what includeSubResourceFiles and LoadSubResourceItems/Derma actually send rather than merely testing whether the folders exist: sending the sidecar for a plugin that sends nothing else would materialise the folder clientside on its own, which is the opposite failure and the reason the sendsToClient gate exists in the first place.

Parameters

Returns

  1. booleanWhether the client will receive any file from this plugin's sub-resources.

Discovery

Sharedcityrp.plugin.Discover() → PluginCandidate[]Source ☍

Discovers every plugin under core/plugins, resolving folder and file plugins into one key space. A folder plugin is a folder of sv_init.lua/cl_init.lua/sh_init.lua; a file plugin is a single sv_<key>.lua, cl_<key>.lua or sh_<key>.lua sitting directly in core/plugins. Folders outrank files, and among files sh_ outranks sv_, which outranks cl_. Conflicts and unrecognised Lua files are logged on the server and are never fatal. Every candidate is returned regardless of its own metadata - cityrp.plugin.Resolve reads .meta.lua and decides afterwards.

Returns

  1. PluginCandidate[]The resolved plugins, ordered by key.

Loading

Sharedcityrp.plugin.AutoRegister()Source ☍

Registers the seeded table for the plugin currently being loaded, unless it registered itself. A fallback rather than the primary path, so a plugin that still calls cityrp.plugin.register with its own table is left alone and nothing registers twice.

Sharedcityrp.plugin.call(name, _)Source ☍

Calls a function for all plugins.

Parameters

  • namestringThe name of the function to call.
  • anyArguments to pass to the called functions.
Sharedcityrp.plugin.ClearGlobal()Source ☍

Clears the PLUGIN global after a plugin's includes have finished.

Sharedcityrp.plugin.get(id) → table?Source ☍

Gets a plugin by its key, or by the display name it registered under. A display name still resolves, but warns once per name: the key is the identity everything else in the loader uses, and the two are not derivable from one another (area registers as "Area Manager", licenseplates as "Licence Plates").

Parameters

  • idstringThe plugin's key, or the display name it registered under.

Returns

  1. table?The plugin table, or nil if not found.
Sharedcityrp.plugin.register(plugin)Source ☍

Registers a new plugin. The plugin is stored under its key, taken from the loader; its display name is recorded as an alias so existing cityrp.plugin.get("Display Name") call sites keep resolving.

Parameters

  • plugintable|PLUGINThe plugin table to register.
Sharedcityrp.plugin.SeedGlobal(entry)Source ☍

Seeds the PLUGIN global for a plugin about to be included. The loader owns the plugin table: a plugin's files read PLUGIN rather than building their own and handing it over. An unmigrated file's local PLUGIN = {} shadows this harmlessly, and its own PLUGIN_SHARED = PLUGIN keeps its sub-files consistent, so both styles coexist.

Parameters

Resolution

Sharedcityrp.plugin.Resolve() → PluginEntry[]Source ☍

Discovers every plugin, reads its metadata and resolves a deterministic load order. Plugins declare dependencies in an optional .meta.lua beside them; a missing required dependency or a required cycle stops the plugins involved from loading, and is logged rather than raised. A plugin whose metadata declares disabled = true, or whose servers/maps conditions exclude it here, takes no part in resolution - it is absent from the returned order, contributes no sub-resources, and is reported to any dependent as disabled rather than not installed; it reaches cityrp.plugin.registry with status "excluded" only for diagnostics. Everything else discovered is returned even on failure, so a caller can still send a failed plugin's files to the client - only inclusion is gated, on status.

Returns

  1. PluginEntry[]Every discovered, available plugin, in load order.

Subresources

Sharedcityrp.plugin.LoadSubResourceDerma(entries)Source ☍

Includes every derma/*.lua file under one loaded folder plugin, same prefix rules as core/derma: the server sends every file but only includes sh_-prefixed ones, the client includes everything it received.

Parameters

Sharedcityrp.plugin.LoadSubResourceEntities(entries)Source ☍

Loads the entities/, weapons/ and effects/ sub-resources of every loaded folder plugin, in load order. File-based plugins (#2507) never have sub-resources. A plugin that failed to resolve, or a missing sub-resource folder, is skipped silently.

Parameters

Sharedcityrp.plugin.LoadSubResourceItems(entries, log)Source ☍

Includes every items/*.lua file under one loaded folder plugin, same convention as core/items: included and AddCSLuaFile'd unconditionally, so item files decide their own realm behaviour. Runs after core/items so plugin items can inherit from bases registered there.

Parameters

Tables

Sharedcityrp.pluginSource ☍
Sharedcityrp.plugin.namesSource ☍

Plugin keys, keyed by the display name each plugin registered under. Looking a plugin up by display name is legacy - cityrp.plugin.get resolves through here and warns.

Sharedcityrp.plugin.storedSource ☍

Registered plugins, keyed by the loader's plugin key - the folder name, or a file plugin's name without its scope prefix. This is the same identity .meta.lua dependencies, availability conditions and load order use; it is not PLUGIN.name, which is a free-text display name.

Classes

SharedPluginStatusSource ☍

Resolution outcome recorded on a plugin entry. Only ok is executed by the loader.

Fields

Sharedcityrp.plugin.discoveredSource ☍
Sharedcityrp.plugin.loadingSource ☍

Key of the plugin the loader is currently including, or nil outside a plugin include. cityrp.plugin.register has no other way to learn which folder it is being called from - see the loader loop in gamemode/sh_init.lua.

Sharedcityrp.plugin.registrySource ☍
Sharedcityrp.plugin.statusSource ☍

Resolution outcomes, for callers comparing against a PluginEntry's status.

SharedEFFECTSource ☍
SharedPLUGINSource ☍
SharedPLUGIN_SHAREDSource ☍

Set for as long as unmigrated plugins still read it. Their own assignment overwrites this with their own table, which is exactly what those files expect.

PluginCandidate

3 fields Source ☍

A plugin found by cityrp.plugin.Discover, before any of its code has run.

SharedPluginCandidate.keySource ☍

Identity key, shared with folder plugin names.

SharedPluginCandidate.pathSource ☍

Path to the folder or file, relative to the gamemode folder.

SharedPluginCandidate.scopeSource ☍

One of "folder", "sh", "sv" or "cl".

PluginDependencyStatus

8 fields Source ☍

A snapshot of one plugin's resolution outcome, as cityrp.plugin.GetDependencyStatus returns it.

SharedPluginDependencyStatus.cycleSource ☍

Keys forming the required-edge cycle, when status is "cycle".

SharedPluginDependencyStatus.keySource ☍

The plugin's key.

SharedPluginDependencyStatus.missingSource ☍

Required dependency keys that were absent or disabled.

SharedPluginDependencyStatus.missingOptionalSource ☍

Optional dependency keys that were absent.

SharedPluginDependencyStatus.orderSource ☍

Position in the load order, absent for an excluded plugin.

SharedPluginDependencyStatus.reasonSource ☍

Why it was excluded, when status is "excluded".

SharedPluginDependencyStatus.scopeSource ☍

One of "folder", "sh", "sv" or "cl".

SharedPluginDependencyStatus.statusSource ☍

Why it did or did not resolve.

PluginEntry

12 fields Source ☍

A discovered plugin once its metadata has been read and its load order resolved.

SharedPluginEntry.cycleSource ☍

Keys forming the cycle, when status is "cycle".

SharedPluginEntry.keySource ☍

Identity key, shared with folder plugin names.

SharedPluginEntry.metaSource ☍

Declared metadata, empty when the plugin has no .meta.lua.

SharedPluginEntry.metaPathSource ☍

Path to the metadata file, relative to the gamemode folder.

SharedPluginEntry.missingSource ☍

Required dependency keys that were absent or disabled.

SharedPluginEntry.missingOptionalSource ☍

Optional dependency keys that were absent.

SharedPluginEntry.orderSource ☍

Position in the computed load order, from 1. Absent when status is

SharedPluginEntry.pathSource ☍

Path to the folder or file, relative to the gamemode folder.

SharedPluginEntry.reasonSource ☍

Why it was excluded, when status is "excluded".

SharedPluginEntry.scopeSource ☍

One of "folder", "sh", "sv" or "cl".

SharedPluginEntry.statusSource ☍

Whether this plugin is cleared to load, and if not, why.

SharedPluginEntry.tableSource ☍

The plugin's own table, seeded by the loader on first include. Absent until

PluginMeta

9 fields Source ☍

Declared metadata for one plugin, normalised and validated.

SharedPluginMeta.afterSource ☍

Keys to load after; "*" means every other plugin.

SharedPluginMeta.beforeSource ☍

Keys to load before; "*" means every other plugin.

SharedPluginMeta.dependenciesSource ☍

Keys this plugin cannot load without.

SharedPluginMeta.disabledSource ☍

Unconditionally excluded from both realms, regardless of servers/maps.

SharedPluginMeta.mapsSource ☍

Map names this plugin is allowed on; empty means every map.

SharedPluginMeta.notMapsSource ☍

Map names this plugin is excluded from; wins over maps.

SharedPluginMeta.notServersSource ☍

Server codes this plugin is excluded from; wins over servers.

SharedPluginMeta.optionalDependenciesSource ☍

Keys this plugin uses when they are present.

SharedPluginMeta.serversSource ☍

Server codes this plugin is allowed on; empty means every server.

SubResourceClass

3 fields Source ☍

One class found under a plugin's entities/, weapons/ or effects/ folder.

SharedSubResourceClass.folderSource ☍

Whether the class is an engine-style folder (init.lua/cl_init.lua/shared.lua,

SharedSubResourceClass.fsNameSource ☍

The folder or file name as file.Find returned it, used to build paths.

SharedSubResourceClass.nameSource ☍

Class name, e.g. "cityrp_breathalyser". Always lowercase.