Skip to content

Ability System

Gemaakt door: Menno Weerman

​​Inhoudsopgave

  • Inleiding - Uitleg over de keuze voor dit onderdeel in de documentatie.

  • Methodes - Overzicht en uitleg van de methodes gebruikt in het analyseren, ontwerpen en realiseren van het systeem.

  • Uitvoering - Gedetailleerde beschrijving van de ontwikkelingsstappen, inclusief de eerste en verbeterde poging.

  • Validatie - Feedback en verbeteringen die zijn doorgevoerd op basis van evaluaties.

  • Reflectie - Leerpunten en verbeteringen voor toekomstige projecten.

  • Bronnen - Overzicht van geraadpleegde bronnen volgens de APA-richtlijnen

Inleiding

De abilities vormen een cruciaal onderdeel van de game, omdat de game draait om een tovenaar die deze abilities gebruikt. Gedurende het ontwikkelproces heb ik ervaren hoe belangrijk het is om onderzoek te doen naar optimalisaties en efficiëntere manieren om functionaliteiten te implementeren.

Methode(s)

Voor de ontwikkeling van het ability-systeem heb ik verschillende methodes gebruikt:

Analyseren
  • Ik heb onderzoek gedaan naar bestaande implementaties van ability-systemen in games.

  • Feedback verzameld van peers en begeleiders om verbeterpunten te identificeren.

Ontwerpen
  • Het systeem is ontworpen met behulp van UML-diagrammen om een duidelijke structuur te creëren.

  • OOP (Object-Oriented Programming) principes toegepast voor flexibiliteit en uitbreidbaarheid.

  • Een component-gebaseerde aanpak gebruikt om abilities los te koppelen van de speler.

Realiseren
  • Versiebeheer en code reviews gebruikt om feedback te krijgen en verwerken.

  • Vragen stellen aan leraren om feedback te krijgen en verwerken.

Uitvoering

Ik heb dit systeem 2 keer gebouwd, hier zal ik gaan uitleggen wat ik de eerste keer gedaan heb. En de 2e keer verbeterd heb toen ik het systeem herschreven.

Poging 1
Analyseren:

Het eerste idee was om een basisclass (Base Ability) te maken waarvan alle abilities erven. Daarnaast was er een AbilityManager die verantwoordelijk was voor het beheren en uitvoeren van abilities.

Ontwerpen:

Het idee van de analyse uitgewerkt in UML: Ability UML Poging 1

Realiseren:
  • Gebruik van een Interface (IAbility) als basis voor de variabelen.

  • Base Ability implementeerde de IAbility Interface.

  • De AbilityManager riep abilities aan en beheerde de lifecycle ervan.

  • Abilities hadden elk hun eigen implementatie, maar de code bleek niet flexibel genoeg voor uitbreiding.

Problemen:
  • De AbilityManager werd te complex doordat hij te veel verantwoordelijkheden kreeg.

  • De abilities waren niet modulair genoeg en uitbreiding vereiste telkens aanpassingen in de basisklassen.

  • Er waren veel "magic numbers" aanwezig in de code, wat de onderhoudbaarheid bemoeilijkte.

Poging 2

Na evaluatie van de eerste poging heb ik besloten om het systeem opnieuw te bouwen met verbeteringen op basis van feedback.

Analyseren:
  • De AbilityManager werd een child van de speler om directe interactie met de spelerinput mogelijk te maken.

  • De Base Ability kreeg variabelen van de AbilityManager en bepaalde automatisch de dichtstbijzijnde vijand als target.

  • Een FireRate Manager toegevoegd om abilities met een cooldown mechanisme efficiënter te beheren.

  • Abilities bepaalden enkel de target en vuurden een projectiel af indien mogelijk.

Ontwerpen:

Het idee van de analyse uitgewerkt in de UML Ability UML verbeterd 1 Ability UML verbeterd 2

Realiseren:
  • AbilityManager als child van de speler: Dit maakte het mogelijk om abilities efficiënter te managen en spelerinput direct te koppelen aan ability-wisselingen.

  • FireRate Manager: Dit zorgde ervoor dat abilities die een cooldown nodig hebben een gecentraliseerd cooldown-systeem gebruiken, wat dubbel werk en inconsistente implementaties voorkwam.

  • Targeting-systeem: De Base Ability ontving nu automatisch een target op basis van de dichtstbijzijnde vijand, in plaats van dat elke individuele ability dit zelf moest implementeren.

  • Gebruik van een static class voor configuratie: Dit hielp bij het elimineren van magic numbers en maakte het makkelijker om balancering aan te passen zonder code te wijzigen.

Resultaten: - De code werd modulairder en makkelijker uitbreidbaar.

  • De performance verbeterde doordat abilities niet meer hun eigen cooldowns en updates/draw beheerden, maar dit via een centrale manager deden.

  • Het onderhoud van het systeem werd eenvoudiger, omdat abilities minder afhankelijk waren van elkaar.

Validatie

Na de eerste versie heb ik een merge request ingediend. Hierop kwam feedback met suggesties voor verbeteringen. Na overleg met Lucas van Diepen heb ik besloten om het systeem opnieuw te ontwerpen.

4 van deze verbeteringspunten kun je hieronder zien, mocht je er meer willen zien kunt u hier kijken: Base Ability Gitlab Lucas Feedback 1 Lucas Feedback 2 Lucas Feedback 3 Lucas Feedback 4

Belangrijke verbeterpunten:
  • Optimalisatie van de AbilityManager structuur: De oorspronkelijke AbilityManager had te veel verantwoordelijkheden. In de nieuwe versie is de manager eenvoudiger en specifieker, waardoor het systeem beter beheersbaar is.

  • Separation of concerns: In plaats van dat de AbilityManager ook verantwoordelijk was voor de logica van abilities, zijn verantwoordelijkheden beter verdeeld over verschillende componenten.

  • Cooldownbeheer per ability: De cooldowns werden oorspronkelijk beheerd door de AbilityManager, maar na feedback is dit verplaatst naar de abilities zelf. Hierdoor werd de manager minder complex en kregen abilities meer controle over hun eigen gedrag.

  • Gebruik van een interface voor Update() en Draw(): Oorspronkelijk werd in de AbilityManager expliciet gecontroleerd welke ability werd aangeroepen, maar dit is vervangen door een generieke aanpak waarbij abilities zelf Update() en Draw() implementeren via een interface. Dit maakt de code schoner en meer uitbreidbaar.

  • Vermijden van "magic numbers": Door een statische klasse te gebruiken voor configuratievariabelen werd de code overzichtelijker en makkelijker te onderhouden.

Daarna bij de 2e feature heb ik ook gevraagd aan Jur of het gebruiken van een static class gebruiken voor alle variabelen van de abilities handig was. Omdat magic numbers (geen variabelen) in de functies niet netjes en herbruikbaar is. Hij gaf inderdaad aan dat dat in dit geval wel een goede oplossing is

Reflectie

Door dit project heb ik geleerd dat er meerdere manieren zijn om een probleem op te lossen. Waar ik in eerste instantie vastzat in mijn eigen aanpak, heeft feedback en onderzoek me geholpen om een veel beter systeem te bouwen.

Belangrijke leerpunten:

  • Meer onderzoek doen naar bestaande oplossingen voordat ik zelf begin met implementeren.
  • Feedback sneller verwerken en iteratief werken in plaats van een volledige oplossing in één keer proberen te bouwen.
  • Code zo ontwerpen dat het uitbreidbaar en herbruikbaar is, zodat toekomstige toevoegingen makkelijker worden.

In de toekomst zal ik meer tijd besteden aan de ontwerp- en analysefase voordat ik begin met coderen.

Bronnen

Hieronder staan de gebruikte bronnen volgens de APA-richtlijnen:

  • MonoGame Team. (2023). MonoGame Documentation. Geraadpleegd op https://docs.monogame.net

  • Barton, C. (2021). Game Programming Patterns. Geraadpleegd op https://gameprogrammingpatterns.com

  • Dean, J. (2017). MonoGame Mastery. Apress.

  • Finkelstein, A., & Finkelstein, J. (2019). Designing Interactive Systems: A Comprehensive Guide to HCI and UX Design. Springer.

  • Schreiner, J., & Doyle, D. (2015). Learning C# by Developing Games with Unity 3D. O'Reilly Media.