Jixryo Trail Cams

Trail cameras strapped to trees or set on steel poles, with SIM cards, motion detection checked by the server, photos, a live feed, alerts on the phone and the tablet, department cameras for the police, and a Staff tab.

Version 1.3.0 Updated See it on its script page

On this page

Jixryo Trail Cams puts real trail cameras in the world. Buy one, strap it to a tree or drive a steel pole into open ground, slot a SIM card, and the camera watches its cone for animals, people and vehicles. Nearby players' games report what is really inside it; the server checks every report, names the species or the vehicle itself, records the sighting and sends the alert to the camera's owner. The TrailCam app shows your cameras as live feeds, the sightings as a photo wall, your alert settings and, for staff, every camera in the city. It comes as two resources: jixryo_trailcam (the cameras) and jixryo_trailcam_app (the TrailCam tablet, the lb-phone app and the app on the Jixryo Tablet).

What players get

  • Two cameras, each its own item, modelled on a cellular trail camera. The Ranger sees 14 m across 110 degrees. The Cellular Pro sees 20 m across 100 degrees, and its solar panel makes the battery last longer. On a tree the camera hangs on a strap fitted to the trunk: each game measures the trunk and shows the small, medium or large strap.
  • Placement. A ghost of the camera follows your aim with its detection cone, and a panel shows the mount, the pole and the SIM card, which way it faces, how high it sits and whether it is in reach and far enough from other cameras. Trunks, posts and walls take a strap; open ground takes the pole item. Tree mounts can be fine-tuned with the game's 3D gizmo. Then the work: wrap the strap round the trunk and cinch it, or drive the pole in (it sinks as you hammer) and screw the camera onto its bracket. Every step is an animation with a progress bar and a skill check, a slip can be retried twice, and nothing is taken from you until the camera is up. Up to 5 cameras per player, within 6 m of you, no higher than 2.5 m up a trunk, at least 20 m from any other camera.
  • SIM cards. A camera reports through its SIM. Without one it still sits there, but no sightings, alerts, photos or live feed get through. Placing a camera puts a SIM from your pockets in; the owner takes it out or puts one in later. Anyone else can pry it out through a hard skill check: the camera's last act is a photo of them and an alert to the owner.
  • The status light blinks slow green while the camera watches, fast green while it arms, amber on a low battery and red without a SIM, and goes dark when the battery dies. At night the four IR windows glow red when it fires.
  • The close-up. "Look at the screen" moves your view in to the camera's own screen: its battery, signal or NO SIM, when it last fired and the time; the panel beside it says the same in words. Anyone can read it; only the owner sees the camera's name.
  • Motion detection. A new camera waits 45 seconds before it starts watching. Games within 60 m scan its cone every 1.5 seconds for distance, field of view and line of sight; the server re-checks the reporter's position and every cooldown, records one event per camera every 20 seconds at most, and keeps the newest 60.
  • Photos are taken when you capture one: the snapshot button in a camera's live feed. A sighting on its own records what was seen and sends the notification without touching anyone's screen. Photos upload to Fivemanage when a key is set, otherwise they are resized to 1280 by 720 and stored in the database; lists only carry thumbnails, and the newest 20 photos per camera are kept.
  • Live view. A full-screen feed from the lens with the camera and area, battery, signal, night and time pills, the heading, the zoom and the key hints. Scroll zooms, the right mouse button toggles night vision, the left takes a snapshot, the arrows switch between your cameras. A session lasts 5 minutes at most, your character stands still, and taking damage, a dead battery or a destroyed camera cuts the feed with a SIGNAL LOST banner.
  • Alerts. Nothing pops up over the game. Motion and camera health arrive as a notification on lb-phone (with the photo when photos are hosted, and a Watch live button), on the TrailCam tablet while it is open, and in the Jixryo Tablet's notifications. Each player picks which kinds they get in the app's settings.
  • Battery. It drains 1.4 percent per real hour (about three days a cell), 0.15 percent per trigger and 1 percent per minute watched; the Cellular Pro drains at 0.6 of that. Swap it with the battery item. The low alert fires at 20 percent, once per battery.
  • Destructible. One shot or swing wrecks a camera, and it hangs off its strap.

What staff get

  • Police cameras. On-duty officers of any job of type leo set department cameras with the Surveillance Cam from the armory. A department camera belongs to the department, not the officer: every on-duty officer of it sees it in the tablet and the phone app, gets its alerts, watches it live, takes it down and swaps its battery. It runs on the department network with no SIM, is named PD-01, PD-02 and so on, sees 22 m across 100 degrees, and nobody outside the department can take it or pry it open. Up to 30 per department.
  • The Staff tab, for players with the god or admin ACE: every camera in the city with search, filters, photos, a staff live view (no battery drain, no snapshots, works without a SIM), teleport, GPS, recharge, repair and remove, returning the camera, its pole and its SIM to the owner when asked (never for a department camera). Every action is re-checked on the server and written to the console with the staff member's name and citizen ID.
  • Sounds. The game's own menu sounds on hovers and clicks in the app, in the live feed and while placing; players switch them off in the app's settings.
  • Known limit, from the README: props are local to each game, so destruction is reported by whoever saw it, and the reporter must be within range of the camera.

Install

  1. What it replaces. Nothing by name. It does not use Jixryo Core.

  2. Order. The cameras depend on ox_lib, oxmysql, qbx_core, ox_inventory and ox_target; the app depends on ox_lib and the cameras. Optional: screenshot-basic (photos), lb-phone (the phone app), the Jixryo Tablet (TrailCam as an app on it). The optional ones are picked up whenever they start.

    server.cfg
    ensure ox_lib
    ensure oxmysql
    ensure qbx_core
    ensure ox_inventory
    ensure ox_target
    ensure jixryo_trailcam
    ensure jixryo_trailcam_app
  3. Items. Add these to ox_inventory/data/items.lua and copy IMAGES/*.png to ox_inventory/web/images/.

    lua
    ['jixryo_trailcam'] = {
        label = 'Ranger Trail Camera', weight = 900, stack = true, close = true,
        description = 'Straps to a tree or a pole and reports to the TrailCam app. Sees 14 m.',
        client = { image = 'jixryo_trailcam.png' }
    },
    ['jixryo_trailcam_pro'] = {
        label = 'Cellular Pro Trail Camera', weight = 1100, stack = true, close = true,
        description = 'Long-range cellular trail camera with a solar panel. Sees 20 m, and the battery lasts longer.',
        client = { image = 'jixryo_trailcam_pro.png' }
    },
    ['jixryo_trailcam_police'] = {
        label = 'Surveillance Cam', weight = 1100, stack = true, close = true,
        description = 'Department surveillance camera. On-duty police only; every on-duty officer can watch it.',
        client = { image = 'jixryo_trailcam_police.png' }
    },
    ['jixryo_trailcam_pole'] = {
        label = 'Trail Cam Pole', weight = 1500, stack = true, close = true,
        description = 'A steel post with a bracket. Mounts a trail camera in open ground.',
        client = { image = 'jixryo_trailcam_pole.png' }
    },
    ['jixryo_trailcam_sim'] = {
        label = 'Trail Cam SIM Card', weight = 10, stack = true, close = true,
        description = 'Lets a trail camera reach the TrailCam app. Goes in when you mount one.',
        client = { image = 'jixryo_trailcam_sim.png' }
    },
    ['jixryo_trailcam_battery'] = {
        label = 'Trail Cam Battery', weight = 250, stack = true, close = true,
        description = 'A fresh battery for a deployed trail camera.',
        client = { image = 'jixryo_trailcam_battery.png' }
    },
    ['jixryo_trailcam_tablet'] = {
        label = 'TrailCam Tablet', weight = 600, stack = false, close = true,
        description = 'Shows what your trail cameras see: feeds, sightings and alerts.',
        client = { image = 'jixryo_trailcam_tablet.png' }
    },
  4. The shop. The README puts the cameras, pole, SIM, battery and tablet in the gg_hunting script's Hunting Lodge menu (Config.Shop["hunting_menu"] in gg_hunting/shared/config.lua), with the cost and level yours to tune. Put the Surveillance Cam, batteries and poles in your police armory, for example an ox_inventory shop limited to the police job.

    lua
    {item = 'jixryo_trailcam', cost = 750, level = 2},
    {item = 'jixryo_trailcam_pro', cost = 1600, level = 4},
    {item = 'jixryo_trailcam_pole', cost = 120, level = 2},
    {item = 'jixryo_trailcam_sim', cost = 75, level = 2},
    {item = 'jixryo_trailcam_battery', cost = 50, level = 2},
    {item = 'jixryo_trailcam_tablet', cost = 400, level = 1},
  5. Database. Nothing to run. The tables jixryo_trailcam_cameras, jixryo_trailcam_events and jixryo_trailcam_settings make themselves on start, and older installs are upgraded: cameras placed before 1.3.0 become Rangers with a SIM card in them, and their stakes become poles. sql/install.sql is a reference copy.

  6. Hosted photos, optional: put your Fivemanage image API key in server.cfg as the convar below (the same key lb-phone uses for images). Without it, photos are stored in the database.

    server.cfg
    set jixryo_trailcam_fivemanage "<your Fivemanage image key>"
  7. The phone app, optional: players install TrailCam from the lb-phone app store, or Config.DefaultApp in the app's config.lua preinstalls it. The tablet needs no install, only the item.

  8. The Jixryo Tablet. With jixryo_tablet running and the Jixryo Tablet switch in the app's config.lua on (its default), TrailCam is an app on that tablet and the tablet item brings it out straight onto TrailCam. Off, or without that resource, the item opens TrailCam's own tablet.

  9. Staff, optional: the Staff tab is for the ACE permissions in Config.admin.aces (god, admin). If your server does not grant them already: add_ace group.admin admin allow.

  10. The app's page ships built in ui/dist; after editing it, cd custom-apps/jixryo_trailcam_app/ui && npm install && npm run build.

  11. Props. The cameras, straps and pole stream from stream/ with 2K textures; a 4K edition sits in editions/4k to copy over them (about four times the video memory, and FiveM warns about oversized assets). A missing camera model falls back to prop_cctv_cam_04a.

  12. Restart the whole server the first time, so every resource sees the new items and every game downloads the props.

How other scripts' calls behave

  • It answers as itself only. The cameras' exports live under jixryo_trailcam, the tablet's under jixryo_trailcam_app; nothing is provided under another name.
  • qbx_core. Players by source and citizen ID, the job's type and duty for department cameras, CreateUseableItem for every camera item and the tablet, and GetJobs for a department's display name. Going on or off duty refreshes which police cameras are yours.
  • ox_inventory. Items are taken and given back with RemoveItem, AddItem, CanCarryItem and GetItemCount.
  • ox_target. Each camera prop gets its options: Look at the screen, Take the camera down, Swap the battery, Insert or take out the SIM card, Pry the SIM card out.
  • screenshot-basic takes every photo; without it, snapshots are refused with a message and motion photos are skipped.
  • lb-phone and lb-tablet. The app registers with AddCustomApp on each that runs (lb-tablet is off by default), pushes with SendCustomAppMessage, and sends alerts with SendNotification, with a Watch live button that opens the feed.
  • The Jixryo Tablet. The app registers with AddApp (id jixryo_trailcam, "TrailCam", ui/dist/app.html), pushes with SendAppMessage, notifies quietly with Notify, and opens the tablet onto itself with Open.
  • Fivemanage. With the key set, the server asks for presigned upload links and stores only links whose host is fivemanage.com or fmapi.net.
  • The world reaches every game through jixryo_trailcam:client:cameraAdded, cameraRemoved and cameraUpdated; the payloads never carry the owner.

Its own API

Client exports of jixryo_trailcam:

ExportWhat it does
startLiveView(camId, staff?)Opens the feed on a camera; staff asks for the staff view, which the server checks. Returns true, or false and why
stopLiveView()Closes the feed
isLive()Whether a feed is open
getLiveState(){ camId, label, staff } of the open feed, or nil
vehicleName(model)"Bravado Bison" for a vehicle model hash, or nil
alertText(alert)The text of an alert, as the notifications word it
placeNames(x, y, z)The zone and street names of a point
playSound(key), setUiSounds(on), getUiSounds()The app's sounds and the player's on or off choice

Client exports of jixryo_trailcam_app:

ExportWhat it does
openTablet()Brings out TrailCam's own tablet
closeTablet()Puts it away

Events:

EventDirectionWhat it carries
jixryo_trailcam:client:cameraAdded, cameraRemoved, cameraUpdatedto every gamea camera placed, taken away, or its light or wreck state changed
jixryo_trailcam:client:newEvent, eventPhototo the camera's audiencea sighting or system event recorded; a photo attached to one
jixryo_trailcam:client:alertto the camera's audience, by their settingsthe notification: kind, camera, label, model, coordinates, thumbnail link
jixryo_trailcam:client:cameraStatusto the camera's audiencedestroyed, taken or nosim
jixryo_trailcam:client:captureto one playerthe server borrows your screen for a motion photo (off by default)
jixryo_trailcam:client:useCamera, useTabletto one playerthe item was used
jixryo_trailcam:client:liveStatelocal, core to appa feed started or ended, and why
jixryo_trailcam:server:motionReport, cameraDestroyed, exitLive, captureDecline, photoUploaded, photoDatafrom a gamea report the server checks before anything is recorded

The app's calls go through 28 server callbacks named jixryo_trailcam:server:<name> (placing, picking up, retiring, SIM cards, the battery, the close-up, the cameras and events, photos, settings, live view and the staff tools); they are not an API, and the server checks every one.

Commands and keybinds

There are no slash commands. One key mapping is registered: trailcam_watch, K by default, rebound in Settings, Key Bindings, FiveM. It only does something with Config.alerts.screen on.

KeyWhoWhat it does
Using a camera itemits holder, on footStarts placing
Placing: scroll, Up and Down, V, E, Escthe placerRotate, tilt, view through the lens, place (tree mounts go on to the gizmo), cancel
Gizmo: left mouse, Tab, right mouse held, V, Enter, Escthe placerDrag an axis, switch move and rotate, look around, view through the lens, mount it here, back
X while the camera goes up, E in skill checksthe placerStop (nothing is taken); hit the checks
Third eye: Look at the screenanyoneThe close-up; Esc, Backspace or a step away leaves it
Third eye: Swap the battery, Insert or take out the SIM cardthe owner, or the department on dutyWhat they say
Third eye: Pry the SIM card outanyone elseA hard skill check, then the SIM into your pocket and a photo of you to the owner
Third eye: Take the camera downthe owner (anyone, with Config.security.stealable)Unstraps it, or unscrews it and pulls the pole
Live feed: scroll, right mouse, left mouse, Left and Right, Esc or Backspacethe viewerZoom, night vision, snapshot (not in staff view), switch camera, exit
Kanyone, with the on-screen card onWatch the camera from the newest card
TrailCam tablet: Q and E, Escits holderPrevious and next tab; close a photo or a question, then put the tablet away
Using the tablet itemits holderBrings out TrailCam's tablet, or the Jixryo Tablet on TrailCam

Configuration

jixryo_trailcam/config.lua:

KeyDefaultWhat it does
itemsbattery jixryo_trailcam_battery, pole jixryo_trailcam_pole, sim jixryo_trailcam_sim, tablet jixryo_trailcam_tabletThe items; tablet nil turns the tablet item off
appResourcejixryo_trailcam_appThe app resource that turns alerts into notifications
modelsranger (14 m, 110 degrees, drain 1.0), pro (20 m, 100 degrees, drain 0.6), police (22 m, 100 degrees, drain 0.5, department)Each camera's item, model, lens, light, IR and screen positions, reach, field of view and drain
defaultModel, fallbackModelranger; prop_cctv_cam_04aCameras from before 1.3.0; the prop used when a model is not streamed
polemountHeight 1.06, plateDepth 0.0125, sinkStart 0.27The pole's geometry
strapradii 0.10, 0.18, 0.30The three strap sizes
placementgizmo true, maxOwned 5, maxDistance 6.0, maxHeight 2.5, minSpacing 20.0, previewAlpha 170, showCone true, allowPreview true, the strap, pole and screw steps with their seconds and checks, skillKeys e, retries 2Placement limits, the ghost and the work
simrequired true, stealable true, pry 6 s medium, medium, hard, swap 3 sSIM cards
lightsenabled true, range 35.0, ir trueThe status light and the IR glow
inspectenabled true, distance 2.5, seconds 20The close-up
detectionenabled true, activationRange 60.0, losCheck true, armSeconds 45, interval 1500, clientThrottle 8000, entityMemory 45000, animals, people, vehicles trueMotion detection
eventsperCamCooldown 20, historyLimit 60, photoWaitSeconds 4, notifyDefaults all onEvents and alerts
photosenabled true, borrowScreens false, perCamCooldown 25, perPlayerCooldown 12, maxCaptureSpeed 8.0, keepPhotos 20, 1280 by 720 at 0.72, thumbnails 320 by 180 at 0.6, maxBytes 700 KiB, maxThumbBytes 60 KiB, upload convar, presign URL, allowed hostsPhotos and where they go
batteryenabled true, drainPerHour 1.4, liveDrainPerMinute 1.0, perEventDrain 0.15, lowThreshold 20The battery
livefov 50, minFov 20, maxFov 70, zoomStep 4, maxSessionSeconds 300, nightvision true, autoNightFrom 20, autoNightTo 6, freezeViewer true, timecycle scanline_cam_cheap at 0.3, snapshotCooldown 3The feed
soundsenabled true, the game's frontend soundsHover, click, back, tick, error and shutter
alertsscreen false, seconds 8, watchKey KThe optional on-screen card
adminaces god, admin, returnItemByDefault trueThe Staff tab
securitystealable false, destructible true, refundDestroyed false, notifyOnTamper true, allowRemoteRetire trueOwnership and tampering
policeenabled true, jobType leo, requireDuty true, maxCameras 30, labelPrefix PDDepartment cameras

jixryo_trailcam_app/config.lua:

KeyDefaultWhat it does
LBPhone, LBTablettrue, falseRegister the app on lb-phone and lb-tablet
The Jixryo Tablet switchtrueTrailCam as an app on the Jixryo Tablet, and the tablet item opens it there
Tabletenabled true, blur true, prop_cs_tablet in the left hand, the bus passenger tablet animationTrailCam's own tablet
Identifier, Name, Description, Developer, DefaultAppjixryo_trailcam, TrailCam, Jixryo, falseThe app store listing
ReopenAfterLivetrueReopen the device on that camera when you exit a feed on purpose
Alertsphone true, tablet trueWhere alerts arrive

Security

  • Identity comes from the source. Ownership is checked by citizen ID, and a department camera by the caller's police job and duty.
  • Distances are re-checked on the server, every number is range-checked, every string clamped and UTF-8 safe, and all SQL is parameterised.
  • Every callback and event is rate limited. Placement and SIM changes hold in-flight locks, and removing a camera takes it out of memory before any database wait, so two players can never both get the item back.
  • Items move once. Placement takes the camera and the pole only when the work is done and gives everything back if anything after that fails. A SIM always leaves the camera before it reaches a pocket.
  • Event text is the server's. Nothing a client types is stored or shown to other players; species and vehicles are named from the model hash.
  • Photos are accepted only for a capture session the server opened, from that player, within 20 seconds, as a JPEG within the size limits or as a link on an allowed host.
  • Nothing leaks. World payloads never include a camera's owner, and the close-up shows a camera's name only to its owner. Live view needs your own camera or the department's, a SIM, a live battery, and refuses while you drive; the battery is charged from the server's clock, not the client's.
  • Staff callbacks re-check the ACE on every call, are rate limited, and write an audit line to the console.

Tests

There is no luarun suite for the cameras or the app. The repository has a contracts check, dev-tools/luacheck/contracts.mjs, that cross-checks every name crossing a boundary between the cameras, the app, their pages and the dev mock. Run on 2026-10-31 it reported ALL CONTRACTS MATCH: 28 server callbacks, 6 client-to-server events, 7 of 10 server-to-client events handled (newEvent, eventPhoto and cameraStatus are consumed by the app's pushes), 7 HUD actions, 7 live phases, 24 app page calls, 5 pushes, and 9 of 10 core exports used by the app.

bash
node dev-tools/luacheck/contracts.mjs .

Check it in game

  1. Start with the items added. The console shows the cameras loaded and any columns added to an older install.
  2. Use a Ranger on foot near a tree: the ghost follows your aim with its cone, the panel shows the mount and the SIM, E places it, the gizmo opens, Enter mounts it. The strap wraps and cinches through the progress bars and skill checks, and the camera is up with "starts watching in 45 seconds".
  3. Use another on open ground with a pole in your pockets: the pole sinks as you hammer, then the camera screws onto its bracket.
  4. Look at the screen with the third eye: the view moves in to the camera's own screen with battery, signal and the time. Esc leaves it.
  5. Walk a second player, an animal or a car through the cone after 45 seconds: a notification on the phone or the tablet names what was seen, and the status light blinks.
  6. Open the TrailCam tablet with its item: your cameras as feeds, the sightings, the settings. Open a live feed, zoom, toggle night vision, take a snapshot; the photo lands on the wall. Shoot the camera: SIGNAL LOST.
  7. As a second player, pry the SIM out: the owner gets the alert and a photo of you, and the light turns red.
  8. As staff, the Staff tab lists every camera; teleport to one, recharge it, repair the wrecked one, remove one with the item returned to its owner. The console shows each action with your name.
Next step

Ready to look around?

Browse the suite, or paste your server.cfg and see what each script does to your server.