RX Murals Configuration

RX Murals keeps its settings in config.lua. This file controls how painting feels, how pictures are rendered, how far murals are drawn, who may administer them, and how much the server accepts.

Restart rx_murals after changing the configuration so server limits and client rendering stay aligned.

General

Config.Locale = 'en'
Config.Notify = 'toast'
Config.WallOffset = 0.02
SettingDefaultBehaviour
Locale'en'Language of every message and of the panel. Must match a file in locales/.
Notify'toast''toast' shows notifications at the top right; 'chat' sends them as chat lines.
WallOffset0.02Distance in metres between the wall surface and every artwork.

English (en) and Turkish (tr) are included. To add a language, copy locales/en.lua, translate it, and set Locale to the new file name. Any key missing from a translation falls back to English.

Raise WallOffset slightly only if paint flickers into a particular wall. Too high a value makes murals look like they float.

Painting

Config.Paint controls the painting area, the brush, the palette, and paint depletion.

Config.Paint = {
    minSide = 0.25,
    maxSide = 3.0,

    brushMin = 0.01,
    brushMax = 0.12,
    brushStep = 0.01,
    brushDefault = 0.03,

    allowCustomColor = true,

    detailEpsilon = 0.32,
    spacingFactor = 0.55,

    warnTris = 800,

    depletion = true,
    paintCapacity = 0.5,
    dipTime = 1200,

    colors = {
        { 20, 16, 12 },
        { 240, 236, 224 },
        { 178, 34, 34 },
        { 32, 74, 135 },
        { 46, 120, 50 },
        { 218, 165, 32 },
        { 120, 72, 34 },
        { 105, 105, 105 }
    }
}

Area and brush

SettingDefaultBehaviour
minSide0.25Shortest allowed side of a painting area, in metres.
maxSide3.0Longest allowed side of a painting area, in metres.
brushMin0.01Thinnest brush, in metres.
brushMax0.12Thickest brush, in metres.
brushStep0.01How much the brush changes per + or - press.
brushDefault0.03Brush width when painting starts.
allowCustomColortrueShows the custom colour picker next to the preset palette.

Stroke detail

Every stroke is simplified before it is drawn. These two values decide how much detail is kept, and the loss is hidden inside the width of the brush.

SettingDefaultBehaviour
detailEpsilon0.32Simplify tolerance as a fraction of brush width. Higher values use fewer triangles but make tiny curls more angular.
spacingFactor0.55Distance between recorded points while painting, as a fraction of brush width.
warnTris800Triangle count at which the painter is warned they are approaching the per-frame budget.

There is no limit per mural. The only budget is how many triangles can be drawn on screen at once (see Rendering), and a painter may spend it on one large mural or several small ones.

Paint depletion

With depletion on, the brush runs dry as it paints and strokes fade. The painter looks at the bucket set down beside them and holds attack or R to refill it.

SettingDefaultBehaviour
depletiontrueEnables paint running out. false gives an endless brush.
paintCapacity0.5Area in square metres one full brush covers.
dipTime1200Milliseconds from dry to full while dipping. Releasing or looking away stops the refill.

Palette

colors is the preset palette, listed as { R, G, B } values from 0 to 255. The defaults are soot black, whitewash, barn red, indigo, forest green, ochre, leather brown, and slate gray. Players cycle through them with the Left and Right arrows or pick them from the panel.

Cloth

The cloth wipes away exactly what it passes over, from a small notch to a whole stroke. It is available inside /mural paint and on its own as /mural erase for walls you are not currently painting.

Config.Eraser = {
    radiusDefault = 0.08,
    radiusMin = 0.01,
    radiusMax = 0.30,
    radiusStep = 0.01,
    toggleKey = 0xCEFD9220
}
SettingDefaultBehaviour
radiusDefault0.08Starting radius of the stand-alone cloth, in metres. Inside /mural paint the cloth starts at the brush size.
radiusMin0.01Smallest cloth radius.
radiusMax0.30Largest cloth radius.
radiusStep0.01How much the radius changes per step.
toggleKey0xCEFD9220Switches between brush and cloth while painting. Defaults to E.

The cloth only removes paint. Pressing it on a picture removes the whole picture.

Pictures

Picture mode fills the painting area with a PNG or JPG image. The image is not pasted on: it is rebuilt from translucent brush strokes laid over each other, so it reads as a painting on the wall. Painters can keep painting on top of it.

Config.Image = {
    requirePermission = true,
    adminsAlwaysAllowed = true,

    maxTris = 800,
    defaultTris = 700,
    paintAlpha = 0.45
}
SettingDefaultBehaviour
requirePermissiontrueLocks the Picture button until an admin enables it for that player in the ledger. false opens pictures to everyone.
adminsAlwaysAllowedtrueAdministrators can always place pictures.
maxTris800Highest stroke count the picture slider allows.
defaultTris700Stroke count the slider starts at.
paintAlpha0.45Opacity of each stroke. Lower is softer and more blended; higher is flatter with harder edges.

The server enforces the permission as well. A picture sent by a player without it is dropped, and the rest of their paint is kept.

More strokes bring the picture closer to the original. A far-away picture is drawn with fewer of its strokes, so it looks blocked in rather than incomplete. In the panel, players choose between soft, normal, sharp, and hard, which map to different paintAlpha values.

Paint bucket

The bucket is placed on the ground to the painter’s right as soon as the area is locked, and it shows the colour currently on the brush.

Config.Props = {
    bucket = {
        model = 'p_bucketcampmil01x',
        side = 0.6,
        fromWall = 0.35,
        reach = 3.0,
        radius = 0.35,
        paint = { z = 0.20, radius = 0.11, segments = 12 }
    }
}
SettingDefaultBehaviour
model'p_bucketcampmil01x'Prop used for the bucket.
side0.6Metres to the painter’s right, along the wall.
fromWall0.35Metres out from the wall.
reach3.0Maximum distance the brush can be dipped from.
radius0.35How precisely the painter must look at the bucket.
paint.z0.20Height of the paint surface above the prop’s origin.
paint.radius0.11Width of the paint surface.
paint.segments12Smoothness of the paint surface’s edge.

If you change model, adjust paint.z and paint.radius until the paint sits just under the rim instead of floating above it or hiding inside the prop.

There is no brush prop in the painter’s hand by design: first person view in RedM only draws the arm for weapons the game places there itself.

Rendering

Config.Poly controls how strokes are simplified and how murals are drawn at a distance.

Config.Poly = {
    simplifyEpsilon = 2.0,
    minSegment = 2.5,
    doubleSided = false,

    fullDetailDist = 18.0,
    lod2Dist = 28.0,
    hideDist = 45.0,
    lodEpsilonMul = 3.0,

    maxTrisPerFrame = 900
}

Detail

SettingDefaultBehaviour
simplifyEpsilon2.0Curve simplification tolerance in canvas pixels. 2.0 is visually lossless for freehand work.
minSegment2.5Segments shorter than this, in canvas pixels, are dropped.
doubleSidedfalseDraws murals from behind the wall as well. Doubles the drawing cost; leave it off.

Distance levels

SettingDefaultBehaviour
fullDetailDist18.0Within this many metres, murals are drawn at full detail.
lod2Dist28.0Up to this distance, murals use the first reduced level. Beyond it, the second.
hideDist45.0Beyond this distance, murals are not drawn.
lodEpsilonMul3.0How much coarser the reduced levels are. They keep the shape of each stroke rather than dropping points at random.

Per-frame budget

maxTrisPerFrame is the total number of triangles drawn in one frame across every mural on screen.

Do not raise maxTrisPerFrame above roughly 950. RedM accepts about 1024 script draw requests per frame, shared by every resource, and silently drops anything beyond that. The default of 900 leaves room for the painting panel and other resources.

When several murals are on screen and the budget runs short, the ones further away step down to a reduced level instead of disappearing. The budget is calculated per client and per frame, so it limits what one screen shows at a time, never how many murals the server can hold.

Framework

Config.Framework = 'auto'
Framework modeUse
'auto'Detects rsg-core or vorp_core automatically.
'standalone'Uses license identifiers and server player names.

Under a framework, murals are recorded against the character, and per-player limits apply per character.

Administrator access

The Wall Ledger lists every mural with its painter, date, location, size, and stroke count. Administrators can preview, teleport to, and remove any mural, clear all of them, and turn picture permission on or off per player.

Config.Admin = {
    command = 'muraladmin',
    ace = 'rx_murals.admin',
    allowCommandAce = true,
    groups = { admin = true, god = true, superadmin = true },
    identifiers = {}
}
SettingDefaultBehaviour
command'muraladmin'Command that opens the Wall Ledger.
ace'rx_murals.admin'ACE permission that marks a mural administrator.
allowCommandAcetrueAnyone allowed to run server commands is also an administrator.
groupsadmin, god, superadminFramework groups treated as administrators.
identifiersEmptySpecific citizen IDs or licenses with administrator access, as ['identifier'] = true.

Any one of these sources is enough to make a player an administrator.

Item mode

With item mode on, painting starts by using an inventory item rather than a command.

Config.Items = {
    enabled = true,
    paint = { name = 'paintkit', label = 'paint kit', consume = false },
    cloth = { name = 'rag', label = 'rag' },
    adminBypass = true
}
SettingDefaultBehaviour
enabledtrueStarts painting and erasing from items instead of commands.
paint.name'paintkit'Inventory item that starts painting.
paint.label'paint kit'Name used in messages telling players what to use.
paint.consumefalseRemoves one item for every finished mural.
cloth.name'rag'Inventory item that starts the stand-alone cloth.
cloth.label'rag'Name used in messages.
adminBypasstrueAdministrators can still use /mural paint and /mural erase.

Set paint or cloth to false to keep that mode on its command. Item names must already exist in your inventory; see Installation for the item entries.

Item mode needs RSG or VORP. On a standalone server the commands stay available and the console reports it on start.

Sync and limits

Config.Sync controls how murals are sent to players, where they are saved, and what the server accepts.

Config.Sync = {
    bps = 1000000,
    saveDelay = 2000,
    dataFile = 'data/murals.json',

    maxStrokes = 2000,
    maxPoints = 60000,
    maxHoles = 800,

    maxPerPlayer = 25,
    maxTotal = 500,

    reach = 30.0
}

Transfer and saving

SettingDefaultBehaviour
bps1000000Transfer rate in bits per second. A large painting of around 100 KB arrives in about a second instead of one heavy packet.
saveDelay2000Milliseconds after the last change before dataFile is written.
dataFile'data/murals.json'Where murals are stored, relative to the resource folder.

Per-mural caps

The server enforces these whatever a client sends.

SettingDefaultBehaviour
maxStrokes2000Most strokes a single mural may hold.
maxPoints60000Most points across all strokes of one mural.
maxHoles800Most cloth wipes stored on one mural.

Mural counts

SettingDefaultBehaviour
maxPerPlayer25Most murals one character may own. Administrators are not limited.
maxTotal500Most murals on the whole server.
reach30.0A mural can only be placed or changed by a player within this many metres of it.

Set either count to 0 to remove the limit. Every mural is sent to each player when they join, so maxTotal also keeps joining fast. Raise it with care on busy servers.

reach rejects requests that come from nowhere near the wall. Corner picks and the cloth work up to about 15 metres, so normal painting is never affected.