RedM documentation

Murphy's Barber

Reference

Character Creator Integration - SetClothesForChar & SetHairForChar

Barber: Creator integration reference with a real storefront demo screenshot and its source.


Official API for external character creators / selectors (e.g. Spooni Character Creator) that need to hand a finished look to murphy_clothing and murphy_barber so it persists and re-applies on every spawn.

Requires: murphy_clothing 3.44.0+ and murphy_barber 1.21.0+.

These two exports are stable API - their signatures and data format will not change across versions. Do not write into the murphy_clothes / murphy_barber SQL tables directly: the exports validate, store and re-apply exactly like the shop/barber would, and keep working if the storage layer changes.


Quick start

lua
-- Server-side, right after your creator finishes a character:
local ok, err = exports.murphy_clothing:SetClothesForChar(charid, {
hats = { model = 3, texture = 0 },
shirts_full = { model = 5, texture = { palette = 2, tint0 = 17, tint1 = 17, tint2 = 17 } },
pants = { model = 2, texture = 1 },
boots = { model = 4, texture = 0 },
})
if not ok then print(err) end
local ok2, err2 = exports.murphy_barber:SetHairForChar(charid, {
hair = { model = 2, texture = 0 },
beard = { model = 1, texture = 0 },
})
if not ok2 then print(err2) end

Both exports:

  • are server-side only;
  • work for online and offline characters - write the row at creation time, it is picked up on the character's next spawn. If the player is online right now, the look is re-applied on screen instantly;
  • return true on success, or false, "error message" if the payload is malformed (nothing is written in that case).

Who owns which category

Resource Categories
murphy_clothing All clothing: hats, coats, shirts_full, vests, pants, boots, masks, accessories, ...
murphy_barber hair, hair_bonnet, beard, beards_complete, beards_chin, beards_mustache, beards_chops + makeup/face overlays

SetClothesForChar silently strips essential categories (skin, heads, body, hair, beard, ...) exactly like a normal shop save - hair sent to the clothing export is discarded, not saved. Always call both exports.


The charid parameter

The framework's character identifier, passed as-is (the exports treat it as opaque - int or string both work):

Framework Value
VORP charIdentifier (number)
RSG / QBR citizenid (string)
REDEMRP2k23 citizenid

Data format: the murphy index format

Both exports take the same shape for clothing/hair entries:

lua
{
[category] = {
model = <number>, -- 1-based index into MURPHY_ASSETS[gender][category]
texture = <number> -- variant index (MP/hash assets)
-- or
texture = { -- tinted/drawable assets
palette = <number>, -- variant index
tint0 = <number>,
tint1 = <number>,
tint2 = <number>,
},
},
}

model is not a game hash - it is an index into the catalog shipped unencrypted in shared/murphy_assets.lua of each resource. Setting model = 0 means "nothing equipped in this category".

Mapping your GUIDs / hashes to catalog indexes

MURPHY_ASSETS is structured as MURPHY_ASSETS[gender][category] (gender = "male" / "female"), an ordered array where each entry is one of:

  • Drawable/NPC asset: { drawable = <hash>, variants = { { albedo = ..., normal = ..., material = ..., palette = ..., tint = {...} }, ... } } → find the index whose drawable equals your GUID; the texture.palette value selects the entry in variants.
  • MP/hash asset: an array of { hash = <hash>, ... } entries → find the index whose entries contain your hash; the bare texture number selects which entry.

A simple reverse-lookup you can build once at startup:

lua
local index = {}
for gender, categories in pairs(MURPHY_ASSETS) do
index[gender] = {}
for category, assets in pairs(categories) do
index[gender][category] = {}
for i, asset in ipairs(assets) do
if asset.drawable then
index[gender][category][asset.drawable] = { model = i }
else
for v, entry in ipairs(asset) do
if entry.hash then
index[gender][category][entry.hash] = { model = i, texture = v }
end
end
end
end
end
end

exports.murphy_clothing:SetClothesForChar(charid, clothes, outfitId)

Param Type Description
charid number/string Framework character identifier (see above)
clothes table Murphy index format, one entry per category
outfitId number (optional) Saved-outfit preset id to link; defaults to 0 (no preset)

Behavior:

  • Essential categories are stripped like a normal save.
  • UPSERTs the character's row in murphy_clothes.
  • Fires the server event murphy_clothing:clothesUpdated(source, charid, clothes) after every write (source is nil when the character is offline).
  • If the player is online, pushes murphy_clothing:loadclothes to their client so the outfit applies immediately.

exports.murphy_barber:SetHairForChar(charid, hairstyle, overlays)

Param Type Description
charid number/string Framework character identifier
hairstyle table Murphy index format; categories: hair, hair_bonnet, beard, beards_complete, beards_chin, beards_mustache, beards_chops
overlays table (optional) List of overlay layer records (see below). Pass nil to leave the character's stored overlays untouched

Behavior:

  • UPSERTs the character's row in murphy_barber and resets its preset link (outfit_id = 0).
  • If overlays is provided, the layers are split into makeup vs permanent overlays via Config.Overlayitems, exactly like a barber save. If nil, existing overlays are preserved.
  • If the player is online, pushes murphy_barber:loadbarberoverlay to their client so the look applies immediately.

Overlay layer format

Each entry in overlays is a full layer record with a name field:

lua
{
name = "eyebrows", -- which overlay slot
visibility = 1,
tx_id = 1, tx_normal = 0, tx_material = 0, tx_color_type = 0,
tx_opacity = 1.0, tx_unk = 0,
palette = 0,
palette_color_primary = 0, palette_color_secondary = 0, palette_color_tertiary = 0,
var = 0, opacity = 1.0,
}

Overlay names - makeup (re-appliable items): eyeliners, shadows, paintedmasks, blush, blush2, foundation, lipsticks. Permanent (face features): eyebrows, scars, scars2, scars3, acne, beardstabble, ageing, complex, disc, freckles, grime, hairstabble, moles, spots. (The exact split is the server's Config.Overlayitems.)


Reading the other direction

To stay in sync when players change their look in the murphy shops:

  • Event: murphy_clothing:clothesUpdated(source, charid, clothes) - server event fired after every clothing save (shop, outfit swap, or SetClothesForChar).
  • Export: exports.murphy_clothing:GetPlayerClothes(source) - returns the online player's worn set with resolved hashes: { [category] = { hash, drawable, albedo, normal, material, palette, tint0, tint1, tint2 } }.
  • Export: exports.murphy_barber:ReloadAppearance(source) - re-applies the stored barber look on top of a freshly loaded skin (useful after revives / skin reloads).

Common pitfalls

  • Don't write the SQL tables directly. Formats and constraints can change between versions; the exports are the stable contract.
  • Hair in the clothing export is discarded (essential-category strip). Use SetHairForChar.
  • model indexes are gender-specific. An index valid in MURPHY_ASSETS.male.hair is not necessarily valid in MURPHY_ASSETS.female.hair - map against the catalog for the character's gender.
  • Check the return value. false, err means nothing was written - log err during integration.

Illustrated integration

Hair and beard controls shown during character creation
Creator storefront demo, 00:22.

This real frame comes from the Creator storefront video. The recording does not identify its plugin version or framework. It illustrates the visible integration; it does not validate the API examples above on every framework.


Last updated: September 9, 2026