Tutorial 2026-05-09

Building a News Reporter Job for FiveM

OntelMonke

OntelMonke

Developer & Content Creator at Agency Scripts

The Role of News Reporters in Roleplay

A news reporter job adds a unique social layer to your FiveM server that no other job provides. Reporters act as the connective tissue between server events, documenting crimes, interviewing players, and broadcasting stories that shape the narrative of your city. Unlike most jobs that operate in isolation, reporting naturally intersects with every faction on the server: police chases become breaking news, gang conflicts become investigative stories, and city council decisions become editorial pieces. This creates organic cross-faction roleplay that server owners constantly try to encourage but rarely achieve through mechanics alone. A good news system gives reporters the tools to capture events, write articles visible to all players, and broadcast live reports that appear on screens around the map. When players see their actions making headlines, it reinforces that their roleplay matters and encourages them to create more compelling stories.

News Station Setup and Job Structure

The news station serves as the hub where reporters clock in, access equipment, write articles, and coordinate with their team. Define the station location, equipment storage, and broadcast studio within your configuration. Structure the job hierarchy with roles like intern, reporter, anchor, and editor-in-chief, each with escalating permissions. Interns can write drafts but need editor approval before publishing. Reporters can publish articles and use camera equipment. Anchors gain access to the broadcast studio for live reports. The editor-in-chief manages the team and controls the news ticker that scrolls across every player's screen:

Config.NewsStation = {
    label = 'Weazel News',
    jobName = 'reporter',
    location = vector3(-598.97, -929.54, 23.89),
    studioRoom = vector3(-592.12, -924.88, 23.89),
    equipmentLocker = vector3(-601.33, -932.17, 23.89),
    grades = {
        [0] = { name = 'Intern',   canPublish = false, canBroadcast = false },
        [1] = { name = 'Reporter', canPublish = true,  canBroadcast = false },
        [2] = { name = 'Anchor',   canPublish = true,  canBroadcast = true  },
        [3] = { name = 'Editor',   canPublish = true,  canBroadcast = true,
                canManage = true },
    },
    equipment = {
        { item = 'news_camera',     label = 'News Camera' },
        { item = 'news_microphone', label = 'Microphone' },
        { item = 'press_badge',     label = 'Press Badge' },
        { item = 'news_notepad',    label = 'Notepad' },
    },
    vehicles = {
        { model = 'rumpo',  label = 'News Van',    grade = 1 },
        { model = 'frogger', label = 'News Chopper', grade = 2 },
    },
}

The news van is essential because it serves as a mobile broadcast station. Equip it with a satellite dish prop on the roof and allow reporters to start live broadcasts from any location as long as they are near the van. The chopper provides aerial footage capabilities for anchors covering large-scale events like police pursuits or city-wide emergencies. Each vehicle should be restricted by job grade to prevent interns from flying the helicopter on their first day.

Camera and Recording System

The camera system is the core mechanic that makes news reporting feel authentic. When a reporter equips the news camera item, switch to a first-person camera view with a recording overlay that shows a red REC indicator, a timer, and a battery level. The camera should support zoom controls using scroll wheel input and a photo capture mode that takes an in-game screenshot and stores it as an article attachment. Use GTA's native camera system to create a smooth handheld camera feel with slight movement sway that makes footage look natural rather than perfectly static:

local isRecording = false
local recordingCam = nil
local recordTimer = 0

function StartCamera()
    if isRecording then return end
    isRecording = true

    local playerPed = PlayerPedId()
    recordingCam = CreateCam('DEFAULT_SCRIPTED_CAMERA', true)

    -- Position camera at player's head height
    local headBone = GetPedBoneCoords(playerPed, 31086, 0.0, 0.0, 0.0)
    SetCamCoord(recordingCam, headBone.x, headBone.y, headBone.z)
    SetCamRot(recordingCam, GetEntityRotation(playerPed, 2))
    SetCamFov(recordingCam, 50.0)
    SetCamActive(recordingCam, true)
    RenderScriptCams(true, true, 500, true, false)

    -- Show recording overlay via NUI
    SendNUIMessage({
        action = 'showRecordingOverlay',
        stationName = 'WEAZEL NEWS',
        reporterName = GetPlayerName(PlayerId())
    })

    -- Camera control thread
    CreateThread(function()
        local currentFov = 50.0
        while isRecording do
            -- Follow player head position
            local head = GetPedBoneCoords(playerPed, 31086, 0.0, 0.0, 0.0)
            SetCamCoord(recordingCam, head.x, head.y, head.z)

            -- Mouse look controls
            local pitch = GetDisabledControlNormal(0, 2) * -5.0
            local yaw = GetDisabledControlNormal(0, 1) * -8.0
            local rot = GetCamRot(recordingCam, 2)
            SetCamRot(recordingCam, rot.x + pitch, rot.y, rot.z + yaw, 2)

            -- Zoom with scroll wheel
            if IsDisabledControlPressed(0, 241) then
                currentFov = math.max(15.0, currentFov - 2.0)
            elseif IsDisabledControlPressed(0, 242) then
                currentFov = math.min(80.0, currentFov + 2.0)
            end
            SetCamFov(recordingCam, currentFov)

            -- Update timer
            recordTimer = recordTimer + 1
            SendNUIMessage({
                action = 'updateTimer',
                time = math.floor(recordTimer / 60)
            })

            DisableAllControlActions(0)
            EnableControlAction(0, 249, true) -- Allow push to talk
            Wait(0)
        end
    end)
end

The recording overlay displayed through NUI should replicate a professional news camera viewfinder with corner brackets framing the shot, a station logo watermark, and a scrolling lower-third bar showing the reporter's name. When the reporter stops recording, fade the overlay out and smoothly transition back to the regular gameplay camera. Store the recording duration and location data so it can be referenced when writing the associated article.

Article Writing and Publishing

Give reporters a full article editor accessible from the news station or via their notepad item in the field. The editor should use an NUI-based rich text interface where reporters type a headline, write the article body, select a category like crime, politics, sports, or entertainment, and attach any photos taken with the camera system. Published articles appear on an in-game newspaper accessible from newspaper box props placed around the city and from phone apps if your server uses a phone system. Store articles in the database with timestamps, author information, and view counts to track which stories generate the most player engagement:

RegisterNetEvent('news:server:publishArticle', function(articleData)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)

    -- Verify job and permissions
    if Player.PlayerData.job.name ~= 'reporter' then return end
    local grade = Config.NewsStation.grades[Player.PlayerData.job.grade.level]
    if not grade or not grade.canPublish then
        TriggerClientEvent('QBCore:Notify', src,
            'Your rank cannot publish articles', 'error')
        return
    end

    -- Sanitize input
    local headline = articleData.headline:sub(1, 120)
    local body = articleData.body:sub(1, 5000)
    local category = articleData.category or 'general'

    -- Insert into database
    local articleId = MySQL.insert.await(
        'INSERT INTO news_articles (author_id, author_name, headline, body, category, created_at) VALUES (?, ?, ?, ?, ?, NOW())',
        {Player.PlayerData.citizenid, Player.PlayerData.charinfo.firstname ..
         ' ' .. Player.PlayerData.charinfo.lastname,
         headline, body, category}
    )

    -- Broadcast notification to all players
    TriggerClientEvent('news:client:newArticle', -1, {
        id = articleId,
        headline = headline,
        category = category,
        author = Player.PlayerData.charinfo.firstname .. ' ' ..
                 Player.PlayerData.charinfo.lastname
    })

    -- Update news ticker
    TriggerClientEvent('news:client:updateTicker', -1,
        'BREAKING: ' .. headline)

    TriggerClientEvent('QBCore:Notify', src,
        'Article published successfully!', 'success')
end)

Live Broadcast System

Live broadcasts are the most exciting feature of a news reporter system because they create server-wide events that every player can witness in real time. When an anchor starts a live broadcast from the studio or near the news van, their audio through voice chat should route to every player on the server within a configurable range or server-wide depending on your preference. Display a broadcast banner on every player's screen showing the station logo, the anchor's name, and a live indicator. The broadcast can optionally display the camera feed on in-game TV screens placed in interiors around the map using render targets. Implement a broadcast cooldown to prevent spam and require the anchor role to prevent every intern from going live on their first day. The broadcast system should handle edge cases gracefully: if the anchor disconnects mid-broadcast, automatically end the broadcast and display a technical difficulties message. If the anchor moves too far from the news van during a field broadcast, warn them that they are losing signal and end the broadcast if they do not return within a reasonable distance.

News Ticker and Notifications

The news ticker is a persistent UI element that scrolls headlines across the bottom of every player's screen, similar to cable news channels. Implement it as an NUI layer that reads from the most recent published articles and rotates through headlines on a timer. Allow the editor-in-chief to push urgent breaking news alerts that override the regular ticker with a red highlighted banner and an alert sound. The ticker should be dismissable by individual players who find it distracting, with a setting to toggle it on or off through the phone or settings menu. Rate-limit ticker updates on the server side to prevent abuse, and keep the ticker queue to the five most recent headlines to avoid overwhelming players with old news. When a player clicks on a ticker headline, open the full article in an NUI newspaper viewer so they can read the complete story without visiting a physical newspaper box.

Interview and Press Conference Mechanics

Add dedicated mechanics for conducting interviews that go beyond regular conversation. When a reporter targets another player with the microphone item, send an interview request that the target can accept or decline. Accepted interviews create a visible press interaction where both players face each other, the reporter holds the microphone prop, and nearby players can see a press indicator above their heads. Everything said during the interview can optionally be logged as a transcript attached to the reporter's notepad for later article writing. For press conferences, create designated podium locations at City Hall, the police station, and the hospital where officials can address multiple reporters simultaneously. The podium location amplifies the speaker's voice range and displays their name and title on a lower-third graphic visible to all nearby players, creating an authentic press event atmosphere that encourages political and institutional roleplay.

Performance and Integration Tips

The news system touches every player on the server through the ticker and broadcast features, so performance optimization is critical. Run the news ticker as a lightweight NUI element that updates on a long interval rather than every frame. Cache published articles on the client side after initial fetch and only request updates when the player opens the newspaper viewer or when a new article notification arrives. For live broadcasts, route audio through the existing voice chat system rather than creating a separate audio channel to avoid bandwidth overhead. Limit the number of stored articles in the database by archiving entries older than thirty days into a separate table that players can access through a newspaper archive menu. Clean up camera entities and NUI overlays aggressively when the reporter job changes, the resource restarts, or the player disconnects to prevent lingering visual artifacts. Consider integrating with your phone system so players can read news articles directly from their phone, subscribe to specific categories, and receive push notifications for breaking news in their areas of interest.

Share this article

Ready to upgrade your server?

Check out our premium FiveM scripts in the Agency Scripts store or join our Discord community for support and updates.