<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Cyber Dev]]></title><description><![CDATA[welcome to my thoughts]]></description><link>https://blog.desmondezoojile.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 09 Jun 2026 15:45:46 GMT</lastBuildDate><atom:link href="https://blog.desmondezoojile.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building a City-Based Maze Game with Dynamic Zombie AI: Technical Challenges, Code, and Solutions]]></title><description><![CDATA[For our hackathon project, we designed a game where players navigate a city-based maze, avoiding zombies and collecting power-ups. Here’s a peek at the technical challenges and creative solutions we tackled to bring this game to life!


We decided to...]]></description><link>https://blog.desmondezoojile.com/building-a-city-based-maze-game-with-dynamic-zombie-ai-technical-challenges-code-and-solutions</link><guid isPermaLink="true">https://blog.desmondezoojile.com/building-a-city-based-maze-game-with-dynamic-zombie-ai-technical-challenges-code-and-solutions</guid><category><![CDATA[javascript game]]></category><category><![CDATA[web game]]></category><category><![CDATA[AI playground hackathon]]></category><category><![CDATA[Bournemouth university hackathon]]></category><category><![CDATA[Hand Tracking]]></category><category><![CDATA[Pathfinding Algorithms]]></category><category><![CDATA[Real-Time Hand Tracking]]></category><category><![CDATA[Hands-Free Controls]]></category><category><![CDATA[p5.js]]></category><category><![CDATA[ml5js]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[city maps]]></category><category><![CDATA[hackathon project]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[#hackathon #ideas #]]></category><dc:creator><![CDATA[Desmond Ezo-Ojile]]></dc:creator><pubDate>Fri, 08 Nov 2024 00:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731398669414/72448713-cdc3-48cf-ae4c-c30248e29485.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<blockquote>
<p><strong><em>For our hackathon project, we designed a game where players navigate a city-based maze, avoiding zombies and collecting power-ups. Here’s a peek at the technical challenges and creative solutions we tackled to bring this game to life!</em></strong></p>
</blockquote>
<hr />
<p>We decided to go with a maze game mainly because it seemed straightforward, and the judging criteria suited it well. In our heads, it was a simple idea we could whip up easily (spoiler: it turned out to be a lot harder than expected! 😂)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731399667100/00bac096-c62c-4e30-9fb0-2e1750833f4e.jpeg" alt="Challenge Rules" class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731399742370/491f92df-f873-430c-bbdd-c72daeea8e54.jpeg" alt class="image--center mx-auto" /></p>
<p><strong>Here’s what we learned (and struggled with) along the way:</strong></p>
<hr />
<h3 id="heading-1-building-the-maze-layout-initial-experiments-and-challenges">1. Building the Maze Layout: Initial Experiments and Challenges</h3>
<p>We started off building a simple maze with a binary multidimensional array, where walls were “1” and paths were “0”. This gave us a nice structured maze, but it felt too plain and predictable.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731400891537/01328bbd-b717-4b1c-a7d3-1e29969be7b3.png" alt="Maze Array" class="image--center mx-auto" /></p>
<p>Even though the result looked like a maze, it just didn’t feel fun or creative enough:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/d3fLnJV30KA">https://youtu.be/d3fLnJV30KA</a></div>
<p> </p>
<h3 id="heading-2-trying-ai-for-city-based-mazes-a-temporary-detour">2. Trying AI for City-Based Mazes: A Temporary Detour</h3>
<p>We thought, "What if we could use AI to turn screenshots of city maps into mazes?" This idea was cool but turned out way more complex than expected. None of us had experience training custom AI models to transform city maps into maze layouts within our timeframe.</p>
<p>So, we took a one-day detour and tried a <strong>body pong game</strong> (similar to ping pong but controlled by body movement) using ML5.js. Here’s a demo of that experiment, presented by one of our teammates:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/Hl6D_rsTKc8">https://youtu.be/Hl6D_rsTKc8</a></div>
<p> </p>
<h3 id="heading-3-eureka-moment-using-map-data-for-a-real-world-maze">3. Eureka Moment: Using Map Data for a Real-World Maze</h3>
<p>Our breakthrough came when we realized we could use a <strong>maps API</strong> to pull in street data, transforming it directly into a navigable maze. With this, we shifted gears and moved to our next big technical challenge: “Integrating Real-World Map Data for Maze Generation.”</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/4EN_pCN97Nw?si=bJ7776_yxReIeo30">https://youtu.be/4EN_pCN97Nw?si=bJ7776_yxReIeo30</a></div>
<p> </p>
<hr />
<h3 id="heading-4-integrating-real-world-map-data-for-maze-generation">4. Integrating Real-World Map Data for Maze Generation</h3>
<p>Using real-world city maps, we designed a layout that felt like an actual city. We imported OpenStreetMap (OSM) data and transformed it into nodes and edges representing streets and intersections, creating a maze-like experience.</p>
<h4 id="heading-the-challenge">The Challenge</h4>
<p>Turning real-world map data into a playable maze was tricky! We needed to handle interconnected streets, dead-ends, and map structure in a way that felt natural yet challenging for players.</p>
<h4 id="heading-the-solution">The Solution</h4>
<p>Using the <strong>OpenStreetMap API</strong>, we fetched city data, then processed it into a grid of paths, simplifying each section for gameplay. Here’s the code that made it happen:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Fetch street data from OpenStreetMap</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchStreetData</span>(<span class="hljs-params">bbox, callback</span>) </span>{
  <span class="hljs-keyword">const</span> query = <span class="hljs-string">`
    [out:json][timeout:25];
    (
      way["highway"](<span class="hljs-subst">${bbox.join(<span class="hljs-string">','</span>)}</span>);
      &gt;;
    );
    out body;
  `</span>;

  fetch(<span class="hljs-string">'https://overpass-api.de/api/interpreter'</span>, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
    <span class="hljs-attr">body</span>: query,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>
    },
  })
  .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())
  .then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> callback(data))
  .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error fetching OSM data:'</span>, error);
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'status'</span>).textContent = <span class="hljs-string">'Error fetching map data.'</span>;
  });
}

<span class="hljs-comment">// Process OSM data into nodes and edges</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processStreetData</span>(<span class="hljs-params">osmData</span>) </span>{
  osmData.elements.forEach(<span class="hljs-function"><span class="hljs-params">element</span> =&gt;</span> {
    <span class="hljs-keyword">if</span> (element.type === <span class="hljs-string">'node'</span>) {
      nodes[element.id] = { <span class="hljs-attr">id</span>: element.id, <span class="hljs-attr">lat</span>: element.lat, <span class="hljs-attr">lon</span>: element.lon, <span class="hljs-attr">neighbors</span>: [] };
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (element.type === <span class="hljs-string">'way'</span>) {
      <span class="hljs-keyword">const</span> nodeRefs = element.nodes;
      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; nodeRefs.length - <span class="hljs-number">1</span>; i++) {
        <span class="hljs-keyword">const</span> <span class="hljs-keyword">from</span> = nodeRefs[i];
        <span class="hljs-keyword">const</span> to = nodeRefs[i + <span class="hljs-number">1</span>];

        <span class="hljs-keyword">if</span> (!edges[<span class="hljs-keyword">from</span>]) edges[<span class="hljs-keyword">from</span>] = [];
        <span class="hljs-keyword">if</span> (!edges[to]) edges[to] = [];
        edges[<span class="hljs-keyword">from</span>].push(to);
        edges[to].push(<span class="hljs-keyword">from</span>);
      }
    }
  });
}
</code></pre>
<p>The <code>fetchStreetData</code> and <code>processStreetData</code> functions create a maze from city data, giving players the fun experience of navigating real-world streets.</p>
<hr />
<h3 id="heading-5-adding-random-elements-for-unpredictability">5. Adding Random Elements for Unpredictability</h3>
<p>To make each session unique, we introduced randomness to the placement of key elements: <strong>safe zones, collectibles, and opponents</strong>.</p>
<p><strong>Safe Zones</strong> offer temporary protection, while <strong>collectibles</strong> give players special powers like speed boosts, health recovery, and invisibility. Each item is placed randomly, making the game feel different each time you play.</p>
<p>Here’s a glimpse of how it works:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Function to create safe zones</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createSafeZones</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> numSafeZones = <span class="hljs-number">3</span>;
  <span class="hljs-keyword">const</span> nodeIds = <span class="hljs-built_in">Object</span>.keys(nodes);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; numSafeZones; i++) {
    <span class="hljs-keyword">const</span> randomNodeId = nodeIds[<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * nodeIds.length)];
    <span class="hljs-keyword">const</span> safeZone = {
      <span class="hljs-attr">lat</span>: nodes[randomNodeId].lat,
      <span class="hljs-attr">lon</span>: nodes[randomNodeId].lon,
      <span class="hljs-attr">marker</span>: L.marker([nodes[randomNodeId].lat, nodes[randomNodeId].lon], {
        <span class="hljs-attr">icon</span>: L.icon({ <span class="hljs-attr">iconUrl</span>: <span class="hljs-string">'images/safe-zone.webp'</span>, <span class="hljs-attr">iconSize</span>: [<span class="hljs-number">32</span>, <span class="hljs-number">32</span>] })
      }).addTo(map)
    };
    safeZones.push(safeZone);
  }
}
</code></pre>
<hr />
<h3 id="heading-6-making-zombie-ai-feel-real">6. Making Zombie AI Feel Real</h3>
<p>Our zombies use basic pathfinding to follow the player, creating a real sense of pursuit. We used a mix of A* pathfinding for nearby zombies and straight-line movement for distant ones to keep CPU usage low.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Function to move opponents towards the player</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">moveOpponents</span>(<span class="hljs-params"></span>) </span>{
  opponents.forEach(<span class="hljs-function"><span class="hljs-params">opponent</span> =&gt;</span> {
    <span class="hljs-keyword">if</span> (!opponent.currentNodeId || !nodes[opponent.currentNodeId]) <span class="hljs-keyword">return</span>;

    <span class="hljs-keyword">const</span> playerLat = nodes[currentNodeId].lat;
    <span class="hljs-keyword">const</span> playerLon = nodes[currentNodeId].lon;
    <span class="hljs-keyword">const</span> neighbors = nodes[opponent.currentNodeId].neighbors;

    <span class="hljs-comment">// Move to the closest neighbor</span>
    <span class="hljs-keyword">let</span> nextNodeId = neighbors.reduce(<span class="hljs-function">(<span class="hljs-params">closest, neighborId</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> distance = getDistanceMeters(playerLat, playerLon, nodes[neighborId].lat, nodes[neighborId].lon);
      <span class="hljs-keyword">return</span> distance &lt; getDistanceMeters(playerLat, playerLon, nodes[closest].lat, nodes[closest].lon) ? neighborId : closest;
    }, neighbors[<span class="hljs-number">0</span>]);

    opponent.currentNodeId = nextNodeId;
    opponent.marker.setLatLng([nodes[nextNodeId].lat, nodes[nextNodeId].lon]);
  });
}
</code></pre>
<p>This approach makes zombies unpredictable, while also keeping the game smooth and engaging.</p>
<hr />
<h3 id="heading-7-hand-tracking-controls-adding-an-immersive-player-experience"><strong>7. Hand Tracking Controls: Adding an Immersive Player Experience</strong></h3>
<p>To take our game to the next level, we wanted players to control movement through hand gestures instead of traditional keyboard inputs. This required us to dive into <strong>hand tracking</strong> technology, specifically using the <strong>ml5.js</strong> library. With this setup, players can simply tilt their palms to navigate the game, making the experience more interactive and unique.</p>
<h4 id="heading-the-challenge-1">The Challenge</h4>
<p>Using hand tracking for real-time control was tricky, especially when converting palm movements into smooth and responsive directional input. We had to identify the correct hand landmarks and translate them accurately into up, down, left, and right movements.</p>
<h4 id="heading-solution-implementing-palm-tilt-detection">Solution: Implementing Palm Tilt Detection</h4>
<p>Using <strong>ml5.js’s Handpose model</strong>, we detected landmarks on the player’s hand. The idea was to compare the position of the wrist and the middle fingertip to determine the tilt direction.</p>
<p>Here’s the core code that made hand tracking work:</p>
<pre><code class="lang-javascript">javascriptCopy code<span class="hljs-comment">// Function to detect palm tilt and determine direction</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">detectPalmTilt</span>(<span class="hljs-params">landmarks</span>) </span>{
  <span class="hljs-keyword">const</span> wrist = landmarks[<span class="hljs-number">0</span>];
  <span class="hljs-keyword">const</span> middleFingerTip = landmarks[<span class="hljs-number">12</span>];
  <span class="hljs-keyword">const</span> deltaX = wrist[<span class="hljs-number">0</span>] - middleFingerTip[<span class="hljs-number">0</span>];
  <span class="hljs-keyword">const</span> deltaY = middleFingerTip[<span class="hljs-number">1</span>] - wrist[<span class="hljs-number">1</span>];
  <span class="hljs-keyword">const</span> angleRad = <span class="hljs-built_in">Math</span>.atan2(deltaY, deltaX);
  <span class="hljs-keyword">let</span> angleDeg = angleRad * (<span class="hljs-number">180</span> / <span class="hljs-built_in">Math</span>.PI);

  <span class="hljs-comment">// Normalize angle to [0, 360)</span>
  <span class="hljs-keyword">if</span> (angleDeg &lt; <span class="hljs-number">0</span>) {
    angleDeg += <span class="hljs-number">360</span>;
  }

  <span class="hljs-comment">// Define thresholds for each direction</span>
  <span class="hljs-keyword">const</span> directionThresholds = {
    <span class="hljs-string">'up'</span>: { <span class="hljs-attr">min</span>: <span class="hljs-number">45</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">135</span> },
    <span class="hljs-string">'right'</span>: { <span class="hljs-attr">min</span>: <span class="hljs-number">315</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">360</span> },
    <span class="hljs-string">'right_ext'</span>: { <span class="hljs-attr">min</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">45</span> },
    <span class="hljs-string">'down'</span>: { <span class="hljs-attr">min</span>: <span class="hljs-number">225</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">315</span> },
    <span class="hljs-string">'left'</span>: { <span class="hljs-attr">min</span>: <span class="hljs-number">135</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">225</span> }
  };

  <span class="hljs-keyword">let</span> detectedDirection = <span class="hljs-literal">null</span>;

  <span class="hljs-keyword">if</span> (angleDeg &gt;= directionThresholds[<span class="hljs-string">'up'</span>].min &amp;&amp; angleDeg &lt; directionThresholds[<span class="hljs-string">'up'</span>].max) {
    detectedDirection = <span class="hljs-string">'up'</span>;
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (
    (angleDeg &gt;= directionThresholds[<span class="hljs-string">'right'</span>].min &amp;&amp; angleDeg &lt; directionThresholds[<span class="hljs-string">'right'</span>].max) ||
    (angleDeg &gt;= directionThresholds[<span class="hljs-string">'right_ext'</span>].min &amp;&amp; angleDeg &lt; directionThresholds[<span class="hljs-string">'right_ext'</span>].max)
  ) {
    detectedDirection = <span class="hljs-string">'right'</span>;
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (angleDeg &gt;= directionThresholds[<span class="hljs-string">'down'</span>].min &amp;&amp; angleDeg &lt; directionThresholds[<span class="hljs-string">'down'</span>].max) {
    detectedDirection = <span class="hljs-string">'down'</span>;
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (angleDeg &gt;= directionThresholds[<span class="hljs-string">'left'</span>].min &amp;&amp; angleDeg &lt; directionThresholds[<span class="hljs-string">'left'</span>].max) {
    detectedDirection = <span class="hljs-string">'left'</span>;
  }

  <span class="hljs-keyword">if</span> (detectedDirection) {
    movePlayer(detectedDirection);
  }
}
</code></pre>
<p>This function calculates the angle between the wrist and middle fingertip to determine the tilt direction of the player’s hand. Based on the tilt, it then triggers movement in the corresponding direction.</p>
<h4 id="heading-code-walkthrough">Code Walkthrough:</h4>
<ul>
<li><p><strong>Identify Hand Landmarks:</strong> Using the ml5.js Handpose model, we capture the hand landmarks, focusing on the wrist (index <code>0</code>) and the tip of the middle finger (index <code>12</code>).</p>
</li>
<li><p><strong>Calculate the Tilt Angle:</strong> We calculate the angle between the wrist and the middle fingertip. By interpreting this angle, we can figure out whether the palm is tilted up, down, left, or right.</p>
</li>
<li><p><strong>Set Directional Thresholds:</strong> To ensure accurate and intuitive control, we set angle ranges for each direction (up, down, left, right). For instance, a tilt angle between 45° and 135° means the hand is tilted up.</p>
</li>
<li><p><strong>Move Player:</strong> If a valid direction is detected, we trigger the <code>movePlayer</code> function in that direction, allowing the player to navigate the maze.</p>
</li>
</ul>
<hr />
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/ba4heAPsoFc?si=yNfOk-dejlfRlb03">https://youtu.be/ba4heAPsoFc?si=yNfOk-dejlfRlb03</a></div>
<p> </p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>This city-based maze game was an exciting challenge, combining real-world map data, gesture-based controls, and dynamic AI. We learned a lot about balancing game complexity with playability, and it gave us some big ideas for future updates—like multi-city maps, expanded AI behaviors, and even more immersive experiences.</p>
<p>Curious to try it yourself? <a target="_blank" href="https://desmondezo1.github.io/city-Maze/">Play the demo here!</a> Let us know what you think!</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Solidity: Constants VS Immutables]]></title><description><![CDATA[Are you currently learning solidity?or do you frequently read solidity code?
Then you should read this article to the end.
My goal for this article is to help you understand the differences between Constants and Immutables, and when it's best to use ...]]></description><link>https://blog.desmondezoojile.com/mastering-solidity-constants-vs-immutables</link><guid isPermaLink="true">https://blog.desmondezoojile.com/mastering-solidity-constants-vs-immutables</guid><category><![CDATA[software development]]></category><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Solidity]]></category><dc:creator><![CDATA[Desmond Ezo-Ojile]]></dc:creator><pubDate>Wed, 01 Nov 2023 22:25:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1698872219429/06f4aae9-23ff-46e3-b562-ce36088feddf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you currently learning solidity?<br />or do you frequently read solidity code?</p>
<p>Then you should read this article to the end.</p>
<p>My goal for this article is to help you understand the differences between Constants and Immutables, and when it's best to use them.</p>
<hr />
<p>Firstly, let's look at the individual terms and see what they mean, and how they are used:</p>
<h2 id="heading-constants">Constants</h2>
<p>A "constant" state is a variable that cannot be changed after the contract is compiled.</p>
<pre><code class="lang-solidity"><span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Example</span> </span>{
    <span class="hljs-comment">// An example of a constant </span>
    <span class="hljs-keyword">uint8</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> speedOfSound <span class="hljs-operator">=</span> <span class="hljs-number">343</span>;

    <span class="hljs-comment">// An example of a string variable (not constant)</span>
    <span class="hljs-keyword">string</span> <span class="hljs-keyword">public</span> username <span class="hljs-operator">=</span> <span class="hljs-string">"@CyberDev_D"</span>;
}
</code></pre>
<h2 id="heading-immutable">Immutable</h2>
<p>An "immutable" state variable is set during contract creation and it cannot be changed after the contract has been deployed to the blockchain.</p>
<pre><code class="lang-solidity"><span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Example</span> </span>{

    <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">immutable</span> timeDeployed;

    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-comment">// the timedeployed is set during the contract creation</span>
        timeDeployed <span class="hljs-operator">=</span> <span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span>
    }
}
</code></pre>
<hr />
<p>I originally found it a bit confusing to differentiate between a constant and an immutable, it almost seemed like they were the same thing, but here's an illustration that would help solidify the core differences.</p>
<h1 id="heading-the-differences">The Differences</h1>
<p>To illustrate:</p>
<h3 id="heading-constants-1">Constants</h3>
<p><img src="https://www.cutrateglass.com/wp-content/uploads/2021/12/Window-replacement-Cut-Rate-glass.jpg" alt="Constants are like the rules that can't be changed after they are set" class="image--center mx-auto" /></p>
<p>Imagine you are a builder, and in the community you are assigned to build houses, there is a rule set by the government.</p>
<p>The rule states that <strong><em>"Every room in any house must have two windows"</em></strong>.</p>
<p>This rule is set before the building starts, and it doesn't matter the style of house, or the size of it, as long as it has a room it must have two windows. That's the "constant" that has been set.</p>
<blockquote>
<h3 id="heading-a-constant-is-set-before-the-building-begins">A constant is set before the building begins</h3>
</blockquote>
<h3 id="heading-immutables">Immutables</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698875824327/16d80b28-4dcc-485f-a42a-d13ad8e21024.jpeg" alt class="image--center mx-auto" /></p>
<p>When building (Compiling) starts, imagine the first foundation brick you lay, bearing a unique serial number, that is assigned to it only during construction. When construction is complete (deployed), that serial number becomes permanent.<br />That means it is immutable, it can no longer be changed.</p>
<blockquote>
<h3 id="heading-an-immutable-is-only-set-during-the-building-process">An Immutable is only set during the building process</h3>
</blockquote>
<p>Using the illustrations above you can note that:</p>
<ul>
<li><p>Constants are set before the building starts</p>
</li>
<li><p>Immutables are set only during the building process</p>
</li>
</ul>
<p>It is important to understand this because it can help you save on gas, if you use them the right way.</p>
<p>For instance :</p>
<p><strong>constant' Keyword</strong>: Variables declared with 'constant' are variables that never change after compilation and are hard-coded into the contract. Since these values are constant and do not change, they do not require storage on the blockchain, which would incur additional gas costs. Instead, the value is replaced at compile-time wherever it is referenced in the code. This results in gas savings when interacting with these variables.</p>
<p><strong>'immutable' Keyword</strong>: Immutable variables are assigned a value only once, during the contract's construction, and are stored in the contract’s storage. However, unlike regular state variables, accessing immutable variables is more gas-efficient. This is because the Ethereum Virtual Machine (EVM) replaces references to these variables with their assigned values after the contract is deployed, similar to constant variables. As a result, reading from immutable variables costs less gas compared to reading from regular state variables.</p>
<hr />
<p>Did you learn anything new from this?</p>
<p>If you did,<br />Please share this article and give me a follow <a target="_blank" href="https://twitter.com/cyberdev_d">@CyberDev_d</a></p>
]]></content:encoded></item><item><title><![CDATA[Here's how decorators work in JavaScript (ES6, TypeScript, ...)]]></title><description><![CDATA[Here's how to use decorators in JavaScript
Introduction
Decorators in general are not a fairly new concept, they've been in use in other languages such as python for quite some time, but they just came into the playfield with the Decorator ECMAScript...]]></description><link>https://blog.desmondezoojile.com/heres-how-decorators-work-in-javascript-es6-typescript</link><guid isPermaLink="true">https://blog.desmondezoojile.com/heres-how-decorators-work-in-javascript-es6-typescript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[decorators]]></category><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[Desmond Ezo-Ojile]]></dc:creator><pubDate>Sat, 26 Nov 2022 06:56:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1669445730044/WwABw1BNm.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-heres-how-to-use-decorators-in-javascript">Here's how to use decorators in JavaScript</h1>
<h2 id="heading-introduction">Introduction</h2>
<p>Decorators in general are not a fairly new concept, they've been in use in other languages such as python for quite some time, but they just came into the playfield with the Decorator ECMAScript proposal, which is currently in stage 3 as of this time of writing this article.</p>
<p>In this article, you should understand what decorators are, how to make use of them, and when it might be necessary to make use of them.  </p>
<h2 id="heading-what-are-decorators">What are decorators?</h2>
<p>Decorators are functions called on classes, class elements, or other JavaScript syntax forms during the definition. They are essentially <a target="_blank" href="https://youtu.be/0aKZvNNf8BA">higher-order functions</a>, </p>
<pre><code>  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">double</span>(<span class="hljs-params">Z</span>)</span>{
   <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">single</span>(<span class="hljs-params">y</span>)</span>{
      Return Z(Z(y));
  }
}
</code></pre><p>( a function that either takes another function as an argument and returns a value or a function that returns another function), which are written to extend the functionality of what is being decorated without fundamentally changing its behaviour.</p>
<p>According to the <a target="_blank" href="https://github.com/tc39/proposal-decorators">official ECMASCRIPT proposal for decorators </a> Decorators have three primary capabilities:</p>
<ul>
<li><p>They can replace the value that is being decorated with a matching value that has the same semantics. (e.g. a decorator can replace a method with another method, a field with another field, a class with another class, and so on).</p>
</li>
<li><p>They can provide access to the value that is being decorated via accessor functions which they can then choose to share.</p>
</li>
<li><p>They can initialize the value that is being decorated, running additional code after the value has been fully defined. In cases where the value is a member of class, then initialization occurs once per instance.</p>
</li>
</ul>
<p>Essentially, decorators can be used to metaprogram and add functionality to a value, without fundamentally changing its external behavior.</p>
<h2 id="heading-how-do-they-work">How do they work?</h2>
<h3 id="heading-syntax">Syntax</h3>
<p>There is no special syntax for <strong>defining</strong> decorators, any function can be applied as a decorator.</p>
<p>A <strong>decorator</strong> expression begins with the <code>@</code> and is followed by the name of the decorator. Decorators are called with  <code>()</code> and could receive arguments. Arbitrary expressions could also be used as a decorator using the syntax <code>@(expression)</code>.
Class expressions could be decorated, not just class declarations.
Decorators come after <code>export</code> and <code>default</code> .</p>
<pre><code><span class="hljs-comment">// Decorator  being defined</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Decorator</span> (<span class="hljs-params">value, context</span>)</span>{
  <span class="hljs-keyword">return</span> value.call();
}

<span class="hljs-comment">// decorator expression being used</span>
@Decorator 
randomFunction(){
  <span class="hljs-comment">//Do something</span>
}

<span class="hljs-comment">//or</span>

@Decorator(<span class="hljs-string">"Some Value"</span>)
randomFunction(){
  <span class="hljs-comment">//Do stuff here...</span>
}
</code></pre><p>Decorators begin with the "@" symbol at the very start or top of the function they are trying to decorate. For example, <code>@Decorator</code> above is a decorator that has been declared for the method <code>randomFunction(){}</code>.</p>
<p>Decorators can be applied to four types of values:</p>
<ul>
<li>Classes</li>
<li>Class Fields</li>
<li>Class Methods</li>
<li>Class accessors</li>
</ul>
<p>When decorators are applied, they are evaluated in three steps:</p>
<ol>
<li><p>First the decorator expressions ( the thing after the <code>@</code>) are evaluated interspersed with computed property names. This action flows from the left to the right and from top to bottom. The result of this evaluation is stored in the equivalent of local variables to be later called after the class definition initially finishes executing.</p>
</li>
<li><p>Decorators are called (as functions) during class definition, after the methods have been evaluated but before the constructor and prototype have been put together. For example <code>@superUser</code> decorator could be evaluated to the function </p>
</li>
</ol>
<pre><code><span class="hljs-comment">// @superUser evaluats to  ==&gt; </span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">superUser</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-comment">//do stuff here</span>
}
</code></pre><p>.</p>
<p> When a decorator is called, it receives two parameters;</p>
<blockquote>
<ol>
<li>The value being decorated or <code>undefined</code> when it's a class field being decorated</li>
<li>A context object containing information about the value being decorated</li>
</ol>
</blockquote>
<pre><code><span class="hljs-comment">// JavaScript takes an input and context object</span>
<span class="hljs-keyword">const</span> Decorator = <span class="hljs-function">(<span class="hljs-params">input, context</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> output
}

<span class="hljs-comment">// Using typescript interface for clarity</span>
type Decorator = (value: Input, <span class="hljs-attr">context</span>: {
  <span class="hljs-attr">kind</span>: string;
  name: string | symbol;
  access: {
    get?(): unknown;
    set?(value: unknown): <span class="hljs-keyword">void</span>;
  };
  private?: boolean;
  <span class="hljs-keyword">static</span>?: boolean;
  addInitializer?(initializer: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">void</span>): <span class="hljs-keyword">void</span>;
}) =&gt; Output | <span class="hljs-keyword">void</span>;
</code></pre><p>The values passed in the context object vary according to the type of value being decorated (classes, class methods, class fields, class accessors).</p>
<p>3.)  Decorators are applied (mutating the constructor and prototype) all at once after all of them have been called. First, the newly constructed class is not made available until after all methods and non-static field decorators have been applied, then the class decorator is called only after all methods and field decorators are called and applied. Then finally, all static fields are executed and applied. </p>
<h3 id="heading-decorators-for-class-methods">Decorators for Class Methods</h3>
<pre><code>type ClassMethodDecorator = (value: <span class="hljs-built_in">Function</span>, <span class="hljs-attr">context</span>: {
  <span class="hljs-attr">kind</span>: <span class="hljs-string">"method"</span>;
  name: string | symbol;
  access: { get(): unknown };
  <span class="hljs-keyword">static</span>: boolean;
  private: boolean;
  addInitializer(initializer: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">void</span>): <span class="hljs-keyword">void</span>;
}) =&gt; <span class="hljs-built_in">Function</span> | <span class="hljs-keyword">void</span>;
</code></pre><p><strong>The class method decorator</strong> receives the method that is being decorated as its first value, and can optionally return a new method to replace it. 
If a new method is returned, it will replace the original on the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">prototype</a> or on the class itself in the case of static methods.</p>
<p>For example:</p>
<pre><code>
<span class="hljs-comment">// The @logged decorator receives the original function `m()` and returns </span>
<span class="hljs-comment">// a new function that wraps the original and logs before and after the function is called</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logged</span>(<span class="hljs-params">value, { kind, name }</span>) </span>{
  <span class="hljs-keyword">if</span> (kind === <span class="hljs-string">"method"</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">...args</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`starting <span class="hljs-subst">${name}</span> with arguments <span class="hljs-subst">${args.join(<span class="hljs-string">", "</span>)}</span>`</span>);
      <span class="hljs-keyword">const</span> ret = value.call(<span class="hljs-built_in">this</span>, ...args);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`ending <span class="hljs-subst">${name}</span>`</span>);
      <span class="hljs-keyword">return</span> ret;
    };
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">C</span> </span>{

  <span class="hljs-comment">// Method decorator "logged"</span>
  @logged
  m(arg) {}
}

<span class="hljs-keyword">new</span> C().m(<span class="hljs-number">1</span>);
<span class="hljs-comment">// starting m with arguments 1</span>
<span class="hljs-comment">// ending m</span>
</code></pre><h3 id="heading-decorators-for-class-fields">Decorators for Class fields</h3>
<pre><code>type ClassFieldDecorator = (value: <span class="hljs-literal">undefined</span>, <span class="hljs-attr">context</span>: {
  <span class="hljs-attr">kind</span>: <span class="hljs-string">"field"</span>;
  name: string | symbol;
  access: { get(): unknown, set(value: unknown): <span class="hljs-keyword">void</span> };
  <span class="hljs-keyword">static</span>: boolean;
  private: boolean;
}) =&gt; <span class="hljs-function">(<span class="hljs-params">initialValue: unknown</span>) =&gt;</span> unknown | <span class="hljs-keyword">void</span>;
</code></pre><p>Unlike the method decorator, the class field decorator doesn't have a direct input value when being decorated. Instead, users can optionally return an initializer function which runs when the field is assigned. This will receive the initial value of the field and return a new initial value. If any other type of value besides a function is returned, an error will be thrown.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logged</span>(<span class="hljs-params">value, { kind, name }</span>) </span>{
  <span class="hljs-keyword">if</span> (kind === <span class="hljs-string">"field"</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">initialValue</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`initializing <span class="hljs-subst">${name}</span> with value <span class="hljs-subst">${initialValue}</span>`</span>);
      <span class="hljs-keyword">return</span> initialValue;
    };
  }

  <span class="hljs-comment">// ...</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">C</span> </span>{
  @logged x = <span class="hljs-number">1</span>;
}

<span class="hljs-keyword">new</span> C();
<span class="hljs-comment">// initializing x with value 1</span>
</code></pre><p>It's also worthy to note that since class fields already return an <code>initializer</code> , they do not receive <code>addInitializer</code> and cannot add additional initialization logic.</p>
<h3 id="heading-decorators-for-classes">Decorators for Classes</h3>
<pre><code>type ClassDecorator = (value: <span class="hljs-built_in">Function</span>, <span class="hljs-attr">context</span>: {
  <span class="hljs-attr">kind</span>: <span class="hljs-string">"class"</span>;
  name: string | <span class="hljs-literal">undefined</span>;
  addInitializer(initializer: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">void</span>): <span class="hljs-keyword">void</span>;
}) =&gt; <span class="hljs-built_in">Function</span> | <span class="hljs-keyword">void</span>;
</code></pre><p>Class decorators receives the class that is being decorated as a the first parameter and then returns a callable ( a function, a class or a Proxy) to replace the original class. If a non callable is returned an error will be thrown.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logged</span>(<span class="hljs-params">value, { kind, name }</span>) </span>{
  <span class="hljs-keyword">if</span> (kind === <span class="hljs-string">"class"</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">value</span> </span>{
      <span class="hljs-keyword">constructor</span>(...args) {
        <span class="hljs-built_in">super</span>(...args);
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`constructing an instance of <span class="hljs-subst">${name}</span> with arguments <span class="hljs-subst">${args. join(<span class="hljs-string">", "</span>)}</span>`</span>);
      }
    }
  }

  <span class="hljs-comment">// ...</span>
}

@logged
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">C</span> </span>{}

<span class="hljs-keyword">new</span> C(<span class="hljs-number">1</span>);
<span class="hljs-comment">// constructing an instance of C with arguments 1</span>
</code></pre><h2 id="heading-heres-how-to-use-decorators-in-your-next-project">Here's how to use Decorators in your next project</h2>
<h3 id="heading-javascript">JavaScript</h3>
<p>Decorators haven't been natively added into JavaScript, and it's still in stage 3 of the 4 staged approval process. Therefore to use decorators in our project we need to set up a transpiler such as <a target="_blank" href="https://babeljs.io/">babel</a>. </p>
<p>Here's a plugin for decorators in barbel
https://babeljs.io/docs/en/babel-plugin-proposal-decorators</p>
<h3 id="heading-typescript">Typescript</h3>
<p>If you are using Typescript you first need to enable the experimental Decorators compiler option either on the command line or in your tsconfig.json to properly use decorators:</p>
<p><strong>Command Line:</strong></p>
<p><code>to --target ES5 --experimentalDecorators</code></p>
<p><strong>tsconfig.json:</strong></p>
<pre><code class="lang-{">  "compiler options": {
    "target": "ES5",
    "experimentalDecorators": true
  }
}
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://giphy.com/gifs/RosannaPansino-decorations-decorate-its-time-YnkUjb6KufcyazTOWO">https://giphy.com/gifs/RosannaPansino-decorations-decorate-its-time-YnkUjb6KufcyazTOWO"</a></div>
]]></content:encoded></item><item><title><![CDATA[How to set up your first Nest.js project]]></title><description><![CDATA[Nest.Js is a progressive Node.Js framework used for building efficient, reliable, and scalable server-side applications. Nest.js- under the hood provides an abstraction for the Express/Fastify frameworks, providing you with an architecture you wouldn...]]></description><link>https://blog.desmondezoojile.com/how-to-set-up-your-first-nestjs-project</link><guid isPermaLink="true">https://blog.desmondezoojile.com/how-to-set-up-your-first-nestjs-project</guid><category><![CDATA[nestjs]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[cli]]></category><dc:creator><![CDATA[Desmond Ezo-Ojile]]></dc:creator><pubDate>Sat, 05 Nov 2022 01:30:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1667517642419/_YBxUJYVX.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Nest.Js is a progressive Node.Js framework used for building efficient, reliable, and scalable server-side applications. Nest.js- under the hood provides an abstraction for the <a target="_blank" href="https://expressjs.com/">Express</a>/<a target="_blank" href="https://www.fastify.io/">Fastify</a> frameworks, providing you with an architecture you wouldn't find in the express framework.  <a target="_blank" href="https://nestjs.com/">Nest.Js</a> is not to be confused with <a target="_blank" href="https://nextjs.org/">Next.Js</a> which is a frontend react framework for production. If you are interested in learning how to set up a Next.Js project you can read this article here.</p>
<p>Let's get you started..</p>
<p>So you've finally decided to go with nest.js and you intend to set up your first project, in order to do that here's what you need:</p>
<ul>
<li><p>Node.js latest version</p>
</li>
<li><p>Nest.Js CLI</p>
</li>
</ul>
<blockquote>
<p>To install the Nest.js CLI  use this command: <code>$ npm i -g @nestjs/cli</code></p>
</blockquote>
<p>Once you have installed the above requirements, you now have the opportunity to use the Nest.Js CLI, with this you can scaffold a new Nest.Js project with just a single command  <code>Nest new  [New project name]</code>.</p>
<p>Here's how to do it.</p>
<p><strong>Step 1</strong></p>
<p>Open your terminal in the directory you want your project to be stored in.
For example, the screenshot below shows mine open in a directory named " learn_nestjs_with_apis ".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667610152239/pFveLUyRI.png" alt="Open terminal in dir.png" /></p>
<p><strong>Step 2</strong></p>
<p>Type the following command into your terminal 
<code>Nest new  [New project name]</code> replace  <strong>[New project name]</strong> with the name of your new project like the screenshot below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667590857476/DJuXcE2xV.png" alt="instllnest.png" /></p>
<p><strong>Step 3</strong></p>
<p>Pick your preferred package manager.
I'd pick NPM for this article, as seen in the screenshot below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667609722818/aRD_Redvl.png" alt="pickapackagemanager.png" /></p>
<p>allow packages to install</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667609763328/KO0G-mxgO.png" alt="installprogressnpmnest.png" /></p>
<p>once that is done you should see this in your terminal </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667609816165/lt8IqB_gb.png" alt="installcompletenestjsproject.png" /></p>
<p>One last thing!
You need to verify your folder structure to ensure the installation was correct, take a look at the folder structure below, that's what yours should look like.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667609954822/10kYUEmWs.png" alt="Nestjs folder structure.png" /></p>
<p>Then finally you can start your project by running this command 
<code>npm  run start:dev</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667636188951/rH5eQlUdF.png" alt="projectstartnest.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667636206222/z4OYceSM0.png" alt="started.png" /></p>
<p><strong>Congratulations</strong>! you've successfully set up your first Nest.js project!</p>
<p>Thank you for reading, please do follow for more articles</p>
]]></content:encoded></item></channel></rss>