Difference between revisions of "Proposals/Client scripting plans"

From Minetest Developer Wiki
Jump to navigation Jump to search
 
(20 intermediate revisions by 5 users not shown)
Line 1: Line 1:
Minetest is planned to get client side scripting. This page summarizes the plans for development, and tries to document the consensus inside the core development team. If your changes don't want to serve this **documenting** purpose, please **don't edit** this page (except trivial edits like grammar corrections), but rather edit the talk page, or suggest changes in irc. This is no Feature request page.
+
Minetest is planned to get client side scripting. This page summarizes the plans for development, and tries to document the consensus inside the core development team. If your changes don't want to serve this '''documenting''' purpose, please '''don't edit''' this page (except trivial edits like grammar corrections), but rather edit the talk page, or suggest changes on IRC. This is no Feature request page.
  
 
== General design ==
 
== General design ==
 +
 
The language will be plaintext lua (no bytecode, as it's insecure and against the open source nature of minetest). There won't be any restrictions on mod licenses though.
 
The language will be plaintext lua (no bytecode, as it's insecure and against the open source nature of minetest). There won't be any restrictions on mod licenses though.
  
The general design should be much like the web browser / javascript relationship. During the connection, the server sends all code that should be executed to the client, which runs it inside a locked down sandbox. Unlike with server mods, there will be no way (without changing c++ source code) to execute code outside of that sandbox.
+
The general design should be much like the Web browser-JavaScript relationship. During the connection, the server sends all code that should be executed to the client, which runs it inside a locked down sandbox. Unlike with server mods, there will be no way (without changing C++ source code) to execute code outside of that sandbox.
  
Unlike with web browsers, lua code should run in a separate thread. Also, to be completely separate, it shouldn't share the lua environment with the mainmenu lua (to forestall intra-environment exploits).
+
Unlike with Web browsers, Lua code should run in a separate thread. Also, to be completely separate, it shouldn't share the Lua environment with the mainmenu Lua (to forestall intra-environment exploits).
  
 
=== Base execution setup ===
 
=== Base execution setup ===
 +
 
Every server mod can have a directory "client" whose content will be sent to the client upon connection. After all files have been recieved, the client executes an "init.lua" file for every of those mods.
 
Every server mod can have a directory "client" whose content will be sent to the client upon connection. After all files have been recieved, the client executes an "init.lua" file for every of those mods.
  
 
To emphase the short-lived-ness of the code, the client shouldn't give any access to the filesystem. This implies that all lua files should be held in memory. There can be caches (even permanent ones, like with the texture cache), but lua code shouldn't be abled to "just access the filesystem", not even subdirectories.
 
To emphase the short-lived-ness of the code, the client shouldn't give any access to the filesystem. This implies that all lua files should be held in memory. There can be caches (even permanent ones, like with the texture cache), but lua code shouldn't be abled to "just access the filesystem", not even subdirectories.
 +
 +
=== Event Driven Architecture ===
 +
 +
Client-side mods operate on asynchronous events.  This is necessary to prevent mods from preventing or otherwise delaying scene rendering.
 +
Events are posted to a separate thread which then dispatches them via Lua (that is, the client-side equivalent to Script API):
 +
* On keypress input
 +
* On mouse input (move, mousebutton)
 +
* Digging/punching/dig complete
 +
* Item events
 +
* Inventory changes
 +
* Local player events (move, jump, crouch, etc.)
 +
* Player events (Server HP change/breath change, eventually to be a network event)
 +
* Network events
 +
*    This is deserialized from within Lua
 +
*    Lua side abstracts as an RPC call
 +
* GUI events
 +
 +
Longer term stretch goals:
 +
* Client-side biome change events
 +
 +
To prevent excessive event generation, a mask of wanted events will be maintained.
 +
Nothing will be queued unless a mod subscribes to the event type.
 +
 +
Functions available to client side mods (aka the Lua API):
 +
* HUD manipulation
 +
* GUI manipulation
 +
* Register ParticleSpawners
 +
* Register sounds and play them
 +
* Register shaders and trigger them on events ??? uh oh how are we going to do this
 +
* Send network events - abstracted to RPC call to the server
 +
*    this will serve as the basis to many of the currently built-in mechanisms
 +
* Emulate local player events or keypresses?
 +
* Set sky/bg/general video effects
 +
* Set player pos/crouch/jump state
 +
* Set player camera pitch/yaw
  
 
=== Communication between server and client ===
 
=== Communication between server and client ===
 +
 +
'''Note''': this section is waiting for approval by hmmmm, doesn't display consensus (yet).
 +
 
Client lua and server lua should be abled to communicate with each other.
 
Client lua and server lua should be abled to communicate with each other.
 
There should be no minetest.client_exec_code(playername, codestring) like call, because it favours a bad setup where code is parsed and re-parsed again, generating lag. Instead, code should be sent.
 
There should be no minetest.client_exec_code(playername, codestring) like call, because it favours a bad setup where code is parsed and re-parsed again, generating lag. Instead, code should be sent.
  
Server and client communicate in **events**, which they can both raise, and handle. Every event type has a name and an associated mod. The data which get sent over the network will include (int,int) event types, to be faster. Therefore, client and server have to register events they want to raise, and both registering functions **while loading**.
+
Server and client communicate in '''events''' which they can both raise, and handle. Every event type has a name and an associated mod. The data which get sent over the network will include (int,int) event types, to be faster. Therefore, client and server have to register events they want to raise, and call both registering functions '''while loading'''. In later code, calling registering functions for unkown events should yield a warning, but without register.
  
 
==== Server functions ====
 
==== Server functions ====
Line 23: Line 63:
 
* minetest.register_on_event(modname, eventname, function(clientid, evtdata))
 
* minetest.register_on_event(modname, eventname, function(clientid, evtdata))
 
* -> changes the event handler for the (modname, eventname) typed event
 
* -> changes the event handler for the (modname, eventname) typed event
* minetest.register_event(clientid, modname)
+
* minetest.register_event(modname, eventname)
 
* -> registers an event type. Doesn't have to be the same order that on_event methods get registered on the other side, but has to be the same events.
 
* -> registers an event type. Doesn't have to be the same order that on_event methods get registered on the other side, but has to be the same events.
 
* minetest.raise_event(clientid/-s, modname, eventname, evtdata)
 
* minetest.raise_event(clientid/-s, modname, eventname, evtdata)
Line 32: Line 72:
 
==== Client functions ====
 
==== Client functions ====
  
minetest.register_on_event(modname, eventname, function(clientid, evtdata))
+
* minetest.register_on_event(modname, eventname, function(evtdata))
-> changes the event handler for the (modname, eventname) typed event
+
* -> changes the event handler for the (modname, eventname) typed event
minetest.register_event(clientid, modname)
+
* minetest.register_event(modname)
-> registers an event type. Doesn't have to be the same order that on_event methods get registered on the other side, but has to be the same events.
+
* -> registers an event type. Doesn't have to be the same order that on_event methods get registered on the other side, but has to be the same events.
minetest.raise_event(modname, eventname, evtdata)
+
* minetest.raise_event(modname, eventname, evtdata)
-> raises an event
+
* -> raises an event
  
 
== API compartments ==
 
== API compartments ==
  
 
=== SAO/CAO control ===
 
=== SAO/CAO control ===
 +
 
There should be ways to modify CAOs from client lua.
 
There should be ways to modify CAOs from client lua.
  
=== Formspec replacement ===
+
=== HUD and Formspec replacement ===
There is still a debate with what to replace formspecs.
+
 
 +
There is still a debate with what to replace huds and formspecs.
 +
 
 +
== Specific features to be implemented using Client-side scripting interfaces ==
 +
https://github.com/minetest/minetest/issues/816 -- Add wield light by Zeg9  ---- generally, to be defined per-game through shaders registered via the client-side mod<br/>
 +
https://github.com/minetest/minetest/issues/958 -- Add player list, viewable by holding Tab by sfan5 ---- Trivially doable using client scripting to bind the key and the Hud interface<br/>
 +
 
 +
[[Category:Modding API‏‎]]
 +
[[Category:Proposal]]

Latest revision as of 21:16, 15 August 2022

Minetest is planned to get client side scripting. This page summarizes the plans for development, and tries to document the consensus inside the core development team. If your changes don't want to serve this documenting purpose, please don't edit this page (except trivial edits like grammar corrections), but rather edit the talk page, or suggest changes on IRC. This is no Feature request page.

General design

The language will be plaintext lua (no bytecode, as it's insecure and against the open source nature of minetest). There won't be any restrictions on mod licenses though.

The general design should be much like the Web browser-JavaScript relationship. During the connection, the server sends all code that should be executed to the client, which runs it inside a locked down sandbox. Unlike with server mods, there will be no way (without changing C++ source code) to execute code outside of that sandbox.

Unlike with Web browsers, Lua code should run in a separate thread. Also, to be completely separate, it shouldn't share the Lua environment with the mainmenu Lua (to forestall intra-environment exploits).

Base execution setup

Every server mod can have a directory "client" whose content will be sent to the client upon connection. After all files have been recieved, the client executes an "init.lua" file for every of those mods.

To emphase the short-lived-ness of the code, the client shouldn't give any access to the filesystem. This implies that all lua files should be held in memory. There can be caches (even permanent ones, like with the texture cache), but lua code shouldn't be abled to "just access the filesystem", not even subdirectories.

Event Driven Architecture

Client-side mods operate on asynchronous events. This is necessary to prevent mods from preventing or otherwise delaying scene rendering. Events are posted to a separate thread which then dispatches them via Lua (that is, the client-side equivalent to Script API):

  • On keypress input
  • On mouse input (move, mousebutton)
  • Digging/punching/dig complete
  • Item events
  • Inventory changes
  • Local player events (move, jump, crouch, etc.)
  • Player events (Server HP change/breath change, eventually to be a network event)
  • Network events
  • This is deserialized from within Lua
  • Lua side abstracts as an RPC call
  • GUI events

Longer term stretch goals:

  • Client-side biome change events

To prevent excessive event generation, a mask of wanted events will be maintained. Nothing will be queued unless a mod subscribes to the event type.

Functions available to client side mods (aka the Lua API):

  • HUD manipulation
  • GUI manipulation
  • Register ParticleSpawners
  • Register sounds and play them
  • Register shaders and trigger them on events ??? uh oh how are we going to do this
  • Send network events - abstracted to RPC call to the server
  • this will serve as the basis to many of the currently built-in mechanisms
  • Emulate local player events or keypresses?
  • Set sky/bg/general video effects
  • Set player pos/crouch/jump state
  • Set player camera pitch/yaw

Communication between server and client

Note: this section is waiting for approval by hmmmm, doesn't display consensus (yet).

Client lua and server lua should be abled to communicate with each other. There should be no minetest.client_exec_code(playername, codestring) like call, because it favours a bad setup where code is parsed and re-parsed again, generating lag. Instead, code should be sent.

Server and client communicate in events which they can both raise, and handle. Every event type has a name and an associated mod. The data which get sent over the network will include (int,int) event types, to be faster. Therefore, client and server have to register events they want to raise, and call both registering functions while loading. In later code, calling registering functions for unkown events should yield a warning, but without register.

Server functions

  • minetest.register_on_event(modname, eventname, function(clientid, evtdata))
  • -> changes the event handler for the (modname, eventname) typed event
  • minetest.register_event(modname, eventname)
  • -> registers an event type. Doesn't have to be the same order that on_event methods get registered on the other side, but has to be the same events.
  • minetest.raise_event(clientid/-s, modname, eventname, evtdata)
  • -> raises an event for client with clientid, or if a table is passed, all clientids in that table.
  • minetest.raise_event_all(modname, eventname, evtdata)
  • -> raises an event for client all clients

Client functions

  • minetest.register_on_event(modname, eventname, function(evtdata))
  • -> changes the event handler for the (modname, eventname) typed event
  • minetest.register_event(modname)
  • -> registers an event type. Doesn't have to be the same order that on_event methods get registered on the other side, but has to be the same events.
  • minetest.raise_event(modname, eventname, evtdata)
  • -> raises an event

API compartments

SAO/CAO control

There should be ways to modify CAOs from client lua.

HUD and Formspec replacement

There is still a debate with what to replace huds and formspecs.

Specific features to be implemented using Client-side scripting interfaces

https://github.com/minetest/minetest/issues/816 -- Add wield light by Zeg9 ---- generally, to be defined per-game through shaders registered via the client-side mod
https://github.com/minetest/minetest/issues/958 -- Add player list, viewable by holding Tab by sfan5 ---- Trivially doable using client scripting to bind the key and the Hud interface