<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carlos Rodriguez</title>
    <description>The latest articles on DEV Community by Carlos Rodriguez (@crodriguez25).</description>
    <link>https://dev.to/crodriguez25</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F373055%2Fe619ea44-8163-488e-8e53-6ee8bd832a91.jpeg</url>
      <title>DEV Community: Carlos Rodriguez</title>
      <link>https://dev.to/crodriguez25</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/crodriguez25"/>
    <language>en</language>
    <item>
      <title>Enceladus Project Dev Blog 2: Game Event Message Bus</title>
      <dc:creator>Carlos Rodriguez</dc:creator>
      <pubDate>Sat, 25 Apr 2020 23:15:35 +0000</pubDate>
      <link>https://dev.to/crodriguez25/enceladus-project-dev-blog-2-game-event-message-bus-4ghb</link>
      <guid>https://dev.to/crodriguez25/enceladus-project-dev-blog-2-game-event-message-bus-4ghb</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;Very early on in the design of this project, I knew that I wanted to allow different game objects and entities to communicate with each other in a clean, decoupled manner. I haven't worked on many Unity3D projects, but the ones I have worked on quickly devolved into spaghetti; a bunch of objects calling other objects explicitly and being dependent on each other. This worked for smaller scale projects, but it quickly became a burden as the scope of the project increased. That's why I created this simple Message Bus class&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;There's not much to this class, but it has been a game changer for the development of this project. In this post, I'll go over the implementation, and give some examples of how it is used in &lt;strong&gt;The Enceladus Project&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Let's start with the usage of this message bus, as this class can really be used without knowing how it works. This class has two public methods, &lt;code&gt;Subscribe&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Emit&amp;lt;T&amp;gt;&lt;/code&gt;. The types (&lt;code&gt;T&lt;/code&gt;) that you're subscribing to or emitting can truly be any type, though they're meant to represent a particular &lt;code&gt;Event&lt;/code&gt; in the game that other objects may be interested in. One example object from &lt;strong&gt;The Enceladus Project&lt;/strong&gt; is the &lt;code&gt;CompleteLandingEvent&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class CompleteLandingEvent
{
    public GameObject LandingPad { get; set; }
    public GameObject Ship { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This event is meant to be emitted when a ship successfully lands at a &lt;code&gt;Landing Pad&lt;/code&gt;. This is an event that potentially many parts of the game might care about, and so it was a good fit for an Event in our system. Here is how this event is actually emitted in the game.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GameEventMessageBus.Emit(new CompleteLandingEvent {
    Ship = gameObject,
    LandingPad = _landingPad
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And just like that, we've let the game know that the ship &lt;code&gt;Ship&lt;/code&gt; has succesfully landed at landing pad &lt;code&gt;LandingPad&lt;/code&gt;. Of course, if there's no one who &lt;code&gt;Subscribe&lt;/code&gt;d to this event, then nothing will happen. So let's add someone who might care.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // LandingPad.cs
    public void Start()
    {
        GameEventMessageBus
            .Subscribe&amp;lt;CompleteLandingEvent&amp;gt;(msg =&amp;gt; ShipLanded(msg.Ship, msg.LandingPad));
    }

    private void ShipLanded(GameObject ship, GameObject landingPad)
    {
        if (landingPad != gameObject) 
            return;

        Animator.SetBool("OpenDoor", true);
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The above script is attached to landing pads. They care about the &lt;code&gt;CompleteLandingEvent&lt;/code&gt; because, when a ship lands at a given landing pad, that landing pad needs to play a “open door” animation.&lt;/p&gt;

&lt;p&gt;In the Start method, we let the message bus know that we care about that event by calling the &lt;code&gt;Subscribe&lt;/code&gt; method. We specify the type of event we’re subscribing to, and we specify the action that should happen when the event is received (play the appropriate animation)&lt;/p&gt;

&lt;p&gt;Now, when the "CompleteLandingEvent" is fired, our station doors should open. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IVzBlHyF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/va6stgxvznpn5hp7j2qu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IVzBlHyF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/va6stgxvznpn5hp7j2qu.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The beauty of this approach is that the code that fires the &lt;code&gt;CompleteLandingEvent&lt;/code&gt; in the first place doesn't know anything at all about the door animations. It just lets "anyone who is interested" know. I can add a second interested party afterwards (say, to open up the Station UI screen) without having to touch any of the existing code. And like I always say, code that doesn't change doesn't break. &lt;/p&gt;
&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Here's the code again. &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;At the top, we instantiate our Dictionary of subscribers. It maps different C# types (our event types like the &lt;code&gt;CompleteLandingEvent&lt;/code&gt;) to a list of Actions that need to happen when that event is fired. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;private static Dictionary&amp;lt;Type, List&amp;lt;Action&amp;lt;object&amp;gt;&amp;gt;&amp;gt; _subscriberDict = new Dictionary&amp;lt;Type, List&amp;lt;Action&amp;lt;object&amp;gt;&amp;gt;&amp;gt;();&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When a caller calls the &lt;code&gt;Subscribe&lt;/code&gt; method, it'll execute this line&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_subscriberDict[type].Add(new Action&amp;lt;object&amp;gt;(o =&amp;gt; handler((T)o)));&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which adds a new Action to our List of Actions that must be performed when this event is called. There's some wrapping and casting happening here, since our lists are &lt;code&gt;List&amp;lt;object&amp;gt;&lt;/code&gt; but our subscribers are expecting the specific type they're subscribed to, but in the end the action will call the &lt;code&gt;handler&lt;/code&gt; with the object of the appropriate type. &lt;/p&gt;

&lt;p&gt;Now, when someone calls the &lt;code&gt;Emit&lt;/code&gt; method...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public static void Emit&amp;lt;T&amp;gt;(T message)
    {
        var type = typeof(T);
        InitializeTypeKey(type);
        foreach(var handler in _subscriberDict[type])
            handler.Invoke(message);
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;we iterate over each handler for that type, and just invoke that handler with the correct message. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This message bus is very simple, and still needs a little work (it'd be nice to have an unsubscribe method as well, to clean up any destroyed objects. I haven't needed it yet but I'm sure I will soon), but this is a great base that has led this project so far to have a neat, decoupled architecture.&lt;/p&gt;

</description>
      <category>enceladusproject</category>
      <category>unity3d</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Enceladus Project Dev Blog 1: Introduction</title>
      <dc:creator>Carlos Rodriguez</dc:creator>
      <pubDate>Sat, 25 Apr 2020 21:51:37 +0000</pubDate>
      <link>https://dev.to/crodriguez25/enceladus-project-dev-blog-1-introduction-56oo</link>
      <guid>https://dev.to/crodriguez25/enceladus-project-dev-blog-1-introduction-56oo</guid>
      <description>&lt;h1&gt;
  
  
  Enceladus Project
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Enceladus Project&lt;/strong&gt; is an in-progress hobby project that I've been working on in my spare time. It is being developed in Unity (C#) and is a very "early stage" work in progress&lt;/p&gt;

&lt;p&gt;This is the first in what I hope will be many useful dev blog post related to the development of this game. I'm not the most experienced Game Developer, but I am a professional Software Engineer and I will be applying what I've learned through my career to Game Development on this project.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what is it?
&lt;/h2&gt;

&lt;p&gt;Enceladus Project is (or will be?) a 2D, sprite-based Space game with Newtonian style flight mechanics. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I2tm24rt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xbi77qgmg241so3vjem2.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I2tm24rt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xbi77qgmg241so3vjem2.PNG" alt="Alt Text" width="880" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is definitely inspired by games like &lt;a href="https://www.elitedangerous.com/"&gt;Elite Dangerous&lt;/a&gt; and &lt;a href="https://www.nomanssky.com/"&gt;No Man's Sky&lt;/a&gt;, and my goal is to give this game the same level of customization and freedom, while also giving the player a focused narrative to aim to achieve. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3DKufEBr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bbvg7ort3858m2po5lr8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3DKufEBr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bbvg7ort3858m2po5lr8.PNG" alt="Alt Text" width="880" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're interested, please stay tuned for updates on the progress of the game as well as some tutorials and code snippets related to the more interesting challenges I've solved while creating this game!&lt;/p&gt;

</description>
      <category>enceladusproject</category>
      <category>unity3d</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
