SystemK v2.03: Bunker Buster #18

Open
Joe wants to merge 17 commits from feature/accesory-shot into main
Owner

Bunker Buster

The Bunker Buster is an accessory-switch weapon that turns the player it hits into a bomb. The shooter fires a White Dubuque IR tag. The device it hits broadcasts a BLE splash to everyone nearby, then takes its own direct damage. It is a new accessory mode, joining the BLE Bomb. Both weapons draw from the same special-weapon charges and share one cooldown.

bunker_buster

Gameplay behavior

A hit sets off the splash before it applies the direct damage, so the target splashes even when the hit tags it out.

  1. Fire. Pressing the accessory switch uses one charge and fires the White tag over IR. It is not a regular shot: it doesn't count toward Shots Fired, isn't blocked by the shot holdoff, and doesn't start one. It still plays the normal shot sound and lights.
  2. Refuse. If no charges are left, the cooldown is still running, or the platform can't prepare the tag, the device plays AUDIO_PLAY_BONK and nothing is fired.
  3. Hit. A device whose Accessory Mode is Bunker Buster and that receives a White Dubuque tag:
    1. Starts a new splash dealing Splash_Damage, shown in white.
    2. Plays the bomb sound and the white tag-received animation.
    3. Counts a tag received and loses Bunker_Buster_Direct_Damage health.
  4. Splash. Other devices receive the splash over BLE and take Splash_Damage, filtered by team and RSSI (see Protocol). Receiving a splash never starts another splash, so there are no chain reactions.

A Dubuque Protocol tag can't say who fired it, so White hits every team. To keep the shooter from busting itself, it ignores White tags for OWN_TAG_REFLECTION_WINDOW_in_ms (1000 ms) after firing one.

Compared with the BLE Bomb: the Bomb splashes directly from the shooter's position, in yellow, with no IR. The Bunker Buster needs line-of-sight, then splashes from the target's position.

Settings

Setting Default BLE key Meaning
Accessory_Mode 1 (BLE Bomb) 11 0 Off, 1 BLE Bomb, 2 Bunker Buster
Bunker_Buster_Direct_Damage 100 12 Damage the hit device takes, after it splashes
Splash_Damage 100 13 Damage dealt by the splash
Splash_Min_RSSI -75 dBm 14 Weakest signal a splash affects, and is relayed at
Splash_Target_Teams 0 15 0 all, 1 originating team only, 2 all except originating team
T_Special_Weapon_Cooldown_in_ms 1000 16 Minimum time between accessory weapon uses
Splash_Hops 0 17 Times the splash may be relayed (0-5)
N_Special_Weapons_On_Reentry 1 6 Charges granted on each reentry

The splash settings that apply are the ones on the hit device, since it originates the splash. Only devices set to Bunker Buster react to a White tag.

Protocol

The IR side is an ordinary Dubuque tag (team White, color White, damage 0). The splash is a broadcast BLE TAG packet whose splash fields sit in bytes 26-30, which were unused before.

Byte Field Meaning 0xFF (legacy)
26 splash_target_teams 0 all, 1 originating team only, 2 all except originating team No team filter
27 splash_min_rssi Receivers ignore the TAG below this RSSI (dBm) -75 dBm
28 hops_remaining Times the TAG may still be relayed Not relayed
29-30 splash_ID uint16 LE; identifies the TAG across all its relays 0xFFFF: none
  • Deduplication. A device acts on a TAG at most once, however many relays it hears. Splashes are deduplicated by splash ID (BLE_Splash_Tracker); legacy TAGs by sender and event number.
  • Relaying. A TAG with hops remaining is relayed before the address check, unchanged except for hops_remaining - 1. Devices in every Playing substate relay it, whether or not it affected them. A relay heard while a splash is on the air waits in a one-slot queue.
  • Team filtering stays relative to the originating device, even after relays.
  • Hop limit. Received hop counts are clamped to SPLASH_MAX_HOPS (5) to prevent relay storms.

Relaying applies to every TAG, so a Medic's targeted heal can also travel beyond its sender's range.

SystemK implementation

The tag is prepared once at game start, fired from the Interacting substate, and recognized by the address of the prepared tag when KEVENT_TAG_SENT comes back.

Where What it does
Game/Accessory.h AccessoryMode_T (Off / BLE Bomb / Bunker Buster), SplashTargetTeams_T, SPLASH_MAX_HOPS
Game/Game.h, Game/Game.c GAME_Build_Bunker_Buster_Tag_Packet(), GAME_Prepared_Bunker_Buster_Tag, and a weak Prepare_Special_Tag() that returns NULL
IR/IR_HW_Interface.h New optional HAL call Prepare_Special_Tag(): prepares a second tag in separate storage so the regular shot stays valid
State_Starting_Game__Counting_Down.c Prepares the White tag when Accessory Mode is Bunker Buster; logs a warning and leaves it NULL if the platform can't
State_Playing__Interacting.c HandleAccessoryWeapon() fires it; HandleBunkerBusterHit() splashes then applies damage; KEVENT_TAG_SENT skips the holdoff and shot count for it
State_Playing.c, BLE/BLE_Packets.*, BLE/BLE_Splash_Tracker.* Splash creation, the TAG bytes 26-30, deduplication, and relaying
Settings/Settings.csv, State_Configuring.c New settings and BLE PARAMETERS keys 11-17
Tests/Tests/test_accessory_splash.c Host unit tests for the shooter, hit, splash, and relay paths

Porting note: a host platform gets the Bunker Buster only by implementing Prepare_Special_Tag(). Without it the weak default returns NULL and the accessory switch bonks.

Hardware coverage comes from six HIL tests in KTag-HIL-Tester/components/Tests/Test_Bunker_Buster.c.

## Bunker Buster The Bunker Buster is an accessory-switch weapon that turns the player it hits into a bomb. The shooter fires a White Dubuque IR tag. The device it hits broadcasts a BLE splash to everyone nearby, then takes its own direct damage. It is a new accessory mode, joining the BLE Bomb. Both weapons draw from the same special-weapon charges and share one cooldown. ![bunker_buster](/attachments/d456c66e-e91a-4bc8-9fbb-d24733560b73) ## Related PRs: - https://git.ktag.clubk.club/Software/2024A-SW/pulls/21 - https://git.ktag.clubk.club/Software/2020TPC-SW/pulls/11 - https://git.ktag.clubk.club/Software/KTag-HIL-Tester/pulls/3 ## Gameplay behavior A hit sets off the splash before it applies the direct damage, so the target splashes even when the hit tags it out. 1. **Fire.** Pressing the accessory switch uses one charge and fires the White tag over IR. It is not a regular shot: it doesn't count toward Shots Fired, isn't blocked by the shot holdoff, and doesn't start one. It still plays the normal shot sound and lights. 2. **Refuse.** If no charges are left, the cooldown is still running, or the platform can't prepare the tag, the device plays `AUDIO_PLAY_BONK` and nothing is fired. 3. **Hit.** A device whose Accessory Mode is Bunker Buster and that receives a White Dubuque tag: 1. Starts a new splash dealing `Splash_Damage`, shown in white. 2. Plays the bomb sound and the white tag-received animation. 3. Counts a tag received and loses `Bunker_Buster_Direct_Damage` health. 4. **Splash.** Other devices receive the splash over BLE and take `Splash_Damage`, filtered by team and RSSI (see Protocol). Receiving a splash never starts another splash, so there are no chain reactions. A Dubuque Protocol tag can't say who fired it, so White hits every team. To keep the shooter from busting itself, it ignores White tags for `OWN_TAG_REFLECTION_WINDOW_in_ms` (1000 ms) after firing one. **Compared with the BLE Bomb:** the Bomb splashes directly from the shooter's position, in yellow, with no IR. The Bunker Buster needs line-of-sight, then splashes from the target's position. ### Settings | Setting | Default | BLE key | Meaning | | --- | --- | --- | --- | | `Accessory_Mode` | 1 (BLE Bomb) | 11 | 0 Off, 1 BLE Bomb, 2 Bunker Buster | | `Bunker_Buster_Direct_Damage` | 100 | 12 | Damage the hit device takes, after it splashes | | `Splash_Damage` | 100 | 13 | Damage dealt by the splash | | `Splash_Min_RSSI` | -75 dBm | 14 | Weakest signal a splash affects, and is relayed at | | `Splash_Target_Teams` | 0 | 15 | 0 all, 1 originating team only, 2 all except originating team | | `T_Special_Weapon_Cooldown_in_ms` | 1000 | 16 | Minimum time between accessory weapon uses | | `Splash_Hops` | 0 | 17 | Times the splash may be relayed (0-5) | | `N_Special_Weapons_On_Reentry` | 1 | 6 | Charges granted on each reentry | The splash settings that apply are the ones on the **hit** device, since it originates the splash. Only devices set to Bunker Buster react to a White tag. ## Protocol The IR side is an ordinary Dubuque tag (team White, color White, damage 0). The splash is a broadcast BLE TAG packet whose splash fields sit in bytes 26-30, which were unused before. | Byte | Field | Meaning | `0xFF` (legacy) | | --- | --- | --- | --- | | 26 | `splash_target_teams` | 0 all, 1 originating team only, 2 all except originating team | No team filter | | 27 | `splash_min_rssi` | Receivers ignore the TAG below this RSSI (dBm) | -75 dBm | | 28 | `hops_remaining` | Times the TAG may still be relayed | Not relayed | | 29-30 | `splash_ID` | uint16 LE; identifies the TAG across all its relays | `0xFFFF`: none | - **Deduplication.** A device acts on a TAG at most once, however many relays it hears. Splashes are deduplicated by splash ID (`BLE_Splash_Tracker`); legacy TAGs by sender and event number. - **Relaying.** A TAG with hops remaining is relayed before the address check, unchanged except for `hops_remaining - 1`. Devices in every Playing substate relay it, whether or not it affected them. A relay heard while a splash is on the air waits in a one-slot queue. - **Team filtering** stays relative to the originating device, even after relays. - **Hop limit.** Received hop counts are clamped to `SPLASH_MAX_HOPS` (5) to prevent relay storms. Relaying applies to every TAG, so a Medic's targeted heal can also travel beyond its sender's range. ## SystemK implementation The tag is prepared once at game start, fired from the Interacting substate, and recognized by the address of the prepared tag when `KEVENT_TAG_SENT` comes back. | Where | What it does | | --- | --- | | `Game/Accessory.h` | `AccessoryMode_T` (Off / BLE Bomb / Bunker Buster), `SplashTargetTeams_T`, `SPLASH_MAX_HOPS` | | `Game/Game.h`, `Game/Game.c` | `GAME_Build_Bunker_Buster_Tag_Packet()`, `GAME_Prepared_Bunker_Buster_Tag`, and a weak `Prepare_Special_Tag()` that returns `NULL` | | `IR/IR_HW_Interface.h` | New optional HAL call `Prepare_Special_Tag()`: prepares a second tag in separate storage so the regular shot stays valid | | `State_Starting_Game__Counting_Down.c` | Prepares the White tag when Accessory Mode is Bunker Buster; logs a warning and leaves it `NULL` if the platform can't | | `State_Playing__Interacting.c` | `HandleAccessoryWeapon()` fires it; `HandleBunkerBusterHit()` splashes then applies damage; `KEVENT_TAG_SENT` skips the holdoff and shot count for it | | `State_Playing.c`, `BLE/BLE_Packets.*`, `BLE/BLE_Splash_Tracker.*` | Splash creation, the TAG bytes 26-30, deduplication, and relaying | | `Settings/Settings.csv`, `State_Configuring.c` | New settings and BLE PARAMETERS keys 11-17 | | `Tests/Tests/test_accessory_splash.c` | Host unit tests for the shooter, hit, splash, and relay paths | **Porting note:** a host platform gets the Bunker Buster only by implementing `Prepare_Special_Tag()`. Without it the weak default returns `NULL` and the accessory switch bonks. Hardware coverage comes from six HIL tests in `KTag-HIL-Tester/components/Tests/Test_Bunker_Buster.c`.
Joe added 16 commits 2026-10-19 02:43:49 +00:00
Fixes for the Konfigurator use case.
All checks were successful
Tests / build-and-test (push) Successful in 24s
92ce95c6cf
Changes to support testing.
All checks were successful
Tests / build-and-test (push) Successful in 14s
eb976ce618
More fixes after HIL testing.
All checks were successful
Tests / build-and-test (push) Successful in 15s
Tests / build-and-test (pull_request) Successful in 17s
aab345b4fa
Refactored to use cooperative timers.
All checks were successful
Tests / build-and-test (push) Successful in 18s
Tests / build-and-test (pull_request) Successful in 14s
a43ed4af68
Restored deleted timer test helpers.
All checks were successful
Tests / build-and-test (push) Successful in 15s
Tests / build-and-test (pull_request) Successful in 16s
d652f9b02a
Updated the README.
All checks were successful
Tests / build-and-test (push) Successful in 7m10s
Tests / build-and-test (pull_request) Successful in 5m34s
6a2a1760cf
Fixes to the NEC Protocol.
All checks were successful
Tests / build-and-test (push) Successful in 1m36s
Tests / build-and-test (pull_request) Successful in 22s
30242c8eed
Added the "NEC Command" weapon type.
All checks were successful
Tests / build-and-test (push) Successful in 6m1s
Tests / build-and-test (pull_request) Successful in 58s
1f67197935
Better concurrency for BLE packets.
All checks were successful
Tests / build-and-test (push) Successful in 18s
Tests / build-and-test (pull_request) Successful in 14s
5f72e025b4
Added an early filter for BLE.
All checks were successful
Tests / build-and-test (push) Successful in 16s
Tests / build-and-test (pull_request) Successful in 15s
b96d1aefc1
Bunker Buster
All checks were successful
Tests / build-and-test (push) Successful in 24s
b53930a7ea
Changes to support faster configuring.
All checks were successful
Tests / build-and-test (push) Successful in 53s
969127054f
Merged latest SystemK release.
Some checks failed
Tests / build-and-test (push) Failing after 7s
6c7920819b
Bumped SystemK version.
All checks were successful
Tests / build-and-test (push) Successful in 24s
Tests / build-and-test (pull_request) Successful in 18s
dee78b9dba
Bunker Busters are yellow.
All checks were successful
Tests / build-and-test (push) Successful in 14s
Tests / build-and-test (pull_request) Successful in 13s
4374f69152
Joe self-assigned this 2026-10-21 21:49:14 +00:00
All checks were successful
Tests / build-and-test (push) Successful in 14s
Tests / build-and-test (pull_request) Successful in 13s
Required
Details
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feature/accesory-shot:feature/accesory-shot
git switch feature/accesory-shot
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Software/SystemK!18
No description provided.