<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Shawn Holland</title>
    <description>The latest articles on Forem by Shawn Holland (@ansigameengine).</description>
    <link>https://forem.com/ansigameengine</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F764738%2F706c3a47-58df-4a97-9bec-20362568a597.png</url>
      <title>Forem: Shawn Holland</title>
      <link>https://forem.com/ansigameengine</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ansigameengine"/>
    <language>en</language>
    <item>
      <title>Developing A Game Engine with Perl: Part 8 - Vim</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Mon, 06 Dec 2021 07:41:20 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-8-vim-2gj5</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-8-vim-2gj5</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;As Always...&lt;/a&gt; &lt;strong&gt;I DO NOT KNOW WHAT I AM DOING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to start reading from the beginning. Check out the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-3b8"&gt;first article in this series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's step back from &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-6-a-colourful-telnet-server-4i7g"&gt;typing code&lt;/a&gt; for a moment and talk about how that code is typed. There are &lt;a href="https://en.wikipedia.org/wiki/Source-code_editor#Notable_examples"&gt;many options&lt;/a&gt; for a developer to code with, and we all have a preference. It's not so much a matter of right and wrong, as it is of comfort and enjoyment. For me, I code in &lt;a href="https://www.vim.org/download.php"&gt;Vim&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DXxsZ3CF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r64ntezh2wlam11ohdhc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DXxsZ3CF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r64ntezh2wlam11ohdhc.jpeg" alt="" width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ...and Coding in Vim is fun
&lt;/h2&gt;

&lt;p&gt;I was introduced to Vim back in college. Our school used &lt;a href="https://en.wikipedia.org/wiki/IBM_AIX"&gt;AIX&lt;/a&gt; for their server OS and we were taught to use Vim. This was also my first introduction to a Unix environment. Coming from a home Dos/Windows environment and entering the Unix world came with challenges. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://mamchenkov.net/wordpress/2004/05/10/vim-for-perl-developers/"&gt;Using Vim&lt;/a&gt; twisted my brain and took a bit to get use to. But today, after using it for many years, it often feels &lt;a href="https://www.youtube.com/watch?v=0KRxhNrtVIY"&gt;very rhythmic&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=iurhjlBum0o"&gt;fun&lt;/a&gt; to code. Also, not gonna lie, it kinda makes me feel that sense of "coolness" I got when watching &lt;a href="https://www.youtube.com/watch?v=Rn2cf_wJ4f4"&gt;Hackers&lt;/a&gt; for the first time. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LS6FsB3F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wan5j8kutdpoihzkhsq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LS6FsB3F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wan5j8kutdpoihzkhsq.gif" alt="Image description" width="480" height="360"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=p96KIwW5RIc"&gt;Hahaha...&lt;/a&gt; That movie does &lt;strong&gt;NOT&lt;/strong&gt; hold up well! Teenager me was so impressionable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$me-&amp;gt;hides_face_in_shame();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can verify my shame level using this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use strict;
use warnings;
use Shameful::movies;

my $movie  = shift;
my $me     = new Shameful::movies();
my $shame  = $me-&amp;gt;watched($movie);
my $return = "Great Movie!";

if ($shame) {
    $return = $me-&amp;gt;hides_face_in_shame($movie);
}

print $return;
exit;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running that code prints out the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localhost:~/Fake_But_Should_Be_Real_Scripts/ # 
perl i_loved_watching.pl Hackers

Hack the planet!... More like Hide your face bro!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ANSI in Vim
&lt;/h2&gt;

&lt;p&gt;Working with ANSI codes directly in Vim I see a lot of &lt;code&gt;^[&lt;/code&gt;. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kU2bjP2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vx03498arazf6pauu39z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kU2bjP2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vx03498arazf6pauu39z.png" alt="Image description" width="474" height="265"&gt;&lt;/a&gt;&lt;br&gt;
Now this &lt;code&gt;^[&lt;/code&gt; isn't the same as &lt;code&gt;shift+6 and [&lt;/code&gt;. No, this represents the escape character and is highlighted blue in my Vim. If it was &lt;code&gt;shift+6 and [&lt;/code&gt; it would be coloured the same as regular text. Something very useful to know, you can type the escape character in Vim by pressing &lt;code&gt;ctrl+v&lt;/code&gt; and then the &lt;code&gt;escape&lt;/code&gt; key. &lt;/p&gt;
&lt;h2&gt;
  
  
  I split Vim up to open multiple files
&lt;/h2&gt;

&lt;p&gt;I use the &lt;code&gt;:split&lt;/code&gt; and &lt;code&gt;:vsplit&lt;/code&gt; command in Vim often to load in other files. Using &lt;code&gt;split&lt;/code&gt; will stack files above/below each other (split horizontally) and &lt;code&gt;vsplit&lt;/code&gt; does side by side (vertically). Sometimes I need to combine &lt;code&gt;split&lt;/code&gt; and &lt;code&gt;vsplit&lt;/code&gt; to have 3 files at once. Switching between each file in (v)split can be done with &lt;code&gt;ctrl+w+w&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ufTfubZN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/89gr4cikr966i90xijah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ufTfubZN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/89gr4cikr966i90xijah.png" alt="Image description" width="880" height="884"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  So Colourful
&lt;/h2&gt;

&lt;p&gt;Vim supports colour schemes. It's something I don't change often, so I always forget and have to look it up. Since I just did it recently after &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-3-hardware-failure-server-upgrade-on1"&gt;upgrading the dev/test server&lt;/a&gt;, I'll share here with you all. You can change it with the :colorscheme command. The one I'm using is :colorscheme peachpuff. I also have syntax highlighting turned on with the :syntax on. I made it permanent by adding the commands to ~/.vimrc I code in &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c"&gt;OpenSuSE Linux&lt;/a&gt;, Vim config files may vary with your OS. &lt;/p&gt;
&lt;h2&gt;
  
  
  Don't try this at work
&lt;/h2&gt;

&lt;p&gt;Running a bulk search and replace can cause unexpected results if you're not careful. I know I'm thankful for &lt;a href="https://en.wikipedia.org/wiki/Undo#History"&gt;whoever invented undo&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WU8WiBEF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y96str6utiqwochk8183.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WU8WiBEF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y96str6utiqwochk8183.png" alt="Image description" width="488" height="408"&gt;&lt;/a&gt;&lt;br&gt;
There are &lt;a href="https://linux.die.net/man/1/sed"&gt;many ways&lt;/a&gt; to &lt;a href="https://linux.die.net/man/1/awk"&gt;search and replace&lt;/a&gt; the contents of a file in Linux and &lt;a href="https://perldoc.perl.org/perlrequick"&gt;Perl&lt;/a&gt;. However, when I'm in Vim, I often find it quickest to use the :%s command. Typically when I need to apply a search and replace to a whole file I use a command like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:%s/\^[//g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The format is &lt;code&gt;:%s/search_pattern/replace_with/g&lt;/code&gt; The search pattern I used in the above example is to find the escape character &lt;code&gt;^[&lt;/code&gt; I mentioned earlier and replace every occurrence with nothing &lt;code&gt;//g&lt;/code&gt;. I have to precede &lt;code&gt;^[&lt;/code&gt; with &lt;code&gt;\&lt;/code&gt; so the &lt;a href="http://vimdoc.sourceforge.net/htmldoc/pattern.html"&gt;regular expression search pattern&lt;/a&gt; knows it's a literal escape character. I type &lt;code&gt;^[&lt;/code&gt; using ctrl+v and pressing escape.&lt;/p&gt;

&lt;h2&gt;
  
  
  How about you?
&lt;/h2&gt;

&lt;p&gt;Do you code in Vim? What sort of tricks and tips have you learned? What colorscheme do you prefer?&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-7-fork-3acm"&gt;Prev &amp;lt;&amp;lt; Part 7 - Fork&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Next &amp;gt;&amp;gt; Coming Soon&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>perl</category>
      <category>gamedev</category>
      <category>devjournal</category>
      <category>vim</category>
    </item>
    <item>
      <title>Developing A Game Engine with Perl: Part 7 - Fork</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Fri, 03 Dec 2021 23:34:45 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-7-fork-3acm</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-7-fork-3acm</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;Pssssst...&lt;/a&gt; &lt;strong&gt;I DO NOT KNOW WHAT I AM DOING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to start reading from the beginning. Check out the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-3b8"&gt;first article in this series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Continuing from our last post, I talked about how &lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine&lt;/a&gt; is a &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-6-a-colourful-telnet-server-4i7g"&gt;colourful telnet server&lt;/a&gt;. We left off with needing to fork the engines telnet server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Player 2 has joined the game!
&lt;/h2&gt;

&lt;p&gt;Time to level up our telnet server and make it multi-player with some knify forky.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mh4vwXMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyx9lszlna5k69crhw62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mh4vwXMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyx9lszlna5k69crhw62.png" alt="Image description" width="487" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've added in the &lt;a href="https://man7.org/linux/man-pages/man3/strftime.3.html"&gt;&lt;code&gt;strftime&lt;/code&gt;&lt;/a&gt; identifier from &lt;a href="https://perldoc.perl.org/POSIX"&gt;Perl's POSIX module&lt;/a&gt; to help with time stamping the output. The &lt;a href="https://man7.org/linux/man-pages/man2/setsid.2.html"&gt;&lt;code&gt;setsid&lt;/code&gt;&lt;/a&gt; identifier is for starting a new session and group ID for each forked process. A.K.A, the child process. &lt;a href="https://perldoc.perl.org/functions/waitpid"&gt;&lt;code&gt;:sys_wait_h&lt;/code&gt;&lt;/a&gt; is for returning without wait after the child process has exited, using the WNOHANG flag when calling &lt;a href="https://man7.org/linux/man-pages/man2/wait.2.html"&gt;waitpid()&lt;/a&gt;. This provides non-blocking wait for all pending &lt;strong&gt;zombie&lt;/strong&gt; children.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zombie Attack!!!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4_dXRqOa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/31gew1fffn1ac0v0zfzn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4_dXRqOa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/31gew1fffn1ac0v0zfzn.jpeg" alt="Image description" width="500" height="281"&gt;&lt;/a&gt;&lt;br&gt;
You see, when a process dies (exits), it becomes a zombie and needs to be &lt;strong&gt;reaped&lt;/strong&gt;. This will be done when our parent process calls &lt;a href="https://man7.org/linux/man-pages/man2/wait.2.html"&gt;waitpid&lt;/a&gt; after receiving a &lt;a href="https://man7.org/linux/man-pages/man7/signal.7.html"&gt;CHLD signal&lt;/a&gt;, indicating the child has stopped or terminated.&lt;/p&gt;

&lt;p&gt;Ok, I hope that will give you enough information to work with while dissecting the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
use POSIX qw(setsid);
use POSIX qw(strftime);
use POSIX ":sys_wait_h";

sub timestamp {
    my $epoc_seconds = time();
    my $time = strftime "%H:%M:%S", localtime($epoc_seconds);
    my $date = strftime "%m/%d/%Y", localtime;
    my $return = $date . " " . $time;
    return ($return);
}

sub logmsg { print timestamp . " -&amp;gt; $0 -&amp;gt; PID:$$: @_ \n" }
logmsg "Begin";

my $socket = new IO::Socket::INET (
    LocalHost =&amp;gt; '192.168.1.15',
    LocalPort =&amp;gt; '27777',
    Proto =&amp;gt; 'tcp',
    Listen =&amp;gt; SOMAXCONN,
    ReuseAddr =&amp;gt; 1
);

my $waitedpid = 0;
my $player_data;
my $player_socket;

sub REAPER {
    local $!;   # don't let waitpid() overwrite current error
    logmsg "Ending Player's Game";
    while ((my $pid = waitpid(-1, WNOHANG)) &amp;gt; 0 &amp;amp;&amp;amp; WIFEXITED($?)) {
        logmsg "Closed Game ID:$pid : WaitPid:$waitedpid : " . ($? ? " with exit $?" : "");
    }
    $SIG{CHLD} = \&amp;amp;REAPER;  # loathe SysV
}
#if we get the CHLD signal call REAPER sub
$SIG{CHLD} = \&amp;amp;REAPER;

logmsg "Ready and waiting for connection";
while(1)
{
    next unless $player_socket = $socket-&amp;gt;accept();
    logmsg ("Incomming Connection");
    logmsg ("Spawning Player A Game");
    my $pid = fork();

    next if $pid; #NEXT if $pid exists (parent)

    #As Child
    setsid();
    my $proc = $$;

    logmsg ("Game ID:$proc -&amp;gt; Ready");

    # get information about a newly connected player
    my $player_address = $player_socket-&amp;gt;peerhost();
    my $player_port    = $player_socket-&amp;gt;peerport();
    logmsg "Game ID:$proc -&amp;gt; Connection from $player_address:$player_port";

    my $response = "Welcome Player: $player_address:$player_port. Press any key to disconnect.";
    $player_socket-&amp;gt;send($response);

    while ($player_socket-&amp;gt;connected()) {
        $player_socket-&amp;gt;recv($player_data, 1024);
            if ($player_data) {
                logmsg "Player Disconnecting $player_address : $player_port";
                $socket-&amp;gt;close();
                logmsg "Player Disconnected";
                last;
            }
    }
    last;
}
exit;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this code and connecting with two players via &lt;a href="https://syncterm.bbsdev.net/"&gt;SyncTERM&lt;/a&gt;, our &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-6-a-colourful-telnet-server-4i7g"&gt;client of choice&lt;/a&gt;, shows the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localhost:~/ANSIGameEngine # perl forking_telnet_server.pl 
12/03/2021 18:16:58 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Begin 
12/03/2021 18:16:58 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Ready and waiting for connection 
12/03/2021 18:17:04 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Incomming Connection 
12/03/2021 18:17:04 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Spawning Player A Game 
12/03/2021 18:17:04 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15979: Game ID:15979 -&amp;gt; Ready 
12/03/2021 18:17:04 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15979: Game ID:15979 -&amp;gt; Connection from 192.168.1.9:33422 
12/03/2021 18:17:08 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Incomming Connection 
12/03/2021 18:17:08 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Spawning Player A Game 
12/03/2021 18:17:08 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15980: Game ID:15980 -&amp;gt; Ready 
12/03/2021 18:17:08 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15980: Game ID:15980 -&amp;gt; Connection from 192.168.1.9:33428 
12/03/2021 18:17:11 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15979: Player Disconnecting 192.168.1.9 : 33422 
12/03/2021 18:17:11 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15979: Player Disconnected 
12/03/2021 18:17:11 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Ending Player's Game 
12/03/2021 18:17:11 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Closed Game ID:15979 : WaitPid:0 :  
12/03/2021 18:17:13 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15980: Player Disconnecting 192.168.1.9 : 33428 
12/03/2021 18:17:13 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15980: Player Disconnected 
12/03/2021 18:17:13 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Ending Player's Game 
12/03/2021 18:17:13 -&amp;gt; forking_telnet_server.pl -&amp;gt; PID:15978: Closed Game ID:15980 : WaitPid:0 :  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lJVxSJuN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/my89biw6wsyhn0kx7klb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lJVxSJuN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/my89biw6wsyhn0kx7klb.png" alt="Image description" width="880" height="1100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How it all works
&lt;/h2&gt;

&lt;p&gt;The main (parent) process that accepts new incoming telnet requests is &lt;code&gt;PID:15978&lt;/code&gt; in the above example. After it sets up the listen server, it waits for a connection request and creates a forked process when a new player connects (child). The code distinguishes the parent (main waiting telnet server) process from the child (player) process with the value &lt;a href="https://perldoc.perl.org/functions/fork"&gt;&lt;code&gt;fork()&lt;/code&gt;&lt;/a&gt; returns. The parent process receives the child's (player) PID as the return value of &lt;code&gt;fork()&lt;/code&gt;, so it loops back up and waits for another player to connect. The child (player) process receives a value of &lt;code&gt;0&lt;/code&gt; from &lt;code&gt;fork()&lt;/code&gt;, so we continue downward in the code. In Perl doing &lt;code&gt;if($pid)&lt;/code&gt; does &lt;strong&gt;NOT&lt;/strong&gt; evaluate &lt;code&gt;TRUE&lt;/code&gt; if &lt;code&gt;$pid == (0 || undef)&lt;/code&gt;, which is what the child (player) process will receive as the returned value from &lt;code&gt;fork()&lt;/code&gt;. We give the child (player) process a new session, record it's PID (&lt;code&gt;$$&lt;/code&gt;) and wait for them to press any key. When the player presses a key the socket is closed and the child (player) process exists and becomes a zombie. This is when the parent (main) process receives the CHLD signal (&lt;code&gt;$SIG{CHLD}&lt;/code&gt;) and calls &lt;strong&gt;&lt;code&gt;REAPER&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How about you?
&lt;/h2&gt;

&lt;p&gt;Have you worked with fork before? Have you unleashed a zombie apocalypse forgetting to reap? Comment about your experience, I'd love to hear your stories.&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-6-a-colourful-telnet-server-4i7g"&gt;Prev &amp;lt;&amp;lt; Part 6 - A Colourful Telnet Server&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-8-vim-2gj5"&gt;Next &amp;gt;&amp;gt; Part 8 - Vim&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers!&lt;br&gt;
Shawn&lt;/p&gt;

</description>
      <category>perl</category>
      <category>linux</category>
      <category>gamedev</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Developing A Game Engine with Perl: Part 6 - A Colourful Telnet Server</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Thu, 02 Dec 2021 09:06:57 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-6-a-colourful-telnet-server-4i7g</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-6-a-colourful-telnet-server-4i7g</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;I'll stop reminding you that...&lt;/a&gt; &lt;strong&gt;I DO NOT KNOW WHAT I AM DOING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to start reading from the beginning. Check out the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-3b8"&gt;first article in this series&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ANSI Game Engine?
&lt;/h2&gt;

&lt;p&gt;Well, at it's core, &lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine&lt;/a&gt; is a very colourful and interactive telnet server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why telnet!?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know, right!? I still ask myself the same question today, but at this point, I'm kinda committed. Initially, it all came down to my decision &lt;strong&gt;NOT&lt;/strong&gt; to code the client side. I looked into it, and it just wasn't something I wanted to do. And honestly, it seemed too far outside my comfort level with Perl. I feel much more comfortable, and interested in, working with server side code, as may be true for other Perl dev's out there. That's where &lt;a href="https://www.perl.org/"&gt;Perl&lt;/a&gt; is quite prolific. Since I was going with &lt;a href="https://en.wikipedia.org/wiki/ANSI_art"&gt;ANSI graphics&lt;/a&gt;, they are best known these days, for me at least, to be used in telnet/terminal clients and &lt;a href="https://en.wikipedia.org/wiki/Bulletin_board_system"&gt;BBS's&lt;/a&gt;, which are mainly telnet based now. This being said, it wasn't long searching google before I came across SyncTERM. &lt;a href="https://syncterm.bbsdev.net/"&gt;SyncTERM&lt;/a&gt; is, in my opinion, the best available choice for cross-platform rendering of ANSI graphics over telnet. I've tried many different clients, on Mac, Windows, and Linux. SyncTERM works the most consistent across these platforms, it's been around for a long time and is still actively being developed. So telnet it is!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Telnet.... Fork me...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The engine has to be multiplayer. Depending on the specific game requirements, this does not necessarily mean players interacting with each other, but at least having multiple players connected at the same time to the same server. This is a minimum initial requirement. To me, this is a great opportunity to work with &lt;a href="http://man.he.net/man2/fork"&gt;Fork&lt;/a&gt;. I really like the idea of creating multiple processes with fork that can interact with each other. This is an area I have little experience with and a great opportunity to learn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you heard of Perl's CPAN?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are a Perl dev, obviously yes. If you code in another language, perhaps you've heard of it. &lt;a href="https://www.cpan.org/"&gt;Comprehensive Perl Archive Network&lt;/a&gt;, or CPAN, is Perl's repository of code modules. If you want to do something, chances are someone has already made a module for that. As of writing this article, CPAN currently has 208,034 Perl modules written by 14,179 authors. It's absolutely amazing!&lt;/p&gt;

&lt;p&gt;This is where I found the modules to develop a telnet server. A forking telnet server, can you believe it? Fork yah! Okokok.... I'll stop making that joke, I promise!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's get to coding!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first step was to get a telnet server that could accept multiple simultaneous connections. I read up on how to make a telnet server with Perl and from that reading I quickly learned about &lt;a href="https://metacpan.org/pod/IO::Socket::INET"&gt;IO::Socket::INET&lt;/a&gt;. It wasn't long after I had working code for a telnet server!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use strict;
use warnings;
use IO::Socket::INET;
print "\nBEGIN\n";

print "Setting up listen socket\n";
my $socket = new IO::Socket::INET (
    LocalHost =&amp;gt; '192.168.1.15',
    LocalPort =&amp;gt; '27777',
    Proto =&amp;gt; 'tcp',
    Listen =&amp;gt; SOMAXCONN,
    ReuseAddr =&amp;gt; 1
);

my $player_socket;
my $player_data;

print "Waiting for connection ...\n";
while(1) {

    next unless $player_socket = $socket-&amp;gt;accept();
    print "Incomming Connection!\n";

    my $player_address = $player_socket-&amp;gt;peerhost();
    my $player_port    = $player_socket-&amp;gt;peerport();

    my $response = "Player Connection Info: $player_address : $player_port. ";
    print "$response\n";

    $response .= "Press Any Key To Disconnect...\n";
    $player_socket-&amp;gt;send($response);

    print "Waiting for player to press a key and disconnect...\n";
    while ($player_socket-&amp;gt;connected()) {

        $player_socket-&amp;gt;recv($player_data, 1024);
        if ($player_data) {
            print "Player Disconnecting $player_address : $player_port\n";
            $socket-&amp;gt;close();
            print "Player Disconnected\n";
            last;
        }

    }
    last;
}
print "Good Bye!\n";
exit;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this code and connecting with SyncTERM shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localhost:~ # perl telnet_server.pl 

BEGIN
Setting up listen socket
Waiting for connection ...
Incomming Connection!
Player Connection Info: 192.168.1.9 : 55414. 
Waiting for player to press a key and disconnect...
Player Disconnecting 192.168.1.9 : 55414
Player Disconnected
Good Bye!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QEvJGtrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/th0yb9l6o49xidryn1xg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QEvJGtrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/th0yb9l6o49xidryn1xg.png" alt="Image description" width="880" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I read my &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c"&gt;Linux OpenSuSE&lt;/a&gt; server's man page for &lt;a href="https://man7.org/linux/man-pages/man2/listen.2.html"&gt;listen(2)&lt;/a&gt;, and the best I can understand is that the value for SOMAXCONN in  &lt;a href="https://perldoc.perl.org/IO::Socket#Listen"&gt;&lt;code&gt;Listen =&amp;gt; SOMAXCONN&lt;/code&gt;&lt;/a&gt; will allow me to have up to  4096 connections!? I think this is correct. It says the value can be found in &lt;code&gt;/proc/sys/net/core/somaxconn&lt;/code&gt; and doing a &lt;a href="https://man7.org/linux/man-pages/man1/cat.1.html"&gt;cat&lt;/a&gt; of that file shows 4096.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localhost:~ # cat /proc/sys/net/core/somaxconn 
4096

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now we just need to fork!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This process turned out to be a bit more difficult to understand (for me) and a few more lines of code then did the telnet portion. I'll pick up from here in the next article.&lt;/p&gt;

&lt;p&gt;Have you done any telnet programming before? If so, what modules have you found useful? (CPAN or otherwise)&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-5-32bit-64bit-perls-storable-5l8"&gt;Prev &amp;lt;&amp;lt; Part 5 - 32bit -&amp;gt; 64bit &amp;amp; Perl's Storable&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-7-fork-3acm"&gt;Next &amp;gt;&amp;gt; Part 7 - Fork&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers!&lt;br&gt;
Shawn&lt;/p&gt;

</description>
      <category>perl</category>
      <category>gamedev</category>
      <category>linux</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Developing A Game Engine with Perl: Part 5 - 32bit -&gt; 64bit &amp; Perl's Storable</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Wed, 01 Dec 2021 03:14:32 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-5-32bit-64bit-perls-storable-5l8</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-5-32bit-64bit-perls-storable-5l8</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;If you haven't heard already...&lt;/a&gt; &lt;strong&gt;I DO NOT KNOW WHAT I AM DOING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to start reading from the beginning. Check out the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-3b8"&gt;first article in this series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Continuing on with the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c"&gt;last article&lt;/a&gt; let's talk about changing system architecture and how that can affect Perl code, specifically &lt;a href="https://perldoc.perl.org/Storable"&gt;Storable&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mouse Input Support&lt;/li&gt;
&lt;li&gt;Hardware Failure&lt;/li&gt;
&lt;li&gt;Server Upgrade&lt;/li&gt;
&lt;li&gt;UEFI vs OpenSuSE Installer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;32bit -&amp;gt; 64bit &amp;amp; Perl's Storable&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the old server had &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-3-hardware-failure-server-upgrade-on1"&gt;HDD failures&lt;/a&gt; and finally &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c"&gt;managing to upgrade&lt;/a&gt; to the new server, I eagerly began getting all the services and software installed to test the engine on new hardware. I was quickly meet with an error I have never seen before.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Byte order is not compatible at /usr/lib/perl5/5.34.0/x86_64-linux-thread-multi/Storable.pm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After doing some quick reading, I came to understand that Perl uses architecture specific ways to save content to files when using Storable. Specifically if you use &lt;code&gt;lock_store&lt;/code&gt; and &lt;code&gt;store&lt;/code&gt;. These are part of Perl's core system and what I use throughout the engine for working with the file structure.&lt;/p&gt;

&lt;p&gt;I had to carefully re-read the perldoc's to discover that you can avoid architecture incompatibility by simply using &lt;code&gt;nstore&lt;/code&gt; and &lt;code&gt;lock_nstore&lt;/code&gt; The method you use for retrieving the stored files doesn't matter, only when storing the data into files does it matter.&lt;/p&gt;

&lt;p&gt;I tried to find ways of being able to convert the stored files from 32bit architecture to 64bit, but ultimately the only real option was to use the old server to re-store the files with lock_nstore.&lt;/p&gt;

&lt;p&gt;Luckily the old PC was still working, and I was able to modify the code and re-store all the files. The change and usage was simple:&lt;/p&gt;

&lt;p&gt;I had to change my use statement from:&lt;br&gt;
&lt;code&gt;use Storable qw(lock_store lock_retrieve);&lt;/code&gt;&lt;br&gt;
to&lt;br&gt;
&lt;code&gt;use Storable qw(lock_nstore lock_retrieve)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And to re-store I changed my code from this:&lt;br&gt;
&lt;code&gt;lock_store($data_ref, $dir_location);&lt;/code&gt;&lt;br&gt;
to&lt;br&gt;
&lt;code&gt;lock_nstore($data_ref, $dir_location);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Have you ever had to write code for architecture compatibility? Or fix code migrated from one architecture to another? What do you prefer for storing data to files in Perl?&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c"&gt;Prev &amp;lt;&amp;lt; Part 4 - UEFI vs OpenSuSE Installer&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-6-a-colourful-telnet-server-4i7g"&gt;Next &amp;gt;&amp;gt; Part 6 - A Colourful Telnet Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers!&lt;br&gt;
Shawn&lt;/p&gt;

</description>
      <category>perl</category>
      <category>gamedev</category>
      <category>linux</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Developing A Game Engine with Perl : Part  4 - UEFI vs OpenSuSE Installer</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Wed, 01 Dec 2021 02:34:10 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;I'm still learning&lt;/a&gt; so remember... &lt;strong&gt;I DO NOT KNOW WHAT I AM DOING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to start reading from the beginning. Check out the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-3b8"&gt;first article in this series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Continuing on with the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-3-hardware-failure-server-upgrade-on1"&gt;last article&lt;/a&gt; let's talk about old hardware with &lt;a href="https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface"&gt;UEFI&lt;/a&gt;. It can be difficult (for me) to know how to get &lt;a href="https://www.opensuse.org/"&gt;Linux OpenSuSE&lt;/a&gt; installed properly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mouse Input Support&lt;/li&gt;
&lt;li&gt;Hardware Failure&lt;/li&gt;
&lt;li&gt;Server Upgrade&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UEFI vs OpenSuSE Installer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;32bit -&amp;gt; 64bit &amp;amp; Perl's Storable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A small computer and almost destroying it...
&lt;/h2&gt;

&lt;p&gt;The last server's hard drive died, and I happen to have this old, but better, computer. It was in pieces, sitting in a box for a long time. Putting it back together was not easy. This &lt;a href="https://www.acer.com/ac/en/US/content/support-product/3916?b=1&amp;amp;pn=DT.SLQAA.001"&gt;Aspire X1470&lt;/a&gt; is a small form factor design, meaning there is no room to spare. Also meaning if your computer has been sitting around in a box, in pieces for a long time, and its' frame gets bent... well that means it's going to be very difficult to get it back together. I managed to rip off a chip heatsink in the process. I tell ya, my stomach turned right over... but luckily it went back on and seems to be holding and working fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  UEFI vs OpenSuSE Installer
&lt;/h2&gt;

&lt;p&gt;This is where things get interesting. After finally getting the computer together, I downloaded the OpenSuSE ISO for 64bit. I went with &lt;a href="https://get.opensuse.org/tumbleweed"&gt;Tumbleweed&lt;/a&gt; again. It worked well with the last server, so I'll just go with what I know. Tumbleweed is a &lt;a href="https://en.wikipedia.org/wiki/Rolling_release"&gt;rolling release linux&lt;/a&gt;, which means I shouldn't have to reinstall when a new version is released and I should still stay up to date. I created a &lt;a href="https://askubuntu.com/questions/1335903/make-a-full-bootable-usb-stick-with-gnome-disk-utility"&gt;bootable USB from ISO in Ubuntu 20.04&lt;/a&gt; (My Desktop). Booted the new computer, installed OpenSuSE, and was happy... until I tried to reboot.&lt;/p&gt;

&lt;p&gt;When I rebooted, I pulled out the USB stick and the BIOS said no boot drives. I knew of UEFI, and started reading. I found that in /boot/efi/ there was no EFI directory. If you don't know anything about UEFI (No worries, neither do I) ..apparently there is supposed to be a Fat32 partition marked as type EFI. The BIOS checks for this location and attempts to load the OS this way as apposed to using the &lt;a href="https://en.wikipedia.org/wiki/Master_boot_record"&gt;MBR&lt;/a&gt; for booting like in the old days. &lt;/p&gt;

&lt;p&gt;Here is what it looks like now in the server using &lt;a href="https://man7.org/linux/man-pages/man8/fdisk.8.html"&gt;fdisk&lt;/a&gt; to look at the partitions and &lt;a href="https://linux.die.net/man/1/tree"&gt;tree&lt;/a&gt; to look at the directory structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localhost:/ # fdisk -l
Device          Start        End    Sectors  Size Type
/dev/sda1        2048    1050623    1048576  512M EFI System
/dev/sda2     1050624 2893709311 2892658688  1.3T Linux filesystem
/dev/sda3  2893709312 2930277134   36567823 17.4G Linux swap

localhost:/ # tree /boot/efi/
/boot/efi/
└── EFI
    ├── boot
    │   ├── MokManager.efi
    │   ├── bootx64.efi
    │   └── fallback.efi
    └── opensuse
        ├── MokManager.efi
        ├── boot.csv
        ├── grub.cfg
        ├── grub.efi
        ├── grubx64.efi
        └── shim.efi

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may need to scroll right to see the partition type EFI.&lt;/p&gt;

&lt;p&gt;Well, this is what was &lt;strong&gt;NOT&lt;/strong&gt; happening when I installed. I tried several different ways to get it to do an EFI install, but it kept doing it MBR style. The difficult thing is I didn't know what to ask google, and every time I had to try a new install method, it took about an hour to do the install, just to check and find out that it was wrong.&lt;/p&gt;

&lt;p&gt;I knew that the installer wasn't loading in EFI mode and was running in legacy mode, but I didn't know how to switch it manually, and why it was choosing legacy in the first place. I checked the BIOS for booting options, and there just wasn't anything that would force it to boot from a HDD's MBR. I also didn't want to do a firmware update, I just wanted to code and get this install done.&lt;/p&gt;

&lt;p&gt;Finally.... the answer was the BIOS just sucks. For some reason it prioritizes legacy mode on USB booting and I could only get it to chose an EFI boot from USB by manually loading it in the boot menu with F12. Allowing it to choose the USB for booting always resulted in legacy mode, regardless of the settings specified in the BIOS. Of course OpenSuSE's installer will not allow you to switch to EFI if you are in legacy mode. Also it does not make it obvious for the uninitiated to know that it is in legacy (MBR) mode. &lt;/p&gt;

&lt;p&gt;I managed to find an obscure article that said &lt;strong&gt;&lt;code&gt;"If you see the options for pressing F keys at the bottom of the install screen, then it's legacy mode"&lt;/code&gt;&lt;/strong&gt; That one little piece of information is all I needed to understand what was happening. I saw that every time I booted into the OpenSuSE installer there were F key options at the bottom. That's when I realized that the BIOS wasn't booting from the USB's EFI partition. After realizing this, I used a manual BIOS boot, picked the correct USB boot drive (of course the BIOS displays both EFI and Legacy USB boot drives with the same name) I got the correct install screen, the EFI boot options were all there. The install went really easy at this point and is up and running now for a few days with no issues.&lt;/p&gt;

&lt;p&gt;Have you ever worked with small form factor computers? What sort of disaster stories, or success stories have you had? Also what about installing an OS with UEFI vs MBR, what sort of experiences have you had?&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-3-hardware-failure-server-upgrade-on1"&gt;Prev &amp;lt;&amp;lt; Part 3 - Hardware Failure &amp;amp; Server Upgrade&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-5-32bit-64bit-perls-storable-5l8"&gt;Next &amp;gt;&amp;gt; Part 5 - 32bit -&amp;gt; 64bit &amp;amp; Perl's Storable&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers!&lt;br&gt;
Shawn&lt;/p&gt;

</description>
      <category>perl</category>
      <category>gamedev</category>
      <category>linux</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Developing A Game Engine with Perl: Part 3 - Hardware Failure &amp; Server Upgrade</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Wed, 01 Dec 2021 01:03:41 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-3-hardware-failure-server-upgrade-on1</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-3-hardware-failure-server-upgrade-on1</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;Remember...&lt;/a&gt; &lt;strong&gt;I DO NOT KNOW WHAT I AM DOING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Continuing from the &lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;last article&lt;/a&gt;, let's talk about the hardware failures and server upgrade.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mouse Input Support&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hardware Failure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server Upgrade&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;UEFI vs OpenSuSE Installer&lt;/li&gt;
&lt;li&gt;32bit -&amp;gt; 64bit &amp;amp; Perl's Storable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  All your bad sectors are belong to us.....
&lt;/h2&gt;

&lt;p&gt;Ugh, seeing these sort of log errors screams panic to me&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nov 25 03:44:25 Dev smartd[627]: Device: /dev/sda [SAT], Self-Test Log error count increased from 3 to 4
Nov 25 03:44:25 Dev smartd[627]: Device: /dev/sda [SAT], previous self-test completed with error (read test element)
Nov 25 03:44:25 Dev smartd[627]: Device: /dev/sda [SAT], Failed SMART usage Attribute: 184 End-to-End_Error.
Nov 25 03:44:25 Dev smartd[627]: Device: /dev/sda [SAT], 136 Offline uncorrectable sectors
Nov 25 03:44:25 Dev smartd[627]: Device: /dev/sda [SAT], 136 Currently unreadable (pending) sectors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My Dev/Test server's hard drive is going bad and I need to deal with this ASAP! It's one of those &lt;a href="https://www.acer.com/ac/en/ID/content/support-product/4000;-;"&gt;all in one PC's Acer makes&lt;/a&gt; You can see it far right, tucked behind the laptops in this pic of my setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gh0StCVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8t6ca8pe8d1sggz4kj1a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gh0StCVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8t6ca8pe8d1sggz4kj1a.jpg" alt="Image description" width="880" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's been a while since I've had to look at system logs in &lt;a href="https://www.opensuse.org/"&gt;Linux OpenSuSE&lt;/a&gt;. I used to remember just doing a &lt;a href="https://man7.org/linux/man-pages/man1/tail.1.html"&gt;tail -f /var/log/messages&lt;/a&gt; or what ever log file you wanted to watch. I guess at some point since then they switched to using systemd journal service and you can now view everything using &lt;a href="https://documentation.suse.com/es-es/sles/15-SP1/html/SLES-all/cha-journalctl.html"&gt;journalctl&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  We can rebuild it, we have the technology...
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qJEe5LJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfxkmd942pem6o4ggx7y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qJEe5LJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfxkmd942pem6o4ggx7y.gif" alt="Image description" width="334" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is actually OK. I back up my code, so I'm not worried about data loss. Aaaand... I just so happen to have another Acer computer that has been sitting in a cardboard box in pieces for a long time. Aaaand... this other computer is much better spec'd. &lt;/p&gt;

&lt;p&gt;Here you can see a &lt;a href="https://github.com/dylanaraps/neofetch"&gt;neofetch&lt;/a&gt; comparison of the 2 servers side by side. Left is the "new" server, right is the old server with the bad HDD.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j2dXVXrY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f70tbyuqndxq3gy3t0p9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j2dXVXrY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f70tbyuqndxq3gy3t0p9.jpg" alt="Image description" width="688" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notable upgrades:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;32bit -&amp;gt; 64bit Architecture&lt;/li&gt;
&lt;li&gt;2 Core -&amp;gt; 4 Core CPU&lt;/li&gt;
&lt;li&gt;4 GB -&amp;gt; 6 GB RAM&lt;/li&gt;
&lt;li&gt;A Very Slow 1 TB -&amp;gt; Much Faster 1.5 TB HDD&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm excited mainly for the extra core count for &lt;a href="https://perldoc.perl.org/functions/fork"&gt;forking&lt;/a&gt; and the working hard drive, that is exceptionally faster.&lt;/p&gt;

&lt;p&gt;Running an &lt;a href="http://manpages.org/fio"&gt;fio test&lt;/a&gt; shows dramatic differences in results.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fio --name=randwrite --ioengine=libaio --iodepth=1 --rw=randwrite --bs=4k --direct=0 --size=512M --numjobs=4 --runtime=240 --group_reporting&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Old server write speeds are around 6789kB/s and took a few minutes to run. The new server performs @ 109MB/s and finished the test in a few seconds. I'd say we should see a huge performance increase, and we do! &lt;/p&gt;

&lt;p&gt;The engine can do a lot of writing to the hard drive at times, and I used to see the lag, now... no lag from the hard drive! Nice and quick! Also no bad sectors.&lt;/p&gt;

&lt;p&gt;I've &lt;a href="https://docs.oracle.com/en-us/iaas/Content/Block/References/samplefiocommandslinux.htm"&gt;read somewhere&lt;/a&gt; that you may not want to perform randwrite against a device that is in use... So, be careful. I did it with no apparent problems, and the bad sectors were already happening well before ever running the fio command. &lt;/p&gt;

&lt;p&gt;Let me know if you have any experience with hard drive failure diagnosing and testing write speeds with fio.&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;Prev &amp;lt;&amp;lt; Part 2 - Mouse Input&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-4-uefi-vs-opensuse-installer-5e1c"&gt;Next &amp;gt;&amp;gt; Part 4 - UEFI vs OpenSuSE Installer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers!&lt;br&gt;
Shawn&lt;/p&gt;

</description>
      <category>perl</category>
      <category>gamedev</category>
      <category>linux</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Developing A Game Engine with Perl : Part  2 - Mouse Input</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Tue, 30 Nov 2021 23:43:03 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj</guid>
      <description>&lt;p&gt;Let me start by saying.... &lt;strong&gt;I DO NOT KNOW WHAT I AM DOING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Literally, developing a game engine is not on my resume... yet! So any code or ways of doing anything you read here, is just what I've figured out and works for me, which by no means should suggest to you that it is the proper way to do what ever it may be. Please consult your local guru first.&lt;/p&gt;

&lt;p&gt;OK, now that we have that established... Please consider the following as entertainment and should you learn along the way with me, that's wonderful!&lt;/p&gt;

&lt;p&gt;Now, by the time of writing this article, I am several months into this undertaking. I'll describe in future posts what the engine is capable of, but for today, let me tell you about what happened over the last 2 weeks. I will likely break them up into separate posts for easier consumption.&lt;/p&gt;

&lt;p&gt;Here's a quick list of the accomplishments, disasters and discoveries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mouse Input Support&lt;/li&gt;
&lt;li&gt;Hardware Failure&lt;/li&gt;
&lt;li&gt;Server Upgrade&lt;/li&gt;
&lt;li&gt;UEFI vs OpenSuSE Installer&lt;/li&gt;
&lt;li&gt;32bit -&amp;gt; 64bit &amp;amp; Perl's Storable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mouse Input Support
&lt;/h2&gt;

&lt;p&gt;Yes, that's right, &lt;a href="https://fb.watch/9CgSmojbM1/"&gt;ANSI Game Engine games will be able to use a mouse&lt;/a&gt;. Seems like such a simple concept, that a game engine should have mouse support. And as it turns out, it is. I just hadn't gotten to it until now. You see, my mind-set up to now has been on the idea of &lt;a href="https://en.wikipedia.org/wiki/List_of_BBS_door_games"&gt;BBS door games&lt;/a&gt; So keyboard only input was something I never questioned.... until &lt;a href="https://fb.watch/9Cf-UjDA41/"&gt;I started developing the engine's Editor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At some point I realized the only way to have the capabilities I wanted in the engine, was to design a graphics &amp;amp; meta editor. Which so far turns out to be basically an MSPaint program that draws in ANSI and contains game meta information. Up until now, I have been relying on procedural code / command line utilities (&lt;a href="https://github.com/cslarsen/jp2a"&gt;jp2a&lt;/a&gt;, &lt;a href="https://github.com/hit9/img2txt"&gt;img2txt&lt;/a&gt;) to convert jpeg's, gif's &amp;amp; png's images into ANSI, or 3rd party &lt;a href="http://wiki.synchro.net/resource:ansi_editors"&gt;ANSI drawing programs&lt;/a&gt; like &lt;a href="https://blocktronics.github.io/moebius/"&gt;Moebius ANSI Art Editor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These tools are great for what they can do, unfortunately, they were never intended for such uses as a game engine. So a purpose built ANSI graphics editor that can also store meta and game information was needed.&lt;/p&gt;

&lt;p&gt;I very quickly realized that editing graphics and meta information by keyboard alone was slooooooooooooow!!! Not gonna work, I thought. I mean, yeah, it could be done, but even a single scene image is 132x57 "pixels". And to edit 7,524 cells with just arrow keys... nah son, that aint gonna happen. So time to start reading about mouse input via telnet/terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking"&gt;As it turns out, it's quite a simple process.&lt;/a&gt; All you need to do is send/print one of a few &lt;a href="https://en.wikipedia.org/wiki/ANSI_escape_code"&gt;ANSI Escape Codes&lt;/a&gt; to the telnet/terminal client and you can get varying levels of detailed mouse input information in return.&lt;/p&gt;

&lt;p&gt;For my application, I needed the most detail, which includes mouse movement, button press, button release and X/Y coordinate information. &lt;/p&gt;

&lt;p&gt;Sending/printing these ANSI escape codes to the telnet/terminal client enables/disables exactly (almost, see limitation on Mouse Button 3 below) what I need.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;my $turn_mouse_on = "\033[?1003h";&lt;/code&gt;&lt;br&gt;
&lt;code&gt;my $turn_mouse_off = "\033[?1003l";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In Perl, \033 is the escape key. The return I started getting from enabling this was perfect.&lt;/p&gt;

&lt;p&gt;It looked something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;input: ^[[M 5&amp;lt;&lt;br&gt;
Mouse Button: 0, Line: 28, Column: 21&lt;/p&gt;

&lt;p&gt;input: ^[[M!5&amp;lt;&lt;br&gt;
Mouse Button: 1, Line: 28, Column: 21&lt;/p&gt;

&lt;p&gt;input: ^[[M"5&amp;lt;&lt;br&gt;
Mouse Button: 2, Line: 28, Column: 21&lt;/p&gt;

&lt;p&gt;input: ^[[M#5&amp;lt;&lt;br&gt;
Mouse Button: 3, Line: 28, Column: 21&lt;/p&gt;

&lt;p&gt;input: ^[[M&amp;lt;80&amp;gt;5&amp;lt;&lt;br&gt;
Mouse Button: 96, Line: 28, Column: 21&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First character &lt;code&gt;^[&lt;/code&gt; is escape (\033) followed by [M followed by the mouse button number and X/Y coordinates, all offset by +32.&lt;/p&gt;

&lt;p&gt;What this offset +32 means is, if you take the first example:&lt;br&gt;
&lt;code&gt;input: ^[[M 5&amp;lt;&lt;/code&gt;&lt;br&gt;
you see the first character after [M is a space. If we look up what space is in Dec from an &lt;a href="https://www.ascii-codes.com/#standard_character_set"&gt;ASCII chart&lt;/a&gt; we find space is Dec 32. If we adjust for offset, by subtracting 32, it is a 0. Mouse button 0 is the main left mouse button on my mouse.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mouse Button 0: Left Mouse Click&lt;br&gt;
Mouse Button 1: Middle Mouse Click&lt;br&gt;
Mouse Button 2: Right Mouse Click&lt;br&gt;
Mouse Button 3: Mouse button release&lt;br&gt;
Mouse Button 96: Mouse Move&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not sure if you see the limitation, but Mouse Button 3 is all we get to let us know that a mouse button was let go. Not which mouse button was let go, just that one was. Unfortunately, this is the best I have been able to discover, and works good enough for now.&lt;/p&gt;

&lt;p&gt;Here is a quick snip of code I use to extract the necessary information. Sometimes they come in a string with multiple mouse inputs back to back, especially on mouse movements when buffered over telnet. So I &lt;a href="https://perldoc.perl.org/functions/split"&gt;split the string&lt;/a&gt; on &lt;code&gt;\033[M&lt;/code&gt; first to get an array of mouse inputs, then split each mouse input on every character to get the mouse button and coordinate information. I use &lt;a href="https://perldoc.perl.org/functions/ord"&gt;ord()&lt;/a&gt; to get the Dec value of each ASCII character, then adjust for the offset:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;input: ^[[M&amp;lt;80&amp;gt;3&amp;lt;^[[M&amp;lt;80&amp;gt;4&amp;lt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my @mouse = split(/\033\[M/,$input);
foreach my $mouse_input (@mouse) {
    my @button_and_coords = split(//, $mouse_input);
    my $mouse_button = ord($button_and_coords[0]) - 32;
    my $column       = ord($button_and_coords[1]) - 32;
    my $line         = ord($button_and_coords[2]) - 32;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've &lt;a href="https://man7.org/linux/man-pages/man4/console_codes.4.html"&gt;read somewhere in a man page&lt;/a&gt; that you shouldn't put terminal controls into code, and should opt for using a &lt;a href="https://en.wikipedia.org/wiki/Ncurses"&gt;library, such as ncurses&lt;/a&gt;. I probably should as well, but I'm still learning and enjoy working directly with the codes today.&lt;/p&gt;

&lt;p&gt;Let me know if you have had any experience coding for using mouse in a terminal and if you've used a library like &lt;a href="https://metacpan.org/pod/Curses"&gt;Curses cpan module for Perl&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-3b8"&gt;Prev &amp;lt;&amp;lt; Developing A Game Engine With Perl&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-3-hardware-failure-server-upgrade-on1"&gt;Next &amp;gt;&amp;gt; Part 3 - Hardware Failure &amp;amp; Server Upgrade&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers!&lt;br&gt;
Shawn&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Developing A Game Engine with Perl</title>
      <dc:creator>Shawn Holland</dc:creator>
      <pubDate>Tue, 30 Nov 2021 03:49:56 +0000</pubDate>
      <link>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-3b8</link>
      <guid>https://forem.com/ansigameengine/developing-a-game-engine-with-perl-3b8</guid>
      <description>&lt;h2&gt;
  
  
  Perl? What... really?
&lt;/h2&gt;

&lt;p&gt;To most in the know, coding a game engine with Perl would be a surprise. I've certainly been asked, "&lt;em&gt;Why Perl?&lt;/em&gt;". You see, unlike C++, C#, Java and others, which are well established languages in game engine design, Perl is not (well) known for it's role in the development of games. Especially not as a game engine language. You are much more likely to see Perl managing the network infrastructure for the gaming industry then you are to see it powering your favourite video games.&lt;/p&gt;

&lt;h2&gt;
  
  
  So why use Perl then?
&lt;/h2&gt;

&lt;p&gt;Because It's what I know. It's that simple. I've spent many years using Perl to solve many problems throughout my career. I've been fortunate to write Perl code that interacts with a wide variety of hardware, Linux servers and network services. But never a game engine. So I answer "&lt;em&gt;Why Perl?&lt;/em&gt;" with "&lt;em&gt;Why not Perl?&lt;/em&gt;"&lt;/p&gt;

&lt;h2&gt;
  
  
  Why design another game engine? Why not just use an existing engine to make games?
&lt;/h2&gt;

&lt;p&gt;I had to ask myself these questions early on. You see, I've always wanted to create games and for most of my life I've been tinkering with other peoples game code. &lt;/p&gt;

&lt;p&gt;Do you remember &lt;a href="https://en.wikipedia.org/wiki/Gorillas_(video_game)"&gt;Gorillas&lt;/a&gt;? The QuickBASIC game that came installed on Dos back in the early 90's.  I sure do. That was one of the first memories I have opening up and messing around with game code. &lt;/p&gt;

&lt;p&gt;What about &lt;a href="https://en.wikipedia.org/wiki/Bulletin_board_system"&gt;Bulletin Board Systems&lt;/a&gt;? The Internet before the Internet, using 16 colour ANSI graphics with a 80x25 "Pixel" resolution. That's OK if you've never heard of a BBS. Or ANSI graphics. But for me, that was my first introduction to hosting a game server, and also where I wrote my first online game. I got to see people logging onto my server and playing my door game for the first time. They are called door games for BBS systems, don't ask me why. I coded it in QuickBASIC (pre Perl days for me) and it ran on my &lt;a href="https://renegadebbs.info/"&gt;Renegade BBS&lt;/a&gt; I was running my own multi-node dial-up BBS with 14.4Kbps modems. That's right, online gaming at 14.4 kbit/s. Can you imagine the ping times!&lt;/p&gt;

&lt;p&gt;One of the things about me is that I prefer to do things myself if I can. This extends into my programming life as well. So fast forward many years later, me still tinkering in various game code / modding along the way, using Perl extensively in my career, I came to the conclusion that I was just gonna do it. I was going to make my own game (engine). But I didn't go to school for it and have little to no actual knowledge in this field. Sure I've written lots of Perl code, but I don't know much more than a casual hobbyist at best when it comes to writing a game. Buuuut.... I &lt;strong&gt;DO&lt;/strong&gt; know how to code in Perl, I &lt;strong&gt;DO&lt;/strong&gt; know a little bit about ANSI Graphics and I &lt;strong&gt;DO&lt;/strong&gt; know about telnet. That's the Language, The graphics (and audio, ANSI codes can be used for producing sounds) and I can make it online play for Windows, Mac and Linux using &lt;a href="https://syncterm.bbsdev.net/"&gt;SyncTERM&lt;/a&gt; as the telnet ANSI client and Linux &lt;a href="https://www.opensuse.org/"&gt;OpenSUSE&lt;/a&gt; as the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  And that's where it all begins.
&lt;/h2&gt;

&lt;p&gt;I know just enough to get started. So I did, and I've made great progress, but I still have much much more to do. Which is why I decided to create a blog, to share what I learn along the way as I journey for the first time in making &lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fb.watch/9CHFnX1uBl/"&gt;&amp;gt;&amp;gt;Watch the first trailer here&amp;lt;&amp;lt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any suggestions or comments please share constructively. Also please visit our social media pages for lots of fun videos and pictures showing the game engine in action. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/ANSIGameEngine/"&gt;ANSI Game Engine on Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/ANSIGameEngine"&gt;ANSI Game Engine on Facebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ansigameengine/developing-a-game-engine-with-perl-part-2-mouse-input-43nj"&gt;Next &amp;gt;&amp;gt; Part 2 - Mouse Input &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers!&lt;br&gt;
Shawn&lt;/p&gt;

</description>
      <category>perl</category>
      <category>gamedev</category>
      <category>linux</category>
      <category>devjournal</category>
    </item>
  </channel>
</rss>
