<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ GameDev - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ GameDev - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 16 May 2026 08:37:42 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/gamedev/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Ben Awad is a GameDev Who Sleeps 9 Hours EVERY NIGHT to be Productive [Podcast #121] ]]>
                </title>
                <description>
                    <![CDATA[ On this week's episode of the podcast, freeCodeCamp founder Quincy Larson interviews Ben Awad, a game developer who creates developer tutorials on YouTube and TikTok. I hope you enjoy our conversation. Can you guess what bass line I'm playing on my b... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ben-awad-is-a-gamedev-who-sleeps-9-hours-every-night-to-be-productive-podcast-121/</link>
                <guid isPermaLink="false">662bc86c57b91227386cc393</guid>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Fri, 26 Apr 2024 15:29:48 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1714145342153/09d7ca1e-feb2-4aac-8a68-b28060ee646c.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>On this week's episode of the podcast, freeCodeCamp founder Quincy Larson interviews Ben Awad, a game developer who creates developer tutorials on YouTube and TikTok.</p>
<p>I hope you enjoy our conversation.</p>
<p>Can you guess what bass line I'm playing on my bass during the intro? It's from a 1979 song.</p>
<p>You can watch the interview on freeCodeCamp's YouTube channel:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/N1pYdEAU9mk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Or you can listen to the podcast in Apple Podcasts, Spotify, or your favorite podcast app. You can also listen to the podcast below, right in your browser:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="152" src="https://open.spotify.com/embed/episode/7kS44IamTh9Rlfv96lL8wf" style="" title="Spotify embed" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Be sure to follow The freeCodeCamp podcast in your favorite podcast app. And share this podcast with a friend. Let's inspire more folks to learn to code and build careers for themselves in tech.</p>
<p>Also, I want to thank the 8,983 kind people who support our charity each month, and who make this podcast possible. You can join them and support our mission at: <a target="_blank" href="https://www.freecodecamp.org/donate">https://www.freecodecamp.org/donate</a></p>
<h2 id="heading-links-we-talk-about-during-the-interview">Links we talk about during the interview:</h2>
<p>Ben's game, Void Pet on Android and iOS (Built in React Native): <a target="_blank" href="https://voidpet.com/">https://voidpet.com/</a></p>
<p>XKCD coming on "Real Programmers" that Quincy mentions: <a target="_blank" href="https://xkcd.com/378/">https://xkcd.com/378/</a></p>
<p>React Native course by Ben Awad: <a target="_blank" href="https://www.freecodecamp.org/news/create-an-app-that-works-on-ios-android-and-the-web-with-react-native-web/">https://www.freecodecamp.org/news/create-an-app-that-works-on-ios-android-and-the-web-with-react-native-web/</a></p>
<p>I couldn't find my Mac Control hotkeys video tutorial that I mentioned anywhere, so I wrote a quick article explaining how to use these: <a target="_blank" href="https://www.freecodecamp.org/news/mac-control-keyboard-shortcuts-hotkeys-that-work-everywhere-in-macos/">https://www.freecodecamp.org/news/mac-control-keyboard-shortcuts-hotkeys-that-work-everywhere-in-macos/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Indie Game Dev Jabrils talks AI, Anime, and How to Build Games [freeCodeCamp Podcast #118] ]]>
                </title>
                <description>
                    <![CDATA[ On this week's episode of the podcast, I interview Jabril. He's an indie game developer who's building a turn-based fighting game called Ultrabouters. Jabril has developed tons of other games as well. He runs the popular Jabrils gamedev focused-YouTu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/indie-game-dev-jabrils-freecodecamp-podcast-118/</link>
                <guid isPermaLink="false">66b8d44d98b552b8a8592afb</guid>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Fri, 05 Apr 2024 14:40:59 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/jabrils-freecodecamp-podcast.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>On this week's episode of the podcast, I interview Jabril. He's an indie game developer who's building a turn-based fighting game called Ultrabouters.</p>
<p>Jabril has developed tons of other games as well. He runs the popular Jabrils gamedev focused-YouTube. He's also published a 5-hour introduction to programming course on freeCodeCamp.</p>
<p>We talk about:</p>
<ul>
<li>How Jabril got into gamedev as a kid when he got a copy of GameMaker</li>
<li>Jabril's career working at a comedy club and a radio station</li>
<li>The anime that Jabril's been working on for years</li>
<li>Jabril's advice to gamedevs who want to make a career out of building video games</li>
</ul>
<p>Can you guess what bass line I'm playing on my bass during the intro? It's a 2009 song that became popular in the 2010's by being associated with a meme.</p>
<p>You can watch the interview on YouTube:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/aWWF9kP70Tc" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Or you can listen to the podcast in Apple Podcasts, Spotify, or your favorite podcast app. You can also listen to the podcast below, right in your browser:</p>
<div class="embed-wrapper"><iframe src="https://play.libsyn.com/embed/episode/id/30695408/height/192/theme/modern/size/large/thumbnail/yes/custom-color/2a4061/time-start/00:00:00/playlist-height/200/direction/backward/download/yes/font-color/FFFFFF" height="192" width="100%" style="border:none" title="Embedded content" loading="lazy"></iframe></div>

<p>Be sure to follow The freeCodeCamp podcast in your favorite podcast app. And share this podcast with a friend. Let's inspire more folks to learn to code and build careers for themselves in tech.</p>
<p>Also, I want to thank the 8,509 kind people who support our charity each month, and who make this podcast possible. You can join them and support our mission at: <a target="_blank" href="https://www.freecodecamp.org/donate">https://www.freecodecamp.org/donate</a></p>
<p>Links we talk about during the interview:</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/programming-for-beginners-how-to-code-with-python-and-c-sharp/">Jabril's full length Programming for Beginners course</a> on freeCodeCamp</p>
<p><a target="_blank" href="https://twitter.com/ossia/status/993171422863417344">That time Quincy angered the entire BTS army with a confused tweet</a></p>
<p>"The best episodes of Shark Tank are the bad ideas." <a target="_blank" href="https://www.youtube.com/watch?v=gcGjYivktyc">How Jabril created a Fake Shark Tank Episode Generator using AI tools</a></p>
<p><a target="_blank" href="https://www.youtube.com/@Jabrils">Subscribe to Jabril on YouTube</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Podcast: Game Development and AI with Lynn Zheng ]]>
                </title>
                <description>
                    <![CDATA[ 99 Game Development and AI with Lynn Zheng Today on the freeCodeCamp Podcast, I'm joined by Lynn Zheng. She's a software engineer at freeCodeCamp and at Salesforce. Lynn grew up in Shenzhen, China – the computer hardware capital of the world. Both of... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/podcast-lynn-zheng-game-development-ai/</link>
                <guid isPermaLink="false">66b8d52dce55d3ba4d93597e</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Fri, 29 Sep 2023 18:55:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/09/Screenshot_9_29_23__1_32_PM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <h1 id="heading-99-game-development-and-ai-with-lynn-zheng">99 Game Development and AI with Lynn Zheng</h1>
<p>Today on the freeCodeCamp Podcast, I'm joined by Lynn Zheng. She's a software engineer at freeCodeCamp and at Salesforce.</p>
<p>Lynn grew up in Shenzhen, China – the computer hardware capital of the world. Both of her parents were engineers. And from an early age, they encouraged Lynn to learn math and computer science. </p>
<p>Lynn got into the prestigious Computer Science program at University of Chicago, where she earned both Bachelors and Masters degree – all by the age of 21.</p>
<p>I met up with Lynn at the Redwood City Public Library in the heart of Silicon Valley. But they didn't have any study rooms available. so we climbed to a nearby rooftop and recorded there.</p>
<p>We talk about Lynn's many game development projects, which culminated in Learn to Code RPG, a Visual Novel game where you learn to code and get a developer job. </p>
<p>And we talk about her experience working as an engineer at one of the largest tech companies in the world, even as she's stuck in work visa limbo.</p>
<p>Next week will be our 100th episode, and I've got something extra special in store for you.</p>
<p>Tell your friends about the freeCodeCamp podcast. Let's inspire more folks to learn to code and build careers for themselves in tech.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-to-code-rpg/">Learn to Code RPG</a></p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/stable-diffusion-crash-course/">Lynn's Stable Diffusion course</a></p>
<p><a target="_blank" href="https://twitter.com/lynnzheng08">Lynn on Twitter</a></p>
<p><a target="_blank" href="https://www.linkedin.com/in/ruolin-zheng/">Lynn on LinkedIn</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn to Code RPG Version 1.5 is Now Playable with Hours of New Gameplay ]]>
                </title>
                <description>
                    <![CDATA[ Hello from the Learn to Code RPG dev team! We are Lynn, KayLa, and Nielda. And we've been hard at work building out new adventures for our characters. I'm excited to announce the launch of Learn to Code RPG v1.5, a year after the launch of Learn to C... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-to-code-rpg-1-5-update/</link>
                <guid isPermaLink="false">66d4601f3a8352b6c5a2aaaa</guid>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lynn Zheng ]]>
                </dc:creator>
                <pubDate>Fri, 23 Dec 2022 02:43:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/splash-2-lowres-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hello from the Learn to Code RPG dev team! We are Lynn, KayLa, and Nielda. And we've been hard at work building out new adventures for our characters.</p>
<p>I'm excited to announce the launch of <strong>Learn to Code RPG v1.5</strong>, a year after the launch of Learn to Code RPG v1. (Fun fact: we're calling it v1.5 instead of v2 because we have grand plans for v2, which we plan to release in early 2023.)</p>
<h2 id="heading-what-is-learn-to-code-rpg">What is Learn to Code RPG?</h2>
<p><strong>Learn to Code RPG</strong> is an interactive visual novel game where you will teach yourself to code, make friends in the tech industry, and pursue your dream of working as a developer. 🎯</p>
<p>The game features:</p>
<ul>
<li><p>Hours of gameplay 🎮</p>
</li>
<li><p>Original art and music 🎨</p>
</li>
<li><p>1,000+ Computer Science quiz questions 📚</p>
</li>
<li><p>50+ achievements you can unlock 🏆</p>
</li>
<li><p>6 different endings 👀</p>
</li>
<li><p>10+ characters you can make friends with, and an adorable cat 🐱</p>
</li>
<li><p>Minigames 👾</p>
</li>
<li><p>A renown system, a money system, and fun items you can buy for your cat and to customize your room 🏠</p>
</li>
</ul>
<h2 id="heading-learn-to-code-rpg-v15-game-trailer">Learn to Code RPG v1.5 Game Trailer</h2>
<p>You can also watch the game trailer below and share the YouTube video with your friends:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/vDfcMD99Kdg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-you-can-download-the-game-and-play-it-for-free-its-available-for-pc-mac-and-linux-on-itchiohttpsfreecodecampitchiolearn-to-code-rpg-and-on-android-from-the-google-play-storehttpsplaygooglecomstoreappsdetailsidorgfreecodecamplearntocoderpgamphlenusampglusamppli1">You can download the game and play it for free. It's available for PC, Mac, and Linux on <a target="_blank" href="https://freecodecamp.itch.io/learn-to-code-rpg">itch.io</a>. And on Android from the <a target="_blank" href="https://play.google.com/store/apps/details?id=org.freecodecamp.learntocoderpg&amp;hl=en_US&amp;gl=US&amp;pli=1">Google Play Store</a>.</h2>
<p>If you'd like to learn more about the game itself and the development process, read on.</p>
<p>We'll walk you through the story, characters, graphics, and code. I'm sure you'll enjoy it. And it may even inspire you to code your own video game.</p>
<h2 id="heading-how-learntocoderpg-went-from-v1-to-v15">How LearnToCodeRPG Went From v1 to v1.5</h2>
<h3 id="heading-the-team">The Team</h3>
<p>When Lynn created v1, she was working solo on the game, juggling writing, coding, and some asset creation.</p>
<p>With this release, to give Lynn more time to focus on coding, KayLa took care of the writing. Nielda helped brainstorm features and create art assets.</p>
<p>Want to see a teamwork showcase? Here's one for the item shop. After purchasing furniture from the shop, the player will see the furniture in their room.</p>
<ul>
<li><p>Lynn programmed the shop, the items, and the room customization</p>
</li>
<li><p>KayLa and Nielda came up with ideas for the items</p>
</li>
<li><p>KayLa wrote fun flavor text for the items</p>
</li>
<li><p>Nielda created all the assets – the room and the items – by tracing over 3D assets and applying textures over them</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/room.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-learn-to-code-rpg-main-story">The Learn to Code RPG Main Story</h3>
<p>In v1 (or what we call the Prologue), the story started as our protagonist, Lydia, decided to get a job in the tech industry. She needed to learn to code, make friends in the industry, find mentors, tackle technical interviews, and eventually arrive at her goal – a shiny new developer job.</p>
<p>Building from the Prologue story, in v1.5 (or what we call Arc I) Lydia starts working as a full-stack developer. She now needs to interact with her new colleagues on a day-to-day basis and react to events that arise.</p>
<p>She will be faced with all the things a real-world software engineer faces – changes in project requirements, communicating with project managers, learning from senior developers, and so on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/Screen-Shot-2022-12-20-at-18.37.09.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Does this look like a familiar scene from working in tech to you?</em></p>
<p>Outside of work, Lydia can also go hang out at Hacker Space with friends she made back when she was first learning to code.</p>
<p>At Hacker Space, Lydia might run into old acquaintances who are also looking for a job. She can decide whether or not to give them a referral.</p>
<p>She can also give back to the community by mentoring high school students with their projects.</p>
<p>There is never a shortage of fun things to do at Hacker Space. 😄</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/itch2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-characters">The Characters</h3>
<p>To give the characters more depth, we brainstormed using the character card format shown below. Here's the character card for Lydia:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/Screen-Shot-2022-12-20-at-19.46.02.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Lydia meets many new colleagues in this arc and our character list has been greatly expanded.</p>
<p>When designing the characters, sometimes our artist Noa will experiment with hair color and style variations until we land on a design that we are happy with:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/mala-3.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Mala's different designs. Which is your favorite?</em></p>
<p>Here's also a sneak peek into one of the many characters and their many expressions:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/darius-4.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Darius's many faces</em></p>
<p>Of course, everyone's favorite, Mint the kitty, is still the key emotional support for this story arc. 🐱</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/mint_small.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-graphics">The Graphics</h3>
<p>Now moving on to other graphics besides character sprite art. Just like in v1, we again created background images by applying a watercolor-like filter to real-world images.</p>
<p>Since a lot of story takes place at the company Lydia is working at, we also tried to find stock images that are coherent in color scheme, like the ones below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/Untitled-design.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Background images for the company Lydia's working at</em></p>
<h3 id="heading-the-code">The Code</h3>
<p>Just like in v1, I used the game engine that I'm most familiar with, <a target="_blank" href="https://www.renpy.org/">the Ren'Py Visual Novel Engine</a>.</p>
<p>During this year of development, a really exciting piece of news for the Ren'Py community is that Ren'Py 8 now supports Python 3. This is exciting to me.</p>
<p>Compared to Python 2.7 (which we used in Ren'Py 7.4 when we developed Learn to Code RPG v1), Python 3 brings in a lot of new features that positively impact our development.</p>
<p>This also means that I had to spend a little time to migrate from Python 2.7 to Python 3 in our project. (It was a small Git commit, trust me 🤓).</p>
<p>Now some exciting stats – Ren'Py's built-in linter is perfect for gathering stats for comparisons between v1 and v1.5:</p>
<pre><code class="lang-pgsql"># v1
Ren<span class="hljs-string">'Py 7.4.8.1895 lint report, generated at: Fri Dec 17 22:11:43 2021
Statistics:
The game contains 1,335 dialogue blocks, containing 15,390 words and 85,105 characters, for an average of 11.5 words and 64 characters per block.
The game contains 40 menus, 20 images, and 49 screens.

# v1.5
Ren'</span>Py <span class="hljs-number">8.0</span><span class="hljs-number">.3</span><span class="hljs-number">.22090809</span> lint report, <span class="hljs-keyword">generated</span> at: Tue <span class="hljs-type">Dec</span> <span class="hljs-number">20</span> <span class="hljs-number">19</span>:<span class="hljs-number">22</span>:<span class="hljs-number">05</span> <span class="hljs-number">2022</span>
<span class="hljs-keyword">Statistics</span>:
The game contains <span class="hljs-number">3</span>,<span class="hljs-number">339</span> dialogue blocks, containing <span class="hljs-number">41</span>,<span class="hljs-number">214</span> words <span class="hljs-keyword">and</span> <span class="hljs-number">220</span>,<span class="hljs-number">501</span>
characters, <span class="hljs-keyword">for</span> an average <span class="hljs-keyword">of</span> <span class="hljs-number">12.3</span> words <span class="hljs-keyword">and</span> <span class="hljs-number">66</span> characters per block.
The game contains <span class="hljs-number">68</span> menus, <span class="hljs-number">19</span> images, <span class="hljs-keyword">and</span> <span class="hljs-number">51</span> screens.
</code></pre>
<p>From the stats we can see that we've nearly tripled the story content. Woohoo! 🤩</p>
<h2 id="heading-next-steps-for-learntocoderpg-from-v15-to-v2">Next Steps for LearnToCodeRPG: From v1.5 to v2</h2>
<p>Hooray! After a whole year of development, we've taken v1 to new heights and are now presenting you with <strong>Learn to Code RPG v1.5</strong>.</p>
<p>What's more exciting: we are only just getting started. Just as Quincy always likes to say, the sky is the limit. ✈️</p>
<p>Here are some things you can look forward to in v2, or even sooner, between v1.5 and v2:</p>
<ul>
<li><p>🌎 Localization: All the text in v1 has been fully translated into Portuguese, and we have an active community working on translating the game into other world languages. You can help too, by starting <a target="_blank" href="https://contribute.freecodecamp.org/#/how-to-translate-files?id=translate-the-learntocode-rpg">here</a>.</p>
</li>
<li><p>🎭 More story and characters (shhh... we have 10+ characters planned and some drawn already)</p>
</li>
<li><p>📚 Expanded bank of quiz questions and spaced repetition to help you learn more efficiently.</p>
</li>
<li><p>💻 Auto-update from inside the game so that you can stay up-to-date with the latest bug fixes, features, and storylines.</p>
</li>
<li><p>... and more on our holiday wishlists! 🎁</p>
</li>
</ul>
<p>Last but not least, we hope you enjoy playing this game as much as we enjoyed developing it! 🥳</p>
<h3 id="heading-links">Links</h3>
<p>You can find the game on itch.io here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://freecodecamp.itch.io/learn-to-code-rpg">https://freecodecamp.itch.io/learn-to-code-rpg</a></div>
<p> </p>
<p>And here's the GitHub repo with all the code:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/freeCodeCamp/LearnToCodeRPG">https://github.com/freeCodeCamp/LearnToCodeRPG</a></div>
<p> </p>
<p>If you haven't read about how v1 of the game took shape, here's an article for you:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.freecodecamp.org/news/learn-to-code-rpg/">https://www.freecodecamp.org/news/learn-to-code-rpg/</a></div>
<p> </p>
<p>And here's the official press kit for the game:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.freecodecamp.org/news/learn-to-code-rpg-press-kit/">https://www.freecodecamp.org/news/learn-to-code-rpg-press-kit/</a></div>
<p> </p>
<p>If you are interested in building a Visual Novel Game yourself, check out this article of mine:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.freecodecamp.org/news/use-python-to-create-a-visual-novel/">https://www.freecodecamp.org/news/use-python-to-create-a-visual-novel/</a></div>
<p> </p>
<p>We hope you enjoy learning what it's like to work in tech by playing the Learn to Code RPG. 🧑‍💻</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn to Code RPG – Full Soundtrack + How I Made It ]]>
                </title>
                <description>
                    <![CDATA[ First: what you probably came here for. Here's the full soundtrack to Learn to Code RPG. 36 minutes of jazz. https://youtu.be/8TDsGUFFXSY If you dig it, subscribe to my new music channel and leave a comment with feedback or your favorite track. I am ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-to-code-rpg-soundtrack/</link>
                <guid isPermaLink="false">66b8d49bf583f6362a68ce13</guid>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ music ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Thu, 23 Dec 2021 18:53:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/Splash-Art-2-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>First: what you probably came here for. Here's the full soundtrack to Learn to Code RPG. 36 minutes of jazz.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/8TDsGUFFXSY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>If you dig it, subscribe to my new music channel and leave a comment with feedback or your favorite track.</p>
<p>I am currently uploading this to Spotify.</p>
<h2 id="heading-how-i-made-the-learn-to-code-rpg-soundtrack">How I Made The Learn to Code RPG Soundtrack</h2>
<p>The Funk of the 70s.<br>The Jazz of the 80s.<br>The Hip Hop of the 90s.</p>
<p>I was a lover of music. But I never really learned how to play.</p>
<p>That changed 3 months into the pandemic. I bought an electric bass. I clocked several hundred hours in Rocksmith practicing the bass lines of Nathan East, Bootsy Collins, and Andy Rourke from The Smiths.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Bootsy_Collins-04.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Bootsy Collins, the legendary bassist for both Parliament and James Brown</em></p>
<p>For theory, I made heavy use of Musician YouTube, including <a target="_blank" href="https://www.youtube.com/watch?v=qFVpSjRUD2E&amp;list=PLW0NGgv1qnfzb1klL6Vw9B0aiM7ryfXV_">Rick Beato</a> and <a target="_blank" href="https://www.youtube.com/watch?v=kBIXDov8G80&amp;list=PLBcZM94cb2Ux02BDGRwFcD09EsFe8T7rr">Adam Neely</a>, and most importantly <a target="_blank" href="https://www.youtube.com/watch?v=OgipSAdZiKw&amp;list=PL_KwW-re--9GGknaye6BBmWeRNqL95xiJ">Paul Del Bello</a>.</p>
<p>I also got guidance from two musicians in the freeCodeCamp community: Lawrence Yeo (AKA <a target="_blank" href="https://open.spotify.com/artist/5K2ELFl9mZj4wSulXtgUcV">Trebles and Blues</a>) and Devin Lane (AKA <a target="_blank" href="https://open.spotify.com/artist/7dFoXdChS3pVrba3MyuuTu">Gentle Return</a>). Check out their tunes.</p>
<p>Before long I came to realize that almost any piece of music could potentially sound good with nothing more than drums, bass, and a piano. But I didn't want to find a drummer or a pianist, so I set out to learn how to play those instruments myself.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/gear.jpeg" alt="Image" width="600" height="400" loading="lazy">
<em>My gear – a Fender Precision bass, Roland Octopad, and M-Audio midi controller</em></p>
<p>I started by learning to read music, doing ear training, memorizing the circle of fifths – all the things I presume you learn in music school. But I quickly abandoned that in favor of just sitting down and writing songs.</p>
<p>I bought a $100 midi controller and a $200 copy of Logic Pro, then got to work learning how to compose chords and melodies, and play to a metronome.</p>
<p>It took about 6 months, but I recorded dozens of instrumental tracks, 10 of which made it into the first release of Learn to Code RPG. I am working on several more songs with similar tempos and instrumentation for future expansions to the game.</p>
<h2 id="heading-how-do-you-make-your-keyboard-sounds">How do you make your keyboard sounds?</h2>
<p>I build my synth patches using Logic's built-in Alchemy additive synth and its analog synth. I also use some of Logic's stock pianos, electric pianos, organs, and its celesta.</p>
<h2 id="heading-what-do-you-use-for-drums">What do you use for drums?</h2>
<p>I play a heavily modified Logic producer drum kit on a Roland Octopad. I use heavy muting and very few plugins. I'm going for a dry, crisp 1970s sound.</p>
<p>You may notice that I only use the kick, snare, ride, and hi-hat. That is all that the 70s greats like Clyde Stubblefield and Gregory Coleman needed to build grooves. So I imposed that constraint upon myself. (I find that reasonable constraints can accelerate the creative process.)</p>
<p>Rather than playing the classic 70s breakbeats, I attempt to weave my own around the song's bass line.</p>
<h2 id="heading-what-is-that-kick-drum-sound">What is that kick drum sound?</h2>
<p>A booming house music kick layered on top of a clicky death metal kick.</p>
<h2 id="heading-what-is-that-bass-sound">What is that bass sound?</h2>
<p>The bass you hear on the Learn to Code RPG soundtrack is a fattened-up analog synth sound with some delay and distortion. I can't quite play bass tight enough for studio-grade recordings, and rather than chopping it my playing, I just played on a keyboard. I EQ the bass at 40 Hz to make room room for the kick, and so it still sounds OK on a phone's speakers.</p>
<h2 id="heading-can-i-use-your-music-in-my-videos-on-my-live-stream">Can I use your music in my videos / on my live stream?</h2>
<p>DM me on Twitter and we can discuss this.</p>
<h2 id="heading-can-you-play-my-tech-conference-roller-skating-rink-art-opening">Can you play my tech conference / roller skating rink / art opening?</h2>
<p>That sounds like a blast. DM me on Twitter.</p>
<p>Thanks for reading about my music. I never thought I'd discover a new all-consuming passion at age 40. But it has been a blast. And I am just getting started. If I am lucky, I will still have 40 years left in me to learn music and create work I am proud of.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn to Code RPG – A Visual Novel Video Game Where you Learn Computer Science Concepts ]]>
                </title>
                <description>
                    <![CDATA[ Hi, everybody – Lynn here. It's my great pleasure to announce the launch of Learn to Code RPG, a project we've been developing in secret for the past eight months. Learn to Code RPG is an interactive visual novel game where you will teach yourself to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-to-code-rpg/</link>
                <guid isPermaLink="false">66d4602333b83c4378a517fa</guid>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lynn Zheng ]]>
                </dc:creator>
                <pubDate>Wed, 22 Dec 2021 17:23:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/Splash-Art.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hi, everybody – Lynn here. It's my great pleasure to announce the launch of <strong>Learn to Code RPG,</strong> a project we've been developing in secret for the past eight months.</p>
<p><strong>Learn to Code RPG</strong> is an interactive visual novel game where you will teach yourself to code, make friends in the tech industry, and pursue your dream of becoming a developer. 🎯</p>
<p>The game features:</p>
<ul>
<li><p>Hours of gameplay 🎮</p>
</li>
<li><p>Original art and music 🎨</p>
</li>
<li><p>600+ Computer Science quiz questions 📚</p>
</li>
<li><p>50+ Easter Eggs you can discover 🚀</p>
</li>
<li><p>6 different endings 👀</p>
</li>
<li><p>Friendly characters and an adorable cat 🐱</p>
</li>
<li><p>Minigames! 👾</p>
</li>
</ul>
<p>This is a first release and we hope to add more content to it in the future. Future releases will have more <strong>characters, scenarios, side quests, art, music,</strong> and, yes, <strong>minigames</strong>. (CS quiz speed run and survival mode, anyone?) We are also planning to localize it into different languages. 🌎 The sky is the limit here. ✈️</p>
<h2 id="heading-you-can-download-it-and-play-it-for-free-on-itchiohttpsfreecodecampitchiolearn-to-code-rpg">You can download it and play it for free on <a target="_blank" href="https://freecodecamp.itch.io/learn-to-code-rpg">itch.io</a>.</h2>
<p>If you'd like to learn more about the game itself, my development process, and so on, read on. This is a very visual devlog (our game is a Visual Novel for a reason) and I'm sure you will enjoy it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/img_1-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Learn to Code RPG – A game where you role play learning to code</em></p>
<h2 id="heading-where-it-all-started">Where It All Started</h2>
<p>Let's start with a bit of background about me.</p>
<p>I've always loved story-rich video games since I was little. 🧒🏻</p>
<p>My interest in game development inspired me to major in Computer Science in college. In June 2021, I graduated from the University of Chicago with a joint Bachelor's and Master's degree in Computer Science.</p>
<p>In July 2021, as I was planning my move to San Francisco to start my career as a software developer, Quincy reached out to me about this game idea.</p>
<blockquote>
<p>A game where you learn to code, make friends, explore the tech culture, and eventually break into the tech industry. 🎯</p>
</blockquote>
<p>Although I dabble in game development engines like Unity and Ren'Py and have created small passion projects in my own time, this would be my first time building a game from the ground up, on a (mostly) one-person team. That is to say, I was a little overwhelmed by this opportunity to make my game development dream come true. 🤯</p>
<p>Well, you know the saying: If you’re offered a seat on a rocket ship 🚀, don’t ask what seat!</p>
<p>So I said yes and dove right in.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-18-at-12.56.15.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Who am I to turn down an offer from CupcakeCPU? 🧁</em></p>
<h2 id="heading-from-zero-to-hero-how-to-build-a-game-in-four-months">From Zero to Hero: How to Build A Game In Four Months</h2>
<h3 id="heading-the-story">The Story</h3>
<p>The story idea was pretty clear from the beginning: The hero/heroine makes the decision to learn to code, conquers obstacles along the journey, meets allies and mentors, and eventually gets to the grand prize – a shiny developer job.</p>
<p>I started with the classic writing framework of <a target="_blank" href="https://en.wikipedia.org/wiki/Hero%27s_journey">The Hero's Journey</a>, or, the 17-stage monomyth.</p>
<p>(Since I started working on this game, time and again I wish I'd taken at least one creative writing class in college. 😅)</p>
<p>Here's a glimpse into my outline for the first and the third stage out of the 17 stages, straight from my Google Doc:</p>
<table><tbody><tr><td><p>1. The Call to Adventure</p></td><td><p>the first stage of the hero’s journey often presents to the audience the current (and sometimes rather mundane) existence of the protagonist.</p></td><td><p><strong>Main Character (abbreviated MC) </strong>graduates and moves back with her parents. She isn’t really sure what her career is going to look like so she spends her days working gigs and browsing job openings. She has applied to some sales and consulting jobs but they turned her down.</p></td></tr></tbody></table>

<table><tbody><tr><td><p>3. Supernatural Aid</p></td><td><p>in this stage of the journey, the protagonist seeks out a sage-like figure and possibly gains a special item or skill in the process.</p></td><td><p><strong>Annika, </strong>MC’s best friend in college, calls MC one day. Annika is excited because she just got an entry-level web dev role, after spending 6 months to brush up her rusty CS skills (from auditing a few CS classes in college). Annika asks about how MC is doing; is delighted that MC is also considering learning to code; and encourages MC that she can do it if she has the right study method and resources.<br>Annika introduces MC to the resource she uses.</p></td></tr></tbody></table>

<h3 id="heading-the-characters">The Characters</h3>
<p>Including the main character which the player controls, we have four major characters in the game:</p>
<ul>
<li><p>The main character, <strong>Lydia</strong>, a recent graduate from college. (In future releases of the game we may be able to present a few different main characters the player can choose from.)</p>
</li>
<li><p><strong>Annika</strong>, the main character's college best friend</p>
</li>
<li><p><strong>Marco</strong>, who becomes the main character's mentor</p>
</li>
<li><p><strong>Layla</strong>, the main character's onboarding buddy at her first dev job</p>
</li>
</ul>
<p>I started designing the characters by collecting images on Pinterest. Then Quincy and I commissioned an artist online to create the character sprites and splash image.</p>
<p>In the images below, you can see the Pinterest character inspirations (copyright belongs to their original artists) and the final design side-by-side.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled265_20211217211947.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Lydia inspiration art + final character card</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled265_20211217212148.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Annika inspiration art + final character card</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled265_20211217211928.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Layla inspiration art + final character card</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled265_20211217211832.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Marco inspiration art + final character card</em></p>
<p>Now that we have the main cast, what else do we need to add more character depth to <strong>Lydia</strong>, so that she is not sitting in her room alone all day long grinding code? Maybe she could use a cat in her room? 🐱</p>
<p>And enter <strong>Mint</strong>, Lydia's cat. (Art by me as a makeshift artist so that our artist could focus on the characters. Digital art 🎨 is my second biggest hobby after game dev.)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/mint.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Mint says hi!</em></p>
<h3 id="heading-the-graphics">The Graphics</h3>
<p>With the character graphics done, you may think that concludes the bulk of the graphics. But not so fast! A visual novel is, as its name suggests, visual, and so it needs a lot more graphics to tell an appealing story.</p>
<p>For example, in this image below, besides the character sprites, there is the background image and some GUI components like the textbox.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-18-at-12.40.00.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Basic graphic components: GUI, character sprites, background</em></p>
<p>To create the background images, I applied special effect filters to stock images to add a watercolor-like texture. This way, the color scheme of our characters blends perfectly into that of the background.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled266_20211217213638.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Top: stock image. Bottom: with filters</em></p>
<p>To illustrate the passage of time in a single day, I changed the lighting of the background images by applying color manipulation programmatically. (Check out <a target="_blank" href="https://github.com/freeCodeCamp/LearnToCodeRPG">our GitHub repo</a> if you are interested in the implementation details!)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/color.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Four modes of lightning</em></p>
<p>For a motivation boost, whenever I feel like procrastinating, I switch my creative gears and doodle miscellaneous items that show up throughout the game. 🤣</p>
<p>And that's how we got in-game cookies, toast, pizza, fried chicken, and more!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/ezgif.com-gif-maker-7-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Yummy!</em></p>
<h3 id="heading-the-code">The Code</h3>
<p>I used the game engine that I'm most familiar with, <a target="_blank" href="https://www.renpy.org/">the Ren'Py Visual Novel Engine</a>. I reused a lot of code from my old passion projects – for example, <a target="_blank" href="https://gist.github.com/RuolinZheng08/b845f416ebda5b02ebc6b62379105564">blinking character sprites</a> and <a target="_blank" href="https://github.com/RuolinZheng08/renpy-rhythm">a rhythm minigame</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/blink2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Blinking characters 😉</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-17-at-19.33.39-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Rhythm Minigame. Can you get a perfect score?</em></p>
<p>I also incorporated some open-source Ren'Py code like <a target="_blank" href="https://wattson.itch.io/kinetic-text-tags">the code for kinetic text tags</a> and <a target="_blank" href="https://tacoen.itch.io/feather-icon">the code for feather icon text.</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/awesome.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Kinetic text tag, which can be turned off for accessibility</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-17-at-22.05.37.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Feather icons are awesome for creating crisp, simplistic GUI</em></p>
<p>I will refrain from diving into the codebase here (because I won't know when to stop then 😆). Just know that it's a lot of code, both for the logic and the GUI. See the Ren'Py Lint report below.</p>
<p>Phew... Can we now move on to something more visual?</p>
<pre><code class="lang-pgsql">Ren<span class="hljs-string">'Py 7.4.8.1895 lint report, generated at: Fri Dec 17 22:11:43 2021
Statistics:
The game contains 1,335 dialogue blocks, containing 15,390 words and 85,105 characters, for an average of 11.5 words and 64 characters per block.
The game contains 40 menus, 20 images, and 49 screens.</span>
</code></pre>
<h3 id="heading-the-progress-tracker">The Progress-Tracker</h3>
<p>Even a one-person project needs a project manager, so why not be my own project manager?</p>
<p>I used Trello to track my process and collaborate with others. I even color-coded labels for different categories of tasks, like <em>coding, UI/UX, writing,</em> and so on as shown in the image below on the first card in the <strong>Backlog</strong> column.</p>
<p>And wow, isn't that a long scroll of tasks done? 😤</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/trello.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>My Trello board</em></p>
<p>Everything in the <strong>TODO</strong> and <strong>Doing</strong> column is moved to <strong>Done</strong>, and that brings us to...</p>
<h2 id="heading-my-takeaway">My Takeaway</h2>
<p>Hooray! After eight months (four months of the idea brewing, plus four months of intense coding, writing, and art making), we present to you <strong>Learn to Code RPG. 🥳</strong></p>
<p>In four in-game months, <strong>Lydia</strong> has grown from <em>an aspiring engineer</em> into <em>an engineer with a dev job</em>. 🎯</p>
<p>In four real-world months, I've grown from <strong>an aspiring game developer</strong> into <strong>a game developer who's actually built a game.</strong> 👾</p>
<p>Naturally here comes the million-dollar question: What's my takeaway from this entire process?</p>
<p>Well, like any creative process, game development isn't easy. I'm extremely fortunate to have a team supporting me: our artist Noa who created the character art, Quincy who created the awesome original music tracks, and proofreaders and playtesters from the freeCodeCamp staff.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-17-at-22.26.07.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>My GitHub contributions tell apart the days when I code vs. the days when I brainstorm or write or draw 🤪</em></p>
<p>I've grown both in terms of technical skills (by finding creative ways to build things in Ren'Py), non-technical skills (by acting as my own project manager), and more (by managing expectations, overcoming imposter syndrome, and seeking a work-life balance).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-18-at-12.33.25.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Do you know what imposter syndrome is? 👻 You bet I do!</em></p>
<p>It was by no means an easy ride, but the outcome is worth every second of hard work. More importantly, I look forward to you playing the game and providing feedback so that I can make the game better in future releases.</p>
<p>I hope you enjoy playing <strong>Learn to Code RPG</strong> as much as I've enjoyed creating it! 🙌</p>
<h2 id="heading-learn-to-code-rpg-links">Learn to Code RPG Links</h2>
<p>You can find the game on itch.io here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://freecodecamp.itch.io/learn-to-code-rpg">https://freecodecamp.itch.io/learn-to-code-rpg</a></div>
<p> </p>
<p><a target="_blank" href="https://github.com/freeCodeCamp/LearnToCodeRPG">And here's the GitHub repo with all the code</a>.</p>
<p>You can also watch the Game Trailer on YouTube and share it with your friends:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/vLK4fOeiIEk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Want to see what the game is like? Check out the <a target="_blank" href="https://www.youtube.com/watch?v=b_IDdQzPRR4">Let's Play with Ania and Lynn</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/b_IDdQzPRR4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>And <a target="_blank" href="https://www.freecodecamp.org/news/learn-to-code-rpg-press-kit/">here's the official press kit for the game</a>.</p>
<p>If you are interested in building a Visual Novel Game yourself, check out this article of mine:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.freecodecamp.org/news/use-python-to-create-a-visual-novel/">https://www.freecodecamp.org/news/use-python-to-create-a-visual-novel/</a></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn to Code RPG – Press Kit ]]>
                </title>
                <description>
                    <![CDATA[ This is the press kit for the game, Learn to Code RPG. Fact Sheet Developer freeCodeCamp.org, a 501(c)(3) nonprofit Platform Windows/Mac/Linux Available on itch.io Price Free Source Code GitHub Release Date December 22, 2021 Developer Contact Quincy ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-to-code-rpg-press-kit/</link>
                <guid isPermaLink="false">66d46021677cb8c6c15f315d</guid>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #Game Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lynn Zheng ]]>
                </dc:creator>
                <pubDate>Wed, 22 Dec 2021 17:22:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/Splash-Art-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This is the press kit for the game, <strong>Learn to Code RPG</strong>.</p>
<h2 id="heading-fact-sheet">Fact Sheet</h2>
<h3 id="heading-developer">Developer</h3>
<p><a target="_blank" href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwjljfGir-z0AhVBKn0KHWCOB9cQFnoECAUQAQ&amp;url=https%3A%2F%2Fwww.freecodecamp.org%2F&amp;usg=AOvVaw2O9Sbs3zh9NHmRpWZrEZt-">freeCodeCamp.org</a>, a 501(c)(3) nonprofit</p>
<h3 id="heading-platform">Platform</h3>
<p>Windows/Mac/Linux</p>
<h3 id="heading-available-on">Available on</h3>
<p><a target="_blank" href="https://freecodecamp.itch.io/learn-to-code-rpg">itch.io</a></p>
<h3 id="heading-price">Price</h3>
<p>Free</p>
<h3 id="heading-source-code">Source Code</h3>
<p><a target="_blank" href="https://github.com/freeCodeCamp/LearnToCodeRPG">GitHub</a></p>
<h3 id="heading-release-date">Release Date</h3>
<p>December 22, 2021</p>
<h3 id="heading-developer-contact">Developer Contact</h3>
<p>Quincy Larson, <a target="_blank" href="mailto:quincy@freecodecamp.org">quincy@freecodecamp.org</a></p>
<p>Lynn Zheng, <a target="_blank" href="mailto:lynn@freecodecamp.org">lynn@freecodecamp.org</a></p>
<h2 id="heading-description">Description</h2>
<p><strong>Learn to Code RPG</strong> is an interactive visual novel game where you will teach yourself to code, make friends in the tech industry, and pursue your dream of becoming a developer. 🎯</p>
<p>In this game, your choices shape and drive the story forward: What will you do on a day-by-day basis? Learn to code? Work as a barista? Visit the Hacker Space? Or chill, relax in the park, or cuddle with a kitten over some video games?</p>
<p>Will you stick to your dream – getting a job in the tech industry – and more importantly, keep that job? The choice is in your hands.</p>
<h2 id="heading-features">Features</h2>
<ul>
<li><p>2+ hours of gameplay 🎮</p>
</li>
<li><p>Original art and music 🎨</p>
</li>
<li><p>600+ CS quiz questions 📚</p>
</li>
<li><p>50+ Easter Eggs you can tweet about 🚀</p>
</li>
<li><p>6 different endings 👀</p>
</li>
<li><p>Friendly characters and an adorable cat 🐱</p>
</li>
<li><p>Minigames! 👾</p>
</li>
</ul>
<h2 id="heading-dev-log-article">Dev Log Article</h2>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-to-code-rpg/">https://www.freecodecamp.org/news/learn-to-code-rpg/</a></p>
<h2 id="heading-screenshots">Screenshots</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Splash-Art-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Learn to Code RPG Splash art</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Learn-to-Code-RPG-Main-Menu-copy.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Learn to Code RPG Game Menu</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-18-at-12.40.00-copy.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Hanging out at the Hacker Space with your best friend Annika</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-17-at-09.43.14.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Chill at home with your cat Mint</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-20-at-18.30.58.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Take CS quizzes</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-17-at-09.43.50.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Quiz question explanation screen</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-17-at-18.51.41.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>NPCs</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-17-at-19.33.39.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Rhythm Minigame</em></p>
<h2 id="heading-videos">Videos</h2>
<h3 id="heading-trailer">Trailer</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/vLK4fOeiIEk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h3 id="heading-lets-play">Let's Play</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/b_IDdQzPRR4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-logo">Logo</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/img_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/img_0.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-character-cards">Character Cards</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Lydia.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Annika.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Marco.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Layla.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Mint.png" alt="Image" width="600" height="400" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Multiplayer Tabletop Game Simulator with Vue, Phaser, Node, Express, and Socket.IO ]]>
                </title>
                <description>
                    <![CDATA[ By M. S. Farzan Putting together all of the pieces of a full stack JavaScript application can be a complex endeavor.   In this tutorial, we're going to build a multiplayer tabletop game simulator using Vue, Phaser, Node/Express, and Socket.IO to lear... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-multiplayer-tabletop-game-simulator/</link>
                <guid isPermaLink="false">66d851eba2a6d73be8613877</guid>
                
                    <category>
                        <![CDATA[ ES6 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express JS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ phaser 3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SocketIO ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 13 Jul 2020 23:31:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/07/How-to-Tabletop-Game-Simulator---Thumb.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By M. S. Farzan</p>
<p>Putting together all of the pieces of a full stack JavaScript application can be a complex endeavor.  </p>
<p>In this tutorial, we're going to build a multiplayer tabletop game simulator using <a target="_blank" href="https://vuejs.org/">Vue</a>, <a target="_blank" href="http://phaser.io/">Phaser</a>, <a target="_blank" href="https://nodejs.org/">Node</a>/<a target="_blank" href="https://expressjs.com/">Express</a>, and <a target="_blank" href="https://socket.io/">Socket.IO</a> to learn several concepts that will be useful in any full stack app.</p>
<p>You can follow along with this video tutorial as well (1 hour 16 minute watch):</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/laNi0fdF_DU" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>All of the project files for this tutorial are available on <a target="_blank" href="https://github.com/sominator/tabletop-project">GitHub</a>.</p>
<h2 id="heading-project-overview">Project Overview</h2>
<p>Our project will feature a Phaser game instance that will allow us to create tokens and cards on screen, and move them around on a digital game board.</p>
<p>The Phaser instance will be wrapped in a Vue component that will handle things like multiplayer chat and commands.  Together, Phaser and Vue will comprise our front end (referred to from here on as the "client"), and we'll use Socket.IO to communicate with other players and tie together the front and back ends of our app.</p>
<p>The back end (referred to from here on as the "server") will be a simple Express server that receives Socket.IO events from the client and acts accordingly.  The whole application will run on Node as its runtime.</p>
<p>You don't need to be an expert in any of the above frameworks to complete this project, but it would be a good idea to have a solid foundation in basic JavaScript and HTML/CSS before trying to tackle the specifics. You can also follow along with my series on <a target="_blank" href="https://www.freecodecamp.org/news/learn-javascript-by-making-digital-tabletop-games-and-web-apps/">Learning JavaScript by Making Digital Tabletop Games and Web Apps</a>.  </p>
<p>You'll also want to make sure that you have Node and <a target="_blank" href="https://github.com/">Git</a> installed, along with your favorite code editor and a command line interface (you can follow my tutorial on setting up an IDE <a target="_blank" href="https://www.freecodecamp.org/news/how-to-set-up-an-integrated-development-environment-ide/">here</a> if you need help).</p>
<p>Let's get started!</p>
<h2 id="heading-part-1-client-basics">Part 1: Client Basics</h2>
<p>We'll begin building our client by installing the <a target="_blank" href="https://cli.vuejs.org/">Vue CLI</a>, which will help us with some tooling and allow us to make changes to our files without having to reload our web browser.</p>
<p>In a command line, type in the following to install the Vue CLI globally:</p>
<pre><code class="lang-cli">npm install -g @vue/cli
</code></pre>
<p>Navigate to a desired directory and create a new folder for our project:</p>
<pre><code class="lang-cli">mkdir tabletop-project
cd tabletop-project
</code></pre>
<p>Now we can use the Vue CLI to template a front end project for us:</p>
<pre><code class="lang-cli">vue create client
</code></pre>
<p>You can just hit "enter" at the ensuing prompts unless you have specific preferences.</p>
<p>The Vue CLI has helpfully templated a front end project for us, which we can view in our code editor:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/1.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's navigate to our new client folder in our CLI and run the template app:</p>
<pre><code class="lang-cli">cd client
npm run serve
</code></pre>
<p>After a little work, the Vue CLI should begin displaying our app in a web browser at the default http://localhost:8080:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/2.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Cool!  We have the basic structure of our client.  Let's break it by creating two new components in the /components folder, called Game.vue and Chat.vue (you can go ahead and delete HelloWorld.vue and anything in the assets folder if you're obsessed with tidiness like I am).</p>
<p>Replace the code in App.vue with the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"game"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Game</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"border"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"input"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Chat</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">import</span> Chat <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Chat.vue'</span>;
    <span class="hljs-keyword">import</span> Game <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Game.vue'</span>;

    <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'App'</span>,
        <span class="hljs-attr">components</span>: {
            Chat,
            Game
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
    <span class="hljs-selector-id">#app</span> {
        <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Trebuchet MS'</span>;
        <span class="hljs-attribute">text-align</span>: left;
        <span class="hljs-attribute">background-color</span>: black;
        <span class="hljs-attribute">color</span>: cyan;
        <span class="hljs-attribute">display</span>: flex;
    }
    <span class="hljs-selector-id">#game</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">50vw</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
    }
    <span class="hljs-selector-id">#input</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">50vw</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
    }
    <span class="hljs-selector-id">#border</span> {
        <span class="hljs-attribute">border-right</span>: <span class="hljs-number">2px</span> solid cyan;
    }
    <span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">1000px</span>) {
        <span class="hljs-selector-id">#app</span> {
            <span class="hljs-attribute">flex-direction</span>: column;
        }
        <span class="hljs-selector-id">#game</span> {
            <span class="hljs-attribute">width</span>: <span class="hljs-number">100vw</span>;
            <span class="hljs-attribute">height</span>: <span class="hljs-number">50vh</span>;
        }
        <span class="hljs-selector-id">#input</span> {
            <span class="hljs-attribute">width</span>: <span class="hljs-number">100vw</span>;
            <span class="hljs-attribute">height</span>: <span class="hljs-number">50vh</span>;
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>As you can see, a Vue component ordinarily has three sections: Template, Script, and Style, which contain any HTML, JavaScript, and CSS for that component, respectively.  We've just imported our Game and Chat components here and added a little styling to give it a cyberpunk feel when it's all up and running.</p>
<p>That's actually all that we need to do to set up our App.vue component, which will house everything else in our client.  Before we can actually do anything with it, we'll need to get our server working!</p>
<h2 id="heading-part-2-server-basics">Part 2: Server Basics</h2>
<p>At our root directory (tabletop-project, above /client), initialize a new project in a new command line interface by typing:</p>
<pre><code class="lang-cli">npm init
</code></pre>
<p>Like with our client, you can go ahead and press "enter" at the prompts unless there are specifics that you'd like to designate at this time.</p>
<p>We'll need to install Express and Socket.IO, along with <a target="_blank" href="https://nodemon.io/">Nodemon</a> to watch our server files for us and reboot as necessary:</p>
<pre><code class="lang-cli">npm install --save express socket.io nodemon
</code></pre>
<p>Let's open up the new package.json file in that root directory and add a "start" command in the "scripts" section:</p>
<pre><code class="lang-javascript">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon server.js"</span>
  },
</code></pre>
<p>Create a new file called server.js in this directory, and enter the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>).createServer(server);
<span class="hljs-keyword">const</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>)(http);

io.on(<span class="hljs-string">'connection'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">socket</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user connected: '</span> + socket.id);

    socket.on(<span class="hljs-string">'send'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">text</span>) </span>{
        <span class="hljs-keyword">let</span> newText = <span class="hljs-string">"&lt;"</span> + socket.id + <span class="hljs-string">"&gt; "</span> + text;
        io.emit(<span class="hljs-string">'receive'</span>, newText);
    });

    socket.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user disconnected: '</span> + socket.id);
    });
});

http.listen(<span class="hljs-number">3000</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server started!'</span>);
});
</code></pre>
<p>Excellent!  Our simple server will now listen at http://localhost:3000, and use Socket.IO to log to the console when a user connects and disconnects, with their socket ID.</p>
<p>When the server receives a "send" event from a client, it will create a new text string that includes the socket ID of the client that emitted the event, and emit its own "receive" event to all clients with the text that it received, interpolated with the socket ID.</p>
<p>We can test the server by returning to our command line and starting it up :</p>
<pre><code class="lang-cli">npm run start
</code></pre>
<p>The command console should now display:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/3-4.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Cool! Let's return to the Chat component of our client to start building out our front end functionality.</p>
<h2 id="heading-part-3-chat">Part 3: Chat</h2>
<p>Let's open a separate command line interface and navigate to the /client directory. Within that directory, install the client version of Socket.IO:</p>
<pre><code class="lang-cli">npm install --save socket.io-client
</code></pre>
<p>In /client/src/components/Chat.vue, add the following code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"output"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>STRUCT<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"(text, index) in textOutput"</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">"index"</span>&gt;</span>{{text}}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"input"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"textInput"</span> <span class="hljs-attr">:placeholder</span>=<span class="hljs-string">"textInput"</span> /&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Send"</span> <span class="hljs-attr">v-on:click</span>=<span class="hljs-string">"submitText"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">import</span> io <span class="hljs-keyword">from</span> <span class="hljs-string">'socket.io-client'</span>;
    <span class="hljs-keyword">let</span> socket = io(<span class="hljs-string">'http://localhost:3000'</span>);

    <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'Chat'</span>,
        <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">return</span> {
                <span class="hljs-attr">textInput</span>: <span class="hljs-literal">null</span>,
                <span class="hljs-attr">textOutput</span>: []
            }
        },
        <span class="hljs-attr">methods</span>: {
            <span class="hljs-attr">submitText</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
                event.preventDefault();
                socket.emit(<span class="hljs-string">'send'</span>, <span class="hljs-built_in">this</span>.textInput);
            }
        },
        <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            socket.on(<span class="hljs-string">'connect'</span>, <span class="hljs-function">() =&gt;</span> {
                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Connected!'</span>);
            });
            socket.on(<span class="hljs-string">'receive'</span>, <span class="hljs-function">(<span class="hljs-params">text</span>) =&gt;</span> {
                <span class="hljs-built_in">this</span>.textOutput.push(text);
                <span class="hljs-built_in">this</span>.textInput = <span class="hljs-literal">null</span>;
            });
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>&gt;</span><span class="css">
    <span class="hljs-selector-id">#container</span> {
        <span class="hljs-attribute">text-align</span>: left;
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">flex-direction</span>: column;
        <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">1vw</span>;
        <span class="hljs-attribute">min-height</span>: <span class="hljs-number">100vh</span>;
    }
    <span class="hljs-selector-tag">h1</span> {
        <span class="hljs-attribute">text-align</span>: center;
    }
    <span class="hljs-selector-class">.hotpink</span> {
        <span class="hljs-attribute">color</span>: hotpink;
    }
    <span class="hljs-selector-id">#input</span> {
        <span class="hljs-attribute">position</span>: fixed;
        <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">95vh</span>;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=text]</span> {
        <span class="hljs-attribute">height</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">width</span>:  <span class="hljs-number">40vw</span>;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid cyan;
        <span class="hljs-attribute">background-color</span>: black;
        <span class="hljs-attribute">color</span>: hotpink;
        <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">1em</span>;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span>{
        <span class="hljs-attribute">height</span>: <span class="hljs-number">25px</span>;
        <span class="hljs-attribute">width</span>: <span class="hljs-number">5vw</span>;
        <span class="hljs-attribute">background-color</span>: black;
        <span class="hljs-attribute">color</span>: cyan;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid cyan;
        <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">2vw</span>;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span><span class="hljs-selector-pseudo">:focus</span>{
        <span class="hljs-attribute">outline</span>: none;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span><span class="hljs-selector-pseudo">:hover</span>{
        <span class="hljs-attribute">color</span>: hotpink;
    }
    <span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">1000px</span>) {
        <span class="hljs-selector-id">#container</span> {
            <span class="hljs-attribute">border-left</span>: none;
            <span class="hljs-attribute">border-top</span>: <span class="hljs-number">2px</span> solid cyan;
            <span class="hljs-attribute">min-height</span>: <span class="hljs-number">50vh</span>;
        }
        <span class="hljs-selector-id">#input</span> {
            <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">43vh</span>;
        }
        <span class="hljs-selector-id">#output</span> {
            <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">10vw</span>;
        }
        <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=text]</span> {
            <span class="hljs-attribute">width</span>: <span class="hljs-number">60vw</span>;
        }
        <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span> {
            <span class="hljs-attribute">min-width</span>: <span class="hljs-number">10vw</span>;
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>Let's examine the above from bottom to top before moving forward.  Between the </p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Multiplayer Card Game with Phaser 3, Express, and Socket.IO ]]>
                </title>
                <description>
                    <![CDATA[ By M. S. Farzan I'm a tabletop game developer, and am continually looking for ways to digitize game experiences.  In this tutorial, we're going to build a multiplayer card game using Phaser 3, Express, and Socket.IO. In terms of prerequisites, you'll... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-multiplayer-card-game-with-phaser-3-express-and-socket-io/</link>
                <guid isPermaLink="false">66d851e78da7a7c34f4c9223</guid>
                
                    <category>
                        <![CDATA[ ES6 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express JS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ phaser 3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SocketIO ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 25 Mar 2020 20:57:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/Client-2-2.PNG" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By M. S. Farzan</p>
<p>I'm a <a target="_blank" href="https://www.nightpathpub.com/entromancy">tabletop game</a> developer, and am continually looking for ways to digitize game experiences.  In this tutorial, we're going to build a multiplayer card game using <a target="_blank" href="http://phaser.io/">Phaser 3</a>, <a target="_blank" href="https://expressjs.com/">Express</a>, and <a target="_blank" href="https://socket.io/">Socket.IO</a>.</p>
<p>In terms of prerequisites, you'll want to make sure that you have <a target="_blank" href="https://nodejs.org/en/">Node</a>/<a target="_blank" href="https://www.npmjs.com/">NPM</a> and <a target="_blank" href="https://github.com/">Git</a> installed and configured on your machine.  Some experience with JavaScript would be helpful, and you may want to run through the <a target="_blank" href="http://phaser.io/tutorials/making-your-first-phaser-3-game">basic Phaser tutorial</a> before tackling this one.</p>
<p>Major kudos to Scott Westover for <a target="_blank" href="https://gamedevacademy.org/create-a-basic-multiplayer-game-in-phaser-3-with-socket-io-part-1/">his tutorial on the topic</a>, Kal_Torak and the Phaser community for answering all my questions, and my good friend Mike for helping me conceptualize the architecture of this project.</p>
<p>Note: we'll be using assets and colors from my tabletop card game, <em><a target="_blank" href="https://www.nightpathpub.com/hacker-battles">Entromancy: Hacker Battles</a></em>.  If you prefer, you can use your own images (or even <a target="_blank" href="http://phaser.io/examples/v3/view/game-objects/shapes/rectangle">Phaser rectangles</a>) and colors, and you can access the entire project code on <a target="_blank" href="https://github.com/sominator/multiplayer-card-project">GitHub</a>.</p>
<p>If you'd prefer a more visual tutorial, you can also follow along with the companion video to this article:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/fEwAgKBgoJM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Let's get started!</p>
<h2 id="heading-the-game">The Game</h2>
<p>Our simple card game will feature a Phaser client that will handle most of the game logic and doing things like dealing cards, providing drag-and-drop functionality, and so on.</p>
<p>On the back end, we'll spin up an Express server that will utilize Socket.IO to communicate between clients and make it so that when one player plays a card, it shows up in another player's client, and vice-versa.</p>
<p>Our goal for this project is to create a basic framework for a multiplayer card game that you can build upon and adjust to suit your own game's logic.</p>
<p>First, let's tackle the client!</p>
<h2 id="heading-the-client">The Client</h2>
<p>To scaffold our client, we're going to clone the semi-official Phaser 3 Webpack Project Template on <a target="_blank" href="https://github.com/photonstorm/phaser3-project-template">GitHub</a>.</p>
<p>Open your favorite command line interface and create a new folder:</p>
<pre><code class="lang-cli">mkdir multiplayer-card-project
cd multiplayer-card-project
</code></pre>
<p>Clone the git project:</p>
<pre><code class="lang-cli">git clone https://github.com/photonstorm/phaser3-project-template.git
</code></pre>
<p>This command will download the template in a folder called "phaser3-project-template" within /multiplayer-card-project.  If you want to follow along with our tutorial's file structure, go ahead and change that template folder's name to "client."</p>
<p>Navigate into that new directory and install all dependencies:</p>
<pre><code class="lang-cli">cd client
npm install
</code></pre>
<p>Your project folder structure should look something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/File-Structure-1-4.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Before we muck with the files, let's go back to our CLI and enter the following command in the /client folder:</p>
<pre><code class="lang-cli">npm start
</code></pre>
<p>Our Phaser template utilizes Webpack to spin up a local server that in turn serves up a simple game app in our browser (usually at http://localhost:8080).  Neat!</p>
<p>Let's open our project in your favorite code editor and make some changes to fit our card game.  Delete everything in /client/src/assets and replace them with the card images from <a target="_blank" href="https://github.com/sominator/multiplayer-card-project/tree/master/client/src/assets">GitHub</a>.</p>
<p>In the /client/src directory, add a folder called "scenes" and another called "helpers."</p>
<p>In /client/src/scenes, add an empty file called "game.js".</p>
<p>In /client/src/helpers, add three empty files: "card.js", "dealer.js", and "zone.js".</p>
<p>Your project structure should now look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/File-Structure-2.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Cool!  Your client might be throwing you errors because we deleted some things, but not to worry.  Open /src/index.js, which is the main entry point to our front end app. Enter the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Phaser <span class="hljs-keyword">from</span> <span class="hljs-string">"phaser"</span>;
<span class="hljs-keyword">import</span> Game <span class="hljs-keyword">from</span> <span class="hljs-string">"./scenes/game"</span>;

<span class="hljs-keyword">const</span> config = {
    <span class="hljs-attr">type</span>: Phaser.AUTO,
    <span class="hljs-attr">parent</span>: <span class="hljs-string">"phaser-example"</span>,
    <span class="hljs-attr">width</span>: <span class="hljs-number">1280</span>,
    <span class="hljs-attr">height</span>: <span class="hljs-number">780</span>,
    <span class="hljs-attr">scene</span>: [
        Game
    ]
};

<span class="hljs-keyword">const</span> game = <span class="hljs-keyword">new</span> Phaser.Game(config);
</code></pre>
<p>All we've done here is restructure the boilerplate to utilize Phaser's "scene" system so that we can separate our game scenes rather than try to cram everything in one file.  Scenes can be useful if you're creating multiple game worlds, building things like instruction screens, or generally trying to keep things tidy.</p>
<p>Let's move to /src/scenes/game.js and write some code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Game</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Phaser</span>.<span class="hljs-title">Scene</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-built_in">super</span>({
            <span class="hljs-attr">key</span>: <span class="hljs-string">'Game'</span>
        });
    }

    preload() {
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardFront'</span>, <span class="hljs-string">'src/assets/CyanCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardBack'</span>, <span class="hljs-string">'src/assets/CyanCardBack.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardFront'</span>, <span class="hljs-string">'src/assets/MagentaCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardBack'</span>, <span class="hljs-string">'src/assets/MagentaCardBack.png'</span>);
    }

    create() {
        <span class="hljs-built_in">this</span>.dealText = <span class="hljs-built_in">this</span>.add.text(<span class="hljs-number">75</span>, <span class="hljs-number">350</span>, [<span class="hljs-string">'DEAL CARDS'</span>]).setFontSize(<span class="hljs-number">18</span>).setFontFamily(<span class="hljs-string">'Trebuchet MS'</span>).setColor(<span class="hljs-string">'#00ffff'</span>).setInteractive();
    }

    update() {

    }
}
</code></pre>
<p>We're taking advantage of <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-github-and-es6-features-to-create-and-structure-your-code/">ES6 classes</a> to create a new Game scene, which incorporates preload(), create() and update() functions.</p>
<p>preload() is used to...well...preload any assets that we'll be using for our game.</p>
<p>create() is run when the game starts up, and where we'll be establishing much of our user interface and game logic.</p>
<p>update() is called once per frame, and we won't be making use of it in our tutorial (but it may be useful in your own game depending on its requirements).</p>
<p>Within the create() function, we've created a bit of text that says "DEAL CARDS" and set it to be interactive:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Deal-Cards.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Very cool.  Let's create a bit of placeholder code to understand how we want this whole thing to work once it's up and running.  Add the following to your create() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-keyword">let</span> self = <span class="hljs-built_in">this</span>;

        <span class="hljs-built_in">this</span>.card = <span class="hljs-built_in">this</span>.add.image(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-string">'cyanCardFront'</span>).setScale(<span class="hljs-number">0.3</span>, <span class="hljs-number">0.3</span>).setInteractive();
        <span class="hljs-built_in">this</span>.input.setDraggable(<span class="hljs-built_in">this</span>.card);

        <span class="hljs-built_in">this</span>.dealCards = <span class="hljs-function">() =&gt;</span> {

        }

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealCards();
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerover'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#ff69b4'</span>);
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerout'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#00ffff'</span>);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drag'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dragX, dragY</span>) </span>{
            gameObject.x = dragX;
            gameObject.y = dragY;
        })
</code></pre>
<p>We've added a lot of structure, but not much has happened.  Now, when our mouse hovers over the "DEAL CARDS" text, it's highlighted in cyberpunk hot pink, and there's a random card on our screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Card.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We've placed the image at the (x, y) coordinates of (300, 300), set its scale to be a bit smaller, and made it interactive and draggable.  We've also added a little bit of logic to determine what should happen when dragged: it should follow the (x, y) coordinates of our mouse.</p>
<p>We've also created an empty dealCards() function that will be called when we click on our "DEAL CARDS" text.  Additionally, we've saved "this" - meaning the scene in which we're currently working - into a variable called "self" so that we can use it throughout our functions without worrying about scope.</p>
<p>Our Game scene is going to get messy fast if we don't start moving things around, so let's delete the code block that begins with "this.card" and move to /src/helpers/card.js to write:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Card</span> </span>{
    <span class="hljs-keyword">constructor</span>(scene) {
        <span class="hljs-built_in">this</span>.render = <span class="hljs-function">(<span class="hljs-params">x, y, sprite</span>) =&gt;</span> {
            <span class="hljs-keyword">let</span> card = scene.add.image(x, y, sprite).setScale(<span class="hljs-number">0.3</span>, <span class="hljs-number">0.3</span>).setInteractive();
            scene.input.setDraggable(card);
            <span class="hljs-keyword">return</span> card;
        }
    }
}
</code></pre>
<p>We've created a new class that accepts a scene as a parameter, and features a render() function that accepts (x, y) coordinates and a sprite.  Now, we can call this function from elsewhere and pass it the necessary parameters to create cards.</p>
<p>Let's import the card at the top of our Game scene:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Card <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/card'</span>;
</code></pre>
<p> And enter the following code within our empty dealCards() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.dealCards = <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) {
                <span class="hljs-keyword">let</span> playerCard = <span class="hljs-keyword">new</span> Card(<span class="hljs-built_in">this</span>);
                playerCard.render(<span class="hljs-number">475</span> + (i * <span class="hljs-number">100</span>), <span class="hljs-number">650</span>, <span class="hljs-string">'cyanCardFront'</span>);
            }
        }
</code></pre>
<p>When we click on the "DEAL CARDS" button, we now iterate through a for loop that creates cards and renders them sequentially on screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Cards.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>NICE.  We can drag those cards around the screen, but it might be nice to limit where they can be dropped to support our game logic.</p>
<p>Let's move over to /src/helpers/zone.js and add a new class:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Zone</span> </span>{
    <span class="hljs-keyword">constructor</span>(scene) {
        <span class="hljs-built_in">this</span>.renderZone = <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-keyword">let</span> dropZone = scene.add.zone(<span class="hljs-number">700</span>, <span class="hljs-number">375</span>, <span class="hljs-number">900</span>, <span class="hljs-number">250</span>).setRectangleDropZone(<span class="hljs-number">900</span>, <span class="hljs-number">250</span>);
            dropZone.setData({ <span class="hljs-attr">cards</span>: <span class="hljs-number">0</span> });
            <span class="hljs-keyword">return</span> dropZone;
        };
        <span class="hljs-built_in">this</span>.renderOutline = <span class="hljs-function">(<span class="hljs-params">dropZone</span>) =&gt;</span> {
            <span class="hljs-keyword">let</span> dropZoneOutline = scene.add.graphics();
            dropZoneOutline.lineStyle(<span class="hljs-number">4</span>, <span class="hljs-number">0xff69b4</span>);
            dropZoneOutline.strokeRect(dropZone.x - dropZone.input.hitArea.width / <span class="hljs-number">2</span>, dropZone.y - dropZone.input.hitArea.height / <span class="hljs-number">2</span>, dropZone.input.hitArea.width, dropZone.input.hitArea.height)
        }
    }
}
</code></pre>
<p>Phaser has built-in dropzones that allow us to dictate where game objects can be dropped, and we've set up one here and provided it with an outline.  We've also added a tiny bit of data called "cards" to the dropzone that we'll use later.</p>
<p>Let's import our new zone into the Game scene:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Zone <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/zone'</span>;
</code></pre>
<p> And call it in within the create() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.zone = <span class="hljs-keyword">new</span> Zone(<span class="hljs-built_in">this</span>);
        <span class="hljs-built_in">this</span>.dropZone = <span class="hljs-built_in">this</span>.zone.renderZone();
        <span class="hljs-built_in">this</span>.outline = <span class="hljs-built_in">this</span>.zone.renderOutline(<span class="hljs-built_in">this</span>.dropZone);
</code></pre>
<p>Not too shabby!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Zone.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We need to add a bit of logic to determine how cards should be dropped into the zone.  Let's do that below the "this.input.on('drag')" function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragstart'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject</span>) </span>{
            gameObject.setTint(<span class="hljs-number">0xff69b4</span>);
            self.children.bringToTop(gameObject);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragend'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropped</span>) </span>{
            gameObject.setTint();
            <span class="hljs-keyword">if</span> (!dropped) {
                gameObject.x = gameObject.input.dragStartX;
                gameObject.y = gameObject.input.dragStartY;
            }
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drop'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropZone</span>) </span>{
            dropZone.data.values.cards++;
            gameObject.x = (dropZone.x - <span class="hljs-number">350</span>) + (dropZone.data.values.cards * <span class="hljs-number">50</span>);
            gameObject.y = dropZone.y;
            gameObject.disableInteractive();
        })
</code></pre>
<p>Starting at the bottom of the code, when a card is dropped, we increment the "cards" data value on the dropzone, and assign the (x, y) coordinates of the card to the dropzone based on how many cards are already on it.  We also disable interactivity on cards after they're dropped so that they can't be retracted:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Zone-Dropped.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We've also made it so that our cards have a different tint when dragged, and if they're not dropped over the dropzone, they'll return to their starting positions.</p>
<p>Although our client isn't quite complete, we've done as much as we can before implementing the back end.  We can now deal cards, drag them around the screen, and drop them in a dropzone. But to move forward, we'll need to set up a server than can coordinate our multiplayer functionality.</p>
<h2 id="heading-the-server">The Server</h2>
<p>Let's open up a new command line at our root directory (above /client) and type:</p>
<pre><code class="lang-cli">npm init
npm install --save express socket.io nodemon
</code></pre>
<p>We've initialized a new package.json and installed Express, Socket.IO, and <a target="_blank" href="https://nodemon.io/">Nodemon</a> (which will watch our server and restart it upon changes).</p>
<p>In our code editor, let's change the "scripts" section of our package.json to say:</p>
<pre><code class="lang-javascript">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon server.js"</span>
  },
</code></pre>
<p>Excellent.  We're ready to put our server together!  Create an empty file called "server.js" in our root directory and enter the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>).createServer(server);
<span class="hljs-keyword">const</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>)(http);

io.on(<span class="hljs-string">'connection'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">socket</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user connected: '</span> + socket.id);

    socket.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user disconnected: '</span> + socket.id);
    });
});

http.listen(<span class="hljs-number">3000</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server started!'</span>);
});
</code></pre>
<p>We're importing Express and Socket.IO, asking for the server to listen on port 3000. When a client connects to or disconnects from that port, we'll log the event to the console with the client's socket id.</p>
<p>Open a new command line interface and start the server:</p>
<pre><code class="lang-cli">npm run start
</code></pre>
<p>Our server should now be running on localhost:3000, and Nodemon will watch our back end files for any changes.  Not much else will happen except for the console log that the "Server started!"</p>
<p>In our other open command line interface, let's navigate back to our /client directory and install the client version of Socket.IO:</p>
<pre><code class="lang-cli">cd client
npm install --save socket.io-client
</code></pre>
<p>We can now import it in our Game scene:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> io <span class="hljs-keyword">from</span> <span class="hljs-string">'socket.io-client'</span>;
</code></pre>
<p>Great!  We've just about wired up our front and back ends.  All we need to do is write some code in the create() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.socket = io(<span class="hljs-string">'http://localhost:3000'</span>);

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'connect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Connected!'</span>);
        });
</code></pre>
<p>We're initializing a new "socket" variable that points to our local port 3000 and logs to the browser console upon connection.</p>
<p>Open and close a couple of browsers at http://localhost:8080 (where our Phaser client is being served) and you should see the following in your command line interface:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Console.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>YAY.  Let's start adding logic to our server.js file that will serve the needs of our card game.  Replace the existing code with the following:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>).createServer(server);
<span class="hljs-keyword">const</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>)(http);
<span class="hljs-keyword">let</span> players = [];

io.on(<span class="hljs-string">'connection'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">socket</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user connected: '</span> + socket.id);

    players.push(socket.id);

    <span class="hljs-keyword">if</span> (players.length === <span class="hljs-number">1</span>) {
        io.emit(<span class="hljs-string">'isPlayerA'</span>);
    };

    socket.on(<span class="hljs-string">'dealCards'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        io.emit(<span class="hljs-string">'dealCards'</span>);
    });

    socket.on(<span class="hljs-string">'cardPlayed'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">gameObject, isPlayerA</span>) </span>{
        io.emit(<span class="hljs-string">'cardPlayed'</span>, gameObject, isPlayerA);
    });

    socket.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user disconnected: '</span> + socket.id);
        players = players.filter(<span class="hljs-function"><span class="hljs-params">player</span> =&gt;</span> player !== socket.id);
    });
});

http.listen(<span class="hljs-number">3000</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server started!'</span>);
});
</code></pre>
<p>We've initialized an empty array called "players" and add a socket id to it every time a client connects to the server, while also deleting the socket id upon disconnection.</p>
<p>If a client is the first to connect to the server, we ask Socket.IO to "<a target="_blank" href="https://socket.io/get-started/chat/#Emitting-events">emit</a>" an event that they're going to be Player A.  Subsequently, when the server receives an event called "dealCards" or "cardPlayed", it should emit back to the clients that they should update accordingly.</p>
<p>Believe it or not, that's all the code we need to get our server working!  Let's turn our attention back to the Game scene.  Right at the top of the create() function, type the following:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.isPlayerA = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.opponentCards = [];
</code></pre>
<p>Under the code block that starts with "this.socket.on(connect)", write:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'isPlayerA'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.isPlayerA = <span class="hljs-literal">true</span>;
        })
</code></pre>
<p>Now, if our client is the first to connect to the server, the server will emit an event that tells the client that it will be Player A.  The client socket receives that event and turns our "isPlayerA" boolean from false to true.</p>
<p>Note: from this point forward, you may need to reload your browser page (set to http://localhost:8080), rather than having Webpack do it automatically for you, for the client to correctly disconnect from and reconnect to the server.</p>
<p>We need to reconfigure our dealCards() logic to support the multiplayer aspect of our game, given that we want the client to deal us a certain set of cards that may be different from our opponent's.  Additionally, we want to render the backs of our opponent's cards on our screen, and vice versa.</p>
<p>We'll move to the empty /src/helpers/dealer.js file, import card.js, and create a new class:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Card <span class="hljs-keyword">from</span> <span class="hljs-string">'./card'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dealer</span> </span>{
    <span class="hljs-keyword">constructor</span>(scene) {
        <span class="hljs-built_in">this</span>.dealCards = <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-keyword">let</span> playerSprite;
            <span class="hljs-keyword">let</span> opponentSprite;
            <span class="hljs-keyword">if</span> (scene.isPlayerA) {
                playerSprite = <span class="hljs-string">'cyanCardFront'</span>;
                opponentSprite = <span class="hljs-string">'magentaCardBack'</span>;
            } <span class="hljs-keyword">else</span> {
                playerSprite = <span class="hljs-string">'magentaCardFront'</span>;
                opponentSprite = <span class="hljs-string">'cyanCardBack'</span>;
            };
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) {
                <span class="hljs-keyword">let</span> playerCard = <span class="hljs-keyword">new</span> Card(scene);
                playerCard.render(<span class="hljs-number">475</span> + (i * <span class="hljs-number">100</span>), <span class="hljs-number">650</span>, playerSprite);

                <span class="hljs-keyword">let</span> opponentCard = <span class="hljs-keyword">new</span> Card(scene);
                scene.opponentCards.push(opponentCard.render(<span class="hljs-number">475</span> + (i * <span class="hljs-number">100</span>), <span class="hljs-number">125</span>, opponentSprite).disableInteractive());
            }
        }
    }
}
</code></pre>
<p>With this new class, we're checking whether the client is Player A, and determining what sprites should be used in either case.</p>
<p>Then, we deal cards to our client, while rendering the backs of our opponent's cards at the top the screen and adding them to the opponentCards array that we initialized in our Game scene.</p>
<p>In /src/scenes/game.js, import the Dealer:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Dealer <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/dealer'</span>;
</code></pre>
<p>Then replace our dealCards() function with:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.dealer = <span class="hljs-keyword">new</span> Dealer(<span class="hljs-built_in">this</span>);
</code></pre>
<p>Under code block that begins with "this.socket.on('isPlayerA')", add the following:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'dealCards'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealer.dealCards();
            self.dealText.disableInteractive();
        })
</code></pre>
<p>We also need to update our dealText function to match these changes:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.socket.emit(<span class="hljs-string">"dealCards"</span>);
        })
</code></pre>
<p>Phew!  We've created a new Dealer class that will handle dealing cards to us and rendering our opponent's cards to the screen.  When the client socket receives the "dealcards" event from the server, it will call the dealCards() function from this new class, and disable the dealText so that we can't just keep generating cards for no reason.</p>
<p>Finally, we've changed the dealText functionality so that when it's pressed, the client emits an event to the server that we want to deal cards, which ties everything together.</p>
<p>Fire up two separate browsers pointed to http://localhost:8080 and hit "DEAL CARDS" on one of them.  You should see different sprites on either screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Client-1.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Client-2.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Note again that if you're having issues with this step, you may have to close one of your browsers and reload the first one to ensure that both clients have disconnected from the server, which should be logged to your command line console.</p>
<p>We still need to figure out how to render our dropped cards in our opponent's client, and vice-versa.  We can do all of that in our game scene!  Update the code block that begins with "this.input.on('drop')" with one line at the end:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drop'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropZone</span>) </span>{
            dropZone.data.values.cards++;
            gameObject.x = (dropZone.x - <span class="hljs-number">350</span>) + (dropZone.data.values.cards * <span class="hljs-number">50</span>);
            gameObject.y = dropZone.y;
            gameObject.disableInteractive();
            self.socket.emit(<span class="hljs-string">'cardPlayed'</span>, gameObject, self.isPlayerA);
        })
</code></pre>
<p>When a card is dropped in our client, the socket will emit an event called "cardPlayed", passing the details of the game object and the client's isPlayerA boolean (which could be true or false, depending on whether the client was the first to connect to the server).</p>
<p>Recall that, in our server code, Socket.IO simply receives the "cardPlayed" event and emits the same event back up to all of the clients, passing the same information about the game object and isPlayerA from the client that initiated the event<em>.</em></p>
<p>Let's write what should happen when a client receives a "cardPlayed" event from the server, below the "this.socket.on('dealCards')" code block:</p>
<pre><code class="lang-javascript">         <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'cardPlayed'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">gameObject, isPlayerA</span>) </span>{
            <span class="hljs-keyword">if</span> (isPlayerA !== self.isPlayerA) {
                <span class="hljs-keyword">let</span> sprite = gameObject.textureKey;
                self.opponentCards.shift().destroy();
                self.dropZone.data.values.cards++;
                <span class="hljs-keyword">let</span> card = <span class="hljs-keyword">new</span> Card(self);
                card.render(((self.dropZone.x - <span class="hljs-number">350</span>) + (self.dropZone.data.values.cards * <span class="hljs-number">50</span>)), (self.dropZone.y), sprite).disableInteractive();
            }
        })
</code></pre>
<p>The code block first compares the isPlayerA boolean it receives from the server against the client's own isPlayerA, which is a check to determine whether the client that is receiving the event is the same one that generated it.</p>
<p>Let's think that through a bit further, as it exposes a key component to how our client - server relationship works, using Socket.IO as the connector.</p>
<p>Suppose that Client A connects to the server first, and is told through the "isPlayerA" event that it should change its isPlayerA boolean to <strong>true</strong>.  That's going to determine what kind of cards it generates when a user clicks "DEAL CARDS" through that client.</p>
<p>If Client B connects to the server second, it's never told to alter its isPlayerA boolean, which stays <strong>false</strong>.  That will also determine what kind of cards it generates.</p>
<p>When Client A drops a card, it emits a "cardPlayed" event to the server, passing information about the card that was dropped, and its isPlayerA boolean, which is <strong>true</strong>.  The server then relays all that information back up to all clients with its own "cardPlayed" event.</p>
<p>Client A receives that event from the server, and notes that the isPlayerA boolean from the server is <strong>true</strong>, which means that the event was generated by Client A itself. Nothing special happens.</p>
<p>Client B receives the same event from the server, and notes that the isPlayerA boolean from the server is <strong>true</strong>, although Client B's own isPlayerA is <strong>false</strong>.  Because of this difference, it executes the rest of the code block.  </p>
<p>The ensuing code stores the "texturekey" - basically, the image - of the game object that it receives from the server into a variable called "sprite". It destroys one of the opponent card backs that are rendered at the top of the screen, and increments the "cards" data value in the dropzone so that we can keep placing cards from left to right.  </p>
<p>The code then generates a new card in the dropzone that uses the sprite variable to create the same card that was dropped in the other client (if you had data attached to that game object, you could use a similar approach to attach it here as well).</p>
<p>Your final /src/scenes/game.js code should look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> io <span class="hljs-keyword">from</span> <span class="hljs-string">'socket.io-client'</span>;
<span class="hljs-keyword">import</span> Card <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/card'</span>;
<span class="hljs-keyword">import</span> Dealer <span class="hljs-keyword">from</span> <span class="hljs-string">"../helpers/dealer"</span>;
<span class="hljs-keyword">import</span> Zone <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/zone'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Game</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Phaser</span>.<span class="hljs-title">Scene</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-built_in">super</span>({
            <span class="hljs-attr">key</span>: <span class="hljs-string">'Game'</span>
        });
    }

    preload() {
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardFront'</span>, <span class="hljs-string">'src/assets/CyanCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardBack'</span>, <span class="hljs-string">'src/assets/CyanCardBack.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardFront'</span>, <span class="hljs-string">'src/assets/magentaCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardBack'</span>, <span class="hljs-string">'src/assets/magentaCardBack.png'</span>);
    }

    create() {
        <span class="hljs-built_in">this</span>.isPlayerA = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.opponentCards = [];

        <span class="hljs-built_in">this</span>.zone = <span class="hljs-keyword">new</span> Zone(<span class="hljs-built_in">this</span>);
        <span class="hljs-built_in">this</span>.dropZone = <span class="hljs-built_in">this</span>.zone.renderZone();
        <span class="hljs-built_in">this</span>.outline = <span class="hljs-built_in">this</span>.zone.renderOutline(<span class="hljs-built_in">this</span>.dropZone);

        <span class="hljs-built_in">this</span>.dealer = <span class="hljs-keyword">new</span> Dealer(<span class="hljs-built_in">this</span>);

        <span class="hljs-keyword">let</span> self = <span class="hljs-built_in">this</span>;

        <span class="hljs-built_in">this</span>.socket = io(<span class="hljs-string">'http://localhost:3000'</span>);

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'connect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Connected!'</span>);
        });

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'isPlayerA'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.isPlayerA = <span class="hljs-literal">true</span>;
        })

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'dealCards'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealer.dealCards();
            self.dealText.disableInteractive();
        })

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'cardPlayed'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">gameObject, isPlayerA</span>) </span>{
            <span class="hljs-keyword">if</span> (isPlayerA !== self.isPlayerA) {
                <span class="hljs-keyword">let</span> sprite = gameObject.textureKey;
                self.opponentCards.shift().destroy();
                self.dropZone.data.values.cards++;
                <span class="hljs-keyword">let</span> card = <span class="hljs-keyword">new</span> Card(self);
                card.render(((self.dropZone.x - <span class="hljs-number">350</span>) + (self.dropZone.data.values.cards * <span class="hljs-number">50</span>)), (self.dropZone.y), sprite).disableInteractive();
            }
        })

        <span class="hljs-built_in">this</span>.dealText = <span class="hljs-built_in">this</span>.add.text(<span class="hljs-number">75</span>, <span class="hljs-number">350</span>, [<span class="hljs-string">'DEAL CARDS'</span>]).setFontSize(<span class="hljs-number">18</span>).setFontFamily(<span class="hljs-string">'Trebuchet MS'</span>).setColor(<span class="hljs-string">'#00ffff'</span>).setInteractive();

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.socket.emit(<span class="hljs-string">"dealCards"</span>);
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerover'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#ff69b4'</span>);
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerout'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#00ffff'</span>);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drag'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dragX, dragY</span>) </span>{
            gameObject.x = dragX;
            gameObject.y = dragY;
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragstart'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject</span>) </span>{
            gameObject.setTint(<span class="hljs-number">0xff69b4</span>);
            self.children.bringToTop(gameObject);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragend'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropped</span>) </span>{
            gameObject.setTint();
            <span class="hljs-keyword">if</span> (!dropped) {
                gameObject.x = gameObject.input.dragStartX;
                gameObject.y = gameObject.input.dragStartY;
            }
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drop'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropZone</span>) </span>{
            dropZone.data.values.cards++;
            gameObject.x = (dropZone.x - <span class="hljs-number">350</span>) + (dropZone.data.values.cards * <span class="hljs-number">50</span>);
            gameObject.y = dropZone.y;
            gameObject.disableInteractive();
            self.socket.emit(<span class="hljs-string">'cardPlayed'</span>, gameObject, self.isPlayerA);
        })
    }

    update() {

    }
}
</code></pre>
<p>Save everything, open two browsers, and hit "DEAL CARDS".  When you drag and drop a card in one client, it should appear in the dropzone of the other, while also deleting a card back, signifying that a card has been played:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Card-Played-1.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Card-Played-2.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>That's it!  You should now have a functional template for your multiplayer card game, which you can use to add your own cards, art, and game logic.</p>
<p>One first step could be to add to your Dealer class by making it shuffle an array of cards and return a random one (hint: check out <a target="_blank" href="https://photonstorm.github.io/phaser3-docs/Phaser.Math.RandomDataGenerator.html#shuffle__anchor">Phaser.Math.RND.shuffle([array])</a>).</p>
<p>Happy coding!</p>
<p>If you enjoyed this article, please consider <a target="_blank" href="https://www.nightpathpub.com/">checking out my games and books</a>, <a target="_blank" href="https://www.youtube.com/msfarzan?sub_confirmation=1">subscribing to my YouTube channel</a>, or <a target="_blank" href="https://discord.gg/RF6k3nB">joining the <em>Entromancy</em> Discord</a>.</p>
<p>M. S. Farzan, Ph.D. has written and worked for high-profile video game companies and editorial websites such as Electronic Arts, Perfect World Entertainment, Modus Games, and MMORPG.com, and has served as the Community Manager for games like <em>Dungeons &amp; Dragons Neverwinter</em> and <em>Mass Effect: Andromeda</em>. He is the Creative Director and Lead Game Designer of <em><a target="_blank" href="https://www.nightpathpub.com/rpg">Entromancy: A Cyberpunk Fantasy RPG</a></em> and author of <em><a target="_blank" href="http://nightpathpub.com/books">The Nightpath Trilogy</a></em>. Find M. S. Farzan on Twitter <a target="_blank" href="https://twitter.com/sominator">@sominator</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ I built a role playing game in JavaScript. You can, too. Here’s how. ]]>
                </title>
                <description>
                    <![CDATA[ By Robert Skalko So you want to try and make a game, but are a bit intimidated? Don’t worry, I was too! I was afraid of using objects, for example. They were this big spooky thing that I shelved away for later. But now I use them all the time! ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learning-javascript-by-making-a-game-4aca51ad9030/</link>
                <guid isPermaLink="false">66c359fcc5e11f7a9c406858</guid>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Life lessons ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 02 Sep 2016 19:20:55 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*dT0K035G8ZPYB6qWv4Vy1Q.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Robert Skalko</p>
<p>So you want to try and make a game, but are a bit intimidated? Don’t worry, I was too!</p>
<p>I was afraid of using objects, for example. They were this big spooky thing that I shelved away for later. But now I use them all the time!</p>
<p>I’m going to walk you through all the steps I went through to build my JavaScript role playing game.</p>
<p>Here’s my game running on CodePen. (Note that it’s not yet optimized for mobile):</p>
<p><strong>First</strong>, pick the point of your game. Is it a puzzle? An RPG? A hack &amp; slash? All right, now think about the technical difficulties of making it. A puzzle game would require a lot of complicated javascript. A hack &amp; slash would need a lot of careful balancing, and so on.</p>
<p>Also, decide whether you want it to be a browser game, a mobile game, or both (a “native web” game).</p>
<p>For example, my game can’t fit well on mobile screen, because the player has 24 spells. That’s not comfortable clicking these small buttons on a tiny screen, so I would need to redesign the game for mobile.</p>
<p><strong>Second</strong>, write down <em>all</em> the things you need to program to actually make the game. For me it was:</p>
<ul>
<li>an inventory system</li>
<li>an item generator</li>
<li>a player stat system</li>
<li>a saving system</li>
</ul>
<p><strong>Third</strong>, start making your game by solving these problems one by one.</p>
<h3 id="heading-need-help-actually-creating-the-game">Need help actually creating the game?</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*aEC1UYYqmYtobaoaCTqg0Q.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>It’s much easier to break your game down into small tasks. You’re not making a game, you’re making an inventory system. Then you’re making a combat system. And so on.</p>
<p>Unless you are already good at drawing — or want to spend months or years getting good at it — use these tools to create assets that will make your game look good:</p>
<ul>
<li><a target="_blank" href="http://game-icons.net">Game-Icons.net</a> — these icons are fun and easy to color</li>
<li><a target="_blank" href="http://opengameart.org">Open Game Art</a> — get some great public domain assets</li>
<li><a target="_blank" href="http://bulkresizephotos.com">Bulk Resize Photos</a> — a great tool for making your own tiny icons</li>
<li><a target="_blank" href="http://spritegen.website-performance.org">CSS Sprite Generator</a> — helps you make CSS spritesheets for your icons</li>
</ul>
<h3 id="heading-issues-i-encountered-them-and-how-i-solved-them">Issues I encountered them and how I solved them</h3>
<h4 id="heading-spritesheets">Spritesheets</h4>
<p>Do you plan on having more than 20 images in your game? If so, you don’t want to make 20 images with image links to each one. You might not think 20 images is that much, but if you decide to add 50 more? That’s where <a target="_blank" href="http://spritegen.website-performance.org">spritesheets</a> come in handy. Put some pictures onto them, copy the CSS file to your project, and just add the class to your element that corresponds with your desired image.</p>
<h4 id="heading-saving-your-games-state">Saving your game’s state</h4>
<p>Do you want your game to be saved? Well you can choose between using the browser’s LocalStorage and storing things on a server. Servers require back end knowledge. If you have none, I suggest using LocalStorage. It saves the game as long as the user doesn’t delete it with some cleanup tool. Here’s how I did it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*8mlKqFNdm2SFjSooVGFsKg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Basically, save all your data in one object, then update your items on load. Use the JSON stringify and parse it later.</p>
<h4 id="heading-modularize-your-code">Modularize your code</h4>
<p>Figure out which part to hard-code and which parts to modularize. I mistakenly started hard-coding spells, which got ugly quickly. I needed 24 of these functions, along with 24 ifCritical functions.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*tCuUgl39v-PFS4KJaLjZWw.png" alt="Image" width="600" height="400" loading="lazy">
<em>I swear I didn’t write this! Uhh.. I was forced to!</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*4FoWNMmrj3KZnxYoeVPqyQ.png" alt="Image" width="600" height="400" loading="lazy">
<em>It even has a function which can add custom functionality!</em></p>
<p>Now you may ask, how does the second spell work? I have a function playerAttack() that uses the spell object to do stuff:</p>
<ul>
<li>It first runs the update spells function, which calls the spells object. Then the spell takes your current stats and turns them into values like “damage” and “mana cost”.</li>
<li>It checks to see whether the damage is more than 0. If yes, it does damage to boss and displays the damage, which spell did it, and the amount. It does this for most other values, too. You might think that a greater-than-zero check is useless, but you’ll think again when the game says you did 0 damage and restored 0 mana.</li>
<li>Then it runs a custom function, if the spell has one. This could be used to give spells special effects which aren’t possible through our main attack function.</li>
</ul>
<h4 id="heading-the-game-loop">The game loop</h4>
<p>For me, the game loop checks and update things: player stats, whether the player is dead, whether the player just leveled up, whether a boss is dead, and so on.</p>
<p>You’ll have to figure this one out yourself. I think it’s good learning experience. Think about for what and when the checks and updates need to run. For example, with a level check, I set it to run every 20 seconds since leveling isn’t that big a deal.</p>
<p>But then I also have a Boss death check which runs every second after battle starts. Why? So players don’t have to wait 20 seconds for a boss to die.</p>
<p>Some other things don’t even need to be in a loop. The functions can just be called when they are needed. Take my update spell function, for example. It’s only called when a player uses a spell.</p>
<h3 id="heading-a-few-things-ive-learned">A few things I’ve learned:</h3>
<ul>
<li>Objects are good. This way, when you have to save data, you just need to save the object — not the 50 individual variables.</li>
<li>Always set timeouts and intervals as variables, so they can be cleared later on — unless they are permanent effects that and you’re sure you won’t ever need to clear them.</li>
<li>One big javascript file might not be a wise idea. CodePen only allows for one JavaScript file, but ideally, you should separate everything into modules.</li>
<li>If you’re not worried about performance, you can just copy and paste the object when it needs to be updated — no need for updating half of the values individually. If the object is huge, you can even define the object first as a variable like: <strong>var object;</strong> and then build it up using some other function when you want it to be updated. I did this with my spells. Every time player casts a spell, the updateSpell() function first defines the spells object again, calculates all the damage and stats, and then fires the spell.</li>
</ul>
<h3 id="heading-funny-things-ive-compromised-on">Funny things I’ve compromised on:</h3>
<ul>
<li>Skill mana costs are per boss level, because if they were at the player level, I’d punish players for leveling up. This also made higher level bosses much harder, which I liked.</li>
<li>Items are created with all stats, but they are not displayed if they are 0. This way, I don’t need to check for undefined, and I can avoid displaying stats if they’re generated as 0. Double win!</li>
<li>I have simplified buffs and debuffs a lot. Basically, there’s a var buffStat, nerfStat, totalStat and stat. So buffs or debuffs never stack.</li>
<li>With bosses, nerf stat skill doesn’t actually nerf it to 0. This is a lot more sophisticated than that. It nerfs the stat by 9999999, then checks to see if it’s less than 0. If yes, it sets it to 0. So if you manage to reach a level where you have stats that are in the billions, I might have to add more zeros.</li>
</ul>
<p>What all of this has thought me is that I should plan a bit further ahead, even if I’m just building a fun project to expand my own skills.</p>
<p>Also, I now have a much better understanding of how bugs arise: sometimes you don’t realize all the edge cases where things can break down the road. And that’s when the bugs bite.</p>
<h3 id="heading-bugs-and-exploits">Bugs and Exploits</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*VsmyUTc8fhqfX9haZAtXDA.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This one amazed me, and scared me a little. I couldn’t believe that my perfect piece of art contained bugs!</p>
<p>Ok, I’m exaggerating a bit. But I did underestimate the sheer number of things that could go wrong without me even realizing it.</p>
<p>Here’s a few bugs and exploits that cropped up, off the top of my head:</p>
<ol>
<li>You could change boss levels while battling a boss, and get better loot drops that way</li>
<li>HP and Mana bars would sometime overflow</li>
<li>You could attack the boss before the battle even started. Talk about a sucker punch!</li>
<li>Mana could go negative, which prevented you from being able to perform even basic attacks, which is the main way you can restore your mana.</li>
<li>Heals temporarily increased your maximum health.</li>
<li>One spell wasn’t actually clickable most of the time due to a CSS problem</li>
<li>Attacking while not in combat put your spells on infinite cooldown</li>
</ol>
<p>These all sound horrifying right? In an MMORPG, these things would be abused from day one and ruin everything!</p>
<p>Well, the good news is that most of them were easily fixable — usually with less than 1 line of code.</p>
<p>Others bugs, though, required me to completely rework the entire system. With the spell system, I went from having to write 3 whole functions for each spell to needing only a small object which takes only a few seconds of editing.</p>
<p>Again, here’s my game if you want to try it out (note that it’s not optimized for mobile devices):</p>
<p>And here’s the code (which is also open source and editable on CodePen):</p>
<p><a target="_blank" href="https://github.com/RobertSkalko/LOOT-RPG-v1.0"><strong>RobertSkalko/LOOT-RPG-v1.0</strong></a><br><a target="_blank" href="https://github.com/RobertSkalko/LOOT-RPG-v1.0">_LOOT-RPG-v1.0 - Kill bosses, get LOOT!_github.com</a></p>
<p>Keep in mind that I’m a beginner (just 2 months into programming) so some of my solutions can be improved. Hopefully though, I gave you at least the basics to get you started!</p>
<p>Have fun creating your Javascript game!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How building HTML5 canvas games helped me learn programming ]]>
                </title>
                <description>
                    <![CDATA[ By Surbhi Oberoi Like many 9 year-olds, the first thing I did when our family got a computer was install games on it. My brother and I would tussle after school over who got to play before mom or dad got home and booted us off of it. As I ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-creating-simple-canvas-games-helped-me-6eef839f450e/</link>
                <guid isPermaLink="false">66c34cee30aba6677fb9f9d4</guid>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gaming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ women in tech ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 25 May 2016 04:54:08 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*bm6Nb2cCdNWKFZh1TKDnAw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Surbhi Oberoi</p>
<p>Like many 9 year-olds, the first thing I did when our family got a computer was install games on it. My brother and I would tussle after school over who got to play before mom or dad got home and booted us off of it.</p>
<p>As I grew up, my interests drifted away from gaming, and toward reading. Then a few days ago, my friend showed me Super Mario on his phone. And just like that, I was hooked on games again.</p>
<p>A thought occurred to me in that moment: why not create a game? Now that I’m learning to code with <a target="_blank" href="http://www.freecodecamp.com">Free Code Camp</a>, I just might be able to create a basic game. But I had no clue where to start. So I started googling.</p>
<p>I found out about canvas API, and how it could be used to create basic games. I took Udacity’s HTML5 Canvas course. It took me three days to finally wrap my head around the concepts of canvas.</p>
<p>After the course, I still felt I needed a tutorial to teach me how to build a game from the scratch step-by-step, so I followed one. This revealed to me that I was still lost on some of the fundamentals of Object Oriented Programming, so I found another course on Udacity for Object Oriented JavaScript.</p>
<p>This was pretty dense, and took some time to digest. I had to watch some videos twice to understand them. But eventually, I finished watching all the videos, and came to the last chapter where you finally create a game. The good part about this course was that they provided a game framework already.</p>
<p>The game was called “Frogger”, where a sprite would have to cross a path full of bugs without colliding with any of them. The sprite could also collect gems to score extra points.</p>
<p>To begin with, I forked their GitHub repo. There were files already created — like when using a generator like Yeoman — and the JavaScript was divided into three files: app.js, engine.js and resources.js. All I had to do was fill in the pre-written functions. Since these functions were already named, I got a fair idea of which arguments to pass and what loops to create.</p>
<p>There are three important aspects to any game:</p>
<ol>
<li><strong>The game loop</strong> — it keeps repeating a process, so that the game won’t stop unless you call the function to stop.</li>
<li><strong>Rendering</strong> — taking cues from the back end works and showing sprites on the front end (using canvas, in this case).</li>
<li><strong>Updating</strong> — updating the positions of the sprites according to the specified moves.</li>
</ol>
<p>This might seem easy for someone who has been coding for years, but starting off fresh required a lot of patience.</p>
<p>After quite a bit of brainstorming and fixing bugs, the game worked. Even though it was quite basic, the sheer joy I felt having created a game was immense.</p>
<p>Here’s what my game looks like:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3j42Ds26BjFQWgjh2otYaOt2T93hmi30t5Bf" alt="Image" width="800" height="450" loading="lazy"></p>
<p>And here’s my code on GitHub:</p>
<p><a target="_blank" href="https://github.com/surbhioberoi/frontend-nanodegree-arcade-game"><strong>surbhioberoi/frontend-nanodegree-arcade-game</strong></a><br><a target="_blank" href="https://github.com/surbhioberoi/frontend-nanodegree-arcade-game">_Contribute to frontend-nanodegree-arcade-game development by creating an account on GitHub._github.com</a></p>
<p>This game can be improved in a number of ways, such as by using random inputs. Here, I’ve hard-coded the positions, which is not a good practice. I am learning to do things in a better way, and the first step is acknowledging that a better way exists.</p>
<p>Over the weekend, I practiced Canvas some more, and it was fun! I created simple things on <a target="_blank" href="https://jsfiddle.net/">JSfiddle</a> — just anything that popped into my head that could use canvas.</p>
<p>I wanted to create something more now. I had heard about Conway’s Game of Life. Initially, I thought that it would be really hard to create it. Despite my skepticism that I could pull it off, I just started thinking about it.</p>
<p>There are two very important things about coding that I learnt after making many silly mistakes: <strong>Never never panic!</strong> Everything is doable — just find out how. And <strong>never begin writing code straight away.</strong> Take time, think, sketch out your data and functionality on a sheet of paper. Try to solve the problem manually first, like you would do without a computer. If you follow this approach, writing code should always be the last step, for it’s important to know what to code first.</p>
<p>In my notebook, I wrote my functions, data, and what I thought would be my inputs. I created the canvas first, then proceeded to create the grid for the Game of Life.</p>
<p>Honestly, it’s frustrating when something does not work how you expect it to, but when it eventually works, all the irritation was worth it. It feels good to create things, and even better when those things are playable games.</p>
<p>The challenging part of creating this game was figuring out how to make the grid area clickable. This really worked me up, but I finally figured out a way: using offset coordinates.</p>
<p>Here’s what The Game of Life looks like:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Mvdb7d2QjbiX1vySvmA00otSioq8-bllnKEJ" alt="Image" width="800" height="450" loading="lazy"></p>
<p>And here’s my code on GitHub:</p>
<p><a target="_blank" href="https://github.com/surbhioberoi/GameOfLife"><strong>surbhioberoi/GameOfLife</strong></a><br><a target="_blank" href="https://github.com/surbhioberoi/GameOfLife">_GameOfLife - Conway's game of life_github.com</a></p>
<p>The problems that I often faced when creating something new was the fear that I wouldn’t be able to do it. I kind of overcame this fear by learning to create games.</p>
<p>Also, I thought that rendering the back end on the front end was the hardest part, and it genuinely scared me. But now I’m getting past that challenge, as well.</p>
<p>I’ve found creating games to be the most fun way of practicing programming, because I’ve always loved playing them. Games have helped me learn programming in an entertaining way, and that I think is the best way to learn anything new.</p>
<p>HTML5 Canvas is really awesome, and once you get a hang of it, it is convenient to use. It’s quite fascinating how you can create so many things with just this one element.</p>
<p>Now, I don’t know whether you like playing games. If there’s something that you enjoy more, just try to create that. When you create something that you actually like, you can overcome the fear of not being able to create it. It will still be hard, but you’ll have the benefit of enjoyable perks along, like having a new game to play afterward. And the best part — the sense of accomplishment — will always be there waiting for you, no matter how long the creative process takes.</p>
<p><em>Originally published at <a target="_blank" href="http://surbhioberoi.com/how-creating-simple-canvas-games-helped-me/">surbhioberoi.com</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
