Skip to content

Conversation

@vjikholg
Copy link

@vjikholg vjikholg commented Dec 26, 2025

Implements #2648 - previous PR was on a branch that for some reason duplicated 4000+ lines of code. This is on a new branch which shouldn't have this issue.

Spring.SendLuaUIMsg now has a single target mode for integer x 0-251, while retaining 'a', 's', '\0' compatibility. Compatible with Zero K widgets calling SendLuaUIMsg as well.

vjikholg and others added 7 commits December 23, 2025 15:56
…ring modes.

The Spring.SendLuaUIMsg API now accepts either a string ("s", "a", or "") retaining compatibility or an integer (0–255) to specify recipients , supporting direct messaging to individual players as well as groups (everyone, spectators, allies).

Updated network packet handling and protocol code to match the new recipient ID scheme.
…252-254). Updated LuaHandle, LuaUnsyncedCtrl to reflect these changes.
…e during merge, unsure why code got reduplicated during merge from main -> fork
@vjikholg vjikholg marked this pull request as ready for review December 26, 2025 23:58
Copy link
Collaborator

@p2004a p2004a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only skimming through, it seems that:

  • Breaks autohost interface compatibility: can't distinguish between old and new format
  • Breaks replay parsing: can't distinguish between old and new format

vjikholg and others added 4 commits December 27, 2025 00:15
… Allows replay parsers/autohost to differentiate between packets. Updated HandleLuaMsg to reflect these changes.
… Allows replay parsers/autohost to differentiate between packets. Updated HandleLuaMsg to reflect these changes. Swapped SendLuaUIMsg to use old logic upon receiving string, new logic upon receiving int.
@p2004a
Copy link
Collaborator

p2004a commented Dec 27, 2025

Stepping back a bit, what is even the use case of #2648 @sprunk? What game wants to do what?

If you squint, you could consider #2040 to be related and in #2355 (comment) we considered pushing that through LuaUIMsg, but with preference to use dedicated network message in the end.

One note from that investigation maybe is also relevant here:

The Callins:RecvLuaMsg also just takes player and message, the mode is not forwarded

so, upon receiving the lua msg callin, game has no way to know whatever that luamsg was send to everobydy, allies, only that player. Is that a problem for whatever use case this functionality is supposed to be used for?

@sprunk
Copy link
Collaborator

sprunk commented Dec 27, 2025

what is even the use case of #2648 @sprunk? What game wants to do what?

I don't quite remember, but I think somebody wanted to implement requests for a specific person, as in you'd have a widget that sends "hey you, and I mean you specifically, please share me a unit" or "hey you, please attack here" to a particular teammate and only the recipient sees it on his GUI. Maybe even send a "hey you specifically, please ceasefire with me" to a particular enemy in FFA.

If you squint, you could consider #2040 to be related and in #2355 (comment) we considered pushing that through LuaUIMsg, but with preference to use dedicated network message in the end.

Good point to consider #2040. My thoughts:

  • Consider adding a way to talk to dediserver/autohost without replay trace #2040 cares about the protocol and specifically asks for something that leaves no replay trace. This is a salient difference to most other existing packet types, so I think it still warrants a new dedicated packet type, and I still think using LUAMSG for a message where the destination isn't Lua would be somewhat inappropriate.
  • Spring.SendLuaUIMsg should have a single-target mode #2648 asks to let an existing Spring.Foo callout have more precise destination specification without actually caring how it is implemented at the protocol level, and as far as other details (e.g. leaving a replay trace) it is happy with the existing design/implementation (i.e. with the behaviour of the LUAMSG packet). The natural way to implement the ticket would have been to just modify the existing packet, if not for backwards compat. In that vein I think it makes sense to do this at the lowest/closest level to what exists, i.e. send the same packet type with a different script arg, since the meaningful parts are the same (still just meant to call a callin at receiver side, still happy with details like leaving a trace). In particular it is still a message for Lua, so I think it's appropriate to use a packet called LUAMSG.
  • but I think I now better understand what you were getting at in NETMSG_SECRET_CHAT: Secret chat messages #2355, that it would be good to have a universal "freestyle data" packet with a bunch of specifiable traits (whether to leave replay trace, which players or network clients to send to, which "internal" destination eg Lua env, etc), and that LUAMSG is already such relatively universal packet to some extent (with script and mode being ways to choose from a bunch of bundles of traits). I don't know, it sounds reasonable actually but somehow not right, though I can't quite put my finger on it. Anyway this sounds out of scope for 2712, and 2040/2355 seems stalled so perhaps we can come back to it when/if somebody picks those up.

game has no way to know whatever that luamsg was send to everobydy, allies, only that player. Is that a problem for whatever use case this functionality is supposed to be used for?

Shouldn't be a problem.

Copy link
Collaborator

@p2004a p2004a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Sprung, good points and I agree, use case seems reasonable.

To the PR itself, the constructions optimizes for backwards compatibility, not clarity, maybe that's still good call at this point, and let's see how things evolve.

* @param uint16_t script
* @param uint_8 destination
* @param vector<uint8_t> rawData
* Packs LuaMsgData into PackPacket object, wrapped in a PacketType (shared ptr?)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: let's drop ?

/*
* @param uint8_t playerNum
* @param uint16_t script
* @param uint_8 destination
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use the same name of variables and params here, but more important: why just list them here without any comment repeating what goes into function arguments?

/*** @function Spring.SendLuaUIMsg
* @param message string
* @param mode string "s"/"specs" | "a"/"allies"
* @param mode string "s"/"specs" | "a"/"allies" | int x \in [0,255];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this valid? I don't think I've seen this format anywhere else. Also x is not too helpful as far as the meaning.

Although I guess the type here is actually just string and "s"/... | int x in [0,255]; is the description. So perhaps it should be like this? idk.

Suggested change
* @param mode string "s"/"specs" | "a"/"allies" | int x \in [0,255];
* @param mode string|integer "s"/"specs" | "a"/"allies" | playerID

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The intention was to write "an integer x belonging to the interval 0-255, but playerID is much better.

Changed locally to match suggestion.

vjikholg and others added 4 commits December 29, 2025 12:56
…types w/ better error handling, explicitly added case where 2nd argument not received. Also updated descriptor wording + formatting.

Readded LuaHandle::LUAMSG_TYPES enum to solve magic numbering for HandleLuaMsg

Renamed HandleLuaMsg variable to better reflect usage, uses LUAMSG_TYPES enum to avoid magic numbering within the LUA_HANDLE_ORDER_UI case.

Renamed CBaseNetProtocol::SendLuaMsg mode argument to recipientID to better reflect usage.
const int msgAllyTeam = teamHandler.AllyTeam(player->team);
sendMsg = teamHandler.Ally(msgAllyTeam, gu->myAllyTeam);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
}

Comment on lines 32 to 36
enum LUAMSG_TYPES {
EVERYONE = (uint8_t) '\0',
ALLIES = (uint8_t) 'a',
SPECTATORS = (uint8_t) 's',
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type casting doesn't work, it's still just int https://godbolt.org/z/8hcxsofPb

Suggested change
enum LUAMSG_TYPES {
EVERYONE = (uint8_t) '\0',
ALLIES = (uint8_t) 'a',
SPECTATORS = (uint8_t) 's',
};
enum class LUAMSG_TYPES: uint8_t {
EVERYONE = '\0',
ALLIES = 'a',
SPECTATORS = 's',
};

Copy link
Author

@vjikholg vjikholg Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I didn't know C++ enums forces a cast to integer unless you specify it above like that.

Comment on lines 3682 to 3683
* @param message string Lua Message to be sent.
* @param mode string/number, mode designator/recipient id. expects none (everyone) | "s"/"specs" | "a"/"allies" | playerID (0-255)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param message string Lua Message to be sent.
* @param mode string/number, mode designator/recipient id. expects none (everyone) | "s"/"specs" | "a"/"allies" | playerID (0-255)
* @param message string Lua Message to be sent.
* @param mode string/number, mode designator/recipient id. expects none (everyone) | "s"/"specs" | "a"/"allies" | playerID (0-255)

vjikholg and others added 3 commits December 31, 2025 13:08
Co-authored-by: Marek Rusinowski <marekrusinowski@gmail.com>
Fixes function descriptor formatting + error typo for LuaUnsyncedCtrl::SendLuaUIMsg

Fixes logic formatting and whitespace in LuaHandle::HandleLuaMsg.

Fixes enum LUAMSG_TYPES implicitly casting `uint8 -> int` by explicitly setting enum-value type in declaration.

Co-authored-by: Marek Rusinowski <marekrusinowski@gmail.com>
Comment on lines 3702 to 3703
} else if (lua_israwnumber(L, 2)) {
recipientID = luaL_optnumber(L, 2, -1); // if no arg, outputs -1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't be no arg since it was just checked in the line above.

Suggested change
} else if (lua_israwnumber(L, 2)) {
recipientID = luaL_optnumber(L, 2, -1); // if no arg, outputs -1
} else if (lua_israwnumber(L, 2)) {
recipientID = lua_tonumber(L, 2);

} else if (lua_israwnumber(L, 2)) {
recipientID = luaL_optnumber(L, 2, -1); // if no arg, outputs -1
if (recipientID < 0 || recipientID > MAX_PLAYERS) {
luaL_error(L, "Invalid player ID sent (expecting between 0-251): ", recipientID);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to use printf formatting, and also use the magic constant rather than hardcode 251:

Suggested change
luaL_error(L, "Invalid player ID sent (expecting between 0-251): ", recipientID);
luaL_error(L, "Invalid player ID sent (%d, expecting between 0-%d): ", recipientID, (int) MAX_PLAYERS);

Ditto for the other error calls.


switch (script) {
case LUA_HANDLE_ORDER_UI: {
case LUA_HANDLE_ORDER_UI_SINGLE: { // expecting 0-251, if invalid int, doesn't register.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0-251 doesn't explain the meaning behind the number so is a bit less helpful than it could be

Suggested change
case LUA_HANDLE_ORDER_UI_SINGLE: { // expecting 0-251, if invalid int, doesn't register.
case LUA_HANDLE_ORDER_UI_SINGLE: { // expects a playerID

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants