Conversation
Reviewer's GuideIntroduces an enabled-by-default Death Rate Profile Switcher that monitors destruction events over a rolling hour, moves from a configured home profile to a safe profile when deaths exceed the threshold, and reverts after a clean hour or a second spike. Sequence diagram for death-rate profile switchingsequenceDiagram
participant Behavior as DeathRateProfileSwitcher
participant Repair as RepairAPI
participant Config as ConfigAPI
loop Each behavior tick or stop
Behavior->>Repair: isDestroyed()
Behavior->>Config: getCurrentProfile()
Behavior->>Behavior: trackDeathEdge()
Behavior->>Behavior: pruneOldDeaths()
alt Home profile and threshold reached
Behavior->>Config: setConfigProfile(TO_PROFILE)
else Safe profile and second spike
Behavior->>Config: setConfigProfile(FROM_PROFILE)
else Safe profile and 60 minutes clean
Behavior->>Config: setConfigProfile(FROM_PROFILE)
end
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 4 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java" line_range="91" />
<code_context>
+ }
+
+ private void process() {
+ if (config.FROM_PROFILE.isEmpty() || config.TO_PROFILE.isEmpty()) return;
+
+ trackDeathEdge();
+ pruneOldDeaths();
</code_context>
<issue_to_address>
**issue (bug_risk):** `process()` calls `isEmpty()` on `FROM_PROFILE` and `TO_PROFILE` without checking for null, so a configuration value represented as null by the dropdown causes every behavior tick to throw `NullPointerException`. `getText()` explicitly accepts null, so null is a supported option value in this configuration path.
**Triggers:** When either profile dropdown has a null value rather than an empty string.
**Suggested fix:** Use a null-safe check such as `String.isNullOrEmpty(...)` or normalize null values in `setConfig()`.
```suggestion
if (config.FROM_PROFILE == null || config.FROM_PROFILE.isEmpty() || config.TO_PROFILE == null || config.TO_PROFILE.isEmpty()) return;
```
</issue_to_address>
### Comment 2
<location path="src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java" line_range="98" />
<code_context>
+
+ String current = configAPI.getCurrentProfile();
+
+ if (revertAt == null) {
+ if (config.FROM_PROFILE.equals(current) && recentDeaths.size() >= config.DEATHS_PER_HOUR_THRESHOLD) {
+ log("Deaths/hour reached " + recentDeaths.size() + " (threshold " + config.DEATHS_PER_HOUR_THRESHOLD +
+ ") on '" + config.FROM_PROFILE + "'. Switching to '" + config.TO_PROFILE + "' for 60 minutes.");
+ configAPI.setConfigProfile(config.TO_PROFILE);
</code_context>
<issue_to_address>
**issue (bug_risk):** The safe-profile state is held only in the in-memory `revertAt` field. If the plugin or bot is restarted while `TO_PROFILE` is active, `revertAt` is reset to null; because the current profile is not `FROM_PROFILE`, the home-profile branch is never entered and the switcher never automatically reverts to `FROM_PROFILE`.
**Triggers:** When the bot/plugin restarts or the feature is re-created during the 60-minute safe-profile period.
**Suggested fix:** Persist the active switch state/deadline, or initialize safe-mode state when the current profile is `TO_PROFILE` and manage its deadline explicitly.
```suggestion
if (revertAt == null && config.TO_PROFILE.equals(current)) {
revertAt = Instant.now().plus(WINDOW);
}
if (revertAt == null) {
```
</issue_to_address>
### Comment 3
<location path="src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java" line_range="107-116" />
<code_context>
+ recentDeaths.clear();
+ }
+ } else {
+ if (recentDeaths.size() >= config.DEATHS_PER_HOUR_THRESHOLD) {
+ log("Deaths/hour reached " + recentDeaths.size() + " again while on '" + config.TO_PROFILE +
+ "'. Being hunted there too - reverting to '" + config.FROM_PROFILE + "' immediately.");
+ configAPI.setConfigProfile(config.FROM_PROFILE);
+ revertAt = null;
+ recentDeaths.clear();
</code_context>
<issue_to_address>
**issue (bug_risk):** Once `revertAt` is set, the safe-profile branch treats deaths as safe-profile deaths and reverts to `FROM_PROFILE` without checking that the current profile is still `TO_PROFILE`. If another component or the user changes to a third profile during the safe interval, deaths on that unrelated profile still trigger the configured home-profile switch.
**Triggers:** When the active profile is changed away from `TO_PROFILE` before the safe interval expires.
**Suggested fix:** Require `config.TO_PROFILE.equals(current)` before applying safe-profile death handling or the timed revert, and reset the state when an unrelated profile is active.
</issue_to_address>
### Comment 4
<location path="src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java" line_range="123-126" />
<code_context>
+ }
+ }
+
+ private void trackDeathEdge() {
+ boolean destroyed = repair.isDestroyed();
+ if (destroyed && !wasDestroyed) {
+ recentDeaths.addLast(Instant.now());
+ }
+ wasDestroyed = destroyed;
</code_context>
<issue_to_address>
**issue (bug_risk):** `wasDestroyed` starts false, so the first tick after the feature becomes active records a death whenever `repair.isDestroyed()` is already true. A ship that was destroyed before the feature was enabled or before the plugin finished loading is therefore counted as a new death and can contribute to an unwarranted profile switch.
**Triggers:** When the feature first processes while the ship is already in the destroyed state.
**Suggested fix:** Initialize `wasDestroyed` from `repair.isDestroyed()` before beginning edge detection, or explicitly ignore the first observation.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 4 findings to address first, and if the profile switch is wrong, the bot can run with the alternate configuration for up to an hour and may make gameplay decisions or incur deaths before reverting. Reverting restores the selected profile, but it cannot undo consequences that occurred while the wrong profile was active.
Blocking findings: src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java:91, src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java:98, src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java:116, src/main/java/dev/shared/haluzer/death_rate_switcher/DeathRateProfileSwitcher.java:126
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
dm94
left a comment
There was a problem hiding this comment.
Fix the errors – and this feature already exists in another publicly available plugin
|
Should be fixed now. |



Adds a new feature under dev.shared.haluzer.death_rate_switcher.
Watches deaths/hour on a configured "home" profile. If deaths spike past a configurable threshold in a rolling 60-minute window (PvP hunting), it switches to a configured "safe" profile for up to 60 minutes. If the death rate spikes again on the safe profile, it reverts immediately; otherwise it reverts automatically after a clean 60-minute window.
Compiled and tested against darkbot-impl 0.9.8 / DarkBot dc48506543, matching this repo's pinned versions.
This is a split-out from #200 per dm94's request for one feature per PR. The first feature (Revive Loop Watchdog) is in #201.
Summary by Sourcery
Add automatic profile switching to respond to elevated death rates and reduce exposure to PvP hunting.
New Features:
Chores: