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

Add a system to allow selection of non-owned units

Open
#567 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
679
Forks
290
Avg merge
3d 2h
Merged PRs (30d)
40

Description

A lot of RTS engines allow the selection of enemy and allied units. Usually this just gives the player an expanded tooltip for the unit, but it can also be used for game mechanics. For example, a bounty system for a FFA mode would be cleanest to implement by selecting enemies and clicking buttons on the UI to configure how much bounty you want to pay. Selecting some allied units could also be good for team games.

LuaUI can probably hack enemy selection in at the moment, but it would be fragile and involve essentially reimplementing the concept of selection. Engine support would be more robust. Selecting enemies prettymuch already works when spectating, or with /godmode enabled. The engine would be good for:
- Setting filters on what can be selected.
- Handling state changes that could cause deselection (eg going outside LOS).
- Sending commands to selected units.

Responsibility for legal selection shouldn't be left up to luaUI, as it is user-space rather than game mechanics-space.

Setting a selection filter could look something like this: Spring.SetUnitSelectable(unitID, playerID, canSelect, visionMask, canCommand, canSeeCommands)
- unitID specifies the unit.
- playerID is for specifying players. This could potentially be used by spectators too to let them send some commands. It would often be convinient for this to be teamID or even allyTeamID, but playerID seems like the most natural and powerful.
- canSelect is a boolean that determines whether to allow selection.
- visionMask is a bit mask (0-15) for the vision state required for this playerID to select the unit. The bits here are ANDed with the vision state. When the vision state of a unit changes, the unit should be rechecked and possibly deselected (sort of as if it had died).
- canCommand is whether commands issued by the player are allowed. gadget:AllowCommand can handle the commands from there. This callin already has a playerID argument.
- canSeeCommands would set whether the commands of the selected unit are accessible, both to luaUI and to the default hold-shift system. This would include Spring.DrawUnitCommands.

The vision mask and command visibility toggle should be luaRules-side because there is potential for widgets to hack information out of selecting unseen enemies. Once a unit is allowed to be selected, further filtering can happen in luaUI with widget:SelectionChanged. Eg the engine will allow mixed selections of allied and enemy units, but games can implement selection filtering in luaUI.

Spectators could even use this system of commanding "enemy" units. Eg, some meme tournament could let spectators have a subtle effect on units to support their favorite player. This _could_ be done with luarules messages, but why do that when commands already exist.

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the existing spectator and /godmode selection paths, then the LuaUI/luaRules interfaces named in the issue, including widget:SelectionChanged, gadget:AllowCommand, and Spring.DrawUnitCommands. Done means an engine-supported selection-filter system covers ownership, vision changes, command permissions, and command visibility without relying on a fragile LuaUI reimplementation.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, lua
Domain
game-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.