Peak Sprays Documentation
Welcome to the official documentation for Peak Sprays, a premium FiveM resource for persistent in-world spray painting, text scenes, and signs.
📑 Table of Contents
🌟 Overview & Features
Peak Sprays provides a highly interactive and persistent graffiti system for FiveM. Unlike traditional spray scripts, Peak Sprays uses DUI (Durable User Interface) canvases rendered in the 3D world, allowing for pixel-perfect detail and real-time synchronization.
Key Features:
- 🎨 Persistent Spray Painting: Paint anywhere on the map. Every stroke is saved to the database and re-rendered for players when they are nearby.
- 🖼️ DUI-Based Rendering: High-performance in-world canvases that support multiple brush styles and sizes.
- ✍️ Text Scenes & Signs: Place temporary or permanent text signs with custom fonts, backgrounds, and visibility settings.
- ✨ Advanced Paint Styles: Aerosol, Fine Marker, Calligraphy, Splatter, Airbrush, Drip Style, and Stencil Stamps.
- 🔍 Live Preview: Players see a holographic preview while placing their canvas and while actively painting.
- 🛠️ Admin Management: A full-featured admin panel to list, teleport to, and delete any spray or scene.
- 🔗 Framework Agnostic: Built-in support for QBCore, Qbox, ESX, vRP, and Standalone.
- 📦 Inventory Integration: Supports item-based usage (Spray Cans and Cloths) for realistic roleplay.
🚀 Installation Guide
Prerequisites
🤖 AI-First Setup (Recommended)
If you are using an AI coding assistant (like Claude, ChatGPT, or Cursor), you can set up this resource in seconds:
- Open
PROMPT.mdin the resource folder. - Copy the content and paste it into your AI assistant.
- Follow its instructions to automatically configure the framework, inventory, and items for your server.
Manual Setup
- Download and place the
peak-spraysfolder into your resources directory. - Import
install/install.sqlinto your database. - Add the items to your inventory system (examples for OX and QBCore are in the
install/directory). - Configure
shared/config.luafor your framework and preferences. - Add
ensure peak-spraysto yourserver.cfgafterox_libandoxmysql.
⚙️ Configuration
The configuration is split into three main files for ease of use:
1. shared/config.lua
The primary configuration for non-technical users.
Config.Framework: 'auto', 'qbcore', 'esx', 'qbox', 'standalone'.Config.SprayPaintItem: Name of the spray can item.Config.ClothItem: Name of the eraser cloth item.Config.CommandName: Command to start painting if not using items.
2. shared/internal_config.lua
Advanced technical settings (DUI limits, render distances, brush presets, animations).
Config.RenderDistance: How far away sprays are rendered (Default: 50.0).Config.MaxStrokesPerPainting: Safety limit for database size (Default: 500).Config.BrushSizes: Custom brush sizes and densities.Config.PaintStyles: Available drawing tools (Spray, Pen, etc.).Config.ColorPresets: The palette available in the UI.
3. server/server-config.lua
Sensitive server-side only settings.
ServerConfig.DiscordWebhook: URL for logging spray creations and deletions.
⌨️ Commands & Controls
Player Commands
| Command | Description |
|---|---|
/spraypaint | Starts the placement of a new spray canvas. |
/erasepaint | Enters erase mode to remove nearby paintings. |
/scene [text] | Opens the text scene editor. |
/sign [text] | Opens the sign editor. |
/hidescenes | Toggles local visibility of scenes and signs. |
/deletescene | Deletes the nearest scene (Owner/Admin only). |
Admin Commands
| Command | Description |
|---|---|
/sprayadmin | Opens the Admin Panel to manage all world paintings. |
Controls (During Painting)
- Mouse: Toggle mouse with
M(Default) to use the UI. - Scroll: Change brush size.
- Left Click: Paint / Apply stroke.
- Right Click: Erase stroke (in erase mode).
- Z / Y: Undo / Redo.
- Enter: Validate and Save.
- ESC: Cancel and Exit.
🛠️ Developer API
Peak Sprays provides a robust API via exports for both Client and Server.
Client Exports
lua-- Get all active paintings on the client local sprays = exports['peak-sprays']:GetAllSprays() -- Get a specific spray by ID local spray = exports['peak-sprays']:GetSprayById(123) -- Get current spray state ('idle', 'painting', 'placing', 'erasing') local state = exports['peak-sprays']:GetSprayState() -- Get nearby paintings local nearby = exports['peak-sprays']:GetNearbyPaintings(coords, radius)
Server Exports
lua-- Check if a player is an admin local isAdmin = exports['peak-sprays']:IsAdmin(source) -- Get the current framework object local core = exports['peak-sprays']:GetFramework() -- Register a usable item manually exports['peak-sprays']:RegisterUsableItem('custom_spray', function(source) -- custom logic end)
Network Events
peak-sprays:cl:newPainting: Triggered when a new painting is added to the world.peak-sprays:cl:removePainting: Triggered when a painting is deleted.peak-sprays:cl:updatePainting: Triggered when a painting is modified (erased/undone).
⚓ Custom Hooks
You can extend the functionality without touching the core logic by modifying the custom.lua files.
Client Hooks (client/custom.lua)
CanSpray(): Returnfalseto prevent a player from painting (e.g., in safe zones).OnSprayCompleted(id, center): Triggered after a player finishes a painting.Open.CustomNotify(msg, type): Use your own notification system.
Server Hooks (server/custom.lua)
ServerCanSpray(source): Server-side validation for spray placement.OnServerSprayCompleted(source, id, data): Handle rewards or XP when a spray is finished.Open.AddMoney / RemoveMoney: Override economy logic for charging players.
🏗️ NUI Development & Building
The UI for Peak Sprays is built with Vue 3 and Vite.
Modifying the UI
- Navigate to the
uifolder. - Run
npm installto install dependencies. - Run
npm run devto start the development server with Hot Module Replacement (HMR).
Building for Release
Before deploying to a live server, you must build the UI:
- Run
npm run buildfrom theuifolder. - This will generate the optimized files in
ui/dist. - Ensure
ui/distis included in your resource folder.
🌍 Localization (Translations)
Peak Sprays supports multiple languages via shared/locales.lua.
How to Translate
- Open
shared/locales.lua. - You can modify existing entries or add a new language table.
- Set your active language at the top of the file:
Config.Locale = 'en'.
📊 Database Schema
spray_paintings
Stores all graffiti data.
corners: JSON object containing 4 world-space coordinates.stroke_data: LONGTEXT containing the serialized drawing history.expires_at: Optional timestamp for auto-deletion.
peak_text_scenes
Stores all text scenes and signs.
display_data: JSON containing fonts, colors, and background settings.
🚀 Performance & Limits
Peak Sprays is designed with performance in mind:
- DUI Culling: Canvases are only created and rendered when players are within
Config.RenderDistance. - Active Limit:
Config.MaxActiveRenderers(Default: 20) ensures only the closest sprays are rendered at once to save VRAM. - Throttling: Strokes are throttled at
Config.StrokeThrottleMs(Default: 16ms) to prevent network congestion during rapid drawing.
[!TIP] For servers with high graffiti density, keep
Config.MaxStrokesPerPaintingaround 500 to maintain fast load times for players.
Documentation generated by Peak Studios. For support, visit our Discord.