openvibers/source.openvibe.games Commits

sandbox: client.js demo + server->client welcome (full-stack verify)

CO Copilot committed 2 Jul 2026 · 2b193b68fb · 2 files, +31 −6

Sandbox client.js now exercises the client JS runtime end to end: npm
require on the client (ov-leftpad), a client Initialize hook, and
net.Receive('OV_Sandbox_Welcome'). Server pushes that welcome on
PlayerInitialSpawn via net.Send, proving server->client net into client
JS. Full-stack test (two realms + net both ways) passes: server->client
welcome delivered; client->server spawn validated and dispatched.

Changes

ddiff --git a/game/openvibe.games/js/gamemodes/sandbox/client.js b/game/openvibe.games/js/gamemodes/sandbox/client.js
iindex ab76bad..2ad4830 100644
---- a/game/openvibe.games/js/gamemodes/sandbox/client.js
++++ b/game/openvibe.games/js/gamemodes/sandbox/client.js
@@@ -1,6 +1,24 @@
--// OpenVibe Sandbox — client realm.
--// The spawn menu is served by the server realm (server.js) and shown via chat.
--// The actual "press Q" binding is installed from the client cfg
--// (openvibe_proton_client.cfg: bind q "say !q"), which routes to the server's
--// !q command through the PlayerSay hook. This file just marks the realm loaded.
--console.log("OpenVibe Sandbox client realm loaded — press Q for the spawn menu.");
++// OpenVibe Sandbox — CLIENT realm (runs inside client.dll QuickJS now).
++OV.log("sandbox client.js running — realm server?=" + OV.isServer());
++
++// npm module usage on the CLIENT
++try {
++ var leftpad = require("ov-leftpad");
++ OV.log("client require('ov-leftpad')('9',4,'0')=" + leftpad("9", 4, "0"));
++} catch (e) { OV.error("client require failed: " + e.message); }
++
++// server -> client net: receive a welcome the server pushes on spawn
++if (globalThis.net) {
++ net.Receive("OV_Sandbox_Welcome", function (len) {
++ var msg = net.ReadString();
++ OV.log("CLIENT received OV_Sandbox_Welcome: " + msg);
++ });
++ OV.log("client net.Receive('OV_Sandbox_Welcome') ready");
++}
++
++// client Initialize hook
++if (globalThis.hook) {
++ hook.Add("Initialize", "SandboxClientInit", function () {
++ OV.log("client Initialize hook fired");
++ });
++}
ddiff --git a/game/openvibe.games/js/gamemodes/sandbox/server.js b/game/openvibe.games/js/gamemodes/sandbox/server.js
iindex 9642b75..9b231da 100644
---- a/game/openvibe.games/js/gamemodes/sandbox/server.js
++++ b/game/openvibe.games/js/gamemodes/sandbox/server.js
@@@ -100,6 +100,7 @@
function registerNet() {
if (!globalThis.net) return;
util.AddNetworkString("OV_Sandbox_Spawn");
++ util.AddNetworkString("OV_Sandbox_Welcome");
net.Receive("OV_Sandbox_Spawn", function (len, ply) {
var id = net.ReadString();
if (!ply) { OV.warn("OV_Sandbox_Spawn with no player; ignoring"); return; }
@@@ -132,6 +133,12 @@
PlayerInitialSpawn(ply) {
ply.chat("Welcome to OpenVibe Sandbox! Press Q (or type !q) for the spawn menu.");
++ // server -> client net: push a welcome the client JS receives & logs.
++ if (globalThis.net && ply) {
++ net.Start("OV_Sandbox_Welcome");
++ net.WriteString("Hello " + ply.name() + " from the server via net.Send!");
++ net.Send(ply);
++ }
},
PlayerSpawn(ply) {