Chat CSMs - call to Compatibilty

Post Reply
Ravise
New member
Posts: 8
Joined: Mon May 25, 2015 18:40

Chat CSMs - call to Compatibilty

by Ravise » Post

Current chat-related CSM API is not designed with multiple mods touching chat messages now. And it seems it's not going to be better soon [1]. This thread is a call to all modders touching the chat API to fix that in userspace, because the kernel guys don't seem to care. Yes, I'm using that terminology on purpose.

I've seen multiple chat-coloring mods, I'm author of ignore and I have two or three features yet in mind. But current state of the minetest API is making independent mods work together hard. As I'm going to write more single-purpose mods for chat anyway, I'd like to come up with a base lib good enough to be used by more than one modder.

Right now, altering messages is done by
  1. Hooking on minetest.register_on_receiving_chat_message
  2. When recieving message, parsing it (per-mod) to get out useful information
  3. Make the edit in the text
  4. Literally printing the message to text console
  5. Returning true, cutting of any mod that would like to touch that message too.
It seems to me, that steps 1, 2, 4, 5 could be done by the lib, allowing modders to focus on 3, i.e. removing most of the boilerplate code mods have to implement now and allowing them to focus on the core functionality of the mod.

My basic idea is
  • The lib will hook on minetest.register_on_receiving_chat_message - with current api, it MUST be the single callback hooked *sigh*
  • Turn the message string into table, giving important metadata to modders with no hardcoding in the mods
  • Run the message table through all registered callbacks
  • Unless told not to do so, print the message to chat

    Code: Select all

    minetest.register_on_receiving_chat_message(function(msg_string)
        msg = msgstr_to_table(msg_string)
        -- you can access msg.author, msg.text, msg.type etc. 
        for cb in registered_callbacks do
            msg = cb(msg)
        end
        if msg.printme then
            msg_string = msgtbl_to_string(msg)
            minetest.display_message(msg_string)
        end
    end)
    
Of course, similar api could be built on sending message side.

I'd like you to tell me:
  • Do you like the idea, i.e. would you be willing to convert your mods from hollow minetest api to the new csm chat lib
  • What fields in the msg_table would you like to have access to
  • What types of messages do you find in-game
so we can built the csm chat lib for it's users (yes, unlike the minetest chat api).

  • E 20200525-1827: link to irc log fixed
Last edited by Ravise on Mon May 25, 2020 16:28, edited 2 times in total.

User avatar
Lejo
Member
Posts: 718
Joined: Mon Oct 19, 2015 16:32
GitHub: Lejo1
In-game: Lejo

Re: Chat CSMs - call to Compatibilty

by Lejo » Post

I understand what you mean but I think this should be done in the core. As the link is broken I don’t know why we couldn’t change this...

Ravise
New member
Posts: 8
Joined: Mon May 25, 2015 18:40

Re: Chat CSMs - call to Compatibilty

by Ravise » Post

I fixed the link, but for whatever reason, it requires moderator review. For instant reference, the link is http://irc.minetest.net/minetest/2020-05-24#i_5692406

User avatar
Lejo
Member
Posts: 718
Joined: Mon Oct 19, 2015 16:32
GitHub: Lejo1
In-game: Lejo

Re: Chat CSMs - call to Compatibilty

by Lejo » Post

I think it’s working right that clientmods should be able to block messages coming through to the other ones.
Otherwise they would be double handled and printed double into the chat.
If that doesn’t happen csm just shouldn’t return true on chat message.

It’s basically up to the creator of the mod.

Ravise
New member
Posts: 8
Joined: Mon May 25, 2015 18:40

Re: Chat CSMs - call to Compatibilty

by Ravise » Post

Currently, the mod can
  • print the modified message and return true, thus cutting of all other callbacks, or
  • return falsy value and let other mods work on the original, unmodified message, or
  • resort to double-printing
  • hardcode it's successors (see lower)
Seriously, is it so hard to imagine modders cooperating when it comes to chat processing? I would like to have my chat
  • timestamped
  • colored to highlight messages from friends, server admins, mods, etc.
  • filtered (to discard "Missed!" messages from mobs, let alone annoying players)
  • throw sound notification on me when I get PM, @notice etc.
Right now, I have following options, both of them I consider equally bad
  • Write all the functionality myself, not being able to reuse already existing mods
  • Bend every mod to work with my setup, making breaking changes in their code, which results in the code not being usable in any other setup (plus having to care about explicitly specifying order of the filters in the code, thus having to fix it manually with any change in the setup)
I'm trying to propose slightly less bad option, common compatibilty layer, allowing modders to produce cooperating mods with minimum effort. As I got no promise to even consider introducing such API from minetest core devs, the changes might not be available any time soon, perhaps never.

Now, making independent mods work together can be only done by making the mods dependant on each other, calling the "childern" mod handler from "parent". That sort of defeats the idea of independent mods, increases functionality-unrelated code in all of the mods and is extremly fragile design, as every parent mod must know the names of all childern handlers.

The root mod MUST've do something like next_handler = modA.handler or modB.handler or modC.handler or modD.handler or modE.handler or modF.handler... This scheme is not sustainable, because every change in any mod (let alone writing new mods) will be breaking change for all parent mods.

Hence the "unnecessary" layer of the chatlib API. In perfect spherical world in vacuum, minetest's API would be designed with considering potential needs of it's users. Well, it's not and I am going to do that myself, because noone else seems to care. But since I'm going to do it, I'd like to do it right, so at least part of already existing mods can migrate, giving me their features for free.

Side effect could be intercepting client-generated messages, which now fully bypass minetest.register_on_receiving_chat_message.

---------------------------

[1]: Minetest's API is checking for truthy value, not literal true. Passing modified message as retval results in being considered truthy - even "" is considered truthy by lua - thus being discarded.

Code: Select all

$ lua
Lua 5.2.4  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> if "" then print("T") else print("F") end
T

User avatar
Lejo
Member
Posts: 718
Joined: Mon Oct 19, 2015 16:32
GitHub: Lejo1
In-game: Lejo

Re: Chat CSMs - call to Compatibilty

by Lejo » Post

Ravise wrote:
Tue May 26, 2020 10:04
Currently, the mod can
  • print the modified message and return true, thus cutting of all other callbacks, or
  • return falsy value and let other mods work on the original, unmodified message, or
  • resort to double-printing
  • hardcode it's successors (see lower)
Seriously, is it so hard to imagine modders cooperating when it comes to chat processing? I would like to have my chat
  • timestamped
  • colored to highlight messages from friends, server admins, mods, etc.
  • filtered (to discard "Missed!" messages from mobs, let alone annoying players)
  • throw sound notification on me when I get PM, @notice etc.
Only the timestamp and the highlight message must cooperate as they both would do minetest.display_chat_message and return true.
The others can just remove the Missed or just make a sound.

Timestamp and colored just need to be done in one mod.
Your filter system would work too of course but I think it would be better to have this in core so that everybody uses it.

Yes it's pretty bad right now but a core solution is allways better...
What about creating an issue on github?

My Idea would just be that the message is passed thought all registers by just returning (if one returns true not) and after the last the returned message is printed to the chat.

PS: What about doing the same serverside?

Ravise
New member
Posts: 8
Joined: Mon May 25, 2015 18:40

Re: Chat CSMs - call to Compatibilty

by Ravise » Post

Lejo wrote:
Tue May 26, 2020 10:17
Only the timestamp and the highlight message must cooperate as they both would do minetest.display_chat_message and return true.
The others can just remove the Missed or just make a sound.
Coloring and ignore depend on detecting message author. Bell and ignore depend on detecting message type. isn't it more sane to write the code once?
Lejo wrote:
Tue May 26, 2020 10:17
Timestamp and colored just need to be done in one mod.
That sort of defeats the idea of independent mod. Also it requires hardcoding the setup, thus making reusing code hard.
Lejo wrote:
Tue May 26, 2020 10:17
Your filter system would work too of course but I think it would be better to have this in core so that everybody uses it. Yes it's pretty bad right now but a core solution is allways better...
Is it in the core? No. Can we expect such change soon? No.
Lejo wrote:
Tue May 26, 2020 10:17
What about creating an issue on github?
Have you seen the irc log? If you want a filtering api make one in lua?, the usecase you have is only a tiny one, can't change every api to hopefully have every usecase.
Lejo wrote:
Tue May 26, 2020 10:17
My Idea would just be that the message is passed thought all registers by just returning (if one returns true not) and after the last the returned message is printed to the chat.
Since the mods would still rely on format of message string, some metadata would have to be introduced anyway. Yes, it would be best if this was done in core, but my experience with interacting with core developers is not pleasant one.
Lejo wrote:
Tue May 26, 2020 10:17
PS: What about doing the same serverside?
Seriously, take a look at the log. As I'm a player, not server admin, I'd like things to be solved on client-side as much as possible, to be independent on benevolence of server admins not/installing server mods for my convenience

User avatar
Lejo
Member
Posts: 718
Joined: Mon Oct 19, 2015 16:32
GitHub: Lejo1
In-game: Lejo

Re: Chat CSMs - call to Compatibilty

by Lejo » Post

Ravise wrote:
Tue May 26, 2020 10:37
Coloring and ignore depend on detecting message author. Bell and ignore depend on detecting message type. isn't it more sane to write the code once?
Sure it would be!
That sort of defeats the idea of independent mod. Also it requires hardcoding the setup, thus making reusing code hard.
Yep, was an idea how to do it without core-support
Is it in the core? No. Can we expect such change soon? No.
Not yet but we should try and an first step for a new feature is an github issue.
Have you seen the irc log? If you want a filtering api make one in lua?, the usecase you have is only a tiny one, can't change every api to hopefully have every usecase.
Yep, I do.
Just, one message in a chat doesn't has to mean so much
Since the mods would still rely on format of message string, some metadata would have to be introduced anyway. Yes, it would be best if this was done in core, but my experience with interacting with core developers is not pleasant one.
Maybe, just sending the data at the beginning + the changed data should also work.
Seriously, take a look at the log. As I'm a player, not server admin, I'd like things to be solved on client-side as much as possible, to be independent on benevolence of server admins not/installing server mods for my convenience
If you have an good idea why not also use it serverside?

User avatar
rubenwardy
Moderator
Posts: 6978
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: Chat CSMs - call to Compatibilty

by rubenwardy » Post

Ravise wrote:
Tue May 26, 2020 10:37
Have you seen the irc log? If you want a filtering api make one in lua?, the usecase you have is only a tiny one, can't change every api to hopefully have every usecase.
That message you quoted was by nephele, who is not a core developer - just a member expressing their opinion
Ravise wrote:
Tue May 26, 2020 10:37
Yes, it would be best if this was done in core, but my experience with interacting with core developers is not pleasant one.
I'm not sure where this has come from in this instance. I responded by saying how the server-side API is designed for a similar usecase, I didn't mean that you should use the server-side but rather the API could be copied in client-side API. Krock and sfan5 discussed a pipeline-based approach, and how to expose the message meta data that is already available in the network protocol

I'll restate what I said anyway:

Minetest's callback model tends to not be very well thought out, sorry. It regularly combines vetoable and non-vetoable callbacks in a way that makes inter-mod support difficult, and mostly completely ignores ability for modifications like you've found.

There's two ways that this problem is solved in the supported server-side modding API:
  1. Pipelining: register_on_hpchange allows modifier callbacks to return a new hp which will be passed into new callbacks, in a pipeline-like form.
  2. Overriding: minetest.format_chat_message is overridden by mods, where they control how to call other overrides.

    Code: Select all

    local old = minetest.format_chat_message
    minetest.format_chat_message = function(name, message, ...)
    	local result = old(name, message, ...)
    	return "something " .. result
    end
    
There's one other problem with this: there would be no way to control the order of the timestamp vs the colour, so you'd want some way of ordering.

I'm wondering if there's a better way of designing callback APIs so that we don't have oversights like this in the future. I'd be interested in how other frameworks do this
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

Ravise
New member
Posts: 8
Joined: Mon May 25, 2015 18:40

Re: Chat CSMs - call to Compatibilty

by Ravise » Post

rubenwardy wrote:
Tue May 26, 2020 13:22
That message you quoted was by nephele, who is not a core developer - just a member expressing their opinion
Ah, my bad. Sorry. To my defense, I expected reply from someone with the authority to speak for the core.

I don't think there are more options than pipelining and overriding/closures if the mods are to stay independent (and I'd be in favour of pipelining, because it looks similar to current api).

As per filter ordering, we can abuse optional_depend list in mod.conf and call the newest defined callback first - that give modders way to say "this filter must be run before filters A, B and C are done". This is far from ideal, I agree, but it's also far better than current state. With optional priority argument when registering callback, mods could inform core, if they wish to be put in the callback queue to the front/back/middle. Furthermore, majority of the filters will have non-crossing functionality: the order of bell->color will do as good as color->bell, so the edge cases should be minimal.

To give example of other in-game lua scripting, take a look on how WoW is handling chat messages: you register your frame (basically your mod) to subscribe so some event (look for CHAT_MSG_, can't link directly), and you react to it. As far as chat is concerned, you subscribe a filter, that can return altered arguments to be passed on.

To give a quick overview how the API is called, see addon https://legacy-wow.com/wotlk-addons/linked-chat-text/ - the source is small enough to understand in one go :)

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests