The money amount of a monster drop is computed as "gained experience + 7", but in a party it was neither derived from, nor distributed like, that experience. DistributeExperienceAfterKillAsync returned a party total without the game rate and the personal experience rates, while AddExpAfterKillAsync returned a value which had them applied. Both landed in the same variable in OnDeathAsync, so the party number was orders of magnitude smaller. That mismatch was worked around by recalculating the killer's solo experience for money purposes, which pinned the party pool to a solo-sized amount: with the pool then split by member count, a party of three received about a third of the solo zen each, while its experience pool grows with the party size. AwardExperienceAsync already computes the per member experience with all rates applied, it just discarded it. It now returns that value, the distribution returns the per member breakdown, and the money is split proportionally to it. The workaround is gone, the pool follows the experience, and each member's zen matches their own level, their own rates and their own master/normal branch. The units lost to the integer division are handed to the shares which were cut the most, one each, so no member is systematically favoured over many kills. Two defects around the money rate are fixed on the way: - MoneyAmountRate was applied for the killer when the drop was created and again for the receiver when a party picked it up, so a rate of 3.0 paid a party 9x. On the "money straight into the inventory" path for a solo killer it was not applied at all. It is now applied exactly once, for the receiver. - ClampMoneyOnPickup was only honoured for solo pick ups. A party member at MaximumInventoryMoney silently lost their share, because the drop was consumed as soon as any other member could take one. The clamp now runs on the shared payout path, after the money rate, so it clamps the amount actually credited. Money without a per player breakdown, such as the fixed amount of an item box, keeps being split equally. Shares of players who are no longer eligible are redistributed among the remaining ones instead of being lost. (cherry picked from commit 53f25aca08e690255571f2bb6c796bb7c10934a2)
OpenMU Project
| Platform | Build Status |
|---|---|
| Windows | |
| Linux (Docker) |
| NuGet Packages | |
|---|---|
| MUnique.OpenMU.Network | |
| MUnique.OpenMU.Network.Packets |
This project aims to create an easy to use, extendable and customizable server for a MMORPG called "MU Online". The server supports multiple versions of the game, but the main focus is version of Season 6 Episode 3 using the ENG (english) protocol. Additionally, the long-term focus is on the open source client which supports a slightly extended network protocol. However, parts of the software can also be suitable for the development of other games, even for other kind of games.
The code is a complete rewrite from scratch - it's not based on pre-existing projects, and it's also explicitly not based on decompiled server sources or their countless derivates.
There also exists a blog which may contain some valuable information about this development.
Current project state
This project is currently under development without any release. You can try the current state by using the available docker image, also mentioned in the quick start guide.
Licensing
This project is released under the MIT license (see LICENSE file).
Used technologies
The project is mainly written in C# and targets .NET 10.0.
The servers admin panel is hosted on an embedded ASP.NET Core webserver (Kestrel) and implemented as Blazor Server App.
At the moment the persistence layer uses the Entity Framework Core and PostgreSQL as database. Additionally, it's also possible to start it in a non-persistent in-memory mode.
The project is prepared to be hosted in a single process or distributed in multiple processes. For the communication between the processes, we use Dapr.
Deployment
We provide Docker images and docker-compose files for easy deployment. Please take a look at the deploy-folder of this project.
Contributions
Contributions are welcome if they meet the following criteria:
-
Language is english.
-
Code should be StyleCop compliant - this project uses the StyleCop.Analyzers for VS2022 so you should see issues directly as warnings.
-
Coding style (naming, etc.) and quality should fit to the current state.
-
No code copied/converted from the well-known decompiled source of the original server.
If you want to contribute, please create a new issue for the feature or bug (if the issue doesn't exist yet) so we can see who is working on something and can discuss possible solutions. If it's a small thing, you can also just send a pull request without adding an issue.
Apart of that, contributions from non-developers are welcome as well. You can test the server, submit issues or suggestions, packet descriptions or documentations about the concepts and mechanics of the game itself. Please use markdown files/syntax for this purpose.
If you have questions about that, don't hesitate to ask in our discord channel or by submitting an issue.
How to contribute code
If you want to contribute code, please do the following steps:
- fork this project from the original MUnique OpenMU Project.
- create a feature branch from the master branch
- commit your changes to your feature branch
- please test your changes, don't send AI generated code without testing it yourself
- submit a pull request to the original master branch
- wait for the code review and merge :)
How to use
Please have a look at the quick start guide.
Gameplay differences to the original server
This project doesn't have the goal to copy the original MU Online server behavior to 100 %. This is not entirely possible, because the original server is written in another programming language and has a completely different architecture. With some points we make our life easier in this project, with other points we try to improve the gameplay.
Calculations
The calculations of attribute values (like character damage decrement etc.) are done with 32 bit float numbers and without rounding off, like the original server does at some places. E.g. distributed stat points always have effect, while in the original server effects might get rounded down. For example, when 4 points of strength gives 1 base damage, the original server doesn't calculate a fraction of 1 damage for 3 points, while OpenMU calculates 0.75 damage. This damage has then an effect in further calculations.
Countdown when changing character or sub-server
The original server uses a five second countdown when a player wants to change his character or the sub-server. Maybe this was done for some performance reasons, as the original server would then save the character/account data. We think that's really annoying and see no real value in that, so we don't use a countdown.