Skip to content

Monster Attribute Scaler Plugin#772

Merged
sven-n merged 6 commits into
MUnique:masterfrom
nolt:monster-attribute-plugin
May 16, 2026
Merged

Monster Attribute Scaler Plugin#772
sven-n merged 6 commits into
MUnique:masterfrom
nolt:monster-attribute-plugin

Conversation

@nolt
Copy link
Copy Markdown
Contributor

@nolt nolt commented May 12, 2026

Monster Attribute Scaler Plugin

What it does:
A feature plugin that scales monster base stats by a configurable percentage.
Each stat group (Damage, AttackRate, DefenseRate, Defense, Health) has its own
percentage setting. Default: +25% to MinimumPhysBaseDmg, MaximumPhysBaseDmg,
AttackRatePvm, DefenseRatePvm, DefenseBase, and MaximumHealth. Supports a
"Scale All" option that sets all stat groups at once. Starts disabled by default.

How it works:
The plugin uses shared multiplicative IElement instances, one per stat group,
added to all monsters at spawn time via IObjectAddedToMapPlugIn and removed
on despawn via IObjectRemovedFromMapPlugIn. Configuration changes in the
Admin Panel take effect immediately by mutating the shared element values,
which propagate to all active monsters through the attribute system's
ValueChanged event. The configuration class handles ScaleAll cascading and
individual field isolation at the property level.

Bug fix — ConfigurationChangeHandler (not plugin-specific, but required for live updates):
The OnPlugInConfigurationChanged method passed the entity primary key (Id)
instead of plugInConfiguration.TypeId to all PlugInManager calls. This caused
ActivatePlugIn, DeactivatePlugIn, and ConfigurePlugIn to silently no-op because
PlugInManager looks up plugins by their [Guid] TypeId, not by the database entity
PK. Fix: replaced 'id' with 'plugInConfiguration.TypeId' in all four calls.

Files modified for this plugin:
OpenMU/src/GameLogic/Properties/PlugInResources.resx
OpenMU/src/GameLogic/Properties/PlugInResources.Designer.cs

Files modified (bug fix, required for live updates):
OpenMU/src/Startup/ConfigurationChangeHandler.cs

Files added for this plugin:
OpenMU/src/GameLogic/PlugIns/MonsterAttributeScaler.cs
OpenMU/src/GameLogic/PlugIns/MonsterAttributeScalerConfiguration.cs

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new feature plugin designed to enhance game difficulty by scaling monster attributes. It leverages the existing plugin architecture to apply multiplicative modifiers to monster stats at spawn time, while providing a configurable interface for server administrators to adjust these values.

Highlights

  • New Plugin Implementation: Introduced the MonsterAttributeScaler plugin to dynamically scale monster base statistics.
  • Configurable Scaling: Added a configuration class allowing users to define a percentage increase for monster stats, defaulting to 25%.
  • Resource Management: Implemented tracking for scaled monsters using ConcurrentDictionaries and hooks to ensure clean-up when monsters are removed from the map, preventing memory leaks.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new MonsterAttributeScaler plugin and its associated configuration to scale monster attributes like health, damage, and defense by a configurable percentage. The code review identified a critical issue where attribute modifiers were not being removed when monsters were removed from the map, which could lead to stat stacking on respawn. Additionally, feedback was provided to refine the health-scaling logic to prevent unintended healing or resurrection, and a suggestion was made to replace Console.WriteLine with a structured logging framework.

Comment thread src/GameLogic/PlugIns/MonsterAttributeScaler.cs Outdated
Comment thread src/GameLogic/PlugIns/MonsterAttributeScaler.cs Outdated
Comment thread src/GameLogic/PlugIns/MonsterAttributeScaler.cs Outdated
Copy link
Copy Markdown
Member

@sven-n sven-n left a comment

Choose a reason for hiding this comment

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

Configuration changes in the Admin Panel require a server restart to take effect.

Do you know why? Because the plugin creates one element per monster and never updates it again.
How about this solution:

  • The plugin just holds one SimpleElement and shares it between all monsters by adding the same instance to all monsters. No tracking of monsters required.
  • When configuration changed, simply apply the change to the one shared SimpleElement instance.

Can you try that?

It could also be interesting to add percentages for different kind of attributes. At the moment, it scales every attribute by the same percentage.

@nolt
Copy link
Copy Markdown
Contributor Author

nolt commented May 13, 2026

Good idea I will try this your solution. I tried to make a plugin as simple as it possible and try to not change anything in source code only plugin files.
And yea I can add few options. Again the goal was to make it simple and scale all attributes at once.

@nolt
Copy link
Copy Markdown
Contributor Author

nolt commented May 13, 2026

Plugin now allows setting % to each stat + option change to all. Also I've implemented your soulution.
NOTE: Admin Panel changing settings works and I tested this but in game tests are not done yet.

@nolt
Copy link
Copy Markdown
Contributor Author

nolt commented May 13, 2026

Long tests ingame with debug and logging. But finally plugin works as it should - tested in game. (1st PR message updated).
Bug has been found in ConfigurationChangeHandler.cs

Here is an detailed explanation from AI.


Bug found and fixed: Live configuration updates from Admin Panel silently did nothing.

Root cause: In ConfigurationChangeHandler.OnPlugInConfigurationChanged (src/Startup/ConfigurationChangeHandler.cs), the id parameter (entity primary key PlugInConfiguration.Id, e.g. 331d9e01-...) was passed to all PlugInManager methods — IsPlugInActive, ActivatePlugIn, DeactivatePlugIn, and ConfigurePlugIn. These methods expect a plugin TypeId (the [Guid] attribute on the plugin class, e.g. 59e5b45f-...). The mismatch caused all four calls to silently no-op (no matching plugin found), so configuration saves to the database persisted correctly but never reached the runtime plugin instance.

Fix: Replaced every usage of the id parameter with plugInConfiguration.TypeId in the four PlugInManager calls at lines 114–126. After the fix, the full pipeline works end-to-end: Admin Panel save → EF change tracker → ConfigurationChangeHandler → PlugInManager.ConfigurePlugIn → PlugInConfigurationChanged event → plugin Configuration setter → SimpleElement.Value update → live stat change on all monsters.

@nolt nolt requested a review from sven-n May 13, 2026 18:37
@sven-n
Copy link
Copy Markdown
Member

sven-n commented May 16, 2026

Thank you :)

@sven-n sven-n merged commit f6b1943 into MUnique:master May 16, 2026
2 checks passed
@nolt nolt deleted the monster-attribute-plugin branch May 17, 2026 18:26
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.

2 participants