<?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: Luis F. Patrocinio</title>
    <description>The latest articles on DEV Community by Luis F. Patrocinio (@patrocinioluisf).</description>
    <link>https://dev.to/patrocinioluisf</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%2F510587%2F421e136f-38e9-44a2-8eac-d212421d76b6.png</url>
      <title>DEV Community: Luis F. Patrocinio</title>
      <link>https://dev.to/patrocinioluisf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/patrocinioluisf"/>
    <language>en</language>
    <item>
      <title>Diving into Doxygen: Documenting for Devs, Teammates, and AIs</title>
      <dc:creator>Luis F. Patrocinio</dc:creator>
      <pubDate>Sat, 14 Mar 2026 16:48:02 +0000</pubDate>
      <link>https://dev.to/patrocinioluisf/diving-into-doxygen-documenting-for-devs-teammates-and-ais-1d59</link>
      <guid>https://dev.to/patrocinioluisf/diving-into-doxygen-documenting-for-devs-teammates-and-ais-1d59</guid>
      <description>&lt;p&gt;Ah, code documentation. That one thing we all love when we need it, but when it's time to actually write it... it can be a drag, right?&lt;/p&gt;

&lt;p&gt;If you've ever worked on a team, you know how crucial good documentation is. It avoids the classic "hey, how do I use this function of yours?" and makes onboarding a new dev a much less painful experience. But what about when it's a solo project? Trust me, your "future self" will be immensely grateful for not having to decipher code that you wrote six months ago.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmyr640aj5stfn545z5c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmyr640aj5stfn545z5c.gif" alt="Homer trying to decipher your code" width="498" height="276"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A quick note before we dive in:&lt;/strong&gt; I originally drafted this post a few months ago, and in that short time, the world of coding has been completely shaken up by AI assistants. You might think that with tools like Copilot writing code for us, old-school practices like documentation are becoming obsolete. But I've found it's exactly the opposite. These fundamentals are now &lt;em&gt;more&lt;/em&gt; important than ever. Think of it this way: good documentation is what trains your AI assistant to be a useful partner, not just a random code generator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0acewyal1x9lbf6gi48x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0acewyal1x9lbf6gi48x.png" alt="Its Dangerous to Walk Alone" width="466" height="333"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;As &lt;a href="https://en.wikipedia.org/wiki/Hal_Abelson" rel="noopener noreferrer"&gt;Harold Abelson&lt;/a&gt; once said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Programs must be written for people to read, and only incidentally for machines to execute."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's the absolute truth. But lately, that quote has gotten a modern upgrade. Today, besides your team and your future self, there's a new "reader" for your code: &lt;strong&gt;Artificial Intelligence&lt;/strong&gt;. Tools like Copilot and other generative AIs have become our new, omnipresent interns, and well-documented code is what guides them to provide truly useful suggestions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn7eh4k4tlzd1lks1x308.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn7eh4k4tlzd1lks1x308.png" alt="oh wait, it was me" width="779" height="784"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The Philosophy: Why Bother? The Classic Benefits (and the New AI Bonus)
&lt;/h3&gt;

&lt;p&gt;When I think about code structure, the &lt;strong&gt;K.I.S.S.&lt;/strong&gt; principle (&lt;em&gt;Keep It Simple, Stupid!&lt;/em&gt;), a concept I've recently come to appreciate, always comes to mind. Code that is direct, predictable, and has clearly defined responsibilities isn't just more elegant; it's infinitely easier to maintain and, of course, to document.&lt;/p&gt;

&lt;p&gt;In my opinion, this is even more valuable in game development. Imagine a single function that handles collision, applies damage, updates the UI, and plays a sound, all at once. That's a nightmare to maintain. It quickly becomes a house of cards, with everything tangled and dependent on everything else.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6s54c77gw9q20naikunj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6s54c77gw9q20naikunj.gif" alt="A huge house of cards" width="430" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Combining simple code with a great documentation tool like Doxygen offers incredible advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  📑 &lt;strong&gt;It standardizes your documentation:&lt;/strong&gt; Creates a consistent pattern that the entire team (and AIs) can follow.&lt;/li&gt;
&lt;li&gt;  🤝 &lt;strong&gt;It makes collaboration easier:&lt;/strong&gt; Reduces the need to ask obvious questions and speeds up development.&lt;/li&gt;
&lt;li&gt;  🤖 &lt;strong&gt;It supercharges your AI:&lt;/strong&gt; Clear comments and tags (&lt;code&gt;@param&lt;/code&gt;, &lt;code&gt;@return&lt;/code&gt;) are fuel for AIs. They use these "magic words" to understand the &lt;em&gt;intent&lt;/em&gt; of your code and generate much more intelligent and accurate suggestions.&lt;/li&gt;
&lt;li&gt;  🛠️ &lt;strong&gt;It generates professional output:&lt;/strong&gt; Automatically transforms your comments into a navigable HTML website or a PDF.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yeah, I also think it's a bit sci-fi to be writing for an AI, but it's our new, and increasingly real, reality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flw7n45d1ehwcnvm62e94.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flw7n45d1ehwcnvm62e94.gif" alt="Work, Robot" width="235" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We let the AI handle the boring and heavy work while we enjoy a little time travel.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Doxygen: The Magic of Turning Comments into Docs
&lt;/h3&gt;

&lt;p&gt;Doxygen generates documentation from comments you write directly in your code. While it's a powerhouse in the C/C++ world, it also supports many other languages.&lt;/p&gt;

&lt;p&gt;The "magic" happens with special comment blocks. Check out this C++ example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @brief Calculates the final damage to be applied to a target.
 *
 * It takes the target's defense and the possibility of a critical hit into account.
 *
 * @param baseDamage The base damage of the weapon or skill.
 * @param targetDefense The target's defense value.
 * @param isCritical A boolean indicating if the hit was critical.
 * @return The final calculated damage.
 */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;CalculateDamage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;baseDamage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;targetDefense&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isCritical&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commands like &lt;code&gt;@brief&lt;/code&gt;, &lt;code&gt;@param&lt;/code&gt;, and &lt;code&gt;@return&lt;/code&gt; are "tags" that Doxygen understands and uses to structure the documentation.&lt;/p&gt;




&lt;h3&gt;
  
  
  Getting Your Hands Dirty: Your First Steps
&lt;/h3&gt;

&lt;p&gt;Want to get started? Using Doxygen from the command line is pretty simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Generate the config file:&lt;/strong&gt; In your terminal, navigate to your project's folder and run &lt;code&gt;doxygen -g&lt;/code&gt;. This will create a configuration file named &lt;code&gt;Doxyfile&lt;/code&gt;, which contains tons of customizable options to define how you want your documentation to look.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Generate the documentation:&lt;/strong&gt; After tweaking the &lt;code&gt;Doxyfile&lt;/code&gt; (at least to point to your source code folder and an output folder), just run &lt;code&gt;doxygen Doxyfile&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's it! A folder containing a navigable HTML site of your documentation will be created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfmtvct02bbpgj7uo4sf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfmtvct02bbpgj7uo4sf.gif" alt="Synthetic Doxyfile" width="600" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Doxyfile configuration file generated with &lt;code&gt;doxygen -s -g&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you don't like the idea of editing the huge (and intimidating) &lt;code&gt;Doxyfile&lt;/code&gt; by hand, there's also &lt;strong&gt;DoxyWizard&lt;/strong&gt;, a graphical user interface that makes the configuration process much easier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ro7xnrhqel0wepehdb6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ro7xnrhqel0wepehdb6.png" alt="DoxyWizard UI" width="800" height="658"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Not Just for C++: Documentation in the Game Dev World
&lt;/h3&gt;

&lt;p&gt;This philosophy of in-code documentation isn't exclusive to Doxygen. Our favorite game engines already have built-in mechanisms for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In &lt;strong&gt;GameMaker&lt;/strong&gt;, the community widely uses the &lt;strong&gt;JSDoc&lt;/strong&gt; standard. By using tags like &lt;code&gt;@description&lt;/code&gt; and &lt;code&gt;@param&lt;/code&gt;, you can create tooltips and other useful info that pops up right in the IDE when you hover over a function. &lt;a href="https://manual.gamemaker.io/lts/en/The_Asset_Editors/Code_Editor_Properties/JSDoc_Script_Comments.htm" rel="noopener noreferrer"&gt;Link to GameMaker Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sepzef667cqq1wjowo0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sepzef667cqq1wjowo0.png" alt="GameMaker Code Example" width="475" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmcwh8r7q5kgmkuwjqsip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmcwh8r7q5kgmkuwjqsip.png" alt="GameMaker Code Documentation" width="475" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In &lt;strong&gt;Godot&lt;/strong&gt;, it's even more integrated. GDScript comments starting with &lt;code&gt;##&lt;/code&gt; are treated as documentation and are displayed in the editor's help panel. They even support BBCode for formatting, like &lt;code&gt;[b]&lt;/code&gt; for bold and &lt;code&gt;[codeblock]&lt;/code&gt; for code examples. &lt;a href="https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_documentation_comments.html" rel="noopener noreferrer"&gt;Link to Godot Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6araadoi4jxz9a7zfgu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6araadoi4jxz9a7zfgu.png" alt="Godot Code Example" width="475" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2xj652z7tnk3xxewqox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2xj652z7tnk3xxewqox.png" alt="Godot Function Example Documentation" width="475" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This just goes to show that, no matter the tool, the practice is universally powerful.&lt;/p&gt;




&lt;h3&gt;
  
  
  So, What Now?
&lt;/h3&gt;

&lt;p&gt;Documenting your code doesn't have to be a headache. With the right tools and a bit of discipline, we can turn a tedious task into a valuable investment for the future of our projects—whether it's for our team, our future selves, or even the AI that's helping us code.&lt;/p&gt;

&lt;p&gt;I'm currently exploring the best way to integrate Doxygen-generated documentation with GitHub Pages to make it all accessible online automatically. Once I have a solid workflow, I promise I'll be back with a new post to share the details. 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9j5h980jk2ecbyxcj3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9j5h980jk2ecbyxcj3s.png" alt="Google-Searching Doxygen Good Examples" width="475" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Until then, why not take a look at your own projects and see where a little documentation could make a big difference? I'm always looking to improve my workflow, especially with AI, so if you've found a better way to do this, let me know over on [&lt;a href="https://www.linkedin.com/in/luisfpatrocinio/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;/&lt;a href="https://x.com/patrocinioluisf" rel="noopener noreferrer"&gt;X&lt;/a&gt;]! I'd love to learn from your experience. 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdrsv7qw9jv6q61awfi2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdrsv7qw9jv6q61awfi2.gif" alt="Mario entering pipe" width="414" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gamedev</category>
      <category>documentation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Taming Tedious Tasks with a Tiny Titan: The ESP32 Auto-Controller</title>
      <dc:creator>Luis F. Patrocinio</dc:creator>
      <pubDate>Mon, 17 Nov 2025 12:38:18 +0000</pubDate>
      <link>https://dev.to/patrocinioluisf/taming-tedious-tasks-with-a-tiny-titan-the-esp32-auto-controller-27pp</link>
      <guid>https://dev.to/patrocinioluisf/taming-tedious-tasks-with-a-tiny-titan-the-esp32-auto-controller-27pp</guid>
      <description>&lt;p&gt;Hey, dev community! Patrocinio here. I'm back after a productive few months of focused learning.&lt;/p&gt;

&lt;p&gt;I've got a lot of new projects and insights ready to go, and I can't wait to share them. Let's jump right in. As someone who lives and breathes the gamedev universe, and while studying the fascinating world of embedded systems, I've always asked myself: how can I merge these two worlds?&lt;/p&gt;

&lt;p&gt;The other day, while playing the incredible Pokémon Red, I stumbled upon a wild challenge: you need 9,999 coins to buy Porygon! And the biggest jackpot in the casino, if you're incredibly lucky, is just 300 coins. I realized that to beat this challenge, the process could be boiled down to a single action: mashing the 'A' button forever. Eventually, the coins would come. My inner engineer immediately screamed, "Why not build a joystick to do that for me?".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1j2lwcfr18u7rd9j1w4v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1j2lwcfr18u7rd9j1w4v.png" alt="Porygon is insanely expensive on Game Corner" width="457" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Just a side note: this mindset is mentioned in the book "A Theory of Fun for Game Design", which talks about how players, by nature, tend to optimize the fun out of games, often looking for the easiest path to victory. It's like we're programmed to "cheat", dominating a pattern. Our brain wants to solve the problem!)&lt;/p&gt;

&lt;p&gt;And so, the uncontrollable urge to create the &lt;strong&gt;PatroAutoController&lt;/strong&gt; was born. I want to share the key lessons from this quest with you.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Armory: Our Forging Tools
&lt;/h3&gt;

&lt;p&gt;For this endeavor, our "loadout" was carefully chosen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  🧠 &lt;strong&gt;The Brain (ESP32):&lt;/strong&gt; A powerful microcontroller with built-in Wi-Fi and Bluetooth. It's our brainy, brawny hero.&lt;/li&gt;
&lt;li&gt;  🕸️ &lt;strong&gt;The Nervous System (FreeRTOS):&lt;/strong&gt; Instead of a giant, confusing &lt;code&gt;loop()&lt;/code&gt;, we used a real-time operating system. This lets us have "mini-brains" (tasks) running in parallel.&lt;/li&gt;
&lt;li&gt;  🛠️ &lt;strong&gt;The Workbench (PlatformIO):&lt;/strong&gt; Using PlatformIO in VS Code is like having a perfectly organized workshop. It manages our libraries, compilation, and uploads.&lt;/li&gt;
&lt;li&gt;  📜 &lt;strong&gt;The Magic Scroll (ESP32-BLE-Gamepad Library):&lt;/strong&gt; This incredible library does all the heavy lifting to turn our ESP32 into a Human Interface Device (HID).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fss1smq9vzmk0zm5cf5zr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fss1smq9vzmk0zm5cf5zr.png" alt="PatroAutoController Assembled" width="620" height="410"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The Build, Level by Level
&lt;/h3&gt;

&lt;p&gt;Building robust software is like forging a sword: each layer adds strength and functionality. But as challenges grow, you don't just need a sword. You start building an arm cannon, a blaster that can fire powerful shots to take down the toughest bosses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs3882qbitkvj9hwcj1c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs3882qbitkvj9hwcj1c.gif" alt="Ice beam to defeat it!" width="460" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  💠Level 1: The Modular and Scalable Architecture
&lt;/h4&gt;

&lt;p&gt;From the very beginning, the goal was clear: the project had to be modular and scalable. I knew this small idea could grow, so I built a solid foundation that would allow for easy expansion and modification in the future. Instead of one giant &lt;code&gt;main.cpp&lt;/code&gt;, we separated the responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;config.h&lt;/code&gt;: Where all the "magic numbers" (pins, delays) live.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;HardwareIO.cpp&lt;/code&gt;: An abstraction layer for the hardware, with functions like &lt;code&gt;io_read_potentiometer()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;JoystickController.cpp&lt;/code&gt;: Where all the Bluetooth logic resides.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;A good architecture is what separates a prototype from a product. It saves us from the spaghetti code monster! It's worth the effort!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  💠Level 2: Mastering the Analog World
&lt;/h4&gt;

&lt;p&gt;This project was also an excuse to explore the potentiometer better. As an analog component, it offers incredibly fine-grained control. All I had to do was adjust the &lt;em&gt;range&lt;/em&gt; in the code to set the speed limits. It was a great opportunity to understand how it works in practice: it acts as a variable resistor, controlling the resistance applied to the current. By turning it, we change the voltage that the ESP32's analog pin reads, giving us a continuous spectrum of values to work with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojoq18wqsauprkslkcsc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojoq18wqsauprkslkcsc.gif" alt="How potentiometer works" width="600" height="624"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inside our task_read_potentiometer...&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;task_read_potentiometer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pvParameters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rawValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;io_read_potentiometer_raw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// We map the ADC value (0-4095) to our desired delay&lt;/span&gt;
    &lt;span class="n"&gt;joystick_delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4095&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIN_DELAY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAX_DELAY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;vTaskDelay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdMS_TO_TICKS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Pause without blocking!&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A quick note: Ever wonder why the ADC value goes from 0 to 4095 specifically? It's because the &lt;strong&gt;ESP32's ADC Resolution is 12-bit&lt;/strong&gt;. That means the number of distinct values it can produce occupies 12 bits. 2¹² = 4096 possible levels.&lt;/p&gt;

&lt;h4&gt;
  
  
  💠Level 2.5: The Unexpected (and Happy) Detour
&lt;/h4&gt;

&lt;p&gt;Initially, I planned to build a USB controller. However, I ran into a crucial hardware limitation: the standard ESP32 I was using doesn't have a native USB controller (OTG). Its USB port is only for programming and serial communication. For a USB controller, I'd need an ESP32-S2 or S3.&lt;/p&gt;

&lt;p&gt;However, this closed door opened another path. This "obstacle" forced me to look at the ESP32's other great feature: Bluetooth. And what a great call that was! The implementation was surprisingly smooth, and the final result was a wireless controller, which, let's be honest, is infinitely cooler.&lt;/p&gt;

&lt;h4&gt;
  
  
  It Looks Like Magic, but It's Technology: How the ESP32 Becomes a Joystick
&lt;/h4&gt;

&lt;p&gt;Okay, but how does this "transformation" happen? How does a simple microcontroller convince a computer or phone that it's a joystick? It's not magic. It's a very clever protocol.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhdrj1kkkmc77uv9etn4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhdrj1kkkmc77uv9etn4.gif" alt="Spongebob and Patrick seeing Techonology" width="500" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a Bluetooth device connects to a computer, it's not a casual meeting. It's more like a job interview. The device has to introduce itself and state exactly what its skills are.&lt;/p&gt;

&lt;p&gt;This is where an incredible feature of Bluetooth (and USB) comes in: the &lt;strong&gt;HID Profile (Human Interface Device)&lt;/strong&gt;. Think of profiles as job titles: a headset uses the audio profile, and a controller uses the HID profile. It's a universal language for mice, keyboards, and, of course, joysticks.&lt;/p&gt;

&lt;p&gt;What the &lt;code&gt;ESP32-BLE-Gamepad&lt;/code&gt; library does behind the scenes is handle this entire "negotiation":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Advertisement:&lt;/strong&gt; The ESP32 starts broadcasting via Bluetooth: "Hello! I'm not just any device, I'm an HID Gamepad!" Your phone or PC sees this ad and already knows how to talk to it.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Contract (Report Descriptor):&lt;/strong&gt; Once the connection starts, the ESP32 sends a detailed "map" to the computer. This map says, in a standardized format, "I have 16 buttons, 2 analog sticks (X/Y axes), a D-pad, etc". The operating system reads this map and creates the virtual joystick device.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhp1wa6pzlqdvtt9po6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhp1wa6pzlqdvtt9po6q.png" alt="ESP32 robot interview" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, our code just needs to send tiny data packets like "Button 2 was pressed". The crucial point is that all this communication must be assembled bit by bit, following strict protocol specifications. &lt;strong&gt;This all needs to be written in low-level, almost machine-level programming. And thankfully, the &lt;code&gt;ESP32-BLE-Gamepad&lt;/code&gt; library handles all of this for us.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It does all the complex byte manipulation behind the scenes, giving us clean, simple functions like &lt;code&gt;joystick_press_button(2)&lt;/code&gt;. In the end, our "magic" as programmers is knowing how to choose and use the right tools that let us focus on our game's logic, not the bureaucracy of protocols.&lt;/p&gt;

&lt;h4&gt;
  
  
  💠Level 3: Unleashing the Bluetooth Magic
&lt;/h4&gt;

&lt;p&gt;With the decision to use BLE, the next FreeRTOS task became the heart of the project. This is the code for the task responsible for pressing the button "infinitely". It's a loop that will run in parallel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inside our task_joystick_press...&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;task_joystick_press&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pvParameters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joystick_is_connected&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;io_blink_led&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Visual Feedback&lt;/span&gt;
      &lt;span class="n"&gt;joystick_press_button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Press Button 2&lt;/span&gt;
      &lt;span class="n"&gt;joystick_release_button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Release immediately&lt;/span&gt;
      &lt;span class="n"&gt;vTaskDelay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdMS_TO_TICKS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joystick_delay&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Wait for the time set by the potentiometer&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;vTaskDelay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdMS_TO_TICKS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Waiting for connection&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The beauty of FreeRTOS shines here: while this task is "sleeping" in &lt;code&gt;vTaskDelay&lt;/code&gt;, the potentiometer task is free to run and update the speed. No blocking, maximum responsiveness!&lt;/p&gt;




&lt;h3&gt;
  
  
  Victory! The Final Result
&lt;/h3&gt;

&lt;p&gt;After defeating a few mini-bosses (like blocked pins and library dependencies), the moment of truth arrived. I powered on the ESP32. On my phone, a new Bluetooth device appeared: &lt;strong&gt;"PatroAutoController"&lt;/strong&gt;. I connected. I opened an emulator. And there it was, my character in the Game Corner, automatically racking up coins. I turned the potentiometer, and the speed changed instantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61a6xlv8y78ouwbjeokw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61a6xlv8y78ouwbjeokw.gif" alt="Pokemon Red - Mastering the Game Corner" width="470" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The feeling of solving a real in-game problem with hardware you built and programmed yourself... it's simply indescribable. And this freedom is achieved through a lot of study and practice!&lt;/p&gt;

&lt;p&gt;You can check out all the code, the structure, and the full documentation in the GitHub repository!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/luisfpatrocinio/esp32-PatroAutoController" rel="noopener noreferrer"&gt;PatroAutoController GitHub Repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Next Level: What's to Come?
&lt;/h3&gt;

&lt;p&gt;This project is proof that a simple idea can become a delightful learning journey. And now, with this modular foundation, the possibilities are endless. An accelerometer-based controller? A web interface for configuration? Who knows?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuirga3ll07cme02m8twx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuirga3ll07cme02m8twx.png" alt="Porygon finally obtained" width="456" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What we do know is that the knowledge we've gained will let us move on to bigger and better things. This is purely the &lt;strong&gt;Mega Man Method™️!&lt;/strong&gt; I hope this story has inspired you to cross the borders between your own passions. We can grab a microcontroller, have a crazy idea, and start building!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8k8ptxnmas96iuvbmty.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8k8ptxnmas96iuvbmty.gif" alt="Porygon ultra mega happy" width="220" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Until next time, and let's keep leveling up our skills!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>cpp</category>
      <category>iot</category>
      <category>esp32</category>
    </item>
    <item>
      <title>Maximizing Memory Management: Object Pooling in Games</title>
      <dc:creator>Luis F. Patrocinio</dc:creator>
      <pubDate>Mon, 28 Apr 2025 04:18:27 +0000</pubDate>
      <link>https://dev.to/patrocinioluisf/maximizing-memory-management-object-pooling-in-games-6bg</link>
      <guid>https://dev.to/patrocinioluisf/maximizing-memory-management-object-pooling-in-games-6bg</guid>
      <description>&lt;p&gt;As I shared in my &lt;a href="https://dev.to/patrocinioluisf/patro-powered-by-passion-games-systems-and-infinite-learning-52f1"&gt;first post&lt;/a&gt;, I started programming games without much ambition -- I just wanted to have fun with my friends. Back then, I didn't really think about what was happening behind the scenes, especially when it came to &lt;strong&gt;memory management&lt;/strong&gt; or &lt;strong&gt;performance&lt;/strong&gt;. I just wanted to make little games, and that was it!&lt;/p&gt;

&lt;p&gt;However, as I dove deeper, studying programming more seriously and working professionally, I learned that &lt;strong&gt;creating and destroying objects all the time comes at a cost&lt;/strong&gt;. And this becomes crucial when porting games to consoles or when we need to ensure a game runs well on more limited systems.&lt;/p&gt;

&lt;p&gt;In any case, in real-time applications like games -- and even more so in embedded systems -- &lt;strong&gt;efficient memory management is ESSENTIAL&lt;/strong&gt;. That’s when I discovered the concept of &lt;strong&gt;Object Pooling&lt;/strong&gt;. I remember that some veteran friends had mentioned it before, but I completely ignored it at the time.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Object Pooling?
&lt;/h2&gt;

&lt;p&gt;Instead of creating and destroying objects during gameplay (which consumes processing power and constantly allocates/deallocates memory), Object Pooling is a technique where you &lt;strong&gt;pre-create a set of objects and reuse them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you need an object, you take an available one from the pool.&lt;br&gt;
When you're done using it, you reset it and return it to the pool for future use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qys9h8v2lhzq6vea4e9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qys9h8v2lhzq6vea4e9.png" alt="Bullet shooting projectiles" width="464" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This avoids costly operations like memory allocation and garbage collection, making your game much faster and more stable -- especially in situations with lots of projectiles, enemies, effects, or particles.&lt;/p&gt;

&lt;p&gt;Notice in the GIF below that our friend Megaman X can only fire up to three bullets at a time. This is a classic example of object pooling: each projectile is kept "off-screen" in a pool of three, deactivated and waiting for the player to fire.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt05xv05r59zaco7yvog.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt05xv05r59zaco7yvog.gif" alt="Megaman Method!" width="440" height="240"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Why is Object Pooling so important?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance Boost&lt;/strong&gt;: Reduces CPU and memory usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Prevents random frame drops or micro-freezes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control&lt;/strong&gt;: You know exactly how many objects exist at any moment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Helps your game handle large numbers of simultaneous objects better.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even with today’s powerful consoles, we can’t go overboard with objects being constantly created and destroyed. And in embedded systems, where resources are extremely limited, techniques like object pooling aren't just good practices -- they’re necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3estmv68h62zw2wy9l5h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3estmv68h62zw2wy9l5h.gif" alt="CPU Heat" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Is it really necessary to implement Object Pooling?
&lt;/h2&gt;

&lt;p&gt;A common question -- especially for those using modern engines like GameMaker, Godot, Unity, or Unreal -- is: &lt;strong&gt;"If there’s already automatic Garbage Collection, do I still need to worry about this?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’ve asked myself that same question before. The answer is: it depends on your project. 😅&lt;/p&gt;

&lt;p&gt;For small games or scenes that don’t frequently instantiate/destroy objects, the engine's garbage collector can handle everything without noticeable issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31ausujc86crh3tub30k.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31ausujc86crh3tub30k.gif" alt="Devil Engine Gameplay" width="400" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, in games that involve a high volume of rapid instances (for example: shooters, hack-and-slash, bullet hells, or intense particle systems), constant creation and destruction will cause &lt;em&gt;overhead&lt;/em&gt; -- and at that point, even the garbage collector won’t prevent performance drops.&lt;/p&gt;

&lt;p&gt;In those cases, implementing Object Pooling manually can make a huge difference in keeping your game &lt;strong&gt;smooth and responsive&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Simple Example of Object Pooling
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Imagine a simple projectile pool:&lt;/strong&gt; At the start of the game, you create 100 projectiles and keep them deactivated.&lt;/p&gt;

&lt;p&gt;When the player shoots, you activate an available projectile from the pool instead of creating a new one. When the projectile hits something or leaves the screen, you deactivate it and return it to the pool.&lt;/p&gt;

&lt;p&gt;Here's a basic pseudocode example. I initially started writing an example in C, but it was getting way too big, so I decided to simplify it with this small block of pseudocode instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pool = createProjectilePool(size=100)

function shoot():
    projectile = pool.getAvailableProjectile()
    if projectile != null:
        projectile.activate(position, direction)

function onProjectileDestroyed(projectile):
    projectile.deactivate()
    pool.returnProjectile(projectile)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the shooting function fetches a reference to an available projectile (with an inactive status) and activates it, repositioning it accordingly.&lt;/p&gt;

&lt;p&gt;When a projectile is destroyed, we simply change its status flag back to deactivated. A deactivated projectile isn't rendered or processed, saving a lot of resources.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The truth is, many modern game development tools already have very efficient &lt;strong&gt;garbage collection mechanisms&lt;/strong&gt;, which can often give the impression that object pooling is obscure or unnecessary -- but it's important to note this is only how it seems!&lt;/p&gt;

&lt;p&gt;However, when developing games for limited systems -- like a small game running on a microcontroller -- every byte of memory matters, and object pooling becomes absolutely essential.&lt;br&gt;
Not to mention that it’s a way to &lt;strong&gt;build faster&lt;/strong&gt;, &lt;strong&gt;more stable&lt;/strong&gt;, and &lt;strong&gt;more optimized games&lt;/strong&gt; overall.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6b2flunkn6ttyr1q07y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6b2flunkn6ttyr1q07y.gif" alt="Image description" width="384" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, if you're just starting your journey in game development, don’t worry if these optimizations seem complex right now. With time and practice, they'll become &lt;strong&gt;natural&lt;/strong&gt;, an effortless habit.&lt;/p&gt;

&lt;p&gt;And if you've already mastered the basics, learning and implementing techniques like &lt;strong&gt;Object Pooling&lt;/strong&gt; is an incredible next step to take your projects to the next level!&lt;/p&gt;

&lt;p&gt;Thanks for reading, and I hope this little knowledge drop was helpful to you!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>optimization</category>
      <category>programming</category>
      <category>memory</category>
    </item>
    <item>
      <title>Wired with WebSockets: Experiments in Real-Time Multiplayer Communication</title>
      <dc:creator>Luis F. Patrocinio</dc:creator>
      <pubDate>Sun, 20 Apr 2025 19:01:25 +0000</pubDate>
      <link>https://dev.to/patrocinioluisf/wired-with-websockets-experiments-in-real-time-multiplayer-communication-2k8</link>
      <guid>https://dev.to/patrocinioluisf/wired-with-websockets-experiments-in-real-time-multiplayer-communication-2k8</guid>
      <description>&lt;p&gt;One of the coolest things I’ve learned on my journey as a developer was understanding &lt;strong&gt;how real-time communication works in games&lt;/strong&gt;. For a long time, it felt distant, complicated, and really hard to understand.&lt;/p&gt;

&lt;p&gt;But that started to change when I joined the &lt;strong&gt;Systems Analysis and Development&lt;/strong&gt; graduation course at &lt;strong&gt;IFPI&lt;/strong&gt;. Throughout the classes and projects, I began to understand how everything works and started seeing &lt;strong&gt;WebSockets&lt;/strong&gt; differently -- as an accessible, powerful, and incredibly fun tool to work with.&lt;/p&gt;

&lt;p&gt;In this post, I want to walk you through that journey in a simple and practical way, starting from the basics and showing how we can implement this kind of communication in games or other real-world applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9g3rj6axeaf153axbzjz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9g3rj6axeaf153axbzjz.png" alt="How Websockets Works Diagram" width="618" height="411"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  WebSockets vs HTTP
&lt;/h2&gt;

&lt;p&gt;One of the main advantages of WebSockets over traditional HTTP is &lt;strong&gt;asynchronous and bidirectional communication&lt;/strong&gt;. It's &lt;strong&gt;bidirectional&lt;/strong&gt; because both the client and the server can "start a conversation," and &lt;strong&gt;asynchronous&lt;/strong&gt; because messages don’t have to follow a strict request-response pattern.&lt;/p&gt;

&lt;p&gt;With HTTP, for example, a game would need to keep &lt;em&gt;polling&lt;/em&gt; constantly (asking "hey, is there anything new?"), which is pretty inefficient. But with WebSockets, a single &lt;strong&gt;persistent connection&lt;/strong&gt; is enough, and the server can notify when something new happens.&lt;/p&gt;

&lt;p&gt;WebSocket connections actually start as regular HTTP requests -- the initial handshake is HTTP, and then the connection is upgraded to a WebSocket. So in a way, it's like an improved version of HTTP, designed to support &lt;strong&gt;real-time&lt;/strong&gt; communication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzywv79sc3b6idi7rnm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzywv79sc3b6idi7rnm3.png" alt="Websockets vs HTTP diagram" width="620" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a WebSocket network, all messages go through the server, which can process, validate, and route them as needed. WebSockets also allow either party to close the connection, which is why it's common to have specific methods to handle these events (like reconnections or state cleanup).&lt;/p&gt;




&lt;h2&gt;
  
  
  Starting with an Echo Server
&lt;/h2&gt;

&lt;p&gt;The first thing I did was implement an &lt;strong&gt;Echo Server&lt;/strong&gt; using &lt;strong&gt;Python&lt;/strong&gt;. This is one of the simplest ways to experiment with WebSockets: &lt;strong&gt;the server just sends back to all clients any message it receives&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websockets&lt;/span&gt;

&lt;span class="c1"&gt;# Set to store active connections
&lt;/span&gt;&lt;span class="n"&gt;connected_clients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Add the connected client to the set
&lt;/span&gt;    &lt;span class="n"&gt;connected_clients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Send the received message to all other connected clients
&lt;/span&gt;            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;connected_clients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Avoid sending it back to the sender
&lt;/span&gt;                    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Remove the disconnected client from the set
&lt;/span&gt;        &lt;span class="n"&gt;connected_clients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Set up the WebSocket server
&lt;/span&gt;    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;websockets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8765&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Keep the server running
&lt;/span&gt;
&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup uses two important Python libraries: &lt;strong&gt;asyncio&lt;/strong&gt; and &lt;strong&gt;websockets&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asyncio&lt;/strong&gt; is a Python &lt;em&gt;little library&lt;/em&gt; that helps handle asynchronous tasks, which means running multiple operations at the same time efficiently, without blocking the program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Websockets&lt;/strong&gt; is another &lt;em&gt;little library&lt;/em&gt; that implements the WebSocket protocol, allowing real-time communication between clients and servers. We use it to create a persistent communication channel without the need to establish new connections each time.&lt;/p&gt;

&lt;p&gt;In this code block above, we set up the server to call the echo function whenever a new client connects. This function listens for messages and echoes them to all other connected clients. Pretty useful haha&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw44ebbc31srl2pli7v0s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw44ebbc31srl2pli7v0s.png" alt="Simple Echo Server Diagram" width="616" height="385"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating a WebSocket Game in the Browser
&lt;/h2&gt;

&lt;p&gt;My second experiment was &lt;strong&gt;connecting multiple people to the same game&lt;/strong&gt; through their browsers. Each player would access a page on their phone and could join the game in real time.&lt;/p&gt;

&lt;p&gt;At this point, I started using &lt;strong&gt;JSON messages&lt;/strong&gt;, which are very common in the web world. Each message sent had a type and some data. For example, when a new player joined the game:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"playerJoined"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Patrocinio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"iconIndex"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type and data message structure allows you to create a &lt;strong&gt;custom protocol&lt;/strong&gt; -- it's like inventing a mini-language between the client and the server. The server would then handle the message based on its type and send updates to the other players. This kind of structure helped me better organize game logic and understand how to build personalized protocols on top of WebSocket.&lt;/p&gt;

&lt;p&gt;It's a powerful approach, because both client and server speak the same "language", based on &lt;strong&gt;standardized message formats&lt;/strong&gt;. Every time a new game feature was added, I just needed to define a new type and its corresponding handler.&lt;/p&gt;

&lt;p&gt;In this case, the game was played on a TV, while players used their phones as controllers. Each phone (via browser) would send information through WebSocket to the game running on the TV.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fys99j4ywmz6t7gur4edj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fys99j4ywmz6t7gur4edj.png" alt="Chicken Spotting diagram" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, notice that in this particular scenario, it wasn’t important for all clients (the players) to know when others joined the game -- that information only mattered to the main game instance (which was also a WebSocket client).&lt;/p&gt;

&lt;p&gt;Since I didn’t yet know how to segment messages for different types of clients, the server echoed everything to everyone. &lt;strong&gt;That meant all players were receiving unnecessary data&lt;/strong&gt;, which caused a small &lt;strong&gt;waste of bandwidth&lt;/strong&gt; and processing. Even so, the server worked well for its experimental purpose -- and the learning experience was what truly mattered.&lt;/p&gt;




&lt;h2&gt;
  
  
  Evolving with WebSockets: Identification, Best Practices, and My Final Project
&lt;/h2&gt;

&lt;p&gt;Over time, I started facing more complex challenges -- like distinguishing between different types of connected devices (phones vs. the game on the TV), identifying clients right after connection, handling disconnections, and avoiding unnecessary broadcasts. I also began adopting some best practices that remain essential in the projects I work on today:&lt;/p&gt;

&lt;p&gt;🔹&lt;strong&gt;Identify&lt;/strong&gt; each client as soon as they connect&lt;br&gt;
🔹&lt;strong&gt;Handle disconnections&lt;/strong&gt; by cleaning up inactive connections&lt;br&gt;
🔹&lt;strong&gt;Avoid unnecessary broadcasts&lt;/strong&gt;, sending messages only to those who need them&lt;br&gt;
🔹&lt;strong&gt;Standardize the message format&lt;/strong&gt;, usually using JSON with type and data fields&lt;br&gt;
🔹&lt;strong&gt;Create a clear protocol structure&lt;/strong&gt;, to make maintenance and expansion easier&lt;br&gt;
🔹Separate clients by room/session, especially in larger games (I still need to learn more about this part haha)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e4ahhlcvb8xkybd8ou8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e4ahhlcvb8xkybd8ou8.png" alt="Image description" width="640" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's important to say that in low-resource environments, like embedded systems, I also learned that JSON is often replaced by &lt;strong&gt;fixed-size binary buffers&lt;/strong&gt; -- a more efficient approach that requires well-defined protocols. This topic is super interesting and definitely deserves its own post. (Coming soon! 😄)&lt;/p&gt;

&lt;p&gt;Today, I’m putting all this knowledge to work in my final university project: a &lt;strong&gt;multiplayer arcade platform where players use their phones to join games via QR Code&lt;/strong&gt;. Everything communicates in real time using WebSockets -- from login to session control.&lt;/p&gt;

&lt;p&gt;It’s a challenging and exciting project, and I’ll definitely be sharing more about it in future posts! Stay tuned!&lt;/p&gt;

&lt;p&gt;🔵⚙️ PS: I added Megaman to cover the QR codes as a reminder: keep learning, keep evolving. Just like Megaman gains new powers with each challenge, we level up with every experiment. &lt;br&gt;
&lt;strong&gt;Trust the Megaman Method™️&lt;/strong&gt;! &lt;/p&gt;

</description>
      <category>multiplayer</category>
      <category>python</category>
      <category>websockets</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Trigonometry Tricks: The Math Behind Game Effects</title>
      <dc:creator>Luis F. Patrocinio</dc:creator>
      <pubDate>Sun, 13 Apr 2025 15:51:25 +0000</pubDate>
      <link>https://dev.to/patrocinioluisf/trigonometry-tricks-the-math-behind-game-effects-3pmi</link>
      <guid>https://dev.to/patrocinioluisf/trigonometry-tricks-the-math-behind-game-effects-3pmi</guid>
      <description>&lt;p&gt;Hey folks! This is one of those posts I was really excited to write: we're finally talking about math! Yes, the one that many people try to run from... but in the world of gamedev, it can become one of our greatest allies.&lt;/p&gt;

&lt;p&gt;I’ve always loved this subject, especially because it blends perfectly with game development -- especially when the goal is to add that visual spice that transforms a prototype into something that &lt;em&gt;feels&lt;/em&gt; like a game. &lt;/p&gt;

&lt;p&gt;Those little effects that make everything look smoother, more dynamic, more alive. That famous magic of &lt;em&gt;game feel&lt;/em&gt; (you’ll see me talk a lot more about that in future posts 😄).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp90074chvdc8j1kvlxu5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp90074chvdc8j1kvlxu5.gif" alt="Celeste Strawberry" width="480" height="256"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🧠 &lt;strong&gt;Math Is Everywhere&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Math is like the invisible engine behind almost everything that works in a game (in world, actually!). From basic movement to physics and particle systems -- there’s always some formula running under the hood.&lt;/p&gt;

&lt;p&gt;And when it comes to bringing systems and movement to life in games, one branch of math really stands out: trigonometry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyg2lv168pkihkcilkd0g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyg2lv168pkihkcilkd0g.gif" alt="Math is everywhere!" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🔺 &lt;strong&gt;The Unit Circle (Wait, don’t run!)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For many, trigonometry is that horrible topic from high school that caused some sleepless nights. But believe me -- in the right context, it’s actually fun and &lt;em&gt;extremely&lt;/em&gt; useful.&lt;/p&gt;

&lt;p&gt;It all starts with the unit (or trigonometric) circle: a representation of a circle where each point on the edge can be described by an angle. That angle gives us two magical values: sine (&lt;code&gt;sin&lt;/code&gt;) and cosine (&lt;code&gt;cos&lt;/code&gt;). These basically tell us the height and width of a point on the circumference.&lt;br&gt;
In the next image, take a look at sin behaviour:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0tmbmqsuv9o9ulxna1o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0tmbmqsuv9o9ulxna1o.gif" alt="The Unit Circle" width="432" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we try to get the sine of any value -- for example, the game’s running time -- we get the projection of that angle from -1 to 1. This creates a sine wave, an awesome and easy ripple effect.&lt;/p&gt;

&lt;p&gt;These functions are cyclical -- they repeat -- and that makes them perfect for simulating smooth, continuous patterns in games.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxw751ta4xydqls1vxm7u.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxw751ta4xydqls1vxm7u.gif" alt="Tiny Witch Balloons" width="520" height="240"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;✨ &lt;strong&gt;Trigonometry in Visual Effects&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Sure, trig includes tangents, secants, cotangents... but let’s keep it simple. Here, we’ll stick to sine and cosine -- they’re more than enough to create some &lt;em&gt;really&lt;/em&gt; cool stuff.&lt;/p&gt;

&lt;p&gt;Here some examples: &lt;/p&gt;

&lt;p&gt;🔸&lt;strong&gt;Circular movement&lt;/strong&gt;: enemies orbiting the player, or spinning items on the map.&lt;br&gt;&lt;br&gt;
🔸&lt;strong&gt;Subtle pulses&lt;/strong&gt;: like that "breathing" effect on menu buttons.&lt;br&gt;&lt;br&gt;
🔸&lt;strong&gt;Oscillations&lt;/strong&gt;: sprites floating or gently swaying.&lt;br&gt;&lt;br&gt;
🔸&lt;strong&gt;Arcing projectiles&lt;/strong&gt;: like arrows or magical spells.&lt;br&gt;&lt;br&gt;
🔸&lt;strong&gt;Rotating lasers&lt;/strong&gt;: using dynamic angles.&lt;br&gt;&lt;br&gt;
🔸&lt;strong&gt;Waves and tremors&lt;/strong&gt;: screen shake or shader effects.&lt;br&gt;&lt;br&gt;
🔸&lt;strong&gt;Wobbly stuff&lt;/strong&gt;: that jiggly, gooey motion like a slime creature or melting object.&lt;/p&gt;

&lt;p&gt;All of this can be done with just a few lines of code using sine, cosine, and time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furndst5yylukx0eh80u4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furndst5yylukx0eh80u4.gif" alt="Crash Bandicoot Crystal" width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🎮 &lt;strong&gt;Trigonometry in Game Logic&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Modern engines come with tons of features built-in -- from collision detection to movement using vectors. But knowing a bit of math gives you more freedom and flexibility to do things &lt;em&gt;your&lt;/em&gt; way.&lt;/p&gt;

&lt;p&gt;For instance, instead of using a bunch of &lt;code&gt;ifs&lt;/code&gt; to determine which direction sprite to show based on player movement, you can just compare the sine and cosine values of the movement angle. Something like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrrfdsw77t709kacnf0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrrfdsw77t709kacnf0w.png" alt="Piece of GML Code" width="600" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That famous quote comes to mind: &lt;em&gt;“It looks like magic, but it’s just math.”&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;📈 &lt;strong&gt;The Learning Curve&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
It seems complicated at first -- and that’s totally normal. Years ago, I used to avoid anything that involved sine or cosine in my projects. I thought, "That stuff isn’t for me."&lt;/p&gt;

&lt;p&gt;But then came our old friend: the &lt;em&gt;Megaman Method™&lt;/em&gt;.🔵⚙️&lt;/p&gt;

&lt;p&gt;Every challenge we overcome gives us a new weapon, a new skill. At first, we get wrecked. But after repeating a few levels and defeating some bosses, we realize we’ve leveled up. And before we know it... we’re using &lt;code&gt;sin(time)&lt;/code&gt; to animate our HUD energy bar 😅&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3fjm2pa5g66eefuksu4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3fjm2pa5g66eefuksu4.gif" alt="Little Liro HP Bar" width="270" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What used to be scary becomes fun. And every new technique is one more power added to our arsenal.&lt;/p&gt;




&lt;p&gt;💡 &lt;strong&gt;EXTRA: Trig Fun Facts&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
🔢 &lt;code&gt;atan2(y, x)&lt;/code&gt; is a hero: this function calculates the correct angle of a vector on a Cartesian plane, accounting for all quadrants. It’s used to aim enemies toward the player, create auto-aiming systems, or just figure out &lt;em&gt;where something’s heading&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;🔫 &lt;strong&gt;Bullet Hell games&lt;/strong&gt;: Games with crazy projectile patterns (like &lt;em&gt;Archvale&lt;/em&gt; or &lt;em&gt;Enter the Gungeon&lt;/em&gt;) use trig all the time! Patterns follow rules like &lt;code&gt;angle + sin(time)&lt;/code&gt; or &lt;code&gt;angle += speed&lt;/code&gt;, creating hypnotic and challenging effects.&lt;/p&gt;

&lt;p&gt;🎨 &lt;strong&gt;Advanced shaders&lt;/strong&gt;: In shaders, just sine and cosine can go a long way. You can create real-time waves, distort textures, make psychedelic effects... it’s the ultimate playground (for the brave-hearted) of trigonometry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fam1msadta3fcv3q7yg2z.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fam1msadta3fcv3q7yg2z.gif" alt="Super Rangers in Bullet Space: Boss Attack Pattern" width="600" height="340"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🚀 &lt;strong&gt;To Wrap It Up...&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You don’t need to master every bit of math to make amazing games. But the more you explore it, the more doors open -- and the more magical your creations become.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbwak5e7xruxc57hctzc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbwak5e7xruxc57hctzc.gif" alt="Space Squadron - Spaceship Movement" width="320" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So if you’ve made it this far, why not try sprinkling a little sine and cosine into your next project? Whether it’s for a visual touch or an elegant solution to a complex logic -- math might just become your best sidekick.&lt;/p&gt;

&lt;p&gt;Make math your ally -- and I promise: this knowledge will transform your projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvj4o3tl1zf3ov7r137kv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvj4o3tl1zf3ov7r137kv.gif" alt="Trust... the... megaman method..." width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Trust the Megaman Method™.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>math</category>
      <category>programming</category>
      <category>gamedev</category>
      <category>vgfx</category>
    </item>
    <item>
      <title>Learning and Leveling Up: Beyond the Tutorial</title>
      <dc:creator>Luis F. Patrocinio</dc:creator>
      <pubDate>Wed, 09 Apr 2025 12:19:36 +0000</pubDate>
      <link>https://dev.to/patrocinioluisf/learning-and-leveling-up-beyond-the-tutorial-4n4m</link>
      <guid>https://dev.to/patrocinioluisf/learning-and-leveling-up-beyond-the-tutorial-4n4m</guid>
      <description>&lt;p&gt;&lt;strong&gt;🚀 Learning by Doing -- and Understanding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a developer, one thing I strongly believe is that there’s no better way to learn than getting hands-on and diving into the official documentation of the technology we’re working with.&lt;/p&gt;

&lt;p&gt;Nothing against step-by-step YouTube tutorials or plug-and-play little libraries that come with everything ready to go. They have their place: they help speed up prototyping, save time with tested and reliable solutions, and even teach us the best ways to apply the core concepts. But when it comes to deep learning -- especially in areas where performance and optimization are crucial (like games or embedded systems) -- understanding how things work under the hood makes all the difference.&lt;/p&gt;

&lt;p&gt;Yes, it’s more work, and it takes more time. But the knowledge we gain stays with us, and it makes us faster when facing future challenges. It’s like Megaman, the classic game character -- he absorbs the power of the enemies he defeats, making it easier to beat even stronger ones later on. I love this metaphor, and you’ll definitely "hear me talk" a lot about the "Megaman Method". 🔵⚙️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcp278q1pr9scio8ox9d3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcp278q1pr9scio8ox9d3.gif" alt="Megaman joins the battle!" width="498" height="280"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;📡 Exploring Wi-Fi Networks on the RP2040&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recently, as part of a hands-on embedded systems residency program I'm currently enrolled in, I worked with the RP2040 microcontroller to scan for Wi-Fi networks using the cyw43 driver from the official Raspberry Pi SDK.&lt;/p&gt;

&lt;p&gt;The proposed challenge was simple: print the found networks to the serial monitor. But I saw a great opportunity to go further. Instead of just printing to the terminal (as suggested), I built an interactive network selector directly on the BitDogLab board (an educational board with buttons and a display -- I’ll be talking about it more around here, too).&lt;/p&gt;

&lt;p&gt;It was an awesome experience -- beyond learning how the driver and SDK work internally, I ended the day with a fully functional piece of software, ready for my portfolio or as a base for future projects. (I even made my own "little library"!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7358t4l5cu0v2qnnsqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7358t4l5cu0v2qnnsqu.png" alt="BitDogLab running PatroWifiScanner" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;⏱️ Understanding Interrupts with a Timer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another interesting challenge we faced involved using interrupts to build a stopwatch. The goal was to better understand how interrupts work on the microcontroller by using callback functions with repeating timers.&lt;/p&gt;

&lt;p&gt;While reviewing a friend's code, I noticed he was manually tracking the elapsed time using a variable. That got me thinking: "Doesn’t the SDK already offer a function to return elapsed or remaining time?" I went digging through the documentation -- and yes, it does: &lt;code&gt;pico_time/time.c -&amp;gt; remaining_alarm_time_ms&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A simple question ended up leading me to a better understanding of the SDK’s built-in features and allowed me to write cleaner, more reliable code -- and with more functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqm4h982vh3xkhhuvvpcs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqm4h982vh3xkhhuvvpcs.gif" alt="Progress bar on PatroStopwatch" width="400" height="313"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;📦 The Art of Building Little Libraries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating small libraries during development is a great way to practice concepts like modularity, code reuse, and project organization. Besides making the software or game more scalable and reusable, this kind of practice reinforces solid design and architecture principles.&lt;/p&gt;

&lt;p&gt;These are essential skills for tackling larger projects -- not to mention the soft skills involved, like autonomy, curiosity, and initiative, all of which are highly valued in any tech team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl87d7ezqeq4p2i0z8pne.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl87d7ezqeq4p2i0z8pne.gif" alt="Making some libraries" width="480" height="366"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🎮 And in Game Development? The Logic Is the Same.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the gamedev world -- especially when working with popular engines like Godot or GameMaker -- we have access to an ocean of plugins, add-ons, and ready-to-use libraries. And that’s great -- but it can become a trap if we stop understanding how and why things work.&lt;/p&gt;

&lt;p&gt;When we create our own systems (a scene manager, AI logic, camera controller, particle system, etc.), we not only learn much more, but we also build real technical baggage, gain independence, and -- over time -- start making smarter decisions in future projects (after all, we already know the pitfalls to look out for at each stage).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zc9zigptzhtg3e2slnj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zc9zigptzhtg3e2slnj.gif" alt="Sonic and Emeralds" width="533" height="300"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🧠 Final Thoughts:&lt;/strong&gt; &lt;br&gt;
Learn by exploring. Go beyond what’s necessary. Don’t be afraid -- or lazy -- to understand why things work the way they do. We only grow from it. 💫&lt;/p&gt;

&lt;p&gt;Thanks for making it to the end -- See ya! ✌🏼&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>learning</category>
      <category>programming</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Patro Powered by Passion: Games, Systems, and Infinite Learning</title>
      <dc:creator>Luis F. Patrocinio</dc:creator>
      <pubDate>Mon, 07 Apr 2025 02:45:13 +0000</pubDate>
      <link>https://dev.to/patrocinioluisf/patro-powered-by-passion-games-systems-and-infinite-learning-52f1</link>
      <guid>https://dev.to/patrocinioluisf/patro-powered-by-passion-games-systems-and-infinite-learning-52f1</guid>
      <description>&lt;h2&gt;
  
  
  👋 Hello, world! I'm Patrocinio!
&lt;/h2&gt;

&lt;p&gt;Hi everyone! My name is Luis Felipe, but I'm best known by my last name: &lt;strong&gt;Patrocinio&lt;/strong&gt; (or just Patro!). I've wanted to start an online profile to share my journey, projects, and ideas with the Dev community for a long time --- and I'm so excited to finally begin!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3nwzn16q1z1zty40ih5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3nwzn16q1z1zty40ih5.png" alt="Image description" width="406" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this first post, I thought it would be cool to share a bit about myself, my background, and some key decisions that led me here --- decisions that changed not just my career, but also the way I view technology and creativity.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎮 From Hobbyist to Professional Game Developer
&lt;/h2&gt;

&lt;p&gt;My journey started with a passion for making games just for fun. Around 2015, while I was still studying Accounting, I teamed up with a close friend to help with some of the bureaucracy and accounting issues of his game studio. I had no idea that distant first contact would change everything.&lt;/p&gt;

&lt;p&gt;That experience made me realize that creating games wasn’t out of reach, so I dove into programming --- making small projects to play with friends, always learning from tutorials and participating in gamedev communities (which opened my eyes to incredible new possibilities!).&lt;/p&gt;

&lt;p&gt;Today, many years later, I run my own game studio &lt;a href="https://blackhole.games/" rel="noopener noreferrer"&gt;Black Hole Games&lt;/a&gt; and also collaborate with other studios, building projects of all sizes and for all kinds of platforms. Game development is part of my everyday life --- it’s how I learn, how I create, and how I connect with others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28u5wisdt5uwfu7l02ks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28u5wisdt5uwfu7l02ks.png" alt="Image description" width="475" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I frequently participate in &lt;strong&gt;game jams&lt;/strong&gt; and have published dozens of games on my &lt;a href="https://patrocinioluisf.itch.io" rel="noopener noreferrer"&gt;itch.io profile&lt;/a&gt; --- many built under super tight deadlines, starting from wild ideas that became fun little games. You can check them out! o/&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Technology as a Form of Creative Expression
&lt;/h2&gt;

&lt;p&gt;To improve my skills, I joined a degree program in &lt;strong&gt;Technology in Systems Analysis and Development&lt;/strong&gt;. I’m always channeling what I learn into game development --- whether it’s data structures, software engineering, web server creation, or AI.&lt;/p&gt;

&lt;p&gt;More recently, I’ve had the chance to dive into a totally new world: &lt;strong&gt;Embedded Systems&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
I’ve fallen &lt;em&gt;completely&lt;/em&gt; in love with low-level hardware programming using &lt;strong&gt;C&lt;/strong&gt;. It’s opening my mind to an entirely different layer of computing. Building everything from absolute scratch is a whole new level of challenge --- and I’m hooked!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqba44jrrafighpgclwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqba44jrrafighpgclwj.png" alt="Image description" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's amazing to think that sitting at a desk, typing sequences of code instructions, allows us to create authentic applications --- from games that deliver fun to systems that control real-world actions. That power to create is what drives me.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What to Expect Here
&lt;/h2&gt;

&lt;h3&gt;
  
  
  I'll be sharing posts about:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎮 Game development experiences and insights (mainly GameMaker and Godot)
&lt;/li&gt;
&lt;li&gt;🧠 Programming concepts and challenges
&lt;/li&gt;
&lt;li&gt;🔧 Embedded systems exploration (yes --- microcontrollers and C!)
&lt;/li&gt;
&lt;li&gt;📓 Reflections and musings from a tech student and lifelong learner
&lt;/li&gt;
&lt;li&gt;👾 Game analysis (retro, indie, and modern titles)
&lt;/li&gt;
&lt;li&gt;💼 Game business and entrepreneurship (from freelancing to running a studio)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌌 A Little More About Me
&lt;/h2&gt;

&lt;p&gt;Outside of programming, I’m fascinated by things that shape how I see the world (and influence my creative process too):&lt;br&gt;&lt;br&gt;
I love &lt;strong&gt;astronomy&lt;/strong&gt; 🪐, &lt;strong&gt;body language&lt;/strong&gt; 🧘‍♂️, &lt;strong&gt;science fiction&lt;/strong&gt; 🧬, &lt;strong&gt;parallel universes&lt;/strong&gt; 🌌, &lt;strong&gt;love stories&lt;/strong&gt; 💞, &lt;strong&gt;sports&lt;/strong&gt; 🏐, &lt;strong&gt;books&lt;/strong&gt; 📚, &lt;strong&gt;good drinks&lt;/strong&gt; 🍹, and of course, &lt;strong&gt;games&lt;/strong&gt; 🕹️.&lt;/p&gt;




&lt;p&gt;✨ Thanks for reading this far! See you in the next post! 🚀&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>programming</category>
      <category>raspberrypi</category>
      <category>welcome</category>
    </item>
  </channel>
</rss>
