Skip to main content
forge-core loads first and underpins every other package. It owns the cross-cutting services the rest of FORGE builds on. You rarely call most of it directly from content, but you will use its logging, database, and identity helpers.

Exports

Lifecycle & meta

ExportSignatureReturns
IsReadyIsReady()boolean
GetVersionGetVersion()version string
RegisterServiceRegisterService(name, version)registers a package in the health registry
GetHealthGetHealth(){ ok, services, ... }

Logging

ExportSignature
LogLog(level, resource, sub, message), level is TRACE|DEBUG|INFO|WARN|ERROR|FATAL
SetLogLevelSetLogLevel(level)
exports["forge-core"]:Log("INFO", "my-pkg", "bootstrap", "ready")

Result & IDs

ExportSignature
ResultResult(ok, code, data, message), build a standard Result table
MakeIdMakeId(namespace, name), validated stable id (namespace:name)
ValidateConfigValidateConfig(schema, config), declarative config validation

Identity & permissions

Identity is the HELIX User ID. A character is a separate concept owned by forge-characters.
ExportSignatureReturns
GetUserIdGetUserId(controller)Result{ data = { user_id } }
GetControllerGetController(user_id)the controller object, or nil (not a Result)
GetActiveUsersGetActiveUsers()array of online user_id strings
HasPermissionHasPermission(user_id, permission)Result (ok when granted; permissive when the permissions feature is disabled)
GrantPermissionGrantPermission(user_id, permission)Result
RevokePermissionRevokePermission(user_id, permission)Result
Default permission grants are empty. A fresh player has no permissions unless a DefaultGroups entry, a SuperAdmin id, or a runtime GrantPermission (for example via forge-admin roles) gives them one.

Database

Backend-neutral SQL with parameter binding. Writes and reads both return a Result.
ExportSignatureReturns
DbExecuteDbExecute(sql, params)Result
DbSelectDbSelect(sql, params)Result{ data = { rows } }
DbTransactionDbTransaction(statements)Result, runs { sql, params } statements atomically
RegisterMigrationsRegisterMigrations(packageName, list)run a package’s schema migrations at bootstrap
Never leave nil holes in a params array; HELIX silently fails on them. Put nullable columns last, or pass empty strings.

Save coordination

Packages mark state dirty and let core coordinate the flush, rather than writing on every change.
ExportSignature
MarkDirtyMarkDirty(resource, owner_id)
ReportSavedReportSaved(resource, owner_id), respond to a forge-core:server:flush

Events

EventPayloadWhen
forge-core:server:playerJoined{ user_id, display_name, is_first_join }a player’s user id resolved
forge-core:server:playerLeft{ user_id }a player disconnected
forge-core:server:flush{ owner_id, resources }the save coordinator asks dirty owners to persist

Configuration

Features toggles the cross-cutting subsystems; Permissions seeds grants.
Features = { Permissions = true, SaveCoordinator = true, PlayerLifecycle = true },
Permissions = {
  DefaultGroups = {},  -- permissions granted to every player on join
  SuperAdmin    = {},  -- user_ids that bypass all permission checks
},