kikito [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=45456 locus.p8 - A sparse spatial grid for Pico-8 <p>Locus is a <em>Two-dimensional</em>, <em>unbounded</em>, <em>sparse</em>, <em>efficient</em>, <em>grid</em> spatial hash for Pico-8.</p> <p> <table><tr><td> <a href="/bbs/?pid=165422#p"> <img src="/bbs/thumbs/pico8_test_locus-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=165422#p"> test_locus</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=165422#p"> [Click to Play]</a> </td></tr></table> </p> <p>The library uses a grid of squared cells and keeps track of which objects &quot;touch&quot; each cell.</p> <p>This is useful in several scenarios:</p> <ul> <li>It can tell &quot;Which objects are in a given rectangular section&quot; quite efficiently</li> <li>This is useful for collision detection; instead of checking n-to-n interactions, locus can be used to restrict the amount of objects to be checked, sometimes dramatically reducing the number of checks.</li> <li>Given that the query area is rectangular, locus can be used to optimize the draw stage, by &quot;only rendering objects that intersect with the screen&quot;</li> </ul> <p>More Info about the API, FAQ and so on @ github:</p> <p><a href="https://github.com/kikito/locus.p8">https://github.com/kikito/locus.p8</a></p> <p>The cart above shows the main features of locus:</p> <ul> <li>Addition and updating of objects in locus</li> <li>Querying locus for updating objects</li> <li>Querying locus for drawing objects on the screen</li> </ul> <p>It does not show deletion or filtering, but hopefully the docs on github clarify how to do that.</p> <p>Feedback most welcome!</p> https://www.lexaloffle.com/bbs/?tid=148381 https://www.lexaloffle.com/bbs/?tid=148381 Sat, 12 Apr 2025 16:21:23 UTC oadd - binary insert for pico8 <p>Pico-8 doesn't provide a built-in way to sort arrays.</p> <p>However it does provide a way to remove items from an array as well as a way to add them to a random position.</p> <p>A lot of the time a full array-sorting function isn't needed; sometimes it's just enough to be able to <em>insert one item into an already sorted array</em>. </p> <p>I did look around in the bbs but I didn't find a function for doing it, so here it is:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>do local lt=function(a,b) return a&lt;b end function oadd(arr,obj,cmp) cmp=cmp or lt local l,r,m=1,#arr while l&lt;=r do m=(l+r)\2 if cmp(arr[m],obj) then l=m+1 else r=m-1 end end add(arr,obj,l) return l end end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The function figures out where to insert the item in an already sorted array (using the same algorithm as quicksort) and inserts the new item there.</p> <p>For arrays of integers or strings it is a drop-in replacement for the built-in <code>add</code> function. The numbers will just be inserted in the right place so that they are sorted. The third optional parameter allows for using different comparation functions. Example:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>local by_z=function(a,b) return a.z&lt;b.z end local obj1={z=14} local obj2={z=5} local arr={} oadd(arr,obj1) oadd(arr,obj2) -- arr should be {obj2,obj1} since obj2.z is smaller.</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Attaching demo cart:</p> <p> <table><tr><td> <a href="/bbs/?pid=162448#p"> <img src="/bbs/thumbs/pico8_oadddemo-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=162448#p"> oadd demo</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=162448#p"> [Click to Play]</a> </td></tr></table> </p> https://www.lexaloffle.com/bbs/?tid=147369 https://www.lexaloffle.com/bbs/?tid=147369 Tue, 18 Feb 2025 21:33:23 UTC hit.p8 - continuous collision detection for rects <h1>Hit</h1> <p>Hello Pico-8 community!</p> <p>Rectangles (&quot;Axis-Aligned Bounding Boxes&quot;, or aabbs, or simply boxes) are the most common way to detect collisions in videogames. Checking that two rectangles intersect is easy and fast.</p> <p>However sometimes game objects need to move fast. Projectiles or even hedgehogs sometimes move so fast that they traverse many pixels per frame. When they move fast enough they can &quot;phase through&quot; objects, if one uses simple rectangle intersection as a mean to detect collisions.</p> <p>Even when the two rectangles intersect, it can be tedious/tricky to find exactly on which position do they land.</p> <p>I present you hit. It's a single function which will solve this particular problem, doing <em>continuous collision detection</em> instead of simple intersection.</p> <p> <table><tr><td> <a href="/bbs/?pid=155210#p"> <img src="/bbs/thumbs/pico8_hit-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=155210#p"> hit</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=155210#p"> [Click to Play]</a> </td></tr></table> </p> <h1>Parameters and return values</h1> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>tx,ty,nx,ny,t,intersect = hit(x1,y1,w1,h1,x2,y2,w2,h2,goalx,goaly)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Hit takes 10 parameters:</p> <ul> <li><code>x1,y1,w1,h1</code>: A first rectangle, represented by its top-left coordinate, a width and height</li> <li><code>x2,y2,w2,h2</code>: A second rectangle</li> <li><code>goalx,goaly</code>: A point in space where the first rectangle &quot;wants to move&quot; (x1,y1 &quot;wants to become&quot; goalx,goaly)</li> </ul> <p>Hit returns nil if the first rectangle can move freely to goalx,goaly without touching the second rectangle. If the rectangles touch at any point during this journey, hit will return:</p> <ul> <li><code>tx,ty</code>: the coordinates where the first rectangle's top-left corner would be when it starts touching the second rectangle</li> <li><code>nx,ny</code>: the &quot;normals&quot; of the contact. Given that we are dealing with aabbs, <code>nx</code> and <code>ny</code> will always be either <code>-1</code>,<code>0</code> or <code>1</code></li> <li><code>t</code>: &quot;how far along&quot; the journey did the contact occur. 0 means that the two boxes touch right at the beginning of the journey, and 1 means they touch at the end. In some degenerate cases t can also be bigger than 1 or smaller than 0 (see below). This parameter is useful for sorting collisions (the one with the smaller t will usually have &quot;happened&quot; first)</li> <li><code>intersect</code>: <code>true</code> if the boxes were intersecting at the beginning of the journey, <code>false</code> if they were not. This parameter is useful to treat intersections differently from non-intersections in the collision resolution</li> </ul> <h1>Usage</h1> <p>Save the hit function to a single file (hit.lua) and then</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>#include hit.lua</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <h1>Cost</h1> <p>Hit costs 422 tokens approximately. Most of the tokens come from the calculation of tx,ty,nx and ny. If those are not needed, then it can be strip down to a much leaner function that only returns true or false.</p> <p>The function has several comments which can be stripped in order to save characters if necessary.</p> <p>Performance-wise, it is not very expensive. There will be always some calls to abs, and number comparisons. For non-degenerate cases there will always be 4 divisions per collision detection.</p> <h1>Notes and degenerate cases</h1> <p>When dealing with collision detection, there's many edge cases to take into account. Some of them are not obvious:</p> <ul> <li>No displacement vector: <code>x1,y1</code> is equal to <code>goalx,goaly</code> already. In this case, hit will return nil if the aabbs don't intersect. If they do intersect, however, then hit will return &quot;the shortest path that would move the first aabb out of the second aabb&quot;. This can be either up, down, left or right, depending on what the nearest path is.</li> <li>First aabb is already intersecting the second aabb at the beginning of the journey. In this case hit will also try to move it towards the shortest exit, but <em>in the direction of the displacement</em>. Note however this can also send the object <em>backwards</em> in the direction it wants to go, if that's the sortest path out. Also note that when the objects are intersecting it is possible that t is either smaller than 0 or bigger than 1</li> <li>Corners: hit does not make any guarantees about collisions being detected if they happen to touch in a single point (e.g. the journey would make two corners coincide) or in a single line (the first aabb moves in such a way that it &quot;slides&quot; over the second, without trying to intersect it). On this cases it may or may not report a collision. </li> <li>Precision: given Pico-8's limited floating point representation, the coordinates <code>tx</code> and <code>ty</code> will often not coincide precisely with what would result by multiplying the displacement vector (<code>goalx-x1,goaly-y1</code>) by <code>t</code>. Hit will &quot;hide&quot; this problem by moving things slightly in order to make the touch &quot;feel&quot; correct despite that, as much as the floating point representation permits.</li> </ul> <h1>Preemptive FAQ</h1> <h2>How does hit work?</h2> <p>Hit combines two algorithms: The Minkowsky Difference and the Liang-Barsky line clipping algorithm.</p> <p>The Minkowsky difference is a geometrical operation, where one object &quot;gets smoothed over&quot; the perimeter of another object. If you do the minkowsky difference between a square and a circle you will get a bigger square with rounded corners. When you do the minkowsky difference between two aabbs you get another (bigger) aabb.</p> <p>The neat thing about this is that if you make one of the rectangles &quot;bigger&quot;, you can make the other &quot;smaller&quot;, and the properties of the collision work the same (as long as you respect some norms). If we make one of the rectangles as big as the Minkowsky diff, we can make the other one as small as a single point.</p> <p>Which means that our &quot;how do I collide these two moving boxes with each other&quot; gets simplified to &quot;how do I intersect this bigger box with this pixel that is moving, in other words, this segment&quot;.</p> <p>The family of algorithms that solve this particular problem is called &quot;line-clipping algorithms&quot;, and the Liang-Barsky one seems to be the fastest generic one. So we clip the diff with the segment, which gives us <code>t</code> and the normals. We then calculate <code>tx</code> and <code>ty</code>, paving over the floating point imprecision as much as possible.</p> <h2>Why no guarantees on the corner cases?</h2> <p>I have done this kind of thing before, and it is simply too time consuming for me. I would rather stop here.</p> <h2>Where have you done this kind of thing before?</h2> <p>I am the original author of the <a href="https://github.com/kikito/bump.lua">bump.lua</a> library, used for collision detection in Lua/L&Ouml;VE , which is somewhat popular. There's some things I learned while writing that library, that I have tried to avoid/simplify while doing this Pico8 version.</p> <h2>Bump.lua had collision resolution. Why doesn't hit have that?</h2> <p>Bump.lua is also much bigger, and includes a whole spacial hash implementation as well.</p> <h2>Have you used this on an actual videogame?</h2> <p>I am building one, this is but one of the pieces.</p> <h2>I found a bug, can I contribute</h2> <p>Yes. <a href="https://github.com/kikito/hit.p8">https://github.com/kikito/hit.p8</a> </p> <p>It can take me a while to answer. Sorry!</p> https://www.lexaloffle.com/bbs/?tid=144551 https://www.lexaloffle.com/bbs/?tid=144551 Sat, 05 Oct 2024 16:25:33 UTC ins - inspect for PICO-8 <p>Here's a function that will transform whatever you pass it into a table that will hopefully be understandable by a human. It'll take any table or other Lua value, so you can, for example, print it:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>print(ins({1,2,3,foo=bar}),1,1) printh(ins({1,2,3,foo=bar}))</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The only parameter besides the string to be transformed is the depth.</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>local deep={l1={l2={l3={l4=&quot;!&quot;}}}}} print(ins(deep)) --prints everything print(ins(deep,2)) --stops at l2 and prints {_}</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p> <table><tr><td> <a href="/bbs/?pid=98806#p"> <img src="/bbs/thumbs/pico8_ins_inspectforpico8-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=98806#p"> ins:inspect for PICO-8</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=98806#p"> [Click to Play]</a> </td></tr></table> </p> <p>As the author of the <a href="https://github.com/kikito/inspect.lua">inspect.lua library</a>, I use it a lot on my day job when I need to debug Lua, and I really miss it when debugging in Pico-8. I found <a href="https://www.lexaloffle.com/bbs/?pid=43636">some previous efforts on this direction</a>, but I was missing a lot:</p> <ul> <li>Marking repeated tables, functions, threads and userdata with numbers</li> <li>Handling nested tables / avoiding printing repeated tables</li> <li>Sorting keys sensibly</li> <li>Printing metatable data</li> <li>Presenting arrays as comma-separated single lines, and hashes in multiple-span lines</li> </ul> <p>I made ins' output take less horizontal space than inspect.lua, so it adapts better to PICO-8's output. And I trimmed features(string escaping, preprocessing).</p> <p>Still, at ~700 tokens, it's ... a chunky boy. You probably shouldn't add it to your project permanently. Think of it as a &quot;debug artillery&quot; function: deploy it to a tab in your game, it should be able to handle whatever you throw at it and return a digestible string. Once you have used it to destroy your problem, remove it.</p> <p>PS: My biggest surprise was that PICO-8 has no built-in sorting function. So I bundled one. Oh and there is no concat, either. The garbage collector must be having fun with all those strings :)</p> <p>EDIT: fixed bug in isidentifier function</p> https://www.lexaloffle.com/bbs/?tid=45025 https://www.lexaloffle.com/bbs/?tid=45025 Sun, 17 Oct 2021 23:37:48 UTC A Convenient Generalization of Schlick's Bias and Gain Functions <p>This is an implementation of the function described on this short paper:</p> <p><a href="https://arxiv.org/abs/2010.09714">https://arxiv.org/abs/2010.09714</a> (<a href="https://twitter.com/jon_barron/status/1318946131078909952">twitter thread</a>)</p> <p>It is amenable to tweeing/easing in games. I have programmed easing functions in the past and one of the problems about them is that you need to code &quot;families of easing functions&quot;:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/45456/easing.png" alt="" /> <p>(That's from <a href="https://github.com/kikito/tween.lua">tween.lua</a>, if you are curious).</p> <p>I like this function because it can aproximate all of the &quot;smooth families of functions&quot; on that graph (all except the &quot;back&quot;, &quot;bounce&quot; and &quot;elastic&quot; families) with a single function, plus it adds an infinitude of variants. Not bad for ~66 tokens.</p> <p> <table><tr><td> <a href="/bbs/?pid=83208#p"> <img src="/bbs/thumbs/pico8_schlick_bias_gain-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=83208#p"> schlick_bias_gain</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=83208#p"> [Click to Play]</a> </td></tr></table> </p> <p>Usage:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>y = easing(x,t,c)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>All params (x, t and c) are restricted to the [0,1] interval. When they are, the result (y) is also in the [0,1] interval.</p> <ul> <li><strong>x</strong> is the input being eased. In games and animations this usually encodes &quot;the percentage of time that has passed since the start of the animation&quot;. Notice that <strong>x</strong> is restricted to [0,1]. If the magnitude you are trying to ease is not on that range, you might have to scale it (like I did in order to display the graphs). </li> <li><strong>t</strong> is &quot;the threshold point&quot; - that's the location of the &quot;inflection&quot; in the curve (the point at which the curve switches from <em>out</em> to <em>in</em>, or viceversa).</li> <li><strong>c</strong> is &quot;the curvature&quot;. At 0-0.5 the curve will &quot;start in in&quot;, gradually approaching linear interpolation at 0.5, and then the curve will &quot;start in out&quot; the more it approaches 1 from there.</li> <li><strong>y</strong> is the return of the easing. In games and animations this is often the &quot;percentage of space the thing moves, for the time that has passed&quot;. Like with <strong>x</strong>, it will be on the [0,1] range, so it might need scaling. </li> </ul> <p>Usually <strong>x</strong> changes over time, while <strong>t</strong> and <strong>c</strong> are &quot;fixed&quot; during an animation. On the attached Cartridge they are animated, but only because we show the whole curve.</p> <p>There are a couple differences between my implementation and the one in the paper:</p> <ul> <li>I had to add 1 to the <strong>x&gt;=t</strong> branch of the function. I believe this is because Pico-8's y-axis goes &quot;down&quot; instead of up, like in &quot;regular math&quot;. Not 100% sure about this.</li> <li>The <strong>s</strong> parameter described in the paper is a &quot;slope&quot;. When it goes from 0 to 1 it acts &quot;one way&quot;, making the curve more &quot;steep&quot; at the beginning and when it goes from 1 to infinity it acts &quot;the other way&quot;, making it more steep at the end. I replaced <strong>s</strong> with <strong>c</strong> (<strong>c = 1/(s+1)</strong>), so that it stays on the [0,1] range, like the other params.</li> </ul> https://www.lexaloffle.com/bbs/?tid=39995 https://www.lexaloffle.com/bbs/?tid=39995 Thu, 22 Oct 2020 08:54:49 UTC Giraffe-Eating Leaves <p>This is a simple game I made with my (now 4-year-old) son. Perhaps influenced by Lexaloffle's BBS icon, its protagonist is a giraffe. It eats falling leaves.</p> <p> <table><tr><td> <a href="/bbs/?pid=80435#p"> <img src="/bbs/thumbs/pico8_giraffeeatingleaves-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=80435#p"> giraffeeatingleaves</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=80435#p"> [Click to Play]</a> </td></tr></table> </p> <p>It has no victory or defeat conditions (my son still doesn't demand them, so I keep not including those).</p> <p>I wanted my son to start getting used to a mouse, so this game has mouse support! It was fun having to activate it via POKEs. (I was reminded of the Sinclair Spectrum 48k of my youth). The game also works with the default &quot;button-based&quot; control scheme.</p> <ul> <li>Arrows: Move head</li> <li>X: Eat</li> </ul> <p>The code, as usual, has been heavily cleaned up before posting.</p> <p>Notes about the graphical design:</p> <ul> <li>I only programmed the giraffe head and the leaves with my son. The telescopic neck and body at the bottom was added as a surprise, later on.</li> <li>On that note, I am very aware that giraffe's mouths are on their snouts, not on their necks. If you feel the need to comment about this particular anatomical anomaly, let me point out that this particular giraffe has a telescopic neck and its legs don't move while it walks.</li> <li>The pinkish falling ... &quot;things&quot; are supposed to be leaves. I think they look more like beets, but my 4yo Chief of Design was very adamant about the colors and shape.</li> </ul> https://www.lexaloffle.com/bbs/?tid=39131 https://www.lexaloffle.com/bbs/?tid=39131 Thu, 06 Aug 2020 23:54:00 UTC Car Coins Corona <p>This is the second game my 3-years-old son and I did together.</p> <p>It started as something simple. A car which moves around. A police car? No, a regular car.</p> <p>Then we added coins. And made the car pick them! Interactivity! Randomness!</p> <p>Then we needed a monster. So of course Covid-19 makes an appearance as the bad guy. You &quot;kill it&quot; with the car (which conveniently uses the same code as the coins).</p> <p>Although to more experienced players the game might feel like it needs some kind of &quot;success screen&quot;, my son doesn't seem to miss it at all.</p> <p>It was also the first time we used the sound editor. Bruno is way too impatient, and I am too inexperienced, to create a whole song for a game just yet.</p> <p>Fun facts:</p> <ul> <li>There's exactly 10 instances of the virus because that's the biggest number Bruno is able to count up to so far (reliably).</li> <li>There's exactly 51 coins because &quot;51&quot; is the number Bruno uses when he wants &quot;a very big number&quot;.</li> </ul> <p>Controls: arrows to move.</p> <p> <table><tr><td> <a href="/bbs/?pid=78809#p"> <img src="/bbs/thumbs/pico8_carcoinscovid-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=78809#p"> carcoinscovid</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=78809#p"> [Click to Play]</a> </td></tr></table> </p> <p>I was not yet familiar with pico-8's add, del, and foreach so the first version of this had a lot of duplicated code and it was a bit of a mess (try coding next to a 3-year old child to see what I mean!). I cleaned it up before posting.</p> https://www.lexaloffle.com/bbs/?tid=38647 https://www.lexaloffle.com/bbs/?tid=38647 Thu, 02 Jul 2020 23:45:21 UTC Dino watering flowers <p>Today was the first day I did a videogame with my son.</p> <p>He's 3 years old. He helped me pick all the colors and with design decision, like what kind of dinosaur to include and what he would be doing.</p> <p>The game itself is literally 6 if blocks, and I wrote it pretty quickly, starting from api.pb . It still felt like an eternity to my toddler! He could see progress while I was drawing the dino and the flowers, but the programming part was meaningless to him. He was vociferously demanding progress. A true client. I had to cut many features. Bounds checking, for example, only works partially. It became a feature (&quot;ooooh where did the dinosaur go?&quot;)</p> <p>CONTROLS: Move with arrows, water flowers with Z.</p> <p>Cleaned up before publishing. <table><tr><td> <a href="/bbs/?pid=78442#p"> <img src="/bbs/thumbs/pico8_dinowateringflowers-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=78442#p"> dinowateringflowers</a><br><br> by <a href="/bbs/?uid=45456"> kikito</a> <br><br><br> <a href="/bbs/?pid=78442#p"> [Click to Play]</a> </td></tr></table> </p> https://www.lexaloffle.com/bbs/?tid=38547 https://www.lexaloffle.com/bbs/?tid=38547 Tue, 23 Jun 2020 20:49:55 UTC