<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Math and Game Thoughts</title>
    <description>A blog mostly dedicated to game programming and mathematics.</description>
    <link>http://thyrgle.github.io/</link>
    <atom:link href="http://thyrgle.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 18 May 2026 19:23:38 +0000</pubDate>
    <lastBuildDate>Mon, 18 May 2026 19:23:38 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Magic Square of Squares Part 1</title>
        <description>&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/Magic_square_of_squares&quot;&gt;Magic Square of Squares&lt;/a&gt; asks for a \(3 \times 3\) Magic Square where all the entries are square numbers.&lt;/p&gt;

&lt;p&gt;To be a \(3 \times 3\) Magic Square \(9\) numbers are arranged in a \(3 \times 3\) square and each column, row, and diagonal add up to the same value. For instance,&lt;/p&gt;

\[\begin{matrix}
2 &amp;amp; 7 &amp;amp; 6 \\
9 &amp;amp; 5 &amp;amp; 1 \\
4 &amp;amp; 3 &amp;amp; 8 \\
\end{matrix}\]

&lt;p&gt;Is a magic square since each row, column, and diagonal sum to \(15\). However, in this case, not every element is a square number so it is not a “Magic Square of Squares”. No \(3 \times 3\) “Magic Square of Squares” is known. I had made &lt;a href=&quot;https://conjecscore.org/problems/magicsos&quot;&gt;a problem&lt;/a&gt; related to finding one on &lt;a href=&quot;https://conjecscore.org/&quot;&gt;conjecscore.org&lt;/a&gt; but had not put really much thought into the problem.&lt;/p&gt;

&lt;p&gt;I decided to spend a little time thinking about it, and decided my first goal would be to find potential values for the center entry.&lt;/p&gt;

&lt;p&gt;I am going to sieve out various impossible chocies for the center entry. That is, a center entry is impossible if it could not possibly be used as a center entry in a “Magic Square of Squares”. To do so, I will leverage two well known properties that &lt;em&gt;any&lt;/em&gt; magic square must have:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Let the sum of any row, column, or digonal be called the magic sum and denote it as \(S\). Then the &lt;a href=&quot;https://math.stackexchange.com/a/5034311/15140&quot;&gt;center value of a magic square is precisely \(S/3\)&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Furthermore, up to symmetry, &lt;a href=&quot;https://math.stackexchange.com/a/5108848/15140&quot;&gt;all magic squares must have the form:&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

\[\begin{matrix}
\frac S3 + a &amp;amp; \frac S3 - a - b &amp;amp; \frac S3 + b \\
\frac S3 - a + b &amp;amp; \frac S3 &amp;amp; \frac S3 + a - b \\
\frac S3 - b &amp;amp; \frac S3 + a + b &amp;amp; \frac S3 - a \\
\end{matrix}\]

&lt;p&gt;Now, we may derive some equalities from the fact that all entries must be square. Since we are interested in the center square, denote it as \(n^2\). Furthermore, both \(n^2 + a\) and \(n^2 - a\) must be squares. Thus,&lt;/p&gt;

\[n^2 + a + n^2 - a = t^2 + f^2\]

&lt;p&gt;on the other hand,&lt;/p&gt;

\[n^2 + a + n^2 - a = 2n^2\]

&lt;p&gt;Combining the two equations shows that \(n^2\) is the average of two squares, that is:&lt;/p&gt;

\[n^2 = \frac{t^2 + f^2}{2}\]

&lt;p&gt;Furthermore \(n = \sqrt{\frac{t^2 + f^2}{2}} = \frac{\sqrt{t^2  + f^2}}{\sqrt{2}}\). This might seem like a silly observation, but we may use the fact that \(n\) is an integer to observe that the prime factorization of \(t^2 + f^2\) must have an &lt;em&gt;odd&lt;/em&gt; power of \(2\) in it.&lt;/p&gt;

&lt;p&gt;There is a &lt;a href=&quot;https://www.geeksforgeeks.org/dsa/highest-power-of-two-that-divides-a-given-number/&quot;&gt;quick way to compute the largest power of \(2\) that divides a number:&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;largest_two_pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This gives a nice sieve for possible center entry values:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Range over \(t\) and \(f\).&lt;/li&gt;
  &lt;li&gt;Compute \(t^2 + f^2\) and check if the largest dividing power of \(2\) is odd.&lt;/li&gt;
  &lt;li&gt;If so, factor out one \(2\) and see if it is a perfect square.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When it comes to ranging over \(t\) and \(f\), this is just an arbitrary size range of numbers we want to check, however, since \(t = n^2 + a &amp;gt; n^2 - a &amp;gt; f\) we may impose the restriction \(t &amp;gt; f\) in the search. Thus, in code, we have something like:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;math&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isqrt&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;largest_two_pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sqrt_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;isqr_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isqr_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;RANGE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20000&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;candidate_n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RANGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;largest_two_pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sqrt_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;candidate_n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;candidate_n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;a-small-adaptation-for-a-better-sieve&quot;&gt;A Small Adaptation for a Better Sieve&lt;/h2&gt;

&lt;p&gt;The output indicates there are \(2000\) candidate values for \(n\) that work. In fact, we can adapt this program slightly to get an even smaller selection of \(n\).&lt;/p&gt;

&lt;p&gt;We observed above that \(n^2 + a\) and \(n^2 - a\) were squares to conclude \(n^2\) was an average of a pair of different squares. It is also true that \(n^2 + b\) and \(n^2 - b\) are squares. Similarly, \(n^2 + a + b\) and \(n^2 - a - b\) are also squares. Thus, we can repeat this argument to see that \(n^2\) is the average of &lt;em&gt;at least&lt;/em&gt; \(3\) different pairs of squares. So, we should only add to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;candidate_n&lt;/code&gt; if \(n\) appears \(3\) times or more. This can be easily done with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Counter&lt;/code&gt; object:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;math&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isqrt&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;largest_two_pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Return the largest power of 2 that divides n.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sqrt_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Checks if sqrt(x) is integral.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;isqr_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isqr_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 1st round
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;RANGE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20000&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;candidate_n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RANGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;largest_two_pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sqrt_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;# tf2 now equals n^2 add n to candidates
&lt;/span&gt;                    &lt;span class=&quot;n&quot;&gt;candidate_n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidate_n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now there are only \(147\) choices of \(n\) available.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Still nothing significant, but hopefully, after some more thought, I can get some better candidates and at least get a &lt;a href=&quot;https://conjecscore.org/problems/magicsos&quot;&gt;decent score on conjecscore&lt;/a&gt;. I will continue thinking about this problem when I have more time. Secondly, next time, I will do a review of the literature (I like to try the problem by myself for a bit first though!)&lt;/p&gt;
</description>
        <pubDate>Sat, 16 May 2026 00:00:00 +0000</pubDate>
        <link>http://thyrgle.github.io/math/2026/05/16/magic-squares-of-squares-pt1.html</link>
        <guid isPermaLink="true">http://thyrgle.github.io/math/2026/05/16/magic-squares-of-squares-pt1.html</guid>
        
        
        <category>math</category>
        
      </item>
    
      <item>
        <title>Modular Game Components</title>
        <description>&lt;p&gt;I tried &lt;a href=&quot;https://godotengine.org/&quot;&gt;Godot&lt;/a&gt; some years back and while it was an impressive piece of software, I found myself struggling with it. (Just to emphasize, I have nothing against Godot! Try it out! It really is a great piece of software that many people use to make great things!) Instead I found that I really liked the simplicity of &lt;a href=&quot;https://www.love2d.org/&quot;&gt;Love2D&lt;/a&gt;. If you wanted to print “Hello, World!” to the screen, it really was as simple as:&lt;/p&gt;

&lt;div class=&quot;language-lua highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;love&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;love&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graphics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello World!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Saying that, Love2D might be too simple (well, for me). The simplicity of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;love.draw&lt;/code&gt; loop exhbits challenges in &lt;em&gt;organization&lt;/em&gt;. For instance, if there is only one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;love.draw&lt;/code&gt; function, how do you keep track of which scene (i.e. which level, menu screen, etc.) you are on? A naive approach to this might look like:&lt;/p&gt;

&lt;div class=&quot;language-lua highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;love&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;scene&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;menu&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;love&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scene&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;menu&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elseif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scene&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;level1&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;but this becomes an unreeadable mess very quickly. Fortunately, &lt;a href=&quot;https://github.com/love2d-community/awesome-love2d&quot;&gt;awesome-love2d&lt;/a&gt; addresses this!&lt;/p&gt;

&lt;h2 id=&quot;modular-components&quot;&gt;Modular Components&lt;/h2&gt;

&lt;p&gt;awesome-love2d keeps a list of libraries compatible with Love2D. In particular, I liked &lt;a href=&quot;https://hump.readthedocs.io/en/latest/index.html&quot;&gt;HUMP&lt;/a&gt;. For the issue of scene management, HUMP provides a submodule &lt;a href=&quot;https://hump.readthedocs.io/en/latest/gamestate.html&quot;&gt;HUMP.gamestate&lt;/a&gt; which allows you to make (along with some other features) separate draw functions for each scene:&lt;/p&gt;

&lt;div class=&quot;language-lua highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;menu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;game&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;-- Do something for drawing menu.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;game&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;-- Do something for drawing the game.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The organization I sought after was now found!&lt;/p&gt;

&lt;p&gt;HUMP even has other features. &lt;a href=&quot;https://hump.readthedocs.io/en/latest/timer.html&quot;&gt;HUMP.timer&lt;/a&gt; (as the name suggests) allows for creating timers. It also has functionality for &lt;em&gt;tweening&lt;/em&gt; values. That is, you can take one value and gradually change it to another value &lt;em&gt;over time&lt;/em&gt;. I really love these two sublibraries. But even I found the HUMP.tween library a little &lt;em&gt;too&lt;/em&gt; lacking. This gave me a predicament: should I use another tweening library, contribute to HUMP, modify HUMP source to accomidate my project, or make my own.&lt;/p&gt;

&lt;h2 id=&quot;making-my-own&quot;&gt;Making My Own&lt;/h2&gt;

&lt;p&gt;There was another problem I have yet to mention: I wanted to write games in Python. I know this is a rather weird choice given that Python is notoriously slow. Admittedly, I wanted to write in Python just because I was most familiar with Python. &lt;a href=&quot;https://pyga.me/&quot;&gt;Pygame&lt;/a&gt; seemed to be relatively similar to Love2D, but &lt;a href=&quot;https://github.com/kadir014/awesome-pygame&quot;&gt;awesome-pygame&lt;/a&gt; had fewer libraries listed. Even worse, after searching, I was not able to find much either. The good news, I could use this opportunity to help contribute to the Pygame ecosystem!&lt;/p&gt;

&lt;h2 id=&quot;learning-from-hump&quot;&gt;Learning From HUMP&lt;/h2&gt;

&lt;p&gt;I wanted a lot of HUMP functionality, but wanted to better enforce the &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy&quot;&gt;Unix philosophy&lt;/a&gt;. Thus, instead of making a HUMP equivalent for Pygame, I sought to make smaller libraries, of which, combining all of them results in something that resembles HUMP. As for scene management, it seems as though there is an equivalent to HUMP.gamestate called &lt;a href=&quot;https://github.com/treygilliland/PyScenes&quot;&gt;PyScenes&lt;/a&gt; but I could not find anything for tweening. So, I decided to start working on a tweening library.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/thyrgle/transytion&quot;&gt;transytion&lt;/a&gt; is a tweening library that originally started out similar to HUMP.timer, but it addressed some of the issues I had with HUMP.timer, namely:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The callback mechanism was a bit cumbersome to use.&lt;/li&gt;
  &lt;li&gt;Stopping tweens should have some sort of (optional) stop callback. Therefore, if something happens (for instance, an enemy dies) the tween can have a convenient to use fail mechanism and switch to doing something else.&lt;/li&gt;
  &lt;li&gt;I wanted an extensive system for composing tweens together instead of glueing callbacks together.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even later I realized that I could utilize Python decorators to simplify tween creation. A function can be associated with a tween (say, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move&lt;/code&gt;), and by using some decorator magic, calling that function will not actually call the function immediately. Instead the function call runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move&lt;/code&gt; &lt;em&gt;then&lt;/em&gt; calls the function. Taken from the documentation, this allows us to write:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tween&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tween_then_call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;say_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;say_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Thus, if one wants a character to move a bit, then say something, move a bit more, and say even more, we can keep things organized:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;say_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;say_something2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This keeps the focus of the code on the underlying logic and &lt;em&gt;not&lt;/em&gt; the animations.&lt;/p&gt;

&lt;h2 id=&quot;beyond-hump&quot;&gt;Beyond HUMP&lt;/h2&gt;

&lt;p&gt;As I continued working with Pygame, there seemed to be other core components missing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;From my experience with &lt;a href=&quot;https://conjecscore.org/&quot;&gt;conjecscore.org&lt;/a&gt;, I found it annoying to manage the layout of content on the screen compared to how it is done in web development. Layout ended up being much harder than I thought it would be. To (partially) fix this, I worked on &lt;a href=&quot;https://github.com/thyrgle/lpyout&quot;&gt;lpyout&lt;/a&gt; as a layout engine for games.&lt;/li&gt;
  &lt;li&gt;The shortest path libraries I found were inconvenient to use (for games at least). For most of these libaries, the input required a graph representation (such as an adjacency matrix). I did not have an adjacency matrix of the world. Instead, I had a grid of the world. I made &lt;a href=&quot;https://github.com/thyrgle/gtravyl&quot;&gt;gtravyl&lt;/a&gt; that takes in a &lt;em&gt;grid representation&lt;/em&gt; of the world and finds the shortest path. Although not as flexible, I believe this is much easier to use than the existing libraries out there while remaining flexible enough for &lt;em&gt;most&lt;/em&gt; use cases.&lt;/li&gt;
  &lt;li&gt;I feel (although potentially a &lt;em&gt;very&lt;/em&gt; controversial opinion) that event listeners are underrated as an organizational tool. This includes games, so I developed &lt;a href=&quot;https://github.com/thyrgle/pypagate&quot;&gt;pypagate&lt;/a&gt; which can create formulas and (from formulas) create listeners. Formulas can describe many situations quite elegantly. Consider the following game scenario from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;README&lt;/code&gt; of pypagate that creates event listeners for when a game should end:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pypagate&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fire_on&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;         &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fire_on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;game_over&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Game over&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Game&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;over&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;My ultimate goal is not to create a game engine but to extend existing game frameworks, such as Pygame, so that we have the modularity of the Unix philosophy &lt;em&gt;with&lt;/em&gt; the feature completeness of an engine. The result is a collectiion of libraries that anyone can use (Apache 2.0 License).&lt;/p&gt;
</description>
        <pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate>
        <link>http://thyrgle.github.io/game/foss/2026/05/11/modular-game-components.html</link>
        <guid isPermaLink="true">http://thyrgle.github.io/game/foss/2026/05/11/modular-game-components.html</guid>
        
        
        <category>game</category>
        
        <category>foss</category>
        
      </item>
    
  </channel>
</rss>
