{"author_link":"\/users\/unitedfailures","author_name":"UnitedFailures","author_uid":"unitedfailures","comments":[],"epoch":1665636490,"event":"LD51","format":"md","ldjam_node_id":310085,"likes":14,"metadata":{"p_key":"169301","p_author":"UnitedFailures","p_authorkey":"1036600","p_urlkey":"397064","p_title":"The Most Important Thing I Learned This Game Jam","p_cat":"LDJam ","p_event":"LD51","p_time":"1665636490","p_likes":"14","p_comments":"0","p_status":"WAYBACK","us_key":"1036600","us_name":"UnitedFailures","us_username":"unitedfailures","event_start":"1664496000","event_key":"114","event_name":"Ludum Dare 51"},"node":{"_collation":{"body_sanitizer":"TextUtils::SanitizeHTML via existing importer","event":"LD51","removed_author":false},"_superparent":296586,"_trust":5,"author":36600,"body":"# Event Handlers are VERY useful!\n\n## Background Flavor...\nI've been programming my own games for the past ~5 years. I have six games published on my itch.io page, and countless projects I've sunk hours of development into that never saw the light of day. None of these projects I had worked on make use of custom event handlers - nor was I aware at the time what event handlers even are. Yet, looking back, I can find tons of places where they would have make my code cleaner and my life easier.\n\n## How I Used To Do Things...\n\nHere's a rough example of how I would have managed character functionality in the past.\n\n```\npublic class Character\n{\n    bool movingForward;\n    CharacterAudio audio;\n    CharacterMovement movement;\n\n    void ManageCharacter()\n    {\n        if(movingForward)\n        {\n            audio.Play(...);\n            movement.MoveForward(...);\n        }\n    }\n\n    \/\/ ...\n}\n```\n\n## Why Do I Not Like This?\nIn software development, one of the best practices you can ever learn is to keep your systems decoupled. IE: We want our systems to not be unnecesarily dependent on eachother to perform their functionality.\n\nIn the example above, I outline an example `Character` class to handles working with `CharacterAudio` and `CharacterMovement` components. Now I'm gonna ask rhetorical questions...\n- What happens if I make a NPC using the `Character` class - but I don't want them to make noise when they walk? Can I remove the `CharacterAudio` component?\n    - In the example above, we will error out if we remove the component. Our `Character` class is `TIGHTLY COUPLED` to its respective `Character...` components.\n- What if we add logic for checking if a component is null before using it?\n    - We can go that route, but now we have to do that for EVERY component referenced in `Character`.\n\nWhy is our `Character` even referencing its components to begin with? Every time we create and add a new `Character...` component - we would need to add a new reference within the `Character` class and plug in the respective component function calls within `ManageCharacter()`. Inevitably, this class becomes bloated with a thousand references and the code becomes harder to work with and read...\n\nNow this is where Event Handlers come in.\n\n## What are Event Handlers and Why Should I Use Them\nBelow is an example of how I would use event handlers to improve our code (I used Unity Actions here, but you can use your preferred method of event handlers).\n\nEssentially, the code below shows each `Character...` component gets a reference to the respective main `Character` component - and subscribes its functionality to the respective `OnMoveForwardAction` event. \n\n```\nusing UnityEngine.Events;\n\npublic class Character\n{\n    public UnityAction OnMoveForwardAction;\n\n    public void MoveForward()\n    {\n        OnMoveForwardAction.Invoke();\n    }\n}\n\n[RequireComponent(typeof(Character))] \/\/ Ensures `CharacterAudio`'s GameObject has a `Character` component\npublic class CharacterAudio\n{\n    public void OnEnable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction += PlayWalkingAudio;\n    }\n\n    public void OnDisable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction -= PlayWalkingAudio;\n    }\n\n    public void PlayWalkingAudio()\n    {\n        ...\n    }\n}\n\n[RequireComponent(typeof(Character))] \/\/ Ensures `CharacterMovement`'s GameObject has a `Character` component\npublic class CharacterMovement\n{\n    public void OnEnable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction += MoveForward;\n    }\n\n    public void OnDisable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction -= MoveForward;\n    }\n\n    public void MoveForward()\n    {\n        ...\n    }\n}\n```\n\nThe `Character` class is unaware of who is subscribed, and simply alerts all subscribers for when the `MoveForward` event occurs. This successfully decouples the `Character` class from all `subcomponents` and cleanly resolves the issues discussed above. It is fine for the `subcomponents` to be coupled to the `Character` class - as this assumption has to be made for defining `subcomponent` functionality.\n\nThe best part of this paradigm is shown when we want to create a new subcomponent. For example, if we want a `CharacterHealthOnMove` component (like some special in-game buff), then we can accomplish this with the following steps\n1. Create the `CharacterHealthOnMove` class.\n2. Define the functionality for gaining health within the class in a function.\n3. Subscribe the above function to the `OnMoveForwardAction` event.\n\n## Conclusion\nCheck out event handlers if you haven't used them before. It'll make it easier to organize, write, and extend your code going forward. I heavily utilized events when coding my submission [**BIG BLOCK MODE**](https:\/\/ldjam.com\/events\/ludum-dare\/51\/$296677) for this jam.\n\nNear the end of the jam, I had events for stuff like blocks falling, game loss, row cleared, etc - and it took literal seconds for me to subscribe audio functionality to these respective events and have it all working within the game. EZ PZ.\n\n#### Note\nThis is my first time writing an informative blog post like this. Sorry if it sucked. I'm open to any feedback: positive or negative. Also feel free to check out our submission if you're interested.\n\nTHANKS!","comments":5,"comments-timestamp":"2022-10-13T13:51:53Z","created":"2022-10-13T03:20:19Z","files":[],"files-timestamp":0,"id":310085,"love":14,"love-timestamp":"2022-10-13T15:11:21Z","meta":[],"modified":"2022-10-13T15:11:21Z","name":"The Most Important Thing I Learned This Game Jam","node-timestamp":"2022-10-13T04:48:10Z","parent":296677,"parents":[1,5,9,296586,296677],"path":"\/events\/ludum-dare\/51\/big-block-mode\/the-most-important-thing-i-learned-this-game-jam","published":"2022-10-13T04:48:10Z","scope":"public","slug":"the-most-important-thing-i-learned-this-game-jam","subsubtype":"","subtype":"","type":"post","version":967041},"node_metadata":{"n_key":"310085","n_urlkey":"397064","n_parent":"296677","n_path":"\/events\/ludum-dare\/51\/big-block-mode\/the-most-important-thing-i-learned-this-game-jam","n_slug":"the-most-important-thing-i-learn","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"36600","n_created":"1665631219","n_modified":"1665673881","n_version":"967041","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/51\/big-block-mode\/the-most-important-thing-i-learned-this-game-jam","text":"# Event Handlers are VERY useful!\n\n## Background Flavor...\nI've been programming my own games for the past ~5 years. I have six games published on my itch.io page, and countless projects I've sunk hours of development into that never saw the light of day. None of these projects I had worked on make use of custom event handlers - nor was I aware at the time what event handlers even are. Yet, looking back, I can find tons of places where they would have make my code cleaner and my life easier.\n\n## How I Used To Do Things...\n\nHere's a rough example of how I would have managed character functionality in the past.\n\n```\npublic class Character\n{\n    bool movingForward;\n    CharacterAudio audio;\n    CharacterMovement movement;\n\n    void ManageCharacter()\n    {\n        if(movingForward)\n        {\n            audio.Play(...);\n            movement.MoveForward(...);\n        }\n    }\n\n    \/\/ ...\n}\n```\n\n## Why Do I Not Like This?\nIn software development, one of the best practices you can ever learn is to keep your systems decoupled. IE: We want our systems to not be unnecesarily dependent on eachother to perform their functionality.\n\nIn the example above, I outline an example `Character` class to handles working with `CharacterAudio` and `CharacterMovement` components. Now I'm gonna ask rhetorical questions...\n- What happens if I make a NPC using the `Character` class - but I don't want them to make noise when they walk? Can I remove the `CharacterAudio` component?\n    - In the example above, we will error out if we remove the component. Our `Character` class is `TIGHTLY COUPLED` to its respective `Character...` components.\n- What if we add logic for checking if a component is null before using it?\n    - We can go that route, but now we have to do that for EVERY component referenced in `Character`.\n\nWhy is our `Character` even referencing its components to begin with? Every time we create and add a new `Character...` component - we would need to add a new reference within the `Character` class and plug in the respective component function calls within `ManageCharacter()`. Inevitably, this class becomes bloated with a thousand references and the code becomes harder to work with and read...\n\nNow this is where Event Handlers come in.\n\n## What are Event Handlers and Why Should I Use Them\nBelow is an example of how I would use event handlers to improve our code (I used Unity Actions here, but you can use your preferred method of event handlers).\n\nEssentially, the code below shows each `Character...` component gets a reference to the respective main `Character` component - and subscribes its functionality to the respective `OnMoveForwardAction` event. \n\n```\nusing UnityEngine.Events;\n\npublic class Character\n{\n    public UnityAction OnMoveForwardAction;\n\n    public void MoveForward()\n    {\n        OnMoveForwardAction.Invoke();\n    }\n}\n\n[RequireComponent(typeof(Character))] \/\/ Ensures `CharacterAudio`'s GameObject has a `Character` component\npublic class CharacterAudio\n{\n    public void OnEnable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction += PlayWalkingAudio;\n    }\n\n    public void OnDisable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction -= PlayWalkingAudio;\n    }\n\n    public void PlayWalkingAudio()\n    {\n        ...\n    }\n}\n\n[RequireComponent(typeof(Character))] \/\/ Ensures `CharacterMovement`'s GameObject has a `Character` component\npublic class CharacterMovement\n{\n    public void OnEnable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction += MoveForward;\n    }\n\n    public void OnDisable()\n    {\n        Character c = GetComponent<Character>();\n        c.OnMoveForwardAction -= MoveForward;\n    }\n\n    public void MoveForward()\n    {\n        ...\n    }\n}\n```\n\nThe `Character` class is unaware of who is subscribed, and simply alerts all subscribers for when the `MoveForward` event occurs. This successfully decouples the `Character` class from all `subcomponents` and cleanly resolves the issues discussed above. It is fine for the `subcomponents` to be coupled to the `Character` class - as this assumption has to be made for defining `subcomponent` functionality.\n\nThe best part of this paradigm is shown when we want to create a new subcomponent. For example, if we want a `CharacterHealthOnMove` component (like some special in-game buff), then we can accomplish this with the following steps\n1. Create the `CharacterHealthOnMove` class.\n2. Define the functionality for gaining health within the class in a function.\n3. Subscribe the above function to the `OnMoveForwardAction` event.\n\n## Conclusion\nCheck out event handlers if you haven't used them before. It'll make it easier to organize, write, and extend your code going forward. I heavily utilized events when coding my submission [**BIG BLOCK MODE**](https:\/\/ldjam.com\/events\/ludum-dare\/51\/$296677) for this jam.\n\nNear the end of the jam, I had events for stuff like blocks falling, game loss, row cleared, etc - and it took literal seconds for me to subscribe audio functionality to these respective events and have it all working within the game. EZ PZ.\n\n#### Note\nThis is my first time writing an informative blog post like this. Sorry if it sucked. I'm open to any feedback: positive or negative. Also feel free to check out our submission if you're interested.\n\nTHANKS!","title":"The Most Important Thing I Learned This Game Jam","wayback_source":[]}