# K3 Studio > A native Windows editor for FiveM servers. It starts FXServer, restarts the resource you save, shows runtime SCRIPT ERRORs on the line they came from, and runs Claude Code with an MCP server that can read the console, query the database and drive the game. K3 Studio is written in Odin with SDL3 + OpenGL and is GPL-3.0. Source and releases: https://github.com/Kr3mu/k3studio ## MCP server K3 Studio runs an MCP server (JSON-RPC over HTTP POST on 127.0.0.1, random port, bearer token) and attaches it to Claude Code with --mcp-config. Game tools act on the first connected player through the fed-bridge dev resource. db_execute asks the user first. - `server_status`(): Whether K3 Studio's FXServer is running, its endpoint, and how many runtime errors are open. - `server_console`(`lines`?: integer): The latest server and client console lines (FXServer output and the FiveM client log). - `server_command`(`command`: string): Runs a command in the FXServer console, e.g. 'ensure inventory' or 'refresh'. - `runtime_errors`(): SCRIPT ERRORs the server and client consoles reported since each resource last restarted, with file, line, count and stack. - `diagnostics`(`path`?: string): Language server diagnostics (qbx-lua-ls: wrong-side natives, undefined globals, ...) for one file or all open files. - `open_file`(`path`: string, `line`?: integer): Opens a file in K3 Studio's editor, optionally at a 1-based line, so the user sees it. - `playtests_run`(`filter`?: string): Runs the playtests (Lua files in each resource's playtests/ folder, in the game or with '-- side: server' on the server) and returns PASS/FAIL per test with the failure's message and line. filter: only tests whose name contains it. - `db_query`(`sql`: string): Runs a read-only SQL statement (SELECT, SHOW, DESCRIBE, EXPLAIN) on the server's database; returns tab-separated rows. - `db_execute`(`sql`: string): Runs a SQL statement that changes data on the server's database; K3 Studio asks the user first. - `game_state`(): The player's position, heading, street, zone, vehicle and interior in the running game. - `game_players`(): Every connected player: id, name, ping and position. - `game_teleport`(`x`: number, `y`: number, `z`: number, `heading`?: number): Moves the player (and their vehicle) to x, y, z, optionally facing heading. - `game_spawn_vehicle`(`model`: string): Spawns a vehicle by model name (e.g. 'adder') and puts the player in it. - `game_walk_to`(`x`: number, `y`: number, `z`: number, `run`?: boolean): Sends the player to x, y, z like a person would: on foot along the navmesh (run: running) or driving when in a vehicle, so zones and markers on the way trigger (game_teleport skips them). Returns at once with the distance; check arrival with game_wait_for or game_state. - `game_press`(`control`: string, `ms`?: integer): Holds a game control down for ms (default 100, max 5000), as if the player pressed it: an id (38) or name (INPUT_PICKUP) from FiveM's controls list. - `game_screenshot`(): Saves what FiveM's window shows as a PNG and returns its path (open it to see the game). The game must be on screen. - `game_wait_for`(`code`: string, `side`?: "game" | "server", `timeout_ms`?: integer): Re-evaluates a Lua condition in the game (side 'server': on the server) every 100 ms until it's truthy, up to timeout_ms (max 7000). Returns its value or 'timed out'. - `game_eval`(`code`: string, `side`?: "game" | "server"): Runs Lua and returns its value: side 'game' runs in the player's client, 'server' on the server. An expression or statements. ## Getting started ### Requirements - Windows 10 or 11 - [Odin](https://odin-lang.org) nightly `dev-2026-10` on `PATH`. SDL3 comes from Odin's `vendor/sdl3`. - MSVC (Visual Studio 2022 or Build Tools), used once to build `tree_sitter.lib` and `nanosvg.lib` - Optional: [bun](https://bun.sh) for the web language servers, packages and the database helper; `git`; the `claude` CLI for the agent; `lua` for the live lens test ### Build and run | Command | What it does | |---|---| | `./run.sh` | Debug build with `-vet -strict-style`, then runs it | | `./run.sh release` | Optimized build (`-o:speed`, windows subsystem, ships a PDB so crash reports are symbolized) | | `./run.sh test` | Unit tests for every package (leaks and bad frees fail the run), then end-to-end `.fedscript` UI tests | | `./run.sh bench` | Benchmarks | `run.bat` takes the same arguments for `cmd`. Output goes to `build/`. You can open a file or folder by passing it as an argument or dropping it onto the window: ```bash build/k3studio.exe path/to/server-data ``` ### First run The first time K3 Studio starts, a short setup takes you through four steps: **Look** (interface scale and code font), **Server** (FXServer and license key), **Agent** (whether Claude Code is found) and **Shortcuts**. You can skip it and change any of these later in Settings. ![Setup: look](/images/onboarding_look.png) ![Setup: server](/images/onboarding_server.png) ### What do you want to make? With no folder open, K3 Studio shows what you can build and edit for the game's streamed assets, grouped into shells, interiors & maps, textures, props, peds & clothing, vehicles and scripts (the chips above filter them), with your recent folders beside them. Tools still to come are marked so. #### Texture dictionaries (.ytd) A `.ytd` opens as its textures, not as text: open one from the Explorer or from **Texture dictionary** on the start page, or make an empty one with **New texture dictionary**. - The list shows every texture with a thumbnail, its size, format (DXT1, DXT5, BC4, BC5, BC7, uncompressed) and mip levels; the selected one shows large on a checkerboard, so transparency is visible. - **Add picture…** and **Replace…** take PNG, JPG, BMP, TGA or PSD. The picture is scaled to powers of two (up to 4096) and stored with every mip level, as DXT1 when it's opaque or DXT5 when it has transparency, or uncompressed when you pick **Uncompressed**. - **Rename…** changes the name models look the texture up by; **Export PNG…** writes the full-size picture; **Delete** removes it. - **Save** (or Ctrl+S) writes the dictionary back as a resource the game streams. Closing it with unsaved changes asks first. The agent panel starts closed; Ctrl+L opens it, and K3 Studio remembers whether it was open. ### Layout ![Workspace](/images/workspace.png) - **Title bar**: menus (File, Edit, View, Go, Run), project switcher, search box (`Ctrl+P`), server status pill, restart - **Rail** (left): Explorer, Search, Git, Server (console), Resources, Game (vehicles and handling for now), Live (problems), Database, Agent; Settings at the bottom - **Side panel**: what the rail item opened - **Editor**: tabs, breadcrumbs, code - **Bottom panel**: Console, Problems, References, Terminal, History - **Agent panel** (right): Claude Code, toggled with `Ctrl+L` You can drag panel edges to resize them, and double-clicking an edge resets it. Sizes are saved. In narrow windows the side panels slide over the editor instead of squeezing it. ### Settings and keybindings ![Settings: keybindings](/images/settings.png) Settings has eight sections, and a search box above them that finds any setting, installed font or theme by name (typing anywhere on the page searches): - **Editor**: code font and text size; tab size, indent with tabs or spaces (or detect per file), closing brackets, format on save and on paste; smooth scrolling, scroll speed, scrolling past the end, Ctrl + wheel zoom; cursor style (line, block, underline), blinking and width; line numbers (on, relative, off), current line highlight, whitespace (none, selection, all), indent guides, matching bracket highlight, inline blame; inlay hints, hover delay, suggestions while typing and how many show, daily language server updates. - **Fonts**: line height, letter spacing, bold keywords, functions or types; the code and interface fonts, from the built-in ones or any font installed on the PC (monospace only for code unless you ask for all), with a preview. - **Files**: auto save (after a delay or when K3 Studio loses focus), trimming trailing spaces and ending files with a newline on save. - **Terminal & server**: the shell (PowerShell, Windows PowerShell, Command Prompt, Git Bash); restarting a resource on save, restarting the server after a crash, running under txAdmin. - **Appearance**: interface scale, reduced motion, themes. - **Theme builder**, **Rendering** and **Keybindings**, below. Keys follow VS Code defaults. You can rebind any action, search by name or by pressing the keys, and you get a warning when a binding conflicts with another. **Import from VS Code** (Settings > Editor) reads your VS Code `settings.json` and takes over the color theme, editor font (the first installed family of `editor.fontFamily`), font size, line height, letter spacing, zoom, tab size and indentation, bracket closing and matching, cursor style, blinking and width, line numbers, line highlight, whitespace, indent guides, format on save and paste, auto save, trimming and final newline, hover, suggestions, inlay hints, wheel zoom, scrolling, inline blame, the default terminal profile and reduced motion. A theme K3 Studio doesn't ship is read from the VS Code extension that installed it. **Rendering**: K3 Studio measures every way it can upload and draw on your GPU (about two seconds, in a hidden window) the first time it starts and whenever the GPU changes, and starts with the fastest. Settings > Rendering shows the result, measures again on request, and lets you pick the methods and vsync (adaptive, on, off) yourself. **Themes** (Settings > Appearance): 113 themes, among them VS Code's own, One Dark Pro, Dracula, Monokai Pro, GitHub, Catppuccin, Tokyo Night, Gruvbox, Nord, Solarized, Rosé Pine and Moegi. Each tile shows the theme's colors; clicking one switches at once. All / Dark / Light filters the list. **Theme builder**: the custom theme's 11 colors (editor, panels, text, accent and seven code colors), each picked from hue, saturation and lightness strips, with a code preview. The first pick copies the current theme. Copy puts the theme on the clipboard as one line (`Name|RRGGBB,…`) and Paste takes one back. | Zoom | Keys | |---|---| | Editor text | `Ctrl+=` / `Ctrl+-` / `Ctrl+0` | | Whole window | `Ctrl+Shift+=` / `Ctrl+Shift+-` / `Ctrl+Shift+0` | ### Installing The installer from [Releases](https://github.com/Kr3mu/k3studio/releases) installs for your user only (no admin). It can add **Open with K3 Studio** to the right-click menu of files, folders and folder backgrounds, and put `k3studio` on your PATH, so `k3studio .` in a terminal opens the current folder (like `code .`). ### Updates Installed builds check GitHub for a newer release at startup. With **Settings > Editor > Updates > Download updates and install them on quit** on (the default), the new installer downloads in the background and runs silently when you close K3 Studio; with it off, K3 Studio asks first and restarts into the new version. **Check for K3 Studio updates** in the command palette checks right away. Builds from source report `dev` and never update. ### Releasing See [Releasing](/docs/releasing) for how to publish a release and the rules releases follow. ## Editor K3 Studio draws everything itself: a single GL draw call with SDF rounded rects, its own glyph atlas with kerning, and a rope text buffer. It only redraws when something changes, so it sits at about 0% CPU when idle. ### Editing ![Multi-cursor](/images/multicursor.png) - Undo/redo, clipboard, IME, selections with mouse and keyboard, smooth scrolling - Multi-cursor: `Ctrl+Alt+Up/Down`, `Alt+click`, `Ctrl+D` (next match), `Ctrl+Shift+L` (all matches). Copy and paste go one line per caret. - Line actions: move (`Alt+Up/Down`), copy (`Shift+Alt+Up/Down`), delete (`Ctrl+Shift+K`), comment (`Ctrl+/`), go to line (`Ctrl+G`) - Fallback fonts (Segoe UI, Segoe UI Symbol, Emoji, Microsoft YaHei) for glyphs the code font doesn't have ### Highlighting Highlighting comes from tree-sitter and uses a semantic palette: keyword, call, **native (amber)**, method, field, parameter, string, number and comment. Supported languages: Lua, JS/TS, JSON, CSS, SCSS, HTML, Svelte (script as TypeScript, style as SCSS), `server.cfg`, SQL and Markdown. ### Explorer and tabs The explorer shows file-type icons, and folders that mean something in FiveM get their own color and glyph: `client`, `server`, `shared`, `web`, `[category]` and others. You can create, rename, move and delete from the right-click menu. When two tabs have the same file name, the label adds as much of the path as it takes to tell them apart (`client/main.lua`, `server/main.lua`). ### Command palette and quick open ![Palette: natives](/images/palette.png) `Ctrl+P` opens files (fuzzy). Typing a prefix switches mode: | Prefix | Mode | |---|---| | `>` | Commands (also `Ctrl+Shift+P`) | | `#` | FiveM natives: inserts the call, tagged client / server / shared | | `@` | Symbols in the file: functions, events, commands, callbacks, CSS rules | | `=` | Lua utilities: `joaat`, hex/signed, colors | ![Palette: symbols](/images/palette_symbols.png) JSON → Lua conversion runs on the selection as a `>` command. ### Search and replace ![Search](/images/search.png) Workspace search can be scoped by side (Client / Server) and by resource. | Action | Keys | |---|---| | Find in file | `Ctrl+F` | | Replace in file | `Ctrl+R` | | Replace in workspace | `Ctrl+Shift+R` | ![Find in file](/images/find.png) ![Replace in workspace](/images/replace_ws.png) ### Snippets Built-in Lua snippets, workspace snippets in `.fed/snippets.json` and personal ones in `%APPDATA%/K3 Studio/snippets.json` all show up in completion. ### Markdown ![Markdown preview](/images/markdown.png) `.md` files open rendered, with headings, lists, tasks, quotes, code, tables, rules and inline HTML. Switch with **Preview | Text**, or double-click a block to edit it at its line. **Ask the agent** opens the composer with the file attached. ### Images ![SVG viewer](/images/image_svg.png) PNG, JPEG, BMP, GIF, TGA, PSD and SVG open as pictures, with fit, 1:1, wheel zoom, and the size and format shown. They're never saved as text. ### Terminal ![Terminal](/images/terminal.png) Named terminals are ConPTY shells (pwsh, or Windows PowerShell if pwsh isn't installed) in the bottom panel. `` Ctrl+` `` toggles the panel, and double-clicking a tab renames it. Terminals keep running while the panel is closed. ### Stats ![Stats](/images/stats.png) Coding time is measured on your computer and never sent anywhere: today, the last 7 days, all time, a 14-day chart, and breakdowns per language and project. You also get lines of code per language and per resource, and today's time sits in the status bar. ## Language servers ![LSP features](/images/lsp_features.png) K3 Studio speaks LSP over stdio JSON-RPC, and each kind of file gets its own server: | Files | Server | |---|---| | Lua | `qbx-lua-ls` | | JS / TS | `typescript-language-server` | | CSS / SCSS / LESS, HTML, JSON | `vscode-langservers-extracted` | | Svelte | `svelte-language-server` | The web servers are installed once with bun and pinned to fixed versions. You can see each server's state (starting / idle) in the Web panel. ### Features | Feature | Keys | |---|---| | Completion | as you type, `Ctrl+Space` | | Hover | mouse over | | Signature help | inside a call | | Go to definition | `F12` | | References | `Shift+F12` (opens the References tab) | | Rename | `F2` | | Format | `Shift+Alt+F` | | Inlay hints | parameter names in Lua and TypeScript | ### FiveM-specific checks - **Wrong-side natives**: calling a server-only native in a client file (and the reverse) is flagged as you type - **`io` / `os.*` on the client**: flagged in client and shared Lua - **Cross-resource globals**: a global you use in one resource but define in another (or on another side) is flagged - **Event and callback names**: names complete inside `Trigger*` / `Register*`, `lib.callback`, ESX and QB calls, using an index of the whole server; `F12` and hover work on them too - **Whole-folder problems**: Lua workspace diagnostics, plus `tsc` / `svelte-check` per app when you open the folder ![Hover on a server.cfg value](/images/hover.png) ## Live This is what makes K3 Studio different from other editors: it's connected to the server it started. ### How it works When K3 Studio starts your server, it writes a dev-only resource called **`fed-bridge`** into it. The bridge reports back through console lines (server stdout and the client log), so **nothing listens on the network**. ### Runtime error lens ![Runtime error lens](/images/error_lens.png) When a `SCRIPT ERROR` happens on the client or the server, it lands on the exact line in the editor. You can see: - the side (client / server) - how many times it happened and how long ago - the stack The console line links to the same spot, and the Live rail item shows a badge with the error count. ### Live lens ![Live lens](/images/live_lens.png) Above every event handler, command and export, you can see how many times it fired, when it last fired, which side called it, and the average time it took. You turn it on per resource from the Run menu. ## Agent & MCP K3 Studio drives **Claude Code** (the `claude` CLI) in its stream-JSON mode. `Ctrl+L` toggles the panel. ### Agent panel ![Agent panel with an edit hunk](/images/agent.png) - Chat, with each step shown as it happens (Read, Edited…) - **Edits are hunks** you accept or reject, or you can turn on *Always accept edits* - The composer wraps and grows. You can attach images, and the open file and the console come along as context chips. - Model and effort pickers (changing them resumes the same conversation) - Sessions you can switch between and resume - Claude Code starts warming up while you're still typing ![Slash commands](/images/agent_slash.png) Type `/` to get suggestions for Claude Code commands and skills. ### Permissions When the agent wants to use a tool, you get a card in the panel: **Ask** each time, or **Always allow** for the rest of the session. ### K3 Studio as an MCP server K3 Studio runs an MCP server over HTTP on `127.0.0.1`, protected by a token, and attaches it to Claude Code. Your own MCP servers still load as usual. | Tool | What it does | |---|---| | `server_status` | Is the server running, and from which folder | | `server_console` | Recent console lines | | `server_command` | Run a console command | | `runtime_errors` | Errors the error lens has collected | | `diagnostics` | Problems from the language servers | | `open_file` | Open a file in K3 Studio | ## Server ### Running FXServer ![Server running with the console](/images/server.png) - Start, stop and restart from the title bar pill or the Run menu. K3 Studio can run FXServer directly or through txAdmin. - **Saving a file restarts only the resource it belongs to.** - Restart on crash (Run menu): gives up after 3 crashes in 2 minutes - txAdmin: K3 Studio looks for `txData` inside, beside or above the server folder, and picks the profile if there's only one non-default profile - Missing FXServer? K3 Studio offers to install the recommended artifact build ### Console The console shows server and client output together, colored by side, with Server / Client filters. It has a command input with history, and file:line references are clickable links. ### New project wizard **File › New project** asks for a folder, license key, database, template (Blank, ESX Legacy, Qbox, TypeScript core), ox resources, and whether to create a git repository. You can also mark the project as using txAdmin. ### server.cfg as a form ![server.cfg form](/images/cfg_form.png) Switch between **Form** and **Text** at the top right. The form has: - **Identity**: server name with a live `^` color preview, project name, description, tags, language, icon - **Players and game**: max players, OneSync, game build, ScriptHook - **Network**: endpoints, whether player IPs are shown - **Security**: pure level, entity control, auth variance and trust, request paranoia, LAN mode, each with a short explanation - **Secrets**: masked, or showing which `exec`'d file holds them - **Executed files**: in `exec` order, with missing files and whether `.gitignore` covers secrets - **Start order**: move `ensure` lines up and down, with warnings when a resource needs a dependency that's missing ### server.cfg as text ![server.cfg checks](/images/cfg_quotes.png) - Completion for commands, for convars after `set` / `setr` / `sets`, for resources and `[categories]` after `ensure`, for `.cfg` files after `exec`, and for aces and principals - Hover docs for commands and convars - Checks: unknown resource, missing `exec` file, repeated `ensure`, placeholder license key, secrets that `.gitignore` doesn't cover ## Resources ### fxmanifest.lua as a form ![Manifest form](/images/manifest_form.png) `fxmanifest.lua` opens as a visual editor (**Form ↔ Text**). Edits are made in place, so your comments stay. - Identity: runtime (`fx_version`), game, author, version, description - Scripts per side (Shared, Client, Server). Files that don't exist are flagged **not found**, and a pattern shows how many files it matches. - In-game UI (`ui_page`) with a **Dev server / Build** switch - Files, dependencies and data files - The add field suggests what each directive takes (`Tab` takes the first suggestion) ![Manifest NUI card](/images/manifest_nui.png) In Text mode, strings complete to what their directive takes: script paths and folder globs, pages, `folder/**`, resource names for dependencies, and `@ox_lib/init.lua`. ![Manifest path completion](/images/manifest_paths.png) ### What runs where K3 Studio works out what runs on each side from the manifest scripts and what they `require`. Client modules need to be listed in `files {}`, while server modules need nothing. When a required file isn't loaded, an editor banner and a form card let you add it to `files {}` or to a side in one click. ### Resources panel and details ![Resource details](/images/resources.png) The Resources panel lists resources by `[category]`, and you can start, stop, restart and refresh them. You can create, rename and delete categories, and move, rename and delete resources; `server.cfg` is updated to match. The details page shows: - **Events**: name, side, whether the resource registers or triggers it, how many callers, and live counts - **Exports** and **callbacks** - **Files** by side - **Dependencies** as a diagram - **Health**: events with no handler, and runtime errors ### Focus on a resource ![Focus mode](/images/focus.png) Right-click a resource and choose **Focus**. The explorer, search, problems, console and Git changes then only show that one folder, while the server and Live stay whole. The status bar shows a pill while focus is on, and `Esc` leaves. ### New resource The new resource wizard has templates for Lua, Lua + ox_lib, Qbox and ESX, and can add the `ensure` line for you. ### Generate documentation **Run › Generate documentation** writes one HTML page for a resource, a category or the whole server. ## Core workspace Support for TypeScript monorepos that ship as **one `core` resource**: `apps/*`, `lib/`, `configs//.json`, built with tsdown and vite. ### New app / New lib ![New app dialog](/images/core_app.png) Right-click in the explorer inside a core, or use the palette: - A kebab-case name (reserved names are refused) - Which sides: client, server, shared - Starter code: config files, an event from server to client, a chat command, a command that opens the UI - For a lib: its side and its barrel export - The files it will create are listed **before** anything is written ### Checks - **Side import guard**: a client file that imports from a `server/` path (or the reverse) is flagged - **Manifest sync**: K3 Studio suggests missing `files {}` globs, for client-required modules and for the built UI page's assets as `/**` - **`ui_page` pointing at the dev server** shows a warning in the form and as a diagnostic, and the In-game UI card has a Dev server / Build switch ## Database ![Table data](/images/db_data.png) ![Query results](/images/db_page.png) Before a connection string is found, the page looks like this: ![Database page, not connected](/images/db_run.png) ### Connection K3 Studio reads `mysql_connection_string` from any `.cfg` in the folder (example files are checked last) and connects **read-only by default**. Queries go through a small mysql2 helper that runs with bun. ### What you can do - Schema tree of every table, with search - Each table has **Data** and **Structure** tabs, a `WHERE` filter and paging - SQL box: `Ctrl+Enter` runs it - Results grid with sortable columns, **Explain** and **Copy CSV** - Recent queries - **Safe mode**: writes need the Writes switch turned on, and then a confirm for each statement ### SQL everywhere ![SQL box with colors and completion](/images/db_colors.png) The SQL box is colored like a `.sql` file and suggests tables, columns and keywords as you type (`Tab` takes one). ![SQL file](/images/sql.png) `.sql` files are highlighted, and completion knows your schema (tables, columns, keywords). This works in the Database SQL box and inside `MySQL.query` / oxmysql strings in both Lua and TypeScript. ## Git K3 Studio uses the git CLI (porcelain v2). Status and every git action run on worker threads, so the UI never waits on git. ### Changes and commit ![Changes and diff](/images/git.png) - Changed and staged files with file icons and their side (client / server) - Side-by-side highlighted diff with a **Stage** button - Commit, or let **Write** have the agent write the message - **Amend the last commit** (if the message is empty, the old one is kept) - An **Undo** bar after commit, stage, unstage, discard (discarded changes are kept in a stash), revert and amend. `Ctrl+Z` works too, as long as the commit is still the tip. ### History ![History](/images/git_history.png) - History with avatars (GitHub by email, initials when offline), refs and age - A commit view with its files and diffs, **Copy hash** and **Revert** - Right-click a commit to revert or reset to it - The Git side panel has a **Changes | History** switch ![Side panel history](/images/git_side_history.png) ### Branches and stash Under the **Branches** tab you can create and switch branches. Under **Stash** you can stash, apply, pop and drop. ### Inline blame ![Inline blame](/images/blame.png) When the caret rests on a line of a saved file that's tracked by git, K3 Studio shows who last changed it, when, and the commit message, at the end of the line. ### Secret guard ![Secrets in this commit](/images/git_secrets.png) Before a commit, K3 Studio checks for secrets: the FiveM license key, the Steam API key, the Tebex secret and the MySQL password. **Move to secrets.cfg** moves those lines into a file that `server.cfg` `exec`s and that is listed in `.gitignore`. ### Focus With [Focus on a resource](/docs/resources#focus-on-a-resource), changes (and stage / unstage all) only include that resource. ## Web & NUI ![Packages, scripts and terminal](/images/web_install.png) ### Packages - The package manager is chosen per project: npm, pnpm, bun or yarn. The default is bun, but an existing lockfile wins. - One-click **Install**, **Add package** (with a dev toggle) and remove - A *"package.json changed · N missing"* warning, and an editor banner when an app's imports are missing because nothing is installed yet - **Add FiveM types** (`@citizenfx/client`, `@citizenfx/server`) ### Scripts Every script in `package.json` gets **Run / Stop** and runs in its own named terminal, with a status dot. When a dev server prints its address (Vite's `Local:`), it shows up as a chip that opens the browser. ### ui_page dev / build The In-game UI card in the [manifest form](/docs/resources#fxmanifestlua-as-a-form) switches `ui_page` between the dev server and the build, and updates `files {}` to match. ### Chrome 103 compatibility FiveM's CEF is Chrome 103. K3 Studio warns about newer CSS features and APIs in NUI files, and about a vite config that has no build target. ## Vehicle handling Open it from the **Game** rail item. K3 Studio lists every vehicle it finds in the `handling.meta` files of your workspace. ### Beginner mode ![Handling: beginner mode](/images/handling.png) About ten sliders in plain language (top speed, acceleration, gears, grip, steering angle, slide when cornering, brakes, weight, ride height, damage). Each one maps to `CHandlingData` fields, shows the raw field and value underneath, has a tick at the stock value, and has its own reset. ### Presets **Faster**, **More grip**, **Drift**, **Heavy**, **Arcade**, **Realistic** and **Police pursuit**. You can stack them and undo them, and fine-tune every slider afterwards. ### Expert mode Every field, with its raw name and stock value, plus checks that compare fields (for example traction min higher than max). ### Flags ![Handling flags](/images/handling_flags.png) Handling and model flags are checkboxes, and K3 Studio writes the hex value for you. ### Saving **Save** writes `handling.meta`. If the manifest is missing the `HANDLING_FILE` `data_file` and `file` entries, K3 Studio adds them, then ensures the resource. ## Releasing K3 Studio A release is a git tag. Pushing a `v*` tag runs [the release workflow](https://github.com/Kr3mu/k3studio/blob/master/.github/workflows/release.yml). The workflow builds K3 Studio with that version, packs [the installer](https://github.com/Kr3mu/k3studio/blob/master/installer/k3studio.iss) and publishes it as a GitHub release. Installed copies of K3 Studio see the new release the next time they start and update themselves (see [Updates](/docs/getting-started#updates)). ### How to release 1. Get `master` ready. Merge everything that ships and make sure the working tree is clean. 2. Run the full test suite and make sure it passes: ```bash ./run.sh test ``` 3. Do a release build and try it by hand: open a workspace, start the server, edit and save a file. ```bash K3_VERSION=0.1.0 ./run.sh release ``` 4. Write the release overview in `docs/releases/vX.Y.Z.md` (named after the tag) and commit it. It opens the release notes on GitHub, above the generated commit list. Keep it brief: a few bullets on what users get, grouped (new, improved, fixes), plus anything they must do after updating (a renamed setting, tools to allow again). Leave out website, test and docs changes. The workflow refuses to release a tag without this file. See [v0.2.5](https://github.com/Kr3mu/k3studio/blob/master/docs/releases/v0.2.5.md) for an example. 5. Push `master`: ```bash git push origin master ``` 6. Tag the commit you tested and push the tag: ```bash git tag v0.1.0 ``` ```bash git push origin v0.1.0 ``` 7. Watch the run in the repository's **Actions** tab. When it's green, the release is at with `K3Studio-0.1.0-setup.exe` attached, your overview first and the generated commit list under it. 8. Edit the release notes on GitHub if needed, for example to call out breaking changes or new settings. 9. Check the update: start an older installed K3 Studio. With auto-update on, it downloads the new version and installs it when you quit. With auto-update off, it asks. ### Rules #### Versions - Tags are `vMAJOR.MINOR.PATCH`, for example `v0.4.2`. The updater compares the numbers part by part, so `v1.10.0` is newer than `v1.9.3`. - No pre-release tags (`v1.0.0-rc1`, `v1.0.0-beta`). The updater can't compare them. - Keep the steps small: bump PATCH or a small MINOR step (0.2.0 → 0.2.5 → 0.3.0), not big jumps. - Every release has a higher version than the one before. The updater only installs a version newer than the one that's running. - Bump **PATCH** for fixes only, **MINOR** for new features or settings, and **MAJOR** for changes that break existing workspaces, settings files or `fed-bridge`. Before 1.0, MINOR covers breaking changes too. - The version only comes from the tag. Don't put it in code: release builds get it as `-define:K3_VERSION=...`, and builds from source report `dev` and never update. #### Tags and releases - Only tag commits on `master` that passed `./run.sh test`. - Never move, delete or re-push a tag once its release is published. Installed copies may already have downloaded that installer. - If the workflow fails **before** publishing, delete the tag, fix the problem, and tag again with the same version: ```bash git push origin :refs/tags/v0.1.0 ``` ```bash git tag -d v0.1.0 ``` - If a published release is broken, don't delete it. Fix it forward with a new PATCH release. To roll back, release the old code under a new, higher version. - A release must not be a draft or marked pre-release. The updater reads GitHub's *latest* release and skips both. #### The installer - The installer asset must keep the `-setup.exe` suffix (`K3Studio--setup.exe`). That suffix is how the updater finds it. - Never change the `AppId` in `installer/k3studio.iss`. If it changes, Windows treats the new install as a separate program and the old one stays behind. - The installer stays per-user (`PrivilegesRequired=lowest`). Silent updates rely on not needing admin. - A new file that K3 Studio needs at runtime (a DLL or data file not baked in with `#load`) must be added to `[Files]` in the installer script, or installed copies break. - The installer must keep working with `/VERYSILENT` (install on quit) and `/SILENT /RELAUNCH` (update and restart). Don't add wizard pages that need input in silent mode. #### The repository - The repository must be public. The updater and installer downloads use GitHub without signing in, and a private repository answers them with 404. - The updater checks `Kr3mu/k3studio` (`RELEASES_API` in `src/updates.odin`). If the repository is renamed or moved, update that constant and ship a release from the **old** location first, so existing installs find the new one. - The workflow needs no secrets: it publishes with the built-in `GITHUB_TOKEN`. It runs with `contents: write` permission.