geckojsc [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=9338 Puyo Trainer! <p> <table><tr><td> <a href="/bbs/?pid=27223#p"> <img src="/bbs/thumbs/pico37710.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=27223#p"> Puyo Trainer! 0.5</a><br><br> by <a href="/bbs/?uid=9338"> geckojsc</a> <br><br><br> <a href="/bbs/?pid=27223#p"> [Click to Play]</a> </td></tr></table> </p> <p>So I recently rediscovered the magic that is Puyo Puyo! However, I'm absolutely terrible at it. I'm a pretty slow thinker and can never analyse the situation quickly enough to predict the fall of blocks and construct large chains.</p> <p>So, I wrote this little training tool that allows you to play Puyo in single-player as slowly as you like! You can spend an infinite amount of time deliberating each move, and even go upwards.</p> <p>Threw in some sfx and autotiling for fun :)</p> <p>[update 2017-02-22]</p> <ul> <li>configurable rotation controls, mainly for those using the web player on mobile devices</li> </ul> <p>[update 2016-08-13]</p> <ul> <li>the 13th row (outside the top of the board) is now treated correctly</li> <li>chain text can't go off-screen (animation fix)</li> </ul> <p>[update 2016-08-12]</p> <ul> <li>revamped menu / settings</li> <li>fixed nuisance puyos not popping (oops)</li> <li>added 'blind piece' mode which greys out the current piece, forcing into the habit of looking ahead</li> </ul> <p>[update 2016-07-29]</p> <ul> <li>the first two pairs can only consist of red, green and blue puyos, regardless of colour count</li> <li>puyos placed outside the top of the board will be removed (hopefully correctly)</li> <li>improved controls some more</li> <li>adjusted purple puyo graphics (thanks to MissingNumbers for input!)</li> <li>optimised the way puyos are stored (no more lag when the board gets full)</li> </ul> <p>[update 2016-07-23]</p> <ul> <li>can now choose the number of colours to play with</li> <li>can optionally play with random nuisance puyos added to the field, to simulate an opponent (for all you people that complained it was too easy)</li> <li>improved controls, fixed some bugs, now possible to fail</li> </ul> https://www.lexaloffle.com/bbs/?tid=4109 https://www.lexaloffle.com/bbs/?tid=4109 Mon, 22 Aug 2016 21:54:02 UTC RPG Dialogue Scripting Demo <p> <table><tr><td> <a href="/bbs/?pid=25342#p"> <img src="/bbs/thumbs/pico25268.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=25342#p"> RPG Dialogue Scripting Demo</a><br><br> by <a href="/bbs/?uid=9338"> geckojsc</a> <br><br><br> <a href="/bbs/?pid=25342#p"> [Click to Play]</a> </td></tr></table> </p> <p>Hey folks! This is a demo cart to showcase use of coroutines to create animations and dialogue.<br /> By having a single active 'script' coroutine we can do the following:</p> <ul> <li>reveal text frame by frame</li> <li>do nothing until player presses [x]</li> <li>give the player a choice of answers [up/down + x] to select</li> <li>do nothing until npc has finished walking</li> <li>do several of the above simultaneously, and only continue once all of them are finished.</li> </ul> <p>all this without blocking the _update() function</p> <p>For more info on coroutines, check out <a href="https://www.lexaloffle.com/bbs/?tid=3458">the forum post</a>. Also keep an eye out for Fanzine #5, where Dan Sanderson will be exploring these topics!</p> https://www.lexaloffle.com/bbs/?tid=3833 https://www.lexaloffle.com/bbs/?tid=3833 Fri, 15 Jul 2016 13:00:40 UTC An Introduction to Metatables <p>Hi! Some folks on the IRC were struggling with metatables, and Ivoah suggested I post an explanation here to help more people get to grips with them. Here goes nothing:</p> <p>A <strong>table</strong> is a mapping of keys to values. They're explained quite well in the PICO-8 manual so I won't go into more detail. In particular you should know that <em>t.foo</em> is just a nicer way of writing <em>t[&quot;foo&quot;]</em> and also that <em>t:foo()</em> is a nicer way of calling the function <em>t.foo(t)</em></p> <p>A <strong>metatable</strong> is a table with some specially named properties defined inside. You apply a metatable to any other table to change the way that table behaves. This can be used to:</p> <ol> <li>define custom operations for your table (+, -, etc.)</li> <li>define what should happen when somebody tries to look up a key that doesn't exist</li> <li>specify how your table should be converted to a string (e.g. for printing)</li> <li>change the way the garbage collector treats your table (e.g. <a href="https://www.lua.org/pil/17.html">tables with weak keys</a>)</li> </ol> <p>Point #2 is especially powerful because it allows you to set default values for missing properties, or specify a <a href="https://en.wikipedia.org/wiki/Prototype-based_programming">prototype</a> object which contains methods shared by many tables.</p> <p>You can attach a metatable to any other table using the <a href="http://www.lua.org/manual/5.2/manual.html#pdf-setmetatable">setmetatable</a> function. </p> <p>All possible metatable events are explained on the lua-users wiki:<br /> &gt;&gt;&gt; <a href="http://lua-users.org/wiki/MetatableEvents">list of metatable events</a> &lt;&lt;&lt;</p> <p>And that's really all you need to know!</p> <p>Edit: it appears that <em>__tostring</em> doesn't currently work in PICO-8 Lua. That means some of the code below is only relevant to vanilla Lua. See the end of the post for workarounds.</p> <p><strong>Vectors Example</strong></p> <p>I'll now demonstrate how metatables could be used to make 2D points/vectors with custom operators.</p> <div> <div style="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> -- define a new metatable to be shared by all vectors local mt = {} -- function to create a new vector function makevec2d(x, y) local t = { x = x, y = y } setmetatable(t, mt) return t end -- define some vector operations such as addition, subtraction: function mt.__add(a, b) return makevec2d( a.x + b.x, a.y + b.y ) end function mt.__sub(a, b) return makevec2d( a.x - b.x, a.y - b.y ) end -- more fancy example, implement two different kinds of multiplication: -- number*vector -&gt; scalar product -- vector*vector -&gt; cross product -- don't worry if you're not a maths person, this isn't important :) function mt.__mul(a, b) if type(a) == &quot;number&quot; then return makevec2d(b.x * a, b.y * a) elseif type(b) == &quot;number&quot; then return makevec2d(a.x * b, a.y * b) end return a.x * b.x + a.y * b.y end -- check if two vectors with different addresses are equal to each other function mt.__eq(a, b) return a.x == b.x and a.y == b.y end -- custom format when converting to a string: function mt.__tostring(a) return &quot;(&quot; .. a.x .. &quot;, &quot; .. a.y .. &quot;)&quot; 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>Now we can use our newly defined 'vector' type like this:</p> <div> <div style="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 a = makevec2d(3, 4) local b = 2 * a print(a) -- calls __tostring internally, so this prints &quot;(3, 4)&quot; print(b) -- (6, 8) print(a + b) -- (9, 12) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Pretty neat right?</p> <p><strong>Object Orientation</strong></p> <p>I mentioned that metatables can be used to define what should happen when a key lookup fails, and that this can be used to create custom methods shared by many tables. For example we might want to be able to do this:</p> <div> <div style="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> a = makevec2d(3, 4) a:magnitude() -- calculate the length of the vector, returning 5 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>In Lua this is not always necessary, for example, we could define an ordinary function to do the job for us:</p> <div> <div style="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> function magnitude(vec) return sqrt(vec.x^2 + vec.y^2) end magnitude(a) -- returns 5 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>In fact, for PICO-8 I would recommend that approach, because it's as efficient as you can get, and it uses the least number of tokens.</p> <p>But I think it's educational to see how metatables can make it possible to use Lua in a more OOP style.</p> <p>First off, we define all our methods in a table somewhere. Note, you can define them in the metatable itself, but I'll put them in a different table to prevent confusion.</p> <div> <div style="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 methods = {} function methods.magnitude(self) return sqrt(self.x^2 + self.y^2) 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 <em>__index</em> property of a metatable is referred to when you try to look up a key 'k' which is not present in the original table 't'.</p> <p>If <strong>index is a function, it is called like <em></strong>index(t, k)</em><br /> If <strong>index is a table, a lookup is performed like <em></strong>index[k]</em></p> <p>So we can add the magnitude function to all our existing vector objects like this:</p> <div> <div style="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> mt.__index = methods </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And now we can do <em>a:magnitude()</em><br /> Which is a shortcut for <em>a.magnitude(a)</em><br /> Which is a shortcut for <em>a[&quot;magnitude&quot;](a)</em></p> <p>Hopefully given all this information, it's clear what's happening:</p> <p>We never defined a magnitude property in 'a', so when we try to lookup the string &quot;magnitude&quot;, the lookup fails and Lua refers to the metatable's __index property instead.</p> <p>Since __index is a table, it looks in there for any property called &quot;magnitude&quot; and finds the magnitude function we defined. This function is then called with the parameter 'a' which we implicitly passed when we used the : operator.</p> <p>Well, that's it from me! I hope somebody finds this post useful, and please let me know if there is something you don't understand, or something that I left out or could have explained better.</p> <hr /> <p>Edit: at the time of writing, __tostring doesn't work in PICO-8 Lua.</p> <p>This means you'll either have to convert your objects explicitly, like so:</p> <div> <div style="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> function vec2str(vec) return &quot;(&quot; .. vec.x .. &quot;, &quot; .. vec.y .. &quot;)&quot; end print(vec2str(a)) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>or, if you are using the object oriented approach outlined above, you could do this:</p> <div> <div style="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> function methods.tostring(vec) return &quot;(&quot; .. vec.x .. &quot;, &quot; .. vec.y .. &quot;)&quot; end local oldprint = print -- override the print function to look for a method called 'tostring' function print(val, ...) if type(val) == &quot;table&quot; and val.tostring then oldprint(val:tostring(), ...) else oldprint(val, ...) end end print(a) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <hr /> <p>edit: minor bbs formatting fix</p> https://www.lexaloffle.com/bbs/?tid=3342 https://www.lexaloffle.com/bbs/?tid=3342 Thu, 12 May 2016 19:12:58 UTC Mewversi <p> <table><tr><td> <a href="/bbs/?pid=15502#p"> <img src="/bbs/thumbs/pico16538.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=15502#p"> Mewversi 0.0.2 0.0.2</a><br><br> by <a href="/bbs/?uid=9338"> geckojsc</a> <br><br><br> <a href="/bbs/?pid=15502#p"> [Click to Play]</a> </td></tr></table> </p> <p>Updated version for UoB Game Dev Society halloween jam :)</p> <ul> <li>now has a fancy title screen and animations</li> <li>now has diagonal chains (like in normal reversi/othello)</li> <li>individual cats can be flipped (including white -&gt; black)</li> </ul> <p> <table><tr><td> <a href="/bbs/?pid=15502#p"> <img src="/bbs/thumbs/pico15501.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=15502#p"> Mewversi 0.0.1</a><br><br> by <a href="/bbs/?uid=9338"> geckojsc</a> <br><br><br> <a href="/bbs/?pid=15502#p"> [Click to Play]</a> </td></tr></table> </p> <p>Puzzle game concept for the 1 Hour Game Jam.</p> <p>I didn't have time to design difficult puzzles, but the concept is there. :)</p> <p>Follows the rules of Reversi (but only for horizontal+vertical chains)</p> <p>To move: make a bridge from a white kitten to your cursor, over 1 or more non-white kittens.</p> <p>Sleepy kittens will become normal (white) when flipped<br /> Fire kittens will destroy their neighbours when flipped<br /> Queasy kittens will become sleepy when flipped</p> <p>To win the level, make all kittens normal (white)!</p> <p>ARROWS: move<br /> Z/C: flip<br /> X: restart level</p> https://www.lexaloffle.com/bbs/?tid=2622 https://www.lexaloffle.com/bbs/?tid=2622 Sat, 17 Oct 2015 17:18:04 UTC Feature Request: Use system cursor for editing? <p>Hi zep! Just a small suggestion, but I'm finding the low-resolution cursor movement really quite awkward to use when I'm so comfortable with existing graphics software on the PC.</p> <p>Would it be possible (as an optional setting) to either:</p> <p>a) detach the in-app cursor from the 128x128 grid by creating some special rendering code independent from the console display?</p> <p>b) hide the in-app cursor and show the system cursor instead?</p> <p>What are others' opinions on this? I suppose it's not a major issue for most people, and I completely understand if you don't want to do it, to preserve the style/feel of the console. :)</p> https://www.lexaloffle.com/bbs/?tid=2343 https://www.lexaloffle.com/bbs/?tid=2343 Thu, 27 Aug 2015 08:45:56 UTC