Back

tk-phone

Complete and immersive physical phone system for FiveM (QBCore).

Contributors


📖 Context: "The Object Before the Script"

In most RP servers, the phone is an immaterial menu magically linked to the player. For PakeTekos, I wanted to introduce an additional layer of realism: the phone is a physical item with a unique serial number.

This approach radically changes gameplay: if a player loses their phone or has it stolen, the new owner gains access to all messages, contacts, and photos stored in the device. It's a catalyst for RP scenarios (blackmail, investigation, data theft) that few servers offer.

📱 A Modern "App Store" Interface

Powered by my tk-ui (Vue/Nuxt) stack, the phone delivers a fluid experience close to a modern smartphone:

  • Integrated VoIP: Real-time calls via pma-voice with dedicated audio channel management.
  • App System: Modular architecture allowing app installation/uninstallation (GPS, SMS, Store, Settings).
  • Persistent Notifications: An unread count system that survives reconnections.

🎯 My Role: Lead Developer & System Architect

I designed the entire bridge between the game engine (Lua) and the interface (Vue.js), with emphasis on raw server-side performance.

1. Optimization: $O(1)$ Caching

Managing thousands of messages and calls can quickly saturate a database. To prevent this, I implemented a server-side caching system using synchronized Maps. This enables near-instantaneous lookups by serial number or phone number, without hitting the MariaDB database on every interaction.

2. UX: NUI Focus & Immersion

The biggest challenge with FiveM interfaces is loss of character control. I developed an intelligent control loop that manages focus:

  • Dynamic Mouse Mode: Cursor activation via hotkey, while blocking combat actions to prevent accidental gunfire.
  • Input Suspension: When a player types a message, game keys are suspended to prevent the character from jumping or running around while writing.

🧠 Under the Hood: Business Logic & Security

⚙️ Call Flow (State Machine)

Call management is a synchronization challenge. I implemented a robust state machine to handle critical edge cases:

  • Acknowledgments: If the recipient hangs up before the server validates the call ID, a "pending cancellation" is recorded to prevent ghost calls.
  • Anonymous Mode: A number-masking system natively integrated into the data flow.
-- Inventory cache management example
AddEventHandler('qb-inventory:server:specialSlotUpdated', function(identifier, slot, inventoryItem, action)
    if slot ~= Config.PhoneSlot then return end
    -- Instantaneous hardware synchronization with virtual owner
    if action == 'add' then
        Cache.ActiveSIMs[phone_number] = Player.citizenid
    elseif action == 'remove' then
        Cache.ActiveSIMs[phone_number] = nil
    end
end)

🔭 Vision & Future

tk-phone is the nerve center of social interaction on the server. Next steps include:

  • Media Sharing: Send in-game photos via an upload system to a CDN (Imgur/Discord).
  • Dark Web: A hidden app accessible only via specific items or locations.
  • NPC Interactions: NPCs can contact the player to give missions based on their history.

Technical Expertise: Vue.js 3, Nuxt, Lua, SQL (MariaDB), VoIP integration, State Management, UI/UX Design.