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

[FR] Add a way to grant local LoS

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

Description

Bill of materials to be done before starting this ticket:
* #1374
* check if there are recent advances in #1366

----

Some user stories:
* have a "scan" ability that just grants LoS over an area for some time.
* have a campaign mission (or king of the hill multiplayer mode, etc) where the area around an objective is permanently revealed.
* have a "parasite" ability that makes you see what an enemy unit sees.

Currently this can be kinda achieved by spawning a fake unit with needed LoS stats. However:
* this is a unit so is returned by `Spring.GetAllUnits`, triggers `wupget:UnitCreated` etc., which requires extra handling. Doable, but every game will have its own handling and there's potentially a lot of places you need to touch.
* it is difficult to do this in a high-quality polished way, i.e. make the unit approach 100% fake, because many ways this can fail are quite difficult to even discover, even if it's possible to work around them. For example, kamikazes (done via engine kamikaze-related unit defs) still trigger on fake units, so roaches blow up if you try to parasite them, or you can use scan to detonate mines. This is just one example found by a happy (but explosive) accident.
* it may not even be possible to reach 100% fake. For example I don't know of a reliable way to make the unit not count against the unit limit.

The request is to add some clean way to do this.

The obvious way would be `Spring.GrantSensor`. A potential difficulty is that there are a lot of things you might want to configure:
* sensor type. For example you might want to optionally add radar or sonar to a scan, to detect cloakers / subs. Maybe the scan/parasite ability only gives radar and no LoS to be more interesting.
* shape. Having something other than a circle would be nice since circles are kinda bad at making up other shapes. Note that this isn't necessarily a static property (e.g. a scan can start small and expand).
* location. Note that this isn't necessarily a static property, e.g. the parasite's sight moves alongside the host.
* duration. A scan lasts N frames, a parasite lasts until unit X dies, a mission objective is permanent.

This is a lot of configurability, and some of that changes over time so you need a handle to the sensor instance! Using the unit interface is almost perfect for this: there are already calls to change a unit's location, to change its duration (i.e. to remove it when the time comes), to change sensor radius and type, and you can still try to build custom shapes from multiple circles. So, perhaps a different approach would be to have some way for the engine to treat a unit as fake for all purposes except LoS, but you'd have the unitID as a handle and use existing unit API to control it. In a way the approach is somewhat similar to #644.

Contributor guide

Open the contributing guide

Research direction

Start by completing the bill of materials in #1374 and checking recent advances in #1366, then review the existing unit interface and the approach discussed in #644. The work is done when the engine has an agreed clean mechanism for local LoS without requiring fake units, including the needed sensor configuration and handle behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
game-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.