BeamMP-Server icon indicating copy to clipboard operation
BeamMP-Server copied to clipboard

Lua API Changes Proposal

Open Lucky4Luuk opened this issue 2 years ago • 15 comments

EDIT: The Rust rewrite is on hold indefinitely, but the Lua API changes can go ahead anyways.

Everything below here is the old post, and will likely change.

Lua API Changes Proposal

With the server rewrite inbound, now is the perfect chance to change the Lua API. Please leave comments down below about the proposed changes, I'll make sure to keep this post up-to-date with the latest agreed upon changes.

Notes on how to read this:

  • If the final argument is ... , it means it should take variadic arguments

Events

  • Remove MP.CreateEventTimer (and MP.CancelEventTimer)
  • Add MP.ScheduleEvent("EventName", TimeInMillis, ...)
  • Add repeating variant MP.ScheduleRepeatingEvent("EventName", TimeInMillis, ...) to schedule events on a loop.
  • Add `MP.CancelRepeatingEvent("EventName") to cancel a repeating event.
  • Change MP.TriggerGlobalEvent to take variadic arguments the same way MP.TriggerLocalEvent does. Currently, it is a bit of a pain to use this function!
  • Ensure MP.TriggerClientEvent can also take no data! In the future, I'd like to see it also take arbitrary events, but I think this is much harder to expect unless the client can automatically decode a certain format we decide upon and give you the right arguments again.
  • Remove MP.Sleep. It sucks.
  • Include a new event onVehicleSwitched. See this issue.

FS

Currently, the filesystem functions are great, they are nice features to have. My only complaint is that it is a bit weird sometimes to mix the FS calls and io calls. Not sure what I want to see changed here, but perhaps expanding it to cover most io usecases would be nice. That way, it also wouldn't be confusing to deal with paths between the 2. Not sure if that is currently a problem, but I think it's confusing to mix the 2 still.

Other

  • Add MP.Get("Category", "Setting") to get any settings from the server config. (#258)
  • Change MP.Set to MP.Set("Category", "Setting", value). This is much more intuitive. (#258)
  • Change the behaviour of loading the config, so it doesn't strip unused values, so mods can write/read their own values in the main config.
  • Add a config flag or cli argument to prevent MP.Set overwriting the max players value.
  • Add a JSON utility library (see this comment)

API Additions

  • Add a command framework for the chat. Many plugins use chat commands, but I feel like everyone always ends up reinventing the wheel. A unified system with permissions could lead to some very nice possible additions, like /help but also properly informing the player if a command is unknown.
  • Support banning players natively, with something like MP.BanPlayer(BeamMpId) and MP.UnbanPlayer(BeamMpId).
  • Add an HTTP(S) module, to make it significantly easier for plugins to make GET/POST requests.
  • Add a websockets module.
  • (IN CASE CLIENT CHANGES ARE FINE TOO) Add a few default events that the server can trigger in the client, so we can streamline the process of modifying the client from the server. Perhaps a way to do everything from adding UI to teleporting the car to forcing a specific car?

Lucky4Luuk avatar Dec 09 '23 23:12 Lucky4Luuk

A command framework is a VERY good idea, if you combine that with a client side tab completer with something like that (minecraft example lol) Sans titre

and that would work to have the command list too for example. And all that will highly improve the user experience :D

boubouleuh avatar Dec 10 '23 14:12 boubouleuh

I agree, that's the main inspiration and reason why I wanted to add a centralized command/permission system.

Another good feature to include is onVehicleSwitched, so we can track the vehicle that a player is switched to. See https://github.com/BeamMP/BeamMP-Server/issues/184

Lucky4Luuk avatar Dec 11 '23 10:12 Lucky4Luuk

Also, issue https://github.com/BeamMP/BeamMP-Server/issues/185 might be worth considering as well? I think it's important to look at stuff like this, because implementing it in a sensible way might break backwards compatibility.

Lucky4Luuk avatar Dec 11 '23 10:12 Lucky4Luuk

Command registration would be great. I wonder could it be done something like this:

-- How to register a command for use in server console AND client side
MP.RegisterCommand('<command here with slash (to allow option for something else>', function (args) 
-- args is a table with each of the args E.g. a string

... end)

-- How to register a command for use in the server console ONLY
MP.RegisterServerCommand('<command here with slash (to allow option for something else>', function (args) 
-- args is a table with each of the args E.g. a string

... end)

Then to enable this to work for tab completion and suggestions we should wait for the new protocol and system for session and the likes and make it a part of that.

Starystars67 avatar Dec 11 '23 11:12 Starystars67

Yes, that seems like a decent idea. The only thing missing from your example would be the permission system, which IMO needs to be integrated into this as well. And you are right, with a new protocol, we should add a packet for auto completion and it'll be a great addition :)

Lucky4Luuk avatar Dec 11 '23 11:12 Lucky4Luuk

There needs to be a ScheduleEvent that repeats, I propose:

  • MP.ScheduleEvent("MyEvent", ms, ...) trigger once
  • MP.ScheduleRepeatedEvent("MyEvent", ms, ...) or ScheduleRepeatEvent("MyEvent", ms, ...) trigger every ms ms

lionkor avatar Dec 17 '23 19:12 lionkor

Of course a repeat event needs to be cancellable, so for example it could return some kind of opaque object (or an int or whatever) that uniquely identifies that repeated schedule

lionkor avatar Dec 17 '23 19:12 lionkor

I agree 100%. I'll add it to the proposal right now.

Lucky4Luuk avatar Dec 17 '23 19:12 Lucky4Luuk

The Lua API could have a serialization wrapper (maybe using json) to help with reading and writing data to the filesystem. Here's the usage of an implementation I wrote in lua:

test = jst.load('test.json') --loads contents of 'test.json' (if found) into test

print('current contents:')
dump(test)

test.banana = 
{
    meow = 'beep',
    ['23'] = 54
}
test:save() --saves contents as JSON to 'test.json'

This could eliminate most of the io.open() usage of scripts.

20dka avatar Dec 28 '23 16:12 20dka

I really like this idea, I've added it to the proposal!

Lucky4Luuk avatar Dec 28 '23 16:12 Lucky4Luuk

Could it be a good idea to start namespacing things and providing enums as well?

MP.events.fireEvent("MyEvent")

local name = MP.settings.get(MP.settings.serverSettings.name)

MP.events.onEvent(MP.events.serverEvents.playerJoin, function()
 -- handle player join
end)

I would also be interested in creating definition files and an addon for the lua-language-server for the BeamMP server and client APIs, so I (and others) can receive completion and more of an IDE-like experience when modding BeamMP. A rework of the APIs could be the perfect time to really nail the API and document it well. I don't really have any C++ experience, but I love Lua and would be glad to help with that part.

carsakiller avatar Feb 02 '24 19:02 carsakiller

@carsakiller Hi, and thank you, I've also been thinking if maybe this is a good idea (namespacing). Your offer to help with LSP stuff is greatly appreciated. We'd love to make an official repo like BeamMP/BeamMP-LSP or something, if you'd be down to write the definition files and all that. I'll get in touch with you once we start implementing these proposals :)

lionkor avatar Feb 03 '24 10:02 lionkor

Sounds good! I'd also like to sit down when I have some more time and give the API design a good think to try to make it as sensible and intuitive as possible for users. I'm no API design master, but I have seen the (rare) good, (often) bad, and the (occasional) ugly when it comes to Lua APIs, specifically in games.

Does this issue contain all the latest planned changes to the API? If not, is there somewhere else I should be looking? Also, is there somewhere I can see the most up-to-date version of the Lua API? I have been using wiki.beammp.com in lieu of docs.beammp.com but I am unsure if it is 100% up-to-date.

carsakiller avatar Feb 04 '24 16:02 carsakiller

This is just all the discussion points - nothing is decided yet :)

lionkor avatar Feb 04 '24 16:02 lionkor

A really important feature for me is being able to get a very precise UNIX timestamp at the server. Unfortunately, os.time can only provide whole seconds, and thus is not precise enough, and os.clock is only an approximation of CPU time used by the program.

Now, this could potentially be solved by including LuaSocket, as requested in #145, by using socket.gettime() which is able to provide many decimal points of precision.

carsakiller avatar Apr 17 '24 14:04 carsakiller