beyond-all-reason / beyond-all-reason/RecoilEngine

It's not obvious when `wupget:FooChanged` are called

Open
#2,265 0 comments 0 reactions 0 assignees View on GitHub
area: documentation area: Lua API
Dominant language
C++
Stars
679
Forks
290
Avg merge
3d 2h
Merged PRs (30d)
40

Description

There's callins like `wupget:TeamDied` or `wupget:PlayerAdded`. It's fairly obvious when they get called. But then there's `wupget:PlayerChanged` and `wupget:TeamChanged` and it's very non-obvious what "changed" means and what exactly needs to happen for them to get called. As far as I can tell:

`wupget:TeamChanged` is called:
* when a new non-spectator player joins the game midgame and is immediately in a team. The playerID is not given.
* when that team's allyteam changes ceasefire status via `/ally x`. The new ceasefire status and the target allyteamID are not given (and neither is the self allyteamID, you have to derive it from teamID).
* **NOT** that team's allyteam changes ceasefire status via gadget `Spring.SetAlly(x, y)`.
* **NOT** when a team's roster changes (via `Spring.AssignPlayerToTeam`, `/team`, or `/spectator`).
* **NOT** when the team dies, for that there is a dedicated `wupget:TeamDied`.

`wupget:PlayerChanged` is called:
* when a skirmish AI controlled by a player changes state (incl. being created at runtime). I'm not sure whether this only applies to AI hosted by the local player or not. The specific AI ID is not given (even if the player is hosting multiple) and neither is what exactly happened to the AI.
* when a player joins or leaves a team (via `Spring.AssignPlayerToTeam`, `/team`, `/spectator`, or becoming a spec via team death). The previous team is not given (and neither is the new one but at least you can get it via callout).
* when the **LOCAL** player changes spectator visibility via `/specteam` or `/specfullview`.
* **NOT** when any other player changes spectator visibility via `/specteam` or `/specfullview`.
* **NOT** when a player joins or leaves (this is fine, there's `wupget:PlayerAdded` and `wupget:PlayerRemoved` for that).
* **NOT** in synced (the callin is unsynced only).

`wupget:AiChanged` or `wupget:AllyteamChanged` do not exist.

----

The first task would be to double-check the above listing. I grepped the codebase but it's somewhat difficult to test it properly without more players.

The second task would be to formally document the callins.

The third task would be to propose API improvements because right now it's barely possible to tell what changed exactly (so from a practical PoV, as a wupget dev you need to invalidate and recalculate everything such as playerlists etc) and many "obvious" changes don't actually produce a change event (so AFAICT e.g. a synced gadget can't know that a player did `/spectator` and has to poll). This will mostly involve adding specific events aimed at the appropriate entity (allyteam, AI), with relevant information in the signature, for example `wupget:AllyteamCeasefireChanged(firstAllyteamID, secondAllyTeamID, bool)`. The generic "changed" events can stay for compat.

The fourth task would be to implement the above once agreed upon.

Contributor guide

Open the contributing guide

Research direction

Start by grepping the codebase for the wupget:TeamChanged, wupget:PlayerChanged, wupget:TeamDied, wupget:PlayerAdded, and wupget:PlayerRemoved callins. Reproduce the listed player, team, AI, and spectator scenarios to verify when each callback fires and what arguments are available. Done means the verified behavior is formally documented, with any API improvements separated into an agreed follow-up scope.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
api, documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.