OrigenNetwork
Docs

Configuration · origen_phone

FileWhat it holds
config/config.luaGameplay settings: prices, limits, keys, app behaviour. Shared with clients
config/bridge.luaWhich external system to use for each category
config/server.luaServer-only secrets (upload key). Never sent to clients
config/apps.luaHome-screen app catalogue and API domain ownership
config/widgets.luaHome-screen widget catalogue
config/pescabichos*.luaPescabichos game data: species, spawn zones, attacks, gyms, progression
locales/*.jsonTranslations

Most day-to-day settings (wallpapers, accents, battery, app access, prices, charging points, shops, valet) live in the admin panel (/telefonoadmin) and are stored in the database, so they change without a restart. The values in config/config.lua for those settings are only the defaults for a fresh installation.

config/config.lua is sent to every client. Never put secrets there: use config/server.lua or a convar.


config/bridge.lua

lua
BridgeConfig = {
    Framework = 'auto',
    Inventory = 'auto',
    Notify = 'auto',
    Banking = 'auto',
    Garage = 'auto',
    Housing = 'auto',
    Dispatch = 'auto',
    Business = 'auto',
    Uploader = 'auto',
    Weather = 'auto',
    Voice = 'auto',
    VehicleKeys = 'auto',
    Fuel = 'auto',
}
ValueBehaviour
'auto'Picks the first started resource from the supported list
'<resource>'Forces a specific resource by its exact folder name
'custom'Uses your implementation in custom/bridge/<category>/
'none'Disables the integration on purpose

See Dependencies for the supported resources of each category.


config/server.lua

lua
ServerConfig.Fivemanage = {
    ApiKey = GetConvar('ogphone_fivemanage_key', ''),
}
OptionDefaultDescription
ServerConfig.Fivemanage.ApiKeyconvar ogphone_fivemanage_keyFivemanage API key used by the default Uploader bridge. Prefer the convar over pasting the key in the file

General

OptionDefaultDescription
Config.Debugconvar ogphone_debugLogs every RPC to the console. Keep off in production
Config.EsxIdentifiernilESX only. xPlayer field holding the character identifier on multicharacter servers. Leave nil on single-character ESX
Config.Carrier'OGN MOVIL'Carrier name shown in the status bar
Config.Currency'$'Currency symbol used by invoices, fines and notifications

Item

OptionDefaultDescription
Config.Item.RequiretrueThe item is required to open the phone
Config.Item.UniquetrueEach phone is a separate item with its own metadata
Config.Item.Name'ognphone'Inventory item name
Config.Item.MetaNumber'ognPhoneNumber'Metadata key for the phone number
Config.Item.MetaFormatted'ognFormattedNumber'Metadata key for the formatted number
Config.Item.MetaName'ognPhoneName'Metadata key for the device name
Config.Item.MetaId'ognPhoneId'Metadata key for the phone record id. Tells which device showing a number is the real one. Written automatically to older items the first time they are opened
Config.Item.Owner'person'Who owns the data: 'person' (the character) or 'item' (the device). Controlled live from the admin panel; this is only the default

Phone numbers

OptionDefaultDescription
Config.PhoneNumber.Format'{2}-{4}'Display format. Numbers are stored as digits only
Config.PhoneNumber.Length4Digits after the prefix
Config.PhoneNumber.Prefixes{ '55', '60', '62', '68', '70' }Prefixes assigned to new numbers

Custom numbers

A VIP service: the player requests a number from Settings and an admin approves or denies it from the panel. Money is charged on approval, not on request.

OptionDefaultDescription
Config.Numbers.EnabledtrueEnables custom number requests
Config.Numbers.Price25000Price. 0 makes it free
Config.Numbers.KeepPrefixtrueThe requested number must start with one of the configured prefixes
Config.Numbers.Reservedsee belowNumbers that cannot be requested
lua
Config.Numbers.Reserved = {
    '550000', '551111', '552222', '555555',
    '600000', '601111', '606060', '666666',
    '700000', '707070', '777777',
}

Opening

OptionDefaultDescription
Config.Command'ogphone'Command to open or close the phone. false disables it
Config.Keybind'F1'Default key. Players can rebind it in the FiveM key bindings
Config.CloseOnDeathtrueCloses the phone when the player dies
Config.CloseWhenSwimmingtrueCloses the phone while swimming
Config.AllowInVehicletrueAllows using the phone inside vehicles

Animation and prop

OptionDefaultDescription
Config.Animation.EnabledtruePlays the phone animation
Config.Animation.Prop`prop_amb_phone`Prop model
Config.Animation.PropBone28422Bone the prop is attached to
Config.Animation.PropOffsetvector3(0.0, 0.0, 0.0)Prop offset
Config.Animation.PropRotationvector3(0.0, 0.0, 0.0)Prop rotation

Notifications

What players see when something arrives with the phone closed. The phone peeks up from the bottom edge with its frame, wallpaper and clock. Content is hidden when the player disabled previews or is in streamer mode.

OptionDefaultDescription
Config.Notifications.OutsidetrueShows the peeking phone. false only plays a sound
Config.Notifications.Side'right''right', 'center' or 'left'
Config.Notifications.Seconds6Time on screen
Config.Notifications.Max3Notifications stacked at once
Config.Notifications.AutoWaketrueTurns the phone on invisibly when the player spawns carrying one, so calls and messages reach them before they open it
Config.Notifications.WakeEvery20Seconds between checks for a carried phone

Server notifications

origen_notify notifications can also appear on the phone. They are not stored in the notification center.

OptionDefaultDescription
Config.ServerNotifications.EnabledfalseShows server notifications on the phone. The options below only apply when enabled
Config.ServerNotifications.Replacetruetrue moves the notification to the phone; false shows it in both places
Config.ServerNotifications.SoundfalsePlays the phone alert tone
Config.ServerNotifications.TypesnilTypes to show. nil or empty shows all. Example: { error = true, primary = true }
Config.ServerNotifications.Cooldown1500Identical text within this many milliseconds is not shown again

Logs

Sends phone activity to a Discord webhook. Message contents, photos and private data are never sent.

OptionDefaultDescription
Config.Logs.Webhook''Discord webhook URL. Empty disables logging
Config.Logs.Name'ORIGEN'Webhook sender name
lua
Config.Logs.What = {
    admin = true,        -- changes made from the admin panel
    numbers = true,      -- custom number requests and their outcome
    recovery = true,     -- recovered lines
    transfers = true,    -- money transfers
    blackmarket = true,  -- black market purchases
}

Storage

OptionDefaultDescription
Config.Storage.Capacity0Capacity in MB. 0 calculates it from Config.Uploader.MaxPhotos (recommended)
Config.Storage.Slack120Extra MB for non-photo content when capacity is auto-calculated
lua
Config.Storage.Weights = {
    photo   = 2400,
    video   = 18000,
    memo    = 900,
    note    = 4,
    message = 1,
}

Size counted per stored item, in kilobytes, when the real size is unknown.


Battery

OptionDefaultDescription
Config.Battery.EnabledfalseEnables battery drain
Config.Battery.DrainSeconds55Seconds per 1% with the phone open
Config.Battery.DrainSecondsIdle100Seconds per 1% with the phone closed
Config.Battery.ChargePerTick5Charge per tick
Config.Battery.ChargeMinutes20Minutes to fully charge at a charging point

Charging points are placed from the admin panel.


Line recovery and phone store

OptionDefaultDescription
Config.Recovery.EnabledtrueEnables line recovery at the carrier store
Config.Recovery.Price5000Recovery fee. 0 makes it free
Config.Recovery.Range3.0Distance from the counter, in meters
Config.Shop.EnabledtrueEnables the phone store
Config.Shop.PhonePrice1500Price of a new phone. 0 makes it free

Store locations are set from the admin panel under Map > Stores. Recovery uses the same counters.

lua
Config.Shop.Ped = {
    model = 's_m_m_highsec_01',
    heading = nil,
    scenario = 'WORLD_HUMAN_CLIPBOARD',
}
 
Config.Shop.Blip = {
    sprite = 606,
    color = 3,
    scale = 0.7,
}

Set Config.Shop.Ped or Config.Shop.Blip to false to disable the clerk or the blip.


Calls

OptionDefaultDescription
Config.Calls.KeyAnswer'RETURN'Default key to answer a ringing call
Config.Calls.KeyHangup'BACK'Default key to decline or hang up
Config.Calls.RingTimeout30Seconds it rings before counting as missed
Config.Calls.MaxDuration3600Safety cutoff, in seconds
Config.Calls.AllowVideotrueEnables video calls
Config.Calls.AllowRecordingtrueEnables call recording. The other party is recorded without being notified
Config.Calls.AllowVoiceFiltertrueEnables the voice changer. The filter runs on the listener's client
Config.Calls.SpeakerRadius3.0Meters within which nearby players join a speakerphone call
Config.Calls.MaxParticipants5Maximum people in a call, including the two who started it
lua
Config.Calls.Emergency = {
    ['911'] = 'police',
    ['112'] = 'police',
    ['police'] = 'police',
    ['061'] = 'ambulance',
    ['ambulance'] = 'ambulance',
    ['mechanic'] = 'mechanic',
}

Short numbers that route a call to a service job.

Video (frame fallback)

Used only when the WebRTC direct connection is not available.

OptionDefaultDescription
Config.Calls.Video.Fps12Frame rate ceiling
Config.Calls.Video.Width240Image width, in pixels
Config.Calls.Video.Quality0.5Starting JPEG quality (0 to 1)
Config.Calls.Video.KBPorSegundo96Maximum upload per side over the game connection, in KB/s
Config.Calls.Video.MaxConcurrent8Video calls sending images at the same time. Beyond this, calls have audio only

Raising KBPorSegundo is the only risky setting in this block. Frames travel over the same connection as the game; too much upload gets players kicked for timeout.

Voicemail

OptionDefaultDescription
Config.Voicemail.Window120Seconds after an unanswered call during which a message can be left
Config.Voicemail.MaxSeconds30Maximum recording length

WebRTC

OptionDefaultDescription
Config.WebRTC.EnabledtrueSends video peer-to-peer. When off or when the connection fails, it falls back to server-relayed frames
Config.WebRTC.Turn'cloudflare''cloudflare' requests TURN credentials from Cloudflare Realtime (needs the ogphone_turn_token_id and ogphone_turn_api_token convars). false uses STUN only
Config.WebRTC.TurnTtl86400Lifetime of the requested credentials, in seconds
Config.WebRTC.Timeout6Seconds to wait for the direct connection before falling back
Config.WebRTC.MaxKbit1000Maximum upload bitrate for direct video, in kbit/s
lua
Config.WebRTC.IceServers = {
    { urls = 'stun:stun.l.google.com:19302' },
    { urls = 'stun:stun1.l.google.com:19302' },
    -- { urls = 'turn:my.server:3478', username = 'user', credential = 'password' },
}

Messages

OptionDefaultDescription
Config.Messages.MaxLength1000Characters per message
Config.Messages.SystemNumber'900100'Sender number for server messages without a sender
Config.Messages.EditWindow900Seconds during which a message can be edited
Config.Messages.PageSize30Messages per page when scrolling
Config.Messages.MaxGroupMembers32Members per group chat
Config.Messages.AllowDeletetrueAllows deleting messages for everyone
Config.Messages.DeleteWindow3600Seconds during which a message can be deleted for everyone

Stickers

Packs bundled with the server, seeded into the database on startup by slug. URLs can be external or from the resource (nui://origen_phone/ui/...). Player packs are created from the gallery.

lua
Config.StickerPacks = {
    {
        slug = 'caras',
        title = 'Caras',
        cover = nil,
        stickers = {
            { emoji = '😀' }, { emoji = '😂' }, -- ...
        },
    },
    -- 'ciudad', 'reacciones'
}

OptionDefaultDescription
Config.Uploader.MaxPhotos500Photos per phone
Config.Uploader.TrashDays30Days in the trash before permanent deletion

Contacts, alarms and mail

OptionDefaultDescription
Config.Contacts.ShareRange5.0Meters within which a number can be shared face to face
Config.Alarms.Max10Alarms per phone
Config.Alarms.RingSeconds30Seconds an alarm rings before stopping
Config.Mail.Domain'ogn.net'Domain of the server's email addresses
Config.Mail.MaxLength4000Characters per email
Config.Mail.MaxRecipients10Recipients per email
Config.Mail.MaxAttachments6Attachments per email (links, not files)

OGN (social network)

OptionDefaultDescription
Config.OGN.EnabledtrueEnables the social network
Config.OGN.UsernamePattern'^[%w%._]+$'Allowed username characters
Config.OGN.UsernameMin3Minimum username length
Config.OGN.UsernameMax20Maximum username length
Config.OGN.MaxCaption2200Characters per caption
Config.OGN.MaxComment500Characters per comment
Config.OGN.MaxMediaPerPost10Media per post
Config.OGN.StoryHours24Story lifetime
Config.OGN.FeedPageSize12Posts per feed page
Config.OGN.CostToVerifyfalsePrice for verification. false disables paid verification

Livestreams

OptionDefaultDescription
Config.OGN.Live.EnabledtrueEnables livestreams
Config.OGN.Live.Fps2Frames per second
Config.OGN.Live.Width320Longest side of the image, in pixels
Config.OGN.Live.Quality0.45JPEG quality (0 to 1)
Config.OGN.Live.MaxConcurrent3Concurrent streams across the server
Config.OGN.Live.MaxViewers20Viewers per stream. Lower this first if bandwidth is tight
Config.OGN.Live.ChatLines60Chat lines kept during the stream

OGN Fans

Pay-to-unlock photos. Non-buyers see the photo pixelated.

OptionDefaultDescription
Config.Fans.Commission0.20Server cut of each sale and tip (0 to 1)
Config.Fans.MinPrice0Minimum photo price. 0 is free
Config.Fans.MaxPrice50000Maximum photo price
Config.Fans.MinTip10Minimum tip
Config.Fans.MaxTip100000Maximum tip
Config.Fans.PageSize20Posts per page
Config.Fans.ImageHosts{ 'fivemanage.com', 'fmfile.com' }Hosts the server may download from to pixelate photos
Config.Fans.MaxImageBytes8388608Maximum size of the downloaded photo, in bytes

DarkChat

The "encryption" is roleplay only: messages are stored in the database and staff can read them.

OptionDefaultDescription
Config.DarkChat.EnabledtrueEnables DarkChat
Config.DarkChat.CodeLength6Room code length
Config.DarkChat.MaxMembers24Members per room
Config.DarkChat.MaxRooms8Rooms a player can have open
Config.DarkChat.InviteRadius3.0Meters within which someone can be added without the code
Config.DarkChat.BurnOptions{ 0, 5, 30, 60, 1440 }Self-destruct options, in minutes. 0 never deletes

Black market

Listings under an alias, delivered through dead drops.

OptionDefaultDescription
Config.BlackMarket.EnabledtrueEnables the black market
Config.BlackMarket.Days3Days a listing lasts
Config.BlackMarket.MaxPerPhone6Active listings per player
Config.BlackMarket.MaxItems6Distinct items per listing
Config.BlackMarket.MaxStock50Units per listing
Config.BlackMarket.Commission0.1Commission per sale
Config.BlackMarket.DropRadius5.0Pickup distance for a dead drop, in meters
Config.BlackMarket.DropMinutes60Minutes a package stays at the drop before the deal is cancelled and refunded
lua
Config.BlackMarket.Blocked = {
    'vehiclekey', 'vehicle_key', 'carkeys', 'keys',
    'vehicledocs', 'vehicle_papers', 'documentacion_vehiculo',
}

Ads and marketplace

OptionDefaultDescription
Config.Ads.Days7Days an ad lasts
Config.Ads.MaxPerPhone5Active ads per phone
Config.Ads.Cost0Cost to publish. 0 is free
Config.Market.MaxItems6Distinct items per listing
Config.Market.MaxStock50Units per listing
Config.Market.Commission0.05Platform commission per sale
lua
Config.Ads.Categories = {
    { id = 'venta',     label = 'Se vende' },
    { id = 'compra',    label = 'Se compra' },
    { id = 'servicios', label = 'Servicios' },
    { id = 'empleo',    label = 'Empleo' },
    { id = 'vivienda',  label = 'Vivienda' },
    { id = 'general',   label = 'General' },
}
 
Config.Market.Blocked = {
    'vehiclekey', 'vehicle_key', 'carkeys', 'keys',
    'vehicledocs', 'vehicle_papers', 'documentacion_vehiculo',
}

Sold items leave the seller's inventory and arrive in the buyer's, delivered by a Mandao courier.


Rides: Taxi and GO

OptionDefaultDescription
Config.Rides.MinDistance100Minimum ride distance, in meters
Config.Rides.DriverCut0.85Share kept by the driver. The rest leaves the economy
Config.Rides.Timeout5Minutes an unaccepted request waits
Config.Rides.StuckMinutes30Minutes after acceptance before the passenger can cancel once in the vehicle
lua
Config.Rides.Taxi = {
    label = 'Taxi',
    employer = {
        jobs = { 'taxi' },
        businesses = { 'taxi' },
    },
    base = 150,
    perKm = 45,
}
 
Config.Rides.Go = {
    label = 'GO',
    employer = false,
    base = 300,
    perKm = 90,
}
FieldDescription
employerWho can drive. jobs are framework jobs, businesses are business names or types from the Business bridge. Meeting either is enough. false lets anyone drive. Checked every time, not only at sign-up
baseBase fare
perKmFare per kilometer

NPC taxi fares

When there are free taxi drivers and few requests, fares from NPC passengers are generated. The server validates the driver's position at pickup and destination and rejects impossible arrival times.

FieldDefaultDescription
enabledtrueEnables NPC fares
every45Seconds between generation checks
chance0.6Chance of a fare on each check (0 to 1)
perDriver1Maximum pending NPC fares per free driver
maxPending4Maximum pending NPC fares in total
nearDriver2500Pickup within this distance of a free driver, in meters
minTrip / maxTrip600 / 4500Trip length range, in meters
radius80.0Radius around the point where the taxi must be
maxSpeed30Maximum plausible average speed, in m/s
fareFactor1.0NPC fare relative to the normal rate
modelslistPed models used as passengers
nameslistPassenger display names
noteslistNotes the passenger sends. Empty strings mean no note
placeslistPickup and drop-off points { x, y, z, label }. The passenger spawns on the nearest sidewalk

Mandao (deliveries)

OptionDefaultDescription
Config.Delivery.Base200Base delivery fare
Config.Delivery.PerKm60Fare per kilometer
Config.Delivery.CourierCut0.85Share kept by the courier
Config.Delivery.Timeout20Minutes an unaccepted job waits
Config.Delivery.Deadline10Minutes to deliver an accepted job. When it expires, goods are delivered anyway and the courier gets a strike
Config.Delivery.StrikeBans{ 10, 30, 60 }Ban minutes per strike. The last entry repeats
Config.Delivery.StrikeReset120Minutes without failures before strikes are forgotten
Config.Delivery.MinDistance150Minimum delivery distance, in meters
Config.Delivery.Reach8.0Distance required to pick up or deliver, in meters
Config.Delivery.MaxItems8Distinct items per player-to-player delivery
Config.Delivery.EmployerfalseWho can deliver. Same format as Config.Rides.Taxi.employer
Config.Delivery.HandleBusinessOrderstrueBusiness orders wait for a courier instead of arriving automatically
Config.Delivery.BusinessFee450What the business pays the courier for delivering its order
lua
Config.Delivery.Depots = {
    { label = 'Almacen de mercancia · Muelle 1', x = 95.67,  y = -1746.8,  z = 28.7,  h = 140.88 },
    { label = 'Almacen de mercancia · Muelle 2', x = 99.68,  y = -1749.3,  z = 28.71, h = 139.86 },
    { label = 'Almacen de mercancia · Muelle 3', x = 103.73, y = -1751.94, z = 28.72, h = 139.62 },
}

Where business order goods are picked up. Empty means pickup at the business itself.


Beboteo (dating)

OptionDefaultDescription
Config.Dating.DailyLikes20Daily likes for non-VIP users
Config.Dating.MaxPhotos6Photos per profile
Config.Dating.VipPrice5000VIP price
Config.Dating.VipDays30VIP duration
Config.Dating.VipLabel'BEBOTEO VIP'VIP badge label
lua
Config.Dating.Genders = {
    hombre = 'dating_gender_male',
    mujer = 'dating_gender_female',
    otro = 'dating_gender_other',
}

The key is stored and compared; the value is the locale key shown.


Bank, invoices and fines

OptionDefaultDescription
Config.Bank.MaxTransfer500000Limit per transfer from the phone
Config.Bank.MaxDaily2000000Total that can be moved per day. 0 removes the limit
Config.Bank.MaxWeekly8000000Total that can be moved per week. 0 removes the limit
Config.FineAccount''Account that receives fine payments. Empty charges the player without depositing anywhere

Crypto

Disabled by default because it fetches live prices from the internet. To enable it, set Config.Crypto.Enabled = true, add { id = 'crypto', label = 'Monedas', slot = 27, default = true } to Apps and crypto = 'crypto' to AppDomains in config/apps.lua.

OptionDefaultDescription
Config.Crypto.EnabledfalseEnables crypto trading
Config.Crypto.ApiCoinGecko public endpointPrice source. No API key needed
Config.Crypto.Currency'usd'Price currency
Config.Crypto.Refresh300Seconds between price fetches (shared by the whole server)
Config.Crypto.Fee0.02House fee per trade
Config.Crypto.MaxPerTrade500000Maximum amount per trade. 0 removes the limit
lua
Config.Crypto.Coins = {
    'bitcoin', 'ethereum', 'solana', 'dogecoin', 'cardano', 'litecoin',
}
 
Config.Crypto.Names = {
    bitcoin  = 'Bitoro',
    ethereum = 'Etherna',
    solana   = 'Solaris',
    dogecoin = 'Perrocoin',
    cardano  = 'Cardina',
    litecoin = 'Ligera',
}

If the price source does not respond, trading is disabled.


Browser

Opens only whitelisted sites. Domains are matched, so origen.net allows all its pages and subdomains.

OptionDefaultDescription
Config.Browser.EnabledtrueEnables the browser
Config.Browser.Home''Start page. Empty starts on the bookmarks
Config.Browser.Sites{}Allowed sites. Empty opens nothing
Config.Browser.Bookmarks{}Bookmarks defined by the server

Music

lua
Config.Music.Stations = {
    -- { id = 'ogn', name = 'Radio OGN', genre = 'Mixed', url = 'https://...' },
}
Config.Music.AllowCustomUrl = true

The URL must be a stream the browser can play (mp3, aac or audio m3u8). It only plays for the player who starts it.


News

lua
Config.News.Publishers = {
    businesses = { 'weazel', 'weazelnews', 'cnt' },
    jobs = { 'reporter', 'weazel', 'weazelnews', 'cnt' },
    error = 'err_news_need_job',
}
Config.News.MaxPerDay = 6

Who can write articles from the phone. Meeting one of businesses or jobs is enough. Set Publishers to false to publish only through the PublishNews export. MaxPerDay is the limit per phone; 0 removes it.


Emergency services

Alerts are sent to the Dispatch bridge with the caller's position.

lua
Config.Services.Cooldown = 60
Config.Services.List = {
    {
        id = 'police',
        label = 'Policia',
        description = 'Robos y peleas',
        icon = 'lucide:shield',
        job = 'police',
        alertTitle = 'Aviso ciudadano',
    },
    {
        id = 'ambulance',
        label = 'Emergencias medicas',
        description = 'Heridos y accidentes',
        icon = 'lucide:cross',
        job = 'ambulance',
        alertTitle = 'Aviso medico',
    },
}
FieldDescription
CooldownSeconds between alerts from the same phone
jobJob that receives the alert
alertTitleTitle of the dispatch alert

Mechanics and tow trucks do not go here: with a business resource they appear as businesses in the app.


Moderation

OptionDefaultDescription
Config.Filter.EnabledtrueEnables the filters
Config.Filter.Words{}Words masked in everything a player writes. Matched inside words, case and accent insensitive. Ships empty
Config.Filter.Mask'***'Replacement text
Config.Filter.ReservedNamessee belowNames forbidden in usernames, aliases and profile names
lua
Config.Filter.ReservedNames = {
    'admin', 'administrador', 'staff', 'moderador', 'soporte', 'support',
    'police', 'policia', 'lspd', 'bcso', 'sheriff', 'ems', 'sama', 'emergencias',
    'origen', 'ogn', 'sistema', 'system', 'oficial', 'official',
}

Admin panel and app access

OptionDefaultDescription
Config.Admin.Command'telefonoadmin'Command that opens the panel
Config.Admin.Ace'ogphone.admin'ACE permission
Config.Admin.Export{ resource = 'origen_admin', method = 'IsAdmin' }Export that receives the source and returns true or false. Runs inside pcall
Config.Admin.Licenses{}Individual identifiers allowed
Config.AppRules.Unemployed'unemployed'Job name for players without a job
Config.AppRules.NoGang'none'Gang name for players not in a gang

App access rules (who gets which app) are set from the admin panel or with the SetAppRule export.


Appearance and sounds

These are defaults; once changed from the panel, the database values take over.

lua
Config.Wallpapers = {
    { id = 'default',  label = 'ORIGEN',             url = 'images/wallpapers/origen.jpg' },
    { id = 'gradient', label = 'wallpaper_gradient', url = 'images/wallpapers/default.svg' },
    { id = 'midnight', label = 'wallpaper_midnight', url = 'images/wallpapers/midnight.svg' },
    { id = 'sunset',   label = 'wallpaper_sunset',   url = 'images/wallpapers/sunset.svg' },
    { id = 'forest',   label = 'wallpaper_forest',   url = 'images/wallpapers/forest.svg' },
    { id = 'carbon',   label = 'wallpaper_carbon',   url = 'images/wallpapers/carbon.svg' },
    { id = 'light',    label = 'wallpaper_light',    url = 'images/wallpapers/light.svg', light = true },
}
 
Config.Accents = {
    { id = 'origen', label = 'ORIGEN',        acc = '#fc0259', rgb = '252, 2, 89',   soft = '#fc0259', pale = '#fd9bbd', deep = '#82173c' },
    { id = 'blue',   label = 'accent_blue',   acc = '#2f7dff', rgb = '47, 125, 255', soft = '#2f7dff', pale = '#a8c8ff', deep = '#173f82' },
    -- green, yellow, red, orange
}

url can be a file in ui/images/wallpapers or an external address. label can be a locale key or plain text.

lua
Config.Sounds.Ringtones = {
    { id = 'ring1', label = 'ringtone_1', file = 'Ringtone1.mp3' },
    -- ring2 ... ring6
}
 
Config.Sounds.Ringback = { sound = 'Remote_Ring', set = 'Phone_SoundSet_Michael', loops = true }
Config.Sounds.Hangup   = { sound = 'Hang_Up', set = 'Phone_SoundSet_Michael' }
 
Config.Sounds.Alerts = {
    { id = 'aviso1', label = 'alert_tone_1', file = 'Notificacion1.mp3' },
    -- aviso2 ... aviso5
    { id = 'silent', label = 'alert_tone_none', file = false },
}

Ringtones and alerts are files in ui/sounds/. The id is saved in each player's settings, so it must not change once published.


Languages

OptionDefaultDescription
Config.DefaultLanguage'es'Default phone language
Config.Languages{ 'es', 'en', 'fr', 'de', 'pt' }Available languages. With one, the language selector is hidden
Config.DateLocaleses-ES, en-GB, fr-FR, de-DE, pt-PTDate and number formatting per language
Config.DateLocale'es-ES'Fallback for a language missing from DateLocales

To add a language, copy locales/en.json, translate it and add its code to Config.Languages and Config.DateLocales.


config/apps.lua

The server's source of truth for which apps exist. Editing the UI is not enough to get into an app.

FieldDescription
idApp identifier
labelDisplay name
slotPosition on the home-screen grid (1 to 24 per page)
dockPlaced in the bottom dock instead of the grid
defaultInstalled by default
fijaCannot be uninstalled from the app store
lua
Apps = {
    { id = 'phone',    label = 'Telefono', dock = 1, default = true, fija = true },
    { id = 'messages', label = 'Mensajes', dock = 2, default = true, fija = true },
    { id = 'ogn',      label = 'OGN',      dock = 3, default = true },
    { id = 'camera',   label = 'Camara',   dock = 4, default = true },
 
    { id = 'store',    label = 'Apps',       slot = 1, default = true, fija = true },
    { id = 'widgets',  label = 'Widgets',    slot = 2, default = true, fija = true },
    { id = 'gallery',  label = 'Galeria',    slot = 3, default = true },
    { id = 'settings', label = 'Ajustes',    slot = 4, default = true, fija = true },
    -- notes, calendar, map, weather, music, news, bank, ads, services, vehicles,
    -- mail, taxi, go, invoices, fines, clock, delivery, dating, calculator,
    -- properties, browser, voicememo, darkchat, blackmarket, fans, pescabichos
}

Remove an app from this list to disable it for everyone. To restrict it to some players (civilians, a gang, a job), use the admin panel instead.

AppDomains maps each server API domain to the app that owns it. When a player loses access to an app, its server methods stop answering them, so access is enforced server-side.


config/widgets.lua

lua
Widgets.Catalogo = {
    { id = 'servidor',    label = 'widget_name_server',     fuente = 'propio' },
    { id = 'weather',     label = 'widget_name_weather',    fuente = 'propio' },
    { id = 'bank',        label = 'widget_name_bank',       fuente = 'propio' },
    { id = 'trabajo',     label = 'widget_name_job',        fuente = 'fuera'  },
    { id = 'emergencias', label = 'widget_name_emergency',  fuente = 'propio' },
    { id = 'multas',      label = 'widget_name_bills',      fuente = 'propio' },
    { id = 'garaje',      label = 'widget_name_garage',     fuente = 'propio' },
    { id = 'negocio',     label = 'widget_name_business',   fuente = 'fuera'  },
    { id = 'facciones',   label = 'widget_name_factions',   fuente = 'propio' },
    { id = 'ruta',        label = 'widget_name_route',      fuente = 'propio' },
    { id = 'radio',       label = 'widget_name_radio',      fuente = 'fuera'  },
    { id = 'anuncios',    label = 'widget_name_ads',        fuente = 'propio' },
    { id = 'battery',     label = 'widget_name_battery',    fuente = 'propio' },
    { id = 'activity',    label = 'widget_name_activity',   fuente = 'propio' },
}
fuenteMeaning
'propio'Filled by the phone itself
'fuera'Filled by another resource with the SetWidgetData export

Widget permissions are managed in the admin panel.


Pescabichos

Game data for the creature-catching app. Names and texts are locale keys (pb_sp_12, pb_sp_12_desc, pb_atk_12_1); rename a creature by editing that key in each locales/*.json. A value that is not a key is shown as written.

FileWhat it holds
config/pescabichos.luaTypes, rarities, spawn zones and species 1 to 50
config/pescabichos_especies2.lua / pescabichos_especies3.luaSpecies 51 onwards
config/pescabichos_combate.luaBattles, type chart, moves per type, gyms, raids, evolution
config/pescabichos_ataques.luaAttacks of each creature
config/pescabichos_progreso.luaPlayer level, unlocks and shop

Species fields

FieldDescription
idCollection number (1 to 200). Also the image name: ui/images/pescabichos/<id>.webp
nombreLocale key of the name
tiposOne or two of asfalto, neon, marea, polvo, pino, chatarra, brasa, niebla
rarezacomun, poco, rara, epica or legendaria
zonasWhere it spawns. Empty is anywhere on land. 'mar' is real water
pesoOptional spawn weight. Defaults to its rarity's
stockOptional maximum across the whole server
redOptional special net required to catch it
dificultadOptional catch difficulty (1 to 5)
horanil always, 'noche' (21-6) or 'dia' (7-20)
familia / faseEvolution line and stage (1, 2 or 3)
pcMinimum and maximum power it spawns with
textoLocale key of its dex entry

Rarities

lua
Pescabichos.Rarezas = {
    comun      = { nombre = 'pb_rarity_comun',      peso = 100, captura = 0.55, huye = 0.08, xp = 100 },
    poco       = { nombre = 'pb_rarity_poco',       peso = 38,  captura = 0.35, huye = 0.12, xp = 200 },
    rara       = { nombre = 'pb_rarity_rara',       peso = 12,  captura = 0.20, huye = 0.18, xp = 500 },
    epica      = { nombre = 'pb_rarity_epica',      peso = 3,   captura = 0.09, huye = 0.25, xp = 1500 },
    legendaria = { nombre = 'pb_rarity_legendaria', peso = 1,   captura = 0.04, huye = 0.35, xp = 4000 },
}
FieldDescription
pesoSpawn weight against the other rarities
capturaBase catch chance
huyeChance it flees after a failed attempt
xpXP granted for catching it

Zones

Land zones are map rectangles { min x, min y, max x, max y }, checked in order (small zones first). Outside all of them the zone is campo.

lua
Pescabichos.Zonas = {
    { id = 'alamo',      nombre = 'pb_area_1', caja = { 300, 3850, 2050, 4600 } },
    { id = 'industrial', nombre = 'pb_area_2', caja = { -350, -3450, 1500, -2350 } },
    -- ...
}

Progression

lua
P.NivelPescadorMax = 50
 
P.Progreso = {
    rareza = { comun = 1, poco = 1, rara = 5, epica = 12, legendaria = 20 },
    salvajes = { abajo = 8, arriba = 3, max = 35 },
    porEncima = { resta = 0.05, limite = 10 },
    topeBicho = 10,
    abre = { entrenar = 3, duelos = 5, equipo = 8, intercambios = 10, incursiones = 10 },
}
FieldDescription
rarezaPlayer level from which each rarity spawns
salvajesWild creature levels relative to the player (abajo, arriba, max)
porEncimaCatch chance penalty per level above the player, and the level gap at which it cannot be caught
topeBichoCreatures can level up to player level plus this
abreLevel at which each feature unlocks