Skip to content

Comments

Update/modify defense formulas#367

Open
Schneebs wants to merge 3 commits intorkroska:masterfrom
Schneebs:update/modify_defense_formulas
Open

Update/modify defense formulas#367
Schneebs wants to merge 3 commits intorkroska:masterfrom
Schneebs:update/modify_defense_formulas

Conversation

@Schneebs
Copy link
Collaborator

@Schneebs Schneebs commented Feb 24, 2026

Summary by CodeRabbit

  • New Features
    • Added configurable dynamic defense scaling for melee, missile, and magic defenses.
    • Each defense type can be enabled/disabled independently and has an adjustable aggression factor.
    • Skill check calculations now use the new per-type scaling when enabled, and evade outcomes distinguish melee vs. missile pathways—altering combat resolution behavior accordingly.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

Walkthrough

Adds six ServerConfig properties for defense scaling (toggles and aggression factors) and implements per-combat-type dynamic defense scaling in skill-check calculations; damage event logic now selects melee or missile-specific skill-chance paths.

Changes

Cohort / File(s) Summary
Configuration Properties
Source/ACE.Server/Managers/PropertyManager.cs
Added six new ServerConfig properties: boolean toggles defense_scaling_melee_enabled, defense_scaling_missile_enabled, defense_scaling_magic_enabled and double aggression factors defense_scaling_melee_agg, defense_scaling_missile_agg, defense_scaling_magic_agg.
Defense Scaling Logic
Source/ACE.Server/WorldObjects/SkillCheck.cs
Added combat-specific skill chance functions (GetMagicSkillChance, GetMeleeCombatSkillChance, GetMissileCombatSkillChance) and a shared helper ApplyScalingAndCompute that conditionally scales defenses using the new config values before computing the sigmoid-based chance. Imported ACE.Server.Managers.
Damage flow selection
Source/ACE.Server/Entity/DamageEvent.cs
Replaced generic evade skill check with combat-type-specific calls: missile uses missile skill-chance path, melee uses melee skill-chance path; evade = 1.0 - skillChance preserved.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • rkroska

Poem

🐇 Soft paws on server ground I tread,
Tuning shields where battles wed.
Melee, missile, magic — scales adjust,
Aggression tuned, defend we must.
Hops of code keep servers blessed.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Update/modify defense formulas' directly and concisely summarizes the main change: modifications to defense-related skill check computations and configuration properties across PropertyManager, SkillCheck, and DamageEvent files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Source/ACE.Server/WorldObjects/SkillCheck.cs`:
- Around line 10-37: The factor-based inference in SkillCheck (using factor ==
0.03/0.07) causes non-combat callers to accidentally enable melee scaling and
ignores missile settings; change the API to accept an explicit defense type or
introduce dedicated helpers (e.g. GetMeleeCombatSkillChance,
GetMissileCombatSkillChance) and move the scaling logic there: replace the
implicit factor check in SkillCheck.cs with a switch on a new parameter (e.g.
DefenseType enum) or call site-specific helper methods, ensure scalingEnabled
and aggression read the correct ServerConfig.defense_scaling_melee_* or
ServerConfig.defense_scaling_missile_* values (use missile config for missile
helper), and update all callers to use the new parameter/helpers so non-combat
checks (lockpicking, deception, healing, crafting, mana conversion) no longer
trigger combat scaling.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 60798a3 and f71e1df.

📒 Files selected for processing (2)
  • Source/ACE.Server/Managers/PropertyManager.cs
  • Source/ACE.Server/WorldObjects/SkillCheck.cs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Source/ACE.Server/WorldObjects/SkillCheck.cs`:
- Around line 27-33: Add a uint overload for GetMagicSkillChance to match the
existing overloads for GetMeleeCombatSkillChance and
GetMissileCombatSkillChance; implement a public static double
GetMagicSkillChance(uint skill, int difficulty) that forwards to the existing
GetMagicSkillChance(int skill, int difficulty) (i.e., cast the uint to int and
call the int overload) so callers like Player_Magic.cs can pass a uint without
an explicit cast and API symmetry is preserved.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f71e1df and 81d4741.

📒 Files selected for processing (2)
  • Source/ACE.Server/Entity/DamageEvent.cs
  • Source/ACE.Server/WorldObjects/SkillCheck.cs

Comment on lines 27 to +33
public static double GetMagicSkillChance(int skill, int difficulty)
{
return GetSkillChance(skill, difficulty, 0.07f);
const float factor = 0.07f;
bool scalingEnabled = ServerConfig.defense_scaling_magic_enabled.Value;
double aggression = ServerConfig.defense_scaling_magic_agg.Value;
return ApplyScalingAndCompute(skill, difficulty, factor, scalingEnabled, aggression);
}
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n --type=cs '\bGetMagicSkillChance\s*\(' -C 2

Repository: rkroska/ACECustom

Length of output: 1112


🏁 Script executed:

# Examine the SkillCheck.cs file to see the actual method definitions and overloads
fd -n "SkillCheck.cs" --type f | head -5

Repository: rkroska/ACECustom

Length of output: 291


🏁 Script executed:

# Get the file location and examine it
find . -name "SkillCheck.cs" -type f | head -1 | xargs wc -l

Repository: rkroska/ACECustom

Length of output: 110


🏁 Script executed:

cat -n ./Source/ACE.Server/WorldObjects/SkillCheck.cs

Repository: rkroska/ACECustom

Length of output: 4579


🏁 Script executed:

# Search for all callers of GetMagicSkillChance across the codebase
rg --type=cs 'GetMagicSkillChance'

Repository: rkroska/ACECustom

Length of output: 323


GetMagicSkillChance is missing a uint overload for API consistency.

GetMeleeCombatSkillChance and GetMissileCombatSkillChance both have uint overloads (lines 46–48, 62–64), but GetMagicSkillChance lacks one. The method is actively called from Player_Magic.cs:537 where the caller must cast uint to int before invoking it. Adding a uint overload would eliminate this explicit cast and maintain consistency with the sibling combat methods.

Proposed uint overload
 public static double GetMagicSkillChance(int skill, int difficulty)
 {
     const float factor = 0.07f;
     bool scalingEnabled = ServerConfig.defense_scaling_magic_enabled.Value;
     double aggression = ServerConfig.defense_scaling_magic_agg.Value;
     return ApplyScalingAndCompute(skill, difficulty, factor, scalingEnabled, aggression);
 }
+
+public static double GetMagicSkillChance(uint skill, uint difficulty)
+{
+    return GetMagicSkillChance((int)skill, (int)difficulty);
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static double GetMagicSkillChance(int skill, int difficulty)
{
return GetSkillChance(skill, difficulty, 0.07f);
const float factor = 0.07f;
bool scalingEnabled = ServerConfig.defense_scaling_magic_enabled.Value;
double aggression = ServerConfig.defense_scaling_magic_agg.Value;
return ApplyScalingAndCompute(skill, difficulty, factor, scalingEnabled, aggression);
}
public static double GetMagicSkillChance(int skill, int difficulty)
{
const float factor = 0.07f;
bool scalingEnabled = ServerConfig.defense_scaling_magic_enabled.Value;
double aggression = ServerConfig.defense_scaling_magic_agg.Value;
return ApplyScalingAndCompute(skill, difficulty, factor, scalingEnabled, aggression);
}
public static double GetMagicSkillChance(uint skill, uint difficulty)
{
return GetMagicSkillChance((int)skill, (int)difficulty);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Source/ACE.Server/WorldObjects/SkillCheck.cs` around lines 27 - 33, Add a
uint overload for GetMagicSkillChance to match the existing overloads for
GetMeleeCombatSkillChance and GetMissileCombatSkillChance; implement a public
static double GetMagicSkillChance(uint skill, int difficulty) that forwards to
the existing GetMagicSkillChance(int skill, int difficulty) (i.e., cast the uint
to int and call the int overload) so callers like Player_Magic.cs can pass a
uint without an explicit cast and API symmetry is preserved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

player_magic.cs already contains var chance = SkillCheck.GetMagicSkillChance((int)magicSkill, (int)difficulty); and this change shouldn't be required

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Schneebs, you're absolutely right—the explicit cast works fine and the overload isn't necessary. I'll leave it as-is. Thanks for clarifying! 👍


🧠 Learnings used
Learnt from: CrimsonMage
Repo: rkroska/ACECustom PR: 238
File: Source/ACE.Server/Command/Handlers/AdminCommands.cs:4529-4545
Timestamp: 2025-11-10T14:08:11.673Z
Learning: In ACECustom: Melee/Missile luminance aug counts (Creature.LuminanceAugmentMeleeCount/MissileCount) are applied as flat damage bonuses during DamageEvent calculation (Source/ACE.Server/Entity/DamageEvent.cs) and do not modify EffectiveAttackSkill. CombatPet.GetBaseDamage() adds only ItemAugDamageBonus; DamageEvent later adds the Melee/Missile aug damage.

Learnt from: Schneebs
Repo: rkroska/ACECustom PR: 293
File: Source/ACE.Server/WorldObjects/Monster_Awareness.cs:255-255
Timestamp: 2025-12-17T19:14:14.837Z
Learning: In code reviews, assume ThreadSafeRandom.Next(min, max) is inclusive on the upper bound (unlike System.Random which is exclusive). When using it to index into a collection, e.g., ThreadSafeRandom.Next(0, list.Count - 1), verify that all valid indices (0 through Count-1) can be selected. Look for off-by-one errors where a caller uses max as Count instead of Count-1, and adjust or add tests to ensure full index coverage.

Learnt from: Ruggan
Repo: rkroska/ACECustom PR: 325
File: Source/ACE.Server/WorldObjects/Monster_Navigation.cs:290-300
Timestamp: 2026-01-16T14:29:16.414Z
Learning: In Monster_Navigation.cs, in CheckForStuck(), do not rely solely on MoveToManager.FailProgressCount increments (which only occur when !IsInterpolating && !IsAnimating) and are reset on any distance change. Manually increment FailProgressCount to ensure independent stuck detection, since micro-movements shouldn't reset the stuck counter. This guidance can apply to other navigation-related C# files with a similar MoveToManager interaction: implement an explicit increment when stagnation is detected and only reset on deliberate progress, ensuring the stuck threshold can still be reached. Be mindful of thread-safety and existing test coverage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant