beyond-all-reason / beyond-all-reason/RecoilEngine
Make selecting individual units more forgiving
- Dominant language
- C++
- Stars
- 679
- Forks
- 290
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 40
Description
Selecting individual units is needlessly hard in default spring. To reproduce.
1. Press the mouse on point A.
2. Move the mouse to point B.
3. Release the mouse.

Step 2 draws a tiny selection box. Step 3 selects nothing because no unit midpoint is inside the box. Any player who does these steps expected to select the unit, but instead ends up with nothing.
This issue was raised by players just before ZK steam so I wrote this abomination of a widget: https://github.com/ZeroK-RTS/Zero-K/blob/master/LuaUI/Widgets/gui_selection_modkeys.lua
I haven't had a problem with it in years, but it is the sort of thing that should be removed now that the engine dev exists to do so. It's basic behaviour is as follows.
- Remember the unitID underneath every mouse press.
- Detect whether a selection box was drawn.
- If a selection box was drawn, and no unit was selected, and the same unitID is under the mouse when released, select the unit.
It also does something to do with double clicks, or that might just be to better target its hax. Ideally the engine could do the single unit selection fix in a way that everyone likes and never has to think about.
I also made a similar widget to help with issuing point-commands on units (guard and area attack) since dragging those commands causes circles to appear by default. It is similarly bad, but less hax is involved to work around the selection system, and choices around area commands strays more into game design than the selection widget: https://github.com/ZeroK-RTS/Zero-K/blob/master/LuaUI/Widgets/cmd_attack_command_helper.lua
Contributor guide
Research direction
Start by reading LuaUI/Widgets/gui_selection_modkeys.lua, which documents the desired single-unit selection behavior, and compare it with the engine's selection handling. Verify how mouse press, drag-box, release, and double-click cases behave. Done means a tiny drag that begins and ends over the same unit selects it when the box selects nothing, without requiring the workaround widget.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, lua
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100