{"id":18887964,"url":"https://github.com/joshalexjacobs/slimebattlesystem","last_synced_at":"2025-04-14T23:07:38.346Z","repository":{"id":142017829,"uuid":"509531727","full_name":"Joshalexjacobs/SlimeBattleSystem","owner":"Joshalexjacobs","description":"A lightweight RPG combat system for Unity that emulates the battle formulas from the original Dragon Quest.","archived":false,"fork":false,"pushed_at":"2022-11-11T06:49:06.000Z","size":58,"stargazers_count":21,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-14T23:07:21.604Z","etag":null,"topics":["csharp","dragonquest","jrpg","rpg","unity","unity3d","unitypackage"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Joshalexjacobs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"ko_fi":"stumpheadgames"}},"created_at":"2022-07-01T17:07:07.000Z","updated_at":"2025-02-01T10:36:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"f359ad38-f643-444d-beed-88d12dab8aee","html_url":"https://github.com/Joshalexjacobs/SlimeBattleSystem","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joshalexjacobs%2FSlimeBattleSystem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joshalexjacobs%2FSlimeBattleSystem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joshalexjacobs%2FSlimeBattleSystem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joshalexjacobs%2FSlimeBattleSystem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Joshalexjacobs","download_url":"https://codeload.github.com/Joshalexjacobs/SlimeBattleSystem/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248975316,"owners_count":21192209,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dragonquest","jrpg","rpg","unity","unity3d","unitypackage"],"created_at":"2024-11-08T07:40:49.770Z","updated_at":"2025-04-14T23:07:38.320Z","avatar_url":"https://github.com/Joshalexjacobs.png","language":"C#","funding_links":["https://ko-fi.com/stumpheadgames"],"categories":[],"sub_categories":[],"readme":"# Slime Battle System 🐉⚔️🛡️\nA lightweight RPG combat system for Unity that emulates the battle formulas from the original Dragon Quest.\n\n## Installation (Unity)\n\n1. Download the latest SlimeBattleSystem.dll release found [here](https://github.com/Joshalexjacobs/SlimeBattleSystem/releases) \n2. Drop it into your assets folder\n3. You should now be able to reference the SlimeBattleSystem namespace within your own scripts\n\n\n# API\n\n*Don't like reading documentation? Take a look at the [sample unity project!](https://github.com/Joshalexjacobs/SlimeBattleSystemSample)*\n\n## Battle System\nA static class that handles all combat logic.\n\n\u003cbr/\u003e\n\n### SetRandomizationSeed\nSets the randomization seed used by most formulas.\n\nParams `string`\n\n```csharp\nstring seed = \"New Seed\";\n    \nBattleSystem.SetRandomizationSeed(seed);\n```\n\n\u003cbr/\u003e\n\n### CalculateTurnOrder\nCalculates a participant's turn order with a random range using their Agility stat. \n\nParams `int`\n\nReturns `int`\n```csharp\nforeach (var participant in participants) {\n    participant.TurnOrder = BattleSystem.CalculateTurnOrder(participant.Stats.Agility);\n}\n```\n\n\u003cbr/\u003e\n\n### DetermineTurnOrder\nDetermines the order a group of Participants will attack in. \n\nParams `List\u003cParticipant\u003e`\n\nReturns `List\u003cParticipant\u003e`, sorted by turn order\n```csharp\nList\u003cParticipant\u003e orderedParticipants = BattleSystem.DetermineTurnOrder(participants);\n```\n\n\u003cbr/\u003e\n\n### DetermineEnemyTarget\nDetermines the player participant an enemy will target during their turn. \n\nParams `List\u003cParticipant\u003e`\n\nReturns `Participant`\n```csharp\nParticipant target = BattleSystem.DetermineEnemyTarget(playerParticipants);\n```\n\n\u003cbr/\u003e\n\n### DetermineAttackDamage\nDetermines whether the attacker hits the target and how much damage is dealt.\n\nParams `Participant (attacker)`, `Participant (target)`\n\nReturns `AttackResult`, contains Type (`AttackType` enum) and Damage (`int`).\n```csharp\nvar results = BattleSystem.DetermineAttackDamage(currentParticipant, target);\n\nbattleLog.UpdateLog($\"{currentParticipant.Name} attacks!.\\n\");\n\nswitch (results.Type)\n{\n    case AttackResults.AttackType.Hit:\n        battleLog.UpdateLog($\"{target.Name}'s Hit Points have been reduced by {results.Damage}.\\n\");\n\n        break;\n    case AttackResults.AttackType.CriticalHit:\n        battleLog.UpdateLog($\"Critical hit!!!\\n\");\n        \n        battleLog.UpdateLog($\"{target.Name}'s Hit Points have been reduced by {results.Damage}.\\n\");\n        \n        break;\n    case AttackResults.AttackType.Missed:\n        battleLog.UpdateLog($\"Missed! {target.Name} dodged the attack.\\n\");\n                \n        break;\n}\n\nif (results.Damage \u003e 0) {\n    target.InflictDamage(results.Damage);\n}\n```\n\n\u003cbr/\u003e\n\n### DetermineParticipantFleeing\nDetermines whether the participant is able to flee or not.\n\nWill use the highest Agility stat of the participants in the runningFrom list. \n\nParams `Participant (runner)`, `List\u003cParticipant\u003e (runningFrom)`\n\nReturns `bool`.\n```csharp\nbool result = BattleSystem.DetermineParticipantFleeing(currentParticipant, enemy);\n\nif (!result)\n{\n    battleLog.UpdateLog(\"But the escape route was cut off!\\n\");\n}\nelse\n{\n    battleLog.UpdateLog($\"{currentParticipant.Name} escaped!\\n\");\n    \n    battleState = BattleState.Ended;\n}\n```\n\n\u003cbr/\u003e\n\n### GetPlayerParticipants\nGets a list of Player and NPC participants.\n\nParams `List\u003cParticipant\u003e`\n\nReturns `List\u003cParticipant\u003e`\n```csharp\nvar playerParticipants = BattleSystem.GetPlayerParticipants(participants);\n```\n\n\u003cbr/\u003e\n\n### GetEnemyParticipants\nGets a list of Enemy participants.\n\nParams `List\u003cParticipant\u003e`\n\nReturns `List\u003cParticipant\u003e`\n```csharp\nvar enemyParticipants = BattleSystem.GetEnemyParticipants(participants);\n```\n\n\u003cbr/\u003e\n\n### GetParticipantWithHighestAgility\nGets the participant with the highest agility.\n\nParams `List\u003cParticipant\u003e`\n\nReturns `Participant`.\n```csharp\nvar participant = GetParticipantWithHighestAgility(participants);\n```\n\n\u003cbr/\u003e\n\n### GetNumberOfRemainingParticipants\nGets the number of remaining participants with hit points greater than 0.\n\nParams `List\u003cParticipant\u003e`\n\nReturns `int`.\n```csharp\nvar enemiesRemaining = BattleSystem.GetNumberOfRemainingParticipants(enemyParticipants);\n```\n\n\u003cbr/\u003e\n\n### IsBattleOver\nGets whether the battle has ended or not.\n\nParams `List\u003cParticipant\u003e`\n\nReturns `bool`.\n```csharp\nif (BattleSystem.IsBattleOver(participants))\n{\n    battleState = BattleState.Ended;\n    \n    soundManager.StopSound(soundManager.battleMusic);\n}\n```\n\n\u003cbr/\u003e\n\n### DetermineExperiencePoints\nGets experience points gained from defeated participants.\n\nParams `List\u003cParticipant\u003e`\n\nReturns `int`.\n```csharp\nvar experiencePoints = BattleSystem.DetermineExperiencePoints(enemyParticipants);\n\nbattleLog.UpdateLog($\"Thy Experience increases by {experiencePoints}.\\n\");\n\nplayer.ExperiencePoints += experiencePoints;\n```\n\n\u003cbr/\u003e\n\n### DetermineGoldPoints\nGets gold points gained from defeated participants.\n\nParams `List\u003cParticipant\u003e`\n\nReturns `int`.\n```csharp\nvar gold = BattleSystem.DetermineGoldPoints(enemyParticipants);\n\nbattleLog.UpdateLog($\"Thy GOLD increases by {goldPoints}.\\n\");\n\nplayer.GoldPoints += gold;\n```\n\n\u003cbr/\u003e\n\n### DetermineItemsDropped\n*Note: I couldn't find a lot on item drop rates so I've taken some liberties here to make this as flexible as possible.*\n\nGets any items gained from defeated participants.\n\nParams `Dictionary\u003cT, int\u003e`, `T` being the class or item object and int being the chance to drop out of 100\n\nReturns `List\u003cT\u003e`\n```csharp\nDictionary\u003cItem, int\u003e droppableItems = new Dictionary\u003cItem, int\u003e(); \n\nforeach (var enemyCombatantDroppableItem in enemyCombatant.droppableItems) {\n    droppableItems.Add(enemyCombatantDroppableItem.item, enemyCombatantDroppableItem.chanceToDrop);\n}\n\nvar itemsDropped = BattleSystem.DetermineItemsDropped\u003cItem\u003e(droppableItems);\n\nforeach (Item item in itemsDropped) {\n    battleLog.UpdateLog($\"{enemy.Name} dropped a {item.name}!\\n\");\n    \n    playerCombatant.items.Add(item);\n}\n```\n\n\u003cbr/\u003e\n\n## AttackResult\nA simple class that is returned after a `Participant` attacks.\n\n```csharp\n  public class AttackResult {\n    public enum AttackType {\n      Hit,\n      CriticalHit,\n      Missed\n    }\n\n    public AttackType Type;\n\n    public int Damage;\n\n    public AttackResult(AttackType type, int damage) {\n      Type = type;\n      Damage = damage;\n    }\n  }\n```\n\n## Participant\nAn enemy, NPC, or player character that participates in battle.\n\n\u003cbr/\u003e\n\n### CalculateAttackPower\nCalculates participants attack power. Should be called after a new weapon is equipped.\n\nParams `int`\n\nReturns `void`\n```csharp\nplayerCombatant.weaponSlot = ironAxe;\n\nplayerParticipant.CalculateAttackPower(ironAxe.attackPower);\n```\n\n\u003cbr/\u003e\n\n### CalculateDefensePower\nCalculates participants defense power. Should be called after a new piece of armor is equipped.\n\nParams `int`\n\nReturns `void`\n```csharp\nplayerCombatant.shieldSlot = leatherShield;\n\nplayerParticipant.CalculateDefensePower(leatherShield.defensePower);\n```\n\n\u003cbr/\u003e\n\n### InflictDamage\nInflicts allotted damage to the participant. Will floor hit points to 0.\n\nParams `int`\n\nReturns `void`\n```csharp\ntarget.InflictDamage(results.damage);\n```\n\n# Confused? Check out the sample project!\n\nhttps://github.com/Joshalexjacobs/SlimeBattleSystemSample\n\n![Unity Sample Gif](https://i.imgur.com/S3mjjGf.gif)\n\n\n*Note: This package was created with the first Dragon Quest game in mind. Most of the logic being handled here is intended for 1v1 battles, but I've done my best to try and support battles bigger than 2 combatants.*\n\n----\n\n# Formulas used\n\n- Battle Turn Order\n- Attacking\n- Dodging\n- Critical Hits\n- Fleeing\n- Awarding Experience Points\n- Awarding Gold Points\n- Determining items dropped\n\n## What's missing?\n\n### Spells, Items, and Status Ailments\nI originally planned on baking these into the package, but after some testing decided that this will be much more flexible if handled by the user. If you're looking for an easy way to do this, check out the [sample repo.](https://github.com/Joshalexjacobs/SlimeBattleSystemSample) \n\n### Leveling and name based stat growth\nIn the original Dragon Quest, your character's name determines how your stats will grow upon leveling. After reviewing the logic I figured this was a bit too complex at this time. For now I'm leaving all leveling and stat growth to the user, but may add this as an optional function in the future.\n\n*For those interested: akiraslime posted a great Dragon Warrior stat growth FAQ [here.](https://gamefaqs.gamespot.com/nes/563408-dragon-warrior/faqs/18342)*\n\n### 75% - 100% Enemy Health Formula\nIn the base game, enemy health is randomly determined between 75% - 100% of their max health (eg. a Magician has a max health pool of 13 hit points. When encountered, a Magician would have 10 - 13 hit points). For simplicity sake, I've decided to omit this logic for now as it could be easily added before beginning the encounter if desired.\n\n### Experience/Gold Multiplier\nI did discover a formula for increasing experience points and gold points based on the number of characters in the player's party. For now I've omitted any multiplier due to the fact that this system is entirely based on the original Dragon Quest (in which there is only 1 member in the party). However, I would love to add some sort of configurable profiles in the future allowing for minor changes like this one.\n\n# Sources and additional reading material\n\n[Game Developer: How Final Fantasy and Dragon Quest handle combat math](https://www.gamedeveloper.com/design/number-punchers-how-i-final-fantasy-i-and-i-dragon-quest-i-handle-combat-math)\n\n[Formula Guide (NES) by Ryan8bit](https://gamefaqs.gamespot.com/nes/563408-dragon-warrior/faqs/61640)\n\n[Names/Stats/Levels FAQ (NES) by akiraslime](https://gamefaqs.gamespot.com/nes/563408-dragon-warrior/faqs/18342)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshalexjacobs%2Fslimebattlesystem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshalexjacobs%2Fslimebattlesystem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshalexjacobs%2Fslimebattlesystem/lists"}