0 im Spiel
Download
Schießerei in einem dunklen Treppenhaus in Mafia II

Doku

HTML interfaces

A resource's page is drawn over the game with a transparent background. Any HTML, CSS and JavaScript works, React and Vue included.

-- resource.lua
client_scripts { "client/main.lua" }
files { "client/ui" }
-- client/main.lua
web.open("client/ui/index.html")

events.onServer("money", function(amount)
    web.emit("money", amount)          -- to the page
end)

web.on("buy", function(item)           -- from the page
    events.emitServer("shop:buy", item)
end)
<!-- client/ui/index.html -->
<div id="money"></div>
<button onclick="m2o.emit('buy', 'pistol')">Buy</button>
<script>
  m2o.on("money", (amount) => {
    document.getElementById("money").textContent = "$" + amount;
  });
</script>

Mouse and keyboard

web.focus(true) gives the page the mouse and keyboard: a cursor appears and the character stops moving. web.focus(false) hands control back to the game.

Addresses

A page reaches the resource's files as https://nui.m2o/<resource>/<path>; relative links (style.css, img/logo.png) work as usual.

Svelte, React, Vue

Any framework works: build the project and ship the build. With Vite:

// vite.config.js
export default {
  base: "./",                 // relative paths: the page lives at https://nui.m2o/<resource>/...
  build: { outDir: "../client/ui" },
};
-- resource.lua
client_scripts { "client/main.lua" }
files { "client/ui" }                    -- the build: index.html, assets/...

-- client/main.lua
web.open("client/ui/index.html")

base: "./" matters: with Vite's default / the page asks for /assets/..., which isn't inside the resource, and stays blank. Inside the page, talk to Lua with m2o.emit / m2o.on as above. To work on it: npm run build, then restart <resource> in the server console; players get the new page right away. Players keep the files they downloaded and only fetch what changed.