Security and limits

Review code trust, host authority, sensitive capabilities, resource lifecycle and hard platform bounds.

Trust model

LayerGuarantee
s&box sandboxAddon code is subject to engine access control. It does not gain unrestricted filesystem, network or reflection access.
Two code gatessettings.allowCodeAddons and the entry's allowCode must both be true.
Parent and provenanceRemote code packages must target litherastudio.litherarp. Manifest paths, code archive presence and exact revisions are validated.
Explicit implementationA matching LitherarpAddonAttribute, implementation id and protocol version are required. Ambiguous implementations are refused.
Host authorityCore hooks run inside authoritative host funnels. Addon network messages resolve the caller and permission on the host.
Failure isolationLifecycle, tick, hook, network, service-event and admission callbacks isolate recoverable exceptions and quarantine repeated failures.

allowCode is still a trust decision. An approved addon can use the same public gameplay and engine surface available to gamemode code inside the s&box sandbox. Capabilities are SDK gates for selected sensitive operations, not a CLR isolation boundary. Review the creator and package revision before enabling it.

Whitelist admission capability

1public void OnHostLoaded( LitherarpAddonContext context )
2{
3 if ( !context.HasCapability( "admission.whitelist_override" ) )
4 return;
5
6 context.RegisterWhitelistAdmissionHandler( request =>
7 {
8 if ( IsAddonBlocked( request.Connection.SteamId ) )
9 {
10 request.Deny( "This account is blocked by the event roster." );
11 return;
12 }
13
14 if ( !request.CoreWhitelistAllowed && IsInvitedGuest( request.Connection.SteamId ) )
15 request.Allow( "Invited event guest." );
16 }, priority: 100 );
17}

LitherarpAddonAdmissionRequest exposes Connection, CoreWhitelistAllowed, IsAllowed, IsDenied, Reason, Allow and Deny. Denial wins over all allows. There is one handler per addon and at most 16 handlers globally. This stage cannot bypass server authorization or sanctions.

Resource lifecycle

The host and client record which managed package owns each manifest resource path. Registry scans and spawn lookups reject resources owned only by inactive packages. Exact package revisions are part of readiness.

s&box does not expose a safe in-process package byte unload. Disabled package bytes can stay cached until restart, but their managed resources are filtered and context registrations are removed. Addon assembly static state can also survive disable, so keep activation state on the instance or context.

Use package-specific resource paths. If two packages publish the same path, the engine can retain whichever bytes were mounted into that path, and LitheraRP cannot reconstruct overwritten engine cache contents during an in-process disable. A restart is the reliable reset for a resource collision.

Hard limits

AreaLimit
Configured addons128.
Required packages, required dependencies, optional dependencies, conflicts64 of each per addon.
Requested or granted capabilities64 ids per addon.
Jobs128 registrations per addon.
Shop entries512 registrations per addon.
NPCs, NPC kinds, NPC overrides or decorators64, 16, 64 per addon.
Clothing and runtime items512 and 1,024 per addon.
Chat commands64 per addon and 512 globally; command name 24 characters; description 160 characters; usage 96 characters; 16 parsed arguments.
Screen panels and Admin Console panels32 screen descriptors and 16 admin panels per addon.
Permission nodes128 per addon.
Phone apps16 per addon.
Toolgun modes and actions16 and 64 per addon.
Toolgun policy context16,384 UTF-8 bytes, JSON depth 32, and 256 distinct targets or committed results.
Damage mutationFinite values from 0 to 1,000,000; world vector components from -1,000,000 to 1,000,000; 16 unique tags of at most 32 characters.
Cancelable denial reason256 characters after trimming outer whitespace. A blank reason becomes Denied by an addon.
Gameplay event subscriptions4,096 per event channel and 256 per normalized owner, including the anonymous owner; priority -1000 to 1000; same-event raise depth 8.
Context cleanup tracking4,096 tracked disposables and 4,096 teardown actions per activation. Surplus cleanup runs immediately instead of being dropped.
Admin log text512 UTF-16 characters for message and 2,048 for detail.
Consumables and dealer products128 each per addon.
Targeted player section8,000 UTF-8 bytes per addon and player.
Addon-provided public snapshot section8,000 UTF-8 bytes per addon section.
Core addons public snapshot section4,194,304 UTF-8 bytes. This critical section contains the complete verified addon plan.
Complete public snapshot8,388,608 UTF-8 bytes across the envelope and all sections.
Addon network64 names per addon; 16,384 UTF-8 bytes platform maximum.
Services and local subscriptions32 services and 128 subscriptions per addon; 65,536 UTF-8 bytes per local event.
Versioned storage1,048,576 UTF-8 bytes per document; 128 documents per scope.
Status effects1,024 active effects across all addons.
Registry priority-1000 to 1000.
Client readiness timeout15 to 300 seconds; default 90.
Package, manifest and cloud operations30 seconds per fetch, mount or resource load operation.

An addon-provided public section that fails serialization or exceeds 8,000 bytes is omitted and reported. The core addons section is critical: serialization failure, its 4,194,304-byte limit, or the 8,388,608-byte total limit fails the snapshot instead of distributing an incomplete addon plan.