Releases: MSK-Scripts/msk_core
Release list
v3.1.2
Changed
- NUI rebuilt on updated dependencies. The web interface was rebuilt with
React 19, Vite 8, TypeScript 7 and FontAwesome 7. There is no API or behavior
change, the Lua side is untouched. FontAwesome 7 ships only woff2, so the
unused.ttffont files were removed fromweb/dist.
Repository
- Added continuous integration (CodeQL analysis for the NUI and a NUI build
check), Dependabot for npm and GitHub Actions, an auto release workflow that
tags and publishes a release from the matching CHANGELOGS.md section, and the
standard community health files (Code of Conduct, Contributing, Security
Policy, issue and pull request templates). These live in the repository only
and are not part of the resource you upload to your server.
To update, replace fxmanifest.lua and web/dist. Pure NUI rebuild, no Lua or
API change.
Changed files
fxmanifest.luaweb/dist/**(rebuilt,.ttffonts removed)web/src/hooks/useNuiEvent.tsweb/package.jsonweb/package-lock.jsonReadme.md
v3.1.1
Changed
-
Both menus now use a namespaced API. The documented way to reach them is
MSK.Context.Register,MSK.Context.Show,MSK.Context.Update,MSK.Context.Hide,
MSK.Context.GetOpenand the same set onMSK.Menu. This matches the rest of the
library, whereMSK.Input.OpenandMSK.Cron.Createalready work that way. Nothing
breaks: the flat names from v3.1.0 (MSK.RegisterContext,MSK.ShowMenu,
MSK.UpdateContextand so on) point at the same functions and stay supported, and the
exports are unchanged (exports.msk_core:RegisterContext(...)). -
MSK.Menu.HidereplacesMSK.Menu.Closeso it lines up withMSK.Context.Hide.
MSK.Menu.Closeremains as an alias.
Fixed
- The Menu module leaked its internal navigation onto the public table.
MSK.Menu.Move,
MSK.Menu.SideScrollandMSK.Menu.Selectwere reachable inside msk_core but did not
exist for consumer resources, so calling them from another script failed. They are
module-internal now and no longer part of the public API.
Pure Lua change, the NUI is untouched. Only the two Menu files have to be replaced,
web/dist can stay as it is.
Changed files
fxmanifest.luamodules/Menu/client.luamodules/Menu/server.lua
v3.1.0
v3.1.0
Added
-
Context Menu. A mouse driven menu with clickable options, sub menus and back
navigation. A menu is registered once under an id and can then be opened as often as
needed. Options support icons, descriptions, images, progress bars, hover metadata,
disabledandreadOnlyrows, and can run a callback (onSelect), trigger a client
or server event (event/serverEvent), or navigate into another registered menu
(menu). While a context menu is open the NUI takes mouse focus, so the player stands
still, which is intended because the mouse is needed to click.- Client:
MSK.RegisterContext,MSK.ShowContext,MSK.UpdateContext,
MSK.HideContext,MSK.GetOpenContext - Server:
MSK.ShowContext(playerId, idOrData),MSK.HideContext(playerId)
- Client:
-
Menu. A keyboard navigated list menu in the style of a classic NativeUI menu, with
a highlighted row, side scroll values, checkboxes and progress bars. It deliberately
does not take NUI focus. The arrow keys are read through the game controls and only
those navigation controls are disabled, so the player can keep walking, driving and
doing everything else while the menu is on screen. The complete state (selected row,
current values, checkbox states) lives in Lua, soonSelected,onSideScroll,
onCheckandonClosealways receive the authoritative values.- Client:
MSK.RegisterMenu,MSK.ShowMenu,MSK.UpdateMenu,MSK.HideMenu,
MSK.GetOpenMenu - Server:
MSK.ShowMenu(playerId, idOrData),MSK.HideMenu(playerId)
- Client:
-
Live updates for both menus.
MSK.UpdateContext(contextId, dataId, updatedData)
andMSK.UpdateMenu(menuId, dataId, updatedData)address a single option through its
idand merge the given fields into it, so only what actually changes is passed. If
exactly that menu is currently open, the UI is refreshed live. This replaces the need
to rebuild and reopen a whole menu just to move a progress bar, relabel a row or
disable an option.
Both menus were written from scratch for msk_core and use the MSK design language (dark
panel, green accent, bundled FontAwesome icons), consistent with the rest of the NUI.
The NUI was rebuilt for this release, so web/dist has to be replaced together with the
Lua files.
Fixed
- A missing text could take down the whole NUI. The color code parser called
String.sliceon whatever it was handed, so a single call with aniltext, for
exampleMSK.Notification('some text')where the second parameter is the message and
was left out, threw inside React. Because the NUI has no error boundary, that one throw
unmounted every component at once: notifications, input, numpad, progressbar, textui and
the new menus all disappeared until the resource was restarted. The parser now returns
an empty result forniland converts numbers to strings, so a bad call degrades to an
empty label instead of killing the interface.
Changed files
fxmanifest.luainit/client.luainit/server.luamodules/Context/client.luamodules/Context/server.luamodules/Menu/client.luamodules/Menu/server.luaweb/src/App.tsxweb/src/types.tsweb/src/index.cssweb/src/lib/colorCodes.tsxweb/src/components/ContextMenu.tsxweb/src/components/ListMenu.tsxweb/src/components/menu/frame.tsxweb/src/dev/DevPanel.tsxweb/dist/index.htmlweb/dist/assets/index.jsweb/dist/assets/index.css
v3.0.1
Fixed
-
QBCore item functions were unreachable and crashed
MSK.GetPlayer().
On QBCore the player wrapper read the item helpers fromself.PlayerData.Functions,
which isnil(QBCore exposes them onPlayer.Functions). Any command or script
that resolved a player and touchedAddItem,RemoveItem,HasItemorGetItem
crashed withattempt to index a nil value (field 'Functions'). They now read from
self.Functions, consistent with the rest of the wrapper. -
Eager loading a module could break other resources or duplicate effects.
Several modules registered shared, msk_core owned listeners (net events, callbacks,
commands, background threads) unconditionally. When a consumer resource eager loaded
such a module (for examplemsk_core 'Notify'in itsfxmanifest.lua), a second copy
of those listeners started inside the consumer and interfered server wide. Every
affected module now guards its shared registrations so they run only inside msk_core,
while consumers keep the full callable API through the export proxy. This makes every
module safe to eager load. Affected modules and their symptom:- Callback: a second responder answered
callbackNotFoundfor other resources'
callbacks and broke them. - Notify (client): notifications were shown twice, once per eager loading resource.
- Command (server): the
msk_core:doesPlayerExistandmsk_core:getPlayerData
callbacks were re registered onto the core with a closure pointing back into the
consumer, so they broke once that consumer stopped. - Ace (server): the
msk_core:isAceAllowedandmsk_core:isPrincipalAceAllowed
callbacks had the same problem. - Entities (client): a second death detection handler reported every death twice.
- Vehicle (client): a second enter/exit thread reported every vehicle event twice.
- DisconnectLogger (client and server): disconnects were logged and drawn more
than once. - Ban (server): bans were enforced twice and the
/banand/unbancommands were
registered a second time. - Cron (server): a second tick loop and
createCronlistener could run a cron job
twice.
- Callback: a second responder answered
-
MSK.Cronwas unusable from consumer resources.
The Cron module returnedtrue, which the consumer loader cached over theMSK.Cron
table, leaving onlyMSK.CreateCronandMSK.DeleteCronreachable. It now returns the
MSK.Crontable, soMSK.Cron.CreateandMSK.Cron.Deletework as documented.
Changed files
bridge/qbcore/server.luamodules/Callback/shared.luamodules/Callback/client.luamodules/Callback/server.luamodules/Notify/client.luamodules/Command/server.luamodules/Ace/server.luamodules/Entities/client.luamodules/Vehicle/client.luamodules/DisconnectLogger/client.luamodules/DisconnectLogger/server.luamodules/Ban/server.luamodules/Cron/server.luafxmanifest.luaReadme.md
v3.0.0
🔧 msk_core — Compatibility Update
The latest version of msk_core is now compatible with all actively maintained MSK scripts.
📦 Scripts requiring an update
msk_garage— update available, please update before usemsk_vehiclekeys— update available, please update before use
✅ No update needed
msk_handcuffs— already fully compatiblemsk_storage— already fully compatible
Please make sure to update msk_garage and msk_vehiclekeys before running them alongside the latest msk_core.
🛒 Get the latest versions at portal.cfx.re
Frontend
Major release — the NUI was rebuilt from scratch. All
SendNUIMessageactions
and NUI callbacks are unchanged, so existing Lua integrations keep working.
🗑️ Removed — legacy html/ NUI (vanilla HTML/jQuery)
html/index.html,html/script.js(~363 lines of jQuery logic)html/css/:import.css,main.css,notify.css,input.css,numpad.css,progressbar.css,textui.css
🏗️ Added — new web/ source (React 18 + Vite + TypeScript + Tailwind CSS v4)
- Entry & app:
web/src/main.tsx,web/src/App.tsx,web/src/index.css(MSK tokens via Tailwind@theme),web/src/types.ts,web/src/vite-env.d.ts - Components:
components/NotifyStack.tsx,Input.tsx,Progressbar.tsx,Numpad.tsx,TextUI.tsx - NUI bridge:
hooks/useNuiEvent.ts,lib/fetchNui.ts,lib/isEnvBrowser.ts - Helpers:
lib/colorCodes.tsx(XSS-safe~r~/~g~/~s~parser),lib/sound.ts - Tooling config:
web/package.json,web/package-lock.json,web/vite.config.ts,web/tsconfig.json,web/index.html,web/.gitignore
🎨 Redesign
- Complete NUI rebuilt in the new MSK design (dark-themed, green accent
#00E676) - Central design tokens via Tailwind
@theme(colors, radii, shadows, animations) — notailwind.config(CSS-first) - New typography: Syne (headlines), Space Mono (uppercase labels/codes), DM Sans (body)
- All 5 UI components reworked: Notify, Input, Progressbar, Numpad, TextUI
- Unified accent on notifications (icon, title & depleting bar instead of clashing accent bars)
📦 Assets & Offline
- FontAwesome Free bundled locally (
fa-solid-900,fa-regular-400,fa-brands-400,fa-v4compatibility) → no more CDN - All font families bundled as
.woff2/.woff(Syne, Space Mono, DM Sans incl. latin-ext/greek/vietnamese subsets) - Sounds moved to
web/public/sounds/(notification.mp3,click.mp3)
🚀 Build & Integration
- Built output committed under
web/dist/(index.html,assets/,sounds/) → server requires no npm/build step - Vite configured with
base: './'(required fornui://), single-bundle output, fonts as separate hashed assets fxmanifest.lua:ui_page→web/dist/index.html,files→web/dist/**/*
🎨 Default Colors (config.lua)
Config.NotifyTypesaligned to the MSK palette (success#00e676, warning#facc15, error#f43f5e, general#f0ede8, info#75d6ff)Config.ProgressColor&Config.TextUIColorchanged from#5eb131to MSK green#00e676
🛠️ Developer Experience
web/src/dev/DevPanel.tsx— built-in panel to trigger/test all UI states in the browser (without FiveM)web/src/dev/mock.ts—GetParentResourceNamestub for standalone developmentnpm run devwith HMR for fast styling iteration
⚠️ Compatibility
- No breaking changes to the Lua-facing NUI API — all actions (
notify,openInput,progressBarStart,openNumpad,textUI, …) and callbacks (submitInput,submitNumpad,closeInput,closeNumpad,progressEnd) are identical - When changing the UI, run
npm run buildinweb/and commitweb/dist
Backend
Major release — full backend rewrite. Legacy export/function names are kept
viaaliases.lua, but please test your scripts against this version.
🏗️ Architecture & Loader
- Complete restructure to a modular layout:
modules/<Name>/{client,server,shared}.lua(ox_lib-style lazy-loading via__index) - New bootstrap layer
init/(shared.lua,client.lua,server.lua) replacing the oldclient/main.lua&server/main.lua - Rewritten
import.lualoader - New
aliases.luaproviding backwards-compatible export/function names - New
bridge/shared.lua; framework bridges (ESX, QBCore, ox_core) refactored on both client and server
✨ New & Expanded Modules
- Player is now available client and server-side (
MSK.Player, identifiers, jobs, money, etc.) - Server-side callbacks added (
modules/Callback/server.lua+ shared) — full client⇄server callback system - Check module (version checker + dependency validation) — replaces legacy
server/versionchecker.lua&version.lua - Society module (server) — society/job account handling
- Offline module (server) — access to offline player data
- World module (client + server)
- Vehicle module gains a server side
- UI modules can now be triggered from the server:
Notify,Input,Numpad,Progress,TextUI,Coordseach got aserver.lua - New shared utility libraries: Math, String, Table, Timeout, Vector (expanded, moved out of the old flat
shared/*), plus Call and Config
📦 Inventory
- New unified
hasItemhandlers (client + server) - Inventory adapters reorganized under
inventories/server/(ox_inventory, core_inventory, jaksam_inventory, custom) - Removed legacy
qs-inventoryadapter (consolidated)
🗑️ Removed (Legacy)
- Old flat
client/,server/,shared/file structure fully removed - Per-feature files (
client/functions/*,server/functions/*) replaced by the new module system
⚙️ Config & Manifest
config.luaupdated (notification types/colors, defaults aligned to the new MSK design)fxmanifest.luarestructured — shared/client/server script globs adapted to the new module layout; bumped toversion '3.0.0'
⚠️ Compatibility
- Public
MSK.*exports andexports('...')are preserved where possible; legacy names are mapped throughaliases.lua - As this is a major version bump, validate custom integrations (especially anything relying on the old
client/,server/,shared/paths or removedqs-inventoryadapter)
Full Changelog: v2.8.4...v3.0.0
Update v2.8.4
- Replace Font Awesome CDN links with jsDelivr links
Update v2.8.3
- Added Support for Jaksam_Inventory
Update v2.8.2
Update v2.8.0
- Changed folder structure
- Rewritten framework bridge (documentation will be updated soon)
- Added
'chat:removeSuggestion'for MSK.RegisterCommand if parametershowSuggestionis set to false - Fixed error on playerConnected on function
GetPlayerDeath - Fixed error with core_inventory on function
HasItem
Full Changelog: v2.7.4...v2.8.0
Update v2.7.4
- Added new Feature for MSK.Player
Full Changelog: v2.7.3...v2.7.4