Mot [Lexaloffle Blog Feed] ChatGPT 4o <p>ChatGPT 4o seems pretty good at writing Pico-8 code. (At least for simple games).</p> <p>I asked it:<br /> &quot;Can we try something different? Like a simple Space Invaders or Galaxians style game?<br /> I have 4 sprites in slots 1,2,3,4 with a player ship, alien invader, player bullet and enemy bullet respectively. Could you make a simple game where the aliens move left and right in formation, and the player moves left to right along the bottom of the screen?&quot;</p> <p>I got this.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/ai1_0.gif" alt="" /> <p>I pasted the gif into the chat window, and it said:</p> <p>&quot;Awesome! It looks like the basic mechanics are working. Let's add a few more features to make the game more interesting:</p> <p>Enemy Bullets: Add bullets fired by the aliens.<br /> Player Lives: Track the player's lives and end the game when they run out.<br /> Score: Add a scoring system for each alien destroyed.&quot;</p> <p>Then gave me an updated version that looks like this:</p> <img style="margin-bottom:16px" border=0 src="/media/39676/ai1_1.gif" alt="" /> <p>Then I got worried that AI is doing all the work and I'm going to turn into the spaceship inhabitants in WAL-E. So I asked it to quiz me on the code and check my answers.</p> <p>It came up with questions like:</p> <p>&quot;Bullet Mechanics:</p> <p>Q3: How does the player fire bullets? What happens when a bullet is fired?<br /> Q4: How are player bullets updated and removed when they move off-screen?<br /> Alien Movement:</p> <p>Q5: How do the aliens move left and right in formation? What happens when they reach the edge of the screen?<br /> Q6: How do the aliens move downwards after reaching the screen edge?&quot;</p> Sun, 19 May 2024 23:16:24 UTC Profiler <p>Here's a little profiler you can drop into an existing program - if you have 313 tokens to spare.<br /> It instruments the global functions to count the number of calls and measure the CPU time spent inside them. Then it dumps it to a CSV file you can open in a spreadsheet viewer, and hopefully get some insight into where your program is spending the most time.</p> <p>Instructions are in the comments at the top.</p> <p>EDIT: </p> <ul> <li>Count fn calls in a single 32bit integer (thanks <a href=""> @freds72</a>). </li> <li>Use &quot;...&quot; arguments syntax to support more than 9 arguments (thanks <a href=""> @Siapran</a>)</li> <li>Save uninstrumented fns to avoid calling the instrumented ones when dumping stats.</li> </ul> <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>--&gt;8 -- profiler -- usage: -- run your program -- press esc to break -- &gt; _prof.begin() -- &gt; resume -- run your program some more (to gather data) -- press esc to break -- &gt; _prof.dump() -- this will dump a profile.csv file to the cart's folder -- notes: -- profiling for more than 2-3 minutes could cause cpu measurements -- to overflow, and give incorrect results. -- measures the amount of cpu spent in each function, where 1 is one whole frame -- so divide by frame rate to get seconds (30, or 60 if using _update60). -- profiling will slow down your program somewhat. _prof={ stats={}, -- list of global functions to *not* instrument donttouch={flip=true,__flip=true,_startframe=true,_update_buttons=true,_get_menu_item_selected=true,_update_framerate=true,_map_display=true,_mark_cpu=true}, -- original uninstrumented functions type=type, stat=stat, printh=printh, all=all, tostr=tostr, pairs=pairs } -- start profiling. -- if called multiple times, will reset stats _prof.begin=function() -- clear stats _prof.stats={} -- instrument functions if not _prof.instr then for n,v in _prof.pairs(_ENV) do if _prof.type(v)==&quot;function&quot; and not _prof.donttouch[n] then -- wrap function _ENV[n]=function(...) -- run and get cpu timing local cpuin=_prof.stat(1) return (function(...) -- update stats local cpuout=_prof.stat(1) local st=_prof.stats[n] or {ct=0,cpu=0} st.ct+=0x0.0001 st.cpu+=cpuout-cpuin _prof.stats[n]=st return ... end)(v(...)) end end end _prof.instr=true end end -- dump profile stats to file -- order is field to order by (name,ct,cpu,avg) -- defaults to &quot;cpu&quot; -- dst is printh destination -- defaults to &quot;profile.csv&quot; _prof.dump=function(order,dst) order = order or &quot;cpu&quot; dst = dst or &quot;profile.csv&quot; local rpt={} for n,v in _prof.pairs(_prof.stats) do local cpu,ct,sh=v.cpu,v.ct,16 -- average is cpu/(ct&lt;&lt;16), except that ct&lt;&lt;16 could -- overflow, in which case shift ct left as many bits -- as possible and shift cpu right the remaining bits. while sh&gt;0 and ct&lt;0x4000 do -- can't exceed 0x7fff as it would be treated as negative ct&lt;&lt;=1 sh-=1 end cpu&gt;&gt;=sh -- create stat local st={name=n,ct=v.ct,cpu=v.cpu,avg=cpu/ct} -- insert into rpt in order local i=#rpt+1 while i&gt;1 and (rpt[i-1][order]&gt;st[order])==(order==&quot;name&quot;) do rpt[i]=rpt[i-1] i-=1 end rpt[i]=st end -- print rpt _prof.printh(&quot;name,ct,cpu,avg&quot;,dst,true) for st in _prof.all(rpt) do _prof.printh(;,&quot;.._prof.tostr(st.ct,2)..&quot;,&quot;;,&quot;,dst) 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>Here's an example of my <a href="">2D transforms demo</a>.<br /> For example you can see it spends a large amount of time in the &quot;map&quot; function (which would normally be suspicious except that the &quot;2D transforms&quot; replaces the standard &quot;map&quot; function with a custom version).</p> <img style="margin-bottom:16px" border=0 src="/media/39676/profiler.png" alt="" /> Fri, 08 Mar 2024 11:03:25 UTC Render from RAM <p> <table><tr><td> <a href="/bbs/?pid=141243#p"> <img src="/bbs/thumbs/pico8_mot_rendertest-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=141243#p"> mot_rendertest</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=141243#p"> [Click to Play]</a> </td></tr></table> </p> <p>A little experiment with rendering directly from Pico-8 RAM using &quot;peek&quot;.<br /> Trying to use as few tokens as possible.</p> Wed, 07 Feb 2024 04:13:04 UTC Mot's Animation System 2 <p> <table><tr><td> <a href="/bbs/?pid=140172#p"> <img src="/bbs/thumbs/pico8_mot_animsys2-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=140172#p"> Mot's Animation System 2</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=140172#p"> [Click to Play]</a> </td></tr></table> </p> <p>This has been sitting on my drive for a year or so. I was meaning to write up some documentation for it, but I'm throwing it up as is for now. (Until I can remember how to use it.)</p> <p>Basically it's a sequel to <a href="">Mot's Animation System</a> built on top of the <a href="">2D transforms</a> library. The main improvement being that it supports rotation.</p> <p>The basic idea is you create &quot;sprite&quot; animations based on frames on your tilemap. You can then combine them into &quot;timeline&quot; animations where position, rotation etc can be set at different points by creating keyframes.<br /> There's also a &quot;storyboard&quot; animation type that simply plays other animations in order.</p> <p>You can import gfx and tilemaps from other carts, save/load your projects. You can also export your animations to embed in your own projects if you wish. It's about 1700 tokens, although 1000 of that is the 2D transforms system. (I can post an example of this if anyone is interested.)</p> <p>I'd write up some more, but I need to remember how it works myself :).</p> <p>Maybe someone wants to have a play with it anyway.</p> <p>EDIT:</p> <p>Here's an example cart playing an exported image.<br /> It uses tabs 2,3,4 of the editor, except I recovered about 200 tokens by stripping out some unused bits.<br /> <table><tr><td> <a href="/bbs/?pid=140172#p"> <img src="/bbs/thumbs/pico8_mot_animsys2_test-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=140172#p"> Animation System 2 test</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=140172#p"> [Click to Play]</a> </td></tr></table> </p> Tue, 16 Jan 2024 00:34:26 UTC Whiplash Taxi Co <p> <table><tr><td> <a href="/bbs/?pid=132559#p"> <img src="/bbs/thumbs/pico8_mot_taxi-7.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=132559#p"> Whiplash Taxi Co</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=132559#p"> [Click to Play]</a> </td></tr></table> </p> <p><strong>UPDATE: Fixed suspension to lean towards the outside of turns, not the inside.</strong></p> <p>Welcome to the <strong>Whiplash Taxi Company</strong>, where our motto is &quot;The slower you're there, the lower the fare!&quot;</p> <p>As a valued employee and taxi driver, your job is to pick up passengers and deliver them to their destination as fast as possible, by any means necessary.</p> <p>Passengers are easy to spot, just look for the big red arrows over their heads.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/mot_taxi p8_2.png" alt="" /> <p>Simply stop next to them so they can jump in!<br /> Then follow the red destination indicator to the destination and stop when it says &quot;stop!&quot;.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/mot_taxi p8_11.png" alt="" /> <p>Repeat this as many times as possible in 5 minutes, and see how much $$$ you can bring in.</p> <p>But beware, sometimes the direct route isn't the quickest.<br /> To make it easier we have provide this giant map of Motsville. You may want to spend some time in &quot;Free Explore&quot; to get the layout. Or try some of the fully legitimate and not just driving-around-random-streets-way-too-fast street circuits, and maybe set a few lap records.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/165_map.png" alt="" /> <p>Remember, at Whiplash Taxis when we say &quot;Break neck speeds&quot;, we mean it!<br /> (Hopefully not literally. Hopefully.)</p> Sun, 30 Jul 2023 10:31:59 UTC Taxi Game (maybe) <p> <table><tr><td> <a href="/bbs/?pid=131761#p"> <img src="/bbs/thumbs/pico8_mot_taxi-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=131761#p"> Taxi game</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=131761#p"> [Click to Play]</a> </td></tr></table> </p> <p>This is basically a Wolfenstein-3D style ray-caster with floor tiles.<br /> There's no gameplay or even collision detection so far.</p> <p>The top right of the Pico-8 map region is used to layout the game, using the sprites in tab 3.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/taxi_0.png" alt="" /> <p>The sprites correspond to 8x8 regions in the top left of the map area, which represent the &quot;texture&quot; to draw.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/taxi_1.png" alt="" /> Sat, 08 Jul 2023 23:12:48 UTC SDF Ray Marcher v2 <p> <table><tr><td> <a href="/bbs/?pid=125495#p"> <img src="/bbs/thumbs/pico8_mot_raymarch2-3.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=125495#p"> SDF Ray Marcher</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=125495#p"> [Click to Play]</a> </td></tr></table> </p> <p>I updated my ray marcher to use RGB colours internally and random dither back to 16 colours.<br /> This should allow me to add things like partially transparent surfaces, or atmospheric fog at some point.</p> <p><img style="margin-bottom:16px" border=0 src="/media/39676/raymarch_53.png" alt="" /><img style="margin-bottom:16px" border=0 src="/media/39676/raymarch_61.png" alt="" /><img style="margin-bottom:16px" border=0 src="/media/39676/raymarch_55.png" alt="" /><img style="margin-bottom:16px" border=0 src="/media/39676/raymarch_57.png" alt="" /></p> Wed, 08 Feb 2023 00:34:57 UTC Combat Chopper <p> <table><tr><td> <a href="/bbs/?pid=123143#p"> <img src="/bbs/thumbs/pico8_mot_chopper-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=123143#p"> Combat Chopper</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=123143#p"> [Click to Play]</a> </td></tr></table> </p> <p><em>WARNING: This game attempts to emulate old 8-bit flight simulators from the 80s and 90s. The flight model leans towards realism rather than easy-to-pickup arcade gameplay (even if it's somewhat primitive compared to serious modern-day flight simulators). As such it's not an easy to pickup game - controlling the helicopter is challenging and takes practice. In combat, even more so.</em></p> <p>Welcome to <em>Combat Chopper</em>, an 80s helicopter combat flight simulator for Pico-8!<br /> Pilot your <strong>P8 64k Apachi</strong> armored attack helicopter on a series of missions destroying key targets in enemy territory.</p> <h2>Getting started</h2> <h3>Training mode</h3> <p>Use the &quot;Training&quot; mode to practice controlling the helicopter before trying to take on any missions. You will need to be comfortable with keeping low, stopping and hovering, and landing, before attempting to engage in combat.<br /> Training mode is exactly like career mode, except there are no objectives, and you cannot be shot down.</p> <h3>Flight controls</h3> <p>The helicopter and weapon systems can be fully controlled using a single controller.</p> <p>When no button is held:</p> <ul> <li>Up/down -&gt; Pitch</li> <li>Left/right -&gt; Roll</li> </ul> <p>When the circle button (Z) is held:</p> <ul> <li>Up/down -&gt; Collective</li> <li>Left/right -&gt; Tail rotor</li> </ul> <p><strong>To take off, hold circle (Z) and press the up arrow</strong> until the helicopter starts climbing.<br /> A little bit of collective will make the helicopter hover just above the ground (due to the &quot;ground cushion effect&quot;). Adding more collective will cause the helicopter to continue climbing.</p> <p>Once airborne, press the arrow keys (without holding circle) to tilt the helicopter, which will cause it to accelerate in that direction.</p> <p>The cockpit gauges help you control your flight:</p> <img style="margin-bottom:16px" border=0 src="/media/39676/113_movement.png" alt="" /> <h3>Player 2 controls (optional)</h3> <p>Although the game can be played with just one controller you can use a second controller for extra precision.<br /> The player 2 arrow keys control the collective (up/down) and tail rotor (left/right).</p> <h3>Stopping</h3> <p>Being able to stop and hover is a useful skill.<br /> Essentially this involves raising the nose and tilting backwards until your speed reduces to zero.<br /> However, keep in mind that the helicopter has momentum and it takes some distance to brake from 100mph down to zero.<br /> Also tilting backwards at speed will cause the helicopter to climb rapidly making you an easy target for SAM launchers. To avoid this, drop the collective down first before lifting the nose. Try to balance the collective and pitch angle to keep the vertical speed as close to zero as possible. When your speed is close to zero, quickly add collective to avoid dropping quickly.</p> <h3>Landing</h3> <p>Landing is tricky to master, but is an essential skill.</p> <p>Use the map view to locate your base.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/map.png" alt="" /> <p>It will be at the coordinates you took off from! Alternatively look for the orange dot on the map.</p> <p>Come to a hover next to your base, then turn to face it using the tail rotor controls.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/chopper_24.png" alt="" /> <p>Approach the the helipad slowly (~10mph) using the collective and vertical speed indicator to control the rate of descent.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/chopper_18.gif" alt="" /> <p>As you reach the helipad, tilt the nose up slightly to come to a hover and lower the collective until you touch down onto the helipad.</p> <h2>Combat</h2> <p>As well as piloting your helicopter, you will also need to destroy enemy units.<br /> This involves locating the enemy, targeting them, and selecting and firing the appropriate weapon.</p> <h3>Weapons and targeting</h3> <p>Hold cross (X) to access the weapon systems.<br /> While held:</p> <ul> <li>Up/down -&gt; Cycles through available targets.</li> <li>Left/right -&gt; Select the weapon/countermeasure to fire.</li> </ul> <p>Tap X to fire the selected weapon at the targeted unit.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/combat.png" alt="" /> <p>From left-to-right the weapons are:<br /> <img style="margin-bottom:16px" border=0 src="/media/39676/123_wepnone.png" alt="" /> - No weapon. (I.e. safety on)<br /> <img style="margin-bottom:16px" border=0 src="/media/39676/124_wepcannon.png" alt="" /> - Cannon. Effective against all unit types, but has limited range.<br /> <img style="margin-bottom:16px" border=0 src="/media/39676/125_wepmissile.png" alt="" /> - Laser guided missile. Seeks the targeted unit. Ineffective against camps and outposts.<br /> <img style="margin-bottom:16px" border=0 src="/media/39676/weprocket.png" alt="" /> - Rockets. Fly straight forward. Effective against camps <img style="margin-bottom:16px" border=0 src="/media/39676/unit_camp.png" alt="" /> and outposts <img style="margin-bottom:16px" border=0 src="/media/39676/unit_outpost.png" alt="" />, but not other targets.<br /> <img style="margin-bottom:16px" border=0 src="/media/39676/wepcounter.png" alt="" /> - Countermeasures. Used to counter surface to air missiles (SAMs).</p> <p>In order to be targeted, an enemy unit must be visible (i.e. in front of you) and in range.<br /> Range depends on your altitude - the higher up you are the greater your targeting range. Beware that this works both ways - enemies can also target you from further away when you are higher up.</p> <p>When a unit is targeted a square reticle is displayed around it, and the unit is displayed in the targeting camera view. Enemy units have a red reticle and an &quot;E&quot; displayed in the bottom left corner of the target camera view. Friendly units have a blue/gray reticle and an &quot;F&quot; displayed.</p> <h3>Enemy fire</h3> <p>The main threat will be surface-to-air missiles (SAMs). Most units will fire these at you when they spot you.<br /> Beware of SAM launchers <img style="margin-bottom:16px" border=0 src="/media/39676/unit_sam.png" alt="" /> as they fire more quickly and their missiles do greater damage.</p> <p>The IR and SAM dashboard lights tell you when an enemy is aiming and firing at you.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/incomingfire.png" alt="" /> <p>If the IR light is lit an enemy is targeting you and getting ready to fire.<br /> The SAM light means a missile has been fired and is actively seeking you, and you should take action to avoid being hit.<br /> This might mean:</p> <ul> <li>Dropping a countermeasure. This is the most effective way to avoid getting hit, but you only have a limited supply. Each countermeasure lasts for 10 seconds.</li> <li>Dropping behind a hill is occasionally effective, if you have enough time.</li> <li>Attempting to evade by turning tightly or rapidly dropping altitude. This is risky but can work.</li> </ul> <p>The other threat is anti-aircraft (AA) guns. <img style="margin-bottom:16px" border=0 src="/media/39676/unit_aa.png" alt="" /><br /> These fire shells at you which, unlike SAMs, do not seek and have a shorter range. However there is no warning indicator for AA guns and they are particularly dangerous if they catch you at close range moving slowly, or if you try to take them head on.</p> <h3>Damage</h3> <p>Damage is displayed in the mission objective display as a red bar. If the bar is fully red then you have been shot down, and your helicopter will crash to the ground.<br /> Damage also affects your engine and the amount of lift your rotors can generate.</p> <p>You can repair your helicopter by landing at a friendly helipad, and dropping the collective down to zero. This will also restock your weapons.</p> <h2>Missions</h2> <p>In career mode you will be given missions.<br /> Each involves destroying one or more enemy units at a specific location, then returning to and landing safely at your base.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/mission.png" alt="" /> <p>The mission objective is displayed at the top of the dashboard.<br /> Use the map to find your way to the objective coordinates. The objective is displayed as a red dot.</p> <p>Once enough units have been destroyed at, or close to, the mission coordinates, the mission objective will change to &quot;Return to Base&quot;, and display the base coordinates.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/returntobase.png" alt="" /> <h2>Tips</h2> <p>Some tips to help keep you in the air.</p> <h3>Keep low</h3> <p>Flying low is challenging. However keeping under 100 feet prevents you from being lit up like a Christmas tree to every SAM capable enemy unit.</p> <h3>Friendly space is to the west</h3> <p>If you need to retreat, head west.</p> <h3>Use the mountains</h3> <p>This is particularly important for missions deeper into enemy territory.<br /> The basic approach is:</p> <ol> <li>Fly to a mountain, keeping low, and come to a hover beside it. Ideally keeping it between you and enemy units.</li> <li>&quot;Pop up&quot; to 200-300 feet and look around for enemy units. Then drop down again before they can fire at you.</li> <li>Choose the next mountain.</li> <li>Decide which enemy units to destroy or avoid in order to reach the next mountain.</li> <li>Destroy the chosen units.</li> </ol> <p>Repeat the process until you are within range of your objective.</p> <h3>Watch out for AA guns</h3> <img style="margin-bottom:16px" border=0 src="/media/39676/unit_aa.png" alt="" /> <p>Getting close to an anti-aircraft gun can quickly spoil your day.<br /> Destroy them from range or avoid.</p> Thu, 29 Dec 2022 00:01:03 UTC Helicopter flight sim <p> <table><tr><td> <a href="/bbs/?pid=120362#p"> <img src="/bbs/thumbs/pico8_mot_chopper-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=120362#p"> Chopper</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=120362#p"> [Click to Play]</a> </td></tr></table> </p> <p><strong>Update: Updated cart to latest version. This is probably close to what will be released.</strong></p> <p>A work-in-progress helicopter combat flight simulation. Loosely based on my memories of playing Gunship on C64 a few decades ago.</p> <p>The heli can be controlled with player 1 input:</p> <ul> <li>By default the arrow keys control the cyclic stick.</li> <li>Hold down circle (z) to switch to collective (up/down) and tail rotor (left/right).</li> <li>Hold down cross (x) for weapons mode, where up/down cycles between targets, and left/right selects the weapon.</li> <li>Tap cross (x) quickly to fire.</li> </ul> <p>So to take off, hold down circle (z) and up.</p> <p>Alternatively you can use player 2 input (E,S,D,F in keyboard) for collective and tail rotor.</p> <p>From left to right the weapons are:</p> <ul> <li>None (i.e. safety on)</li> <li>Cannon - auto aims. Effective against all unit types. Limited range.</li> <li>Lazer guided missile - Seeks current target. Effective against tanks.</li> <li>Unguided rockets - Fly straight ahead. Effective against infantry camps.</li> <li>Countermeasures - Drop one of these to divert incoming missiles.</li> </ul> Wed, 09 Nov 2022 05:22:16 UTC Walking Simulator <p> <table><tr><td> <a href="/bbs/?pid=117935#p"> <img src="/bbs/thumbs/pico8_mot_walksim-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=117935#p"> Walking Simulator</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=117935#p"> [Click to Play]</a> </td></tr></table> </p> <p>A little texture-mapped graphics engine with BSP-tree models and fog shading.<br /> Doesn't even try to maintain 30 FPS consistently :-)</p> <ul> <li>Player one controls aim. </li> <li>Player two controls strafe. </li> <li>X/O moves up and down.</li> </ul> <p>I still don't have a plan for this cart.</p> Sun, 25 Sep 2022 10:06:28 UTC 2D transforms <p> <table><tr><td> <a href="/bbs/?pid=116309#p"> <img src="/bbs/thumbs/pico8_mot_asteriods-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=116309#p"> Asteroid Demo</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=116309#p"> [Click to Play]</a> </td></tr></table> </p> <p>This game is a little demo of a 2D transformation library I put together.<br /> I chose a simple Asteroids clone because it is a good example of rotation and scaling.<br /> The first tab contains the game. The second tab contains the library.</p> <p>The library adds commands that affect 2D drawing commands, allowing you to rotate, scale and translate output, similar to the transformation commands in HTML Canvas or the old OpenGL 1.1 matrix stack.</p> <p>It affects the following Pico-8 drawing commands:</p> <ul> <li>pset</li> <li>line</li> <li>rect/rectfill</li> <li>circ/circfill</li> <li>map</li> </ul> <p>Note: spr and sspr are <strong>not</strong> affected.</p> <p>The transformation commands are:</p> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"></p> <h3>xident()</h3> <p>Resets all transformations (to the &quot;identity&quot;).<br /> Essentially cancelling all scaling, rotation and translation.<br /> Typically this should be used at the top of _draw()</p> <h3>xtran(x,y)</h3> <p>Translate (move) by (x,y)</p> <h3>xrot(a)</h3> <p>Rotate output by a turns (anticlockwise)</p> <h3>xscale(f)</h3> <h3>xscale(x,y)</h3> <p>Scale output by factor. You can also scale x and y axis independently.</p> <h3>xpush()</h3> <p>Save the current transformation (to the transformation stack).</p> <h3>xpop()</h3> <p>Restore the last saved transformation.<br /> </div></div></div></p> Fri, 26 Aug 2022 04:30:08 UTC Instant Replays! <h1>Add an instant replay to your game!</h1> <img style="margin-bottom:16px" border=0 src="/media/39676/replaytest3_1.gif" alt="" /> <p>(Shown here: <a href="">OMEGA ZONE</a> by <a href=""> @kometbomb</a>)</p> <p>New from the mind that brought you <a href="">Instant 3D!</a> and still hasn't apologized, <strong>Instant Replays!</strong></p> <p>Paste this snippet into the end of your game and be <em>amazed at your new replay capabilities</em>!!! Or it could <em>fail completely</em>! That's the mystery of 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>do local prev={ _update=_update, _update60=_update60, _draw=_draw, btn=btn, btnp=btnp } local bstate,pstate,addr,isplay={},{},0x8000,false local function updatebtns() for i=0,5 do pstate[i]=bstate[i] end if isplay then local mask=peek(addr) addr+=1 if(mask==0xff)run() for i=0,5 do bstate[i]=mask&amp;(1&lt;&lt;i)~=0 end else local mask=0 for i=0,5 do bstate[i]=prev.btn(i) if(bstate[i]) mask|=1&lt;&lt;i end if addr&lt;0x8000+0x42ff then poke(addr,mask) addr+=1 end end end local function doreplay() poke(addr,0xff) memcpy(0,0x8000,0x4300) cstore(0,0,0x4300,&quot;mot_replay.p8&quot;) dset(63,1) run() end cartdata(&quot;replay&quot;) cartdata=function() end isplay=dget(63)==1 if not isplay then local seed=rnd(0xffff.ffff) poke4(addr,seed)addr+=4 srand(seed) menuitem(5,&quot;replay&quot;,doreplay) else reload(0,0,0x4300,&quot;mot_replay.p8&quot;) memcpy(0x8000,0,0x4300) reload(0,0,0x4300) local seed=peek4(addr)addr+=4 srand(seed) menuitem(5,&quot;end replay&quot;,function()dset(63,0)run()end) end if _update then _update=function() updatebtns() prev._update() end end if _update60 then _update60=function() updatebtns() prev._update60() end end btn=function(i) return bstate[i] end btnp=function(i) return bstate[i] and not pstate[i] end _draw=function() prev._draw() camera() clip() if isplay then print(&quot;replay&quot;,103,121,8) else print(((addr-0x8000)/0x4300*100\1)..&quot;%&quot;,115,121,8) end 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>Okay, I've exceeded by exclamation point quota.</p> <p>This is a little experiment in capturing the player's input and replaying it exactly as before in order to make the game play out exactly the same way - assuming everything goes to plan.</p> <p>To use, paste the snippet into the end of you cart, after the existing code. Then play the game for a minute and select &quot;Replay&quot; from the pause menu. The replay will continue looping until you select &quot;End replay&quot; from the pause menu.</p> <p>Note - There are a bunch of requirements/caveats for this to actually work:</p> <ul> <li>Your game must be controlled by the player 1 gamepad only. Player 2 controls, mouse, keyboard etc is not captured.</li> <li>Pico-8 must be able to read/write to an external cart (named &quot;mot_replay.p8&quot;). I don't think this will work in binary/web exports.</li> <li>Your game must not use: <ul> <li>Pico-8 memory above 0x8000</li> <li>Menu item slot 5</li> <li>Cart data slot 63</li> </ul></li> <li>The snippet will hijack your cart data and use cartdata(&quot;replay&quot;) instead</li> <li>Replays cut off after 10 minutes or so due to limited storage space.</li> </ul> <p>And there's probably other ways it can fail that I haven't thought of :-). Try it and see..</p> <p>A few games it seems to work with:</p> <img style="margin-bottom:16px" border=0 src="/media/39676/harold s bad day 1 4_0.png" alt="" /> <p><a href="">Harold's Bad Day</a> by <a href=""> @biovoid</a></p> <img style="margin-bottom:16px" border=0 src="/media/39676/phoenix_0.png" alt="" /> <p><a href="">Phoenix</a> by <a href=""> @pahammond</a><br /> (Had to remove the cartdata() call from the snippet)</p> <img style="margin-bottom:16px" border=0 src="/media/39676/ninja cat 1 0_1.png" alt="" /> <p><a href="">Ninja Cat</a> by <a href=""> @cubee</a><br /> (Had to remove the cartdata() call from the snippet)</p> <img style="margin-bottom:16px" border=0 src="/media/39676/superdiscbox_0.png" alt="" /> <p><a href="">Super Disc Box</a> by <a href=""> @Farbs</a></p> Sun, 06 Feb 2022 08:55:00 UTC Mot's Grand Prix track editor <p> <table><tr><td> <a href="/bbs/?pid=97963#p"> <img src="/bbs/thumbs/pico8_mot_grandprix_editor-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=97963#p"> mot_grandprix_editor</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=97963#p"> [Click to Play]</a> </td></tr></table> </p> <p>This is the track editor for <a href="">Mot's Grand Prix</a></p> <p><strong>I don't recommend running this in browser as you cannot save/load tracks - anything you build will be lost.<br /> Rather download the file and run it in Pico-8 itself.</strong><br /> You will also need to download the main game and run it in Pico-8 in order to race on any tracks you create.</p> <p>This editor requires a keyboard and mouse.</p> <h2>Existing tracks</h2> <p>You can download the tracks from the existing game from this <a href="">Google Drive folder</a>. Place them in your carts folder (next to the editor) then select &quot;Load&quot; from the editor hamburger menu (top right) to load them.</p> <h2>Basic usage</h2> <p><strong>IMPORTANT: There are known bugs that will crash the editor, so save often!</strong></p> <ul> <li>Use the arrow keys to scroll along the track.</li> <li>Use the hamburger menu (top right) to load save and export tracks.</li> <li>The &quot;New&quot; menu creates new stages, curves and items (described in detail further down).</li> <li>Click &quot;Drive&quot; to drive on the track (select &quot;Editor&quot; from the pause menu to return to the editor).</li> <li>Select things by clicking on them. You can then edit their properties, or delete them by clicking &quot;-&quot;.</li> <li>After making a change you usually have to click &quot;Update&quot; (bottom right) to update the visual model (I didn't have enough tokens to make this automatic).</li> </ul> <h2>Track format</h2> <p>The basic components of a race track are:</p> <ul> <li>Stages</li> <li>Curves</li> <li>Items</li> </ul> <h3>Stages</h3> <p>Are used to partition the race track. Every track must have at least one stage.<br /> The advantage of having multiple stages is that their curves and items are stored independently of the other stages, so if you modify the curves in a stage you only need to fixup the positions of the background items within that stage. Also they can help you keep track of what part of the track you are working on.</p> <p>Click &quot;New-&gt;Stage&quot; to add a new stage. The new stage will be inserted immediately after the current stage.</p> <p>The current stage is displayed top-left underneath the menu bar.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/Screenshot 2021-09-29 200847.png" alt="" /> <p>You can click on the name to edit it. Or click &quot;-&quot; to delete it.<br /> Deleting a stage deletes all its curves and background items, so be careful.</p> <h3>Curves</h3> <p>Curves define the shape of the race track, i.e. the corners, straights, hills, valleys etc.<br /> <em>Note: Despite the name a &quot;curve&quot; doesn't have to actually curve. It can be completely straight.</em></p> <p>Click on the race track itself to select a curve.</p> <p>Click &quot;New-&gt;Curve&quot; to add a new curve.<br /> If a curve is already selected, the new curve will be inserted immediately before it in the current stage.<br /> If no curve is selected, the new curve will be added to the end of the current stage.<br /> To delete the curve, select it and click the &quot;-&quot; button next to the curve (NOT the one next to the stage!)</p> <p>Edit the curves properties to modify it.<br /> Most properties are edited using sliders. Drag with the left mouse for small increments and right mouse for large.<br /> <strong>Remember to click &quot;Update&quot; to see the result of a change.</strong></p> <img style="margin-bottom:16px" border=0 src="/media/39676/mot_grandprix_edit_4.png" alt="" /> <ul> <li><strong>Length</strong> = Length of the curve in units (units are about 4-10 meters long - scale isn't very accurate in this game)</li> <li><strong>Turn</strong> = How sharply the road turns. 0 is straight, negative values turn left, positive turn right.<br /> For reference the hairpin turn in &quot;Suzuka&quot; is -0.32, which is close to the limit of how sharply cars can corner in this game.</li> <li><strong>Pitch</strong> = Vertical gradient. 0 is flat, -1 is up 45 degrees, 1 is down 45 degrees.<br /> Pitch is an optional property. Tick the tick-box to enable it. If omitted the pitch from the previous curve will be used.<br /> Pitch is linearly interpolated. The value you set is actually the pitch at the <em>end</em> of the current curve. It will smoothly transition from the previous pitch to that value across the curve.</li> <li><strong>Left/Right</strong> = Define the horizontal range, i.e. how far left/right cars can go without crashing into a barrier.<br /> The left and right barriers are visually represented by the &quot;L Barrier&quot; and &quot;R Barrier&quot; settings below. It's a good idea to set these - otherwise the player will simply crash into an invisible barrier.<br /> The road is 8 units wide, so the &quot;Left&quot; usually is -4 or less, and right 4 or greater, although they can be set to -3/3 to clip into the gravelly region of the road. The AI cars expect the full width of the road to be available though, so be careful when doing this.<br /> Left/right are also optional, linearly interpolated properties.</li> <li><strong>L Barrier/R Barrier</strong> = Define the visual left and right barriers. Each one is a list of item types that will be repeated. Tick the tick box to specify the barrier type, then click &quot;[New]&quot; to add an item type.<br /> Select the item type from the list (use the mouse wheel to scroll). <em>Make sure to only select item types starting with &quot;Barrier_&quot;</em> (I didn't have enough tokens to automatically filter the list).<br /> Generally it makes sense to use just one barrier types, or combine &quot;Barrier_Fence&quot; with one of the other types.<br /> L Barrier/R Barrier are optional.</li> <li><strong>Trees</strong> = Generate random trees on the left/right side of the map.<br /> This is a list of horizontal positions to place the trees at trees' horizontal positions vary randomly by a few units as well.<br /> Trees are optional.</li> </ul> <h3>Items</h3> <p>Items are background items, like stadiums, buildings, signs. They don't affect gameplay, but make the track look more alive.<br /> Click on a background item to select it.<br /> You can also use the &quot;&lt;&quot; and &quot;&gt;&quot; buttons to cycle through the items in a stage (useful if you accidentally place one in a position where it is never visible and can't be selected normally).<br /> Click &quot;New-&gt;Item&quot; to create a new item, then select the item type from the list (mouse wheel to scroll).<br /> The item will be created in the current stage, a few units in front of the camera.<br /> To delete the item, click the &quot;-&quot; button next to it.</p> <p>Background items have 3 properties representing their position relative to the race track.</p> <ul> <li>X = Horizontal position relative to the race track (negative = left, positive = right)</li> <li>Y = Vertical position relative to the ground (negative = up, positive = down)</li> <li>Z = Distance along track from start of stage.</li> </ul> <h2>Other properties</h2> <p>You can also edit the sky and ground colours by selecting &quot;Properties&quot; in the hamburger menu.</p> <h2>Generated content</h2> <p>The following items are generated automatically and cannot be edited:</p> <ul> <li>Race track shoulder things (I tried to Google for the proper name, but only found things that stop horses from biting your shoulders...)</li> <li>Distance to turn signs</li> <li>Racing line markers</li> </ul> <h2>Exporting</h2> <p>To race on your track in the actual game, you need to export it:</p> <ol> <li>Click &quot;Export&quot; in the hamburger menu. This will copy a string to the clipboard.</li> <li>Open up &quot;Mot's Grand Prix&quot; in Pico-8.</li> <li>Open tab 8.</li> <li>Choose a track to replace (there isn't enough compressed space left to add any more).</li> <li>Replace the string for one of the existing tracks. <strong>Be sure to switch to &quot;Puny font&quot; mode (press Ctrl+P) before pasting from the clipboard.</strong></li> <li>Optionally edit the &quot;finline&quot; variable to set the finish line distance.</li> <li>If you want to change the track name on the start screen, edit the &quot;tracknames&quot; variable in tab 1.</li> </ol> <p>Your track should now be in the game.</p> Thu, 30 Sep 2021 23:37:44 UTC Mot's Grand Prix <p> <table><tr><td> <a href="/bbs/?pid=97606#p"> <img src="/bbs/thumbs/pico8_mot_grandprix2-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=97606#p"> Mot's Grand Prix</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=97606#p"> [Click to Play]</a> </td></tr></table> </p> <p>Title screen artwork by <a href="">Marco Vale</a></p> <p><strong>Update: The track editor is <a href="">now available here</a>.</strong></p> <p><strong>Update 2: Added Autodromo Nazionale di Monza circuit</strong></p> <p><strong>Update 3: Added last two tracks (Hockenheim and Spa Francorchamps) plus championship mode. The BBS version now plays identically to the <a href=""> multi-cart version</a>.</strong></p> <p><strong>Update 4: Minor update to add some side-textures to buildings. (No more boring gray boxes.)</strong></p> <p>Step back in time to an era when folk were real folk and racecar steering wheels were real steering wheels.<br /> Mot's Grand Prix is a pseudo 3D Formula 1 racer inspired by Grand Prix Circuit, Continental Circus and a bunch of other 80s/90s racers I've forgotten :).</p> <p>Strap into your single seater and blast around 6 classic race courses:</p> <ul> <li>Brands Hatch</li> <li>Hockenheim (old layout)</li> <li>Autodromo Nazionale Monza</li> <li>Silverstone</li> <li>Spa Francorchamps</li> <li>Suzuka</li> </ul> <p>Or enter the championship and try to be top of the points table at the end of the season.</p> <p>The game has 4 difficulty levels plus a practice mode to learn the courses without the pressure of racing.</p> <h3>Controls</h3> <ul> <li>Left/Right = Steer</li> <li>Z/Up = Accelerate</li> <li>X/Down = Brake</li> </ul> <h3>Mouse control</h3> <p>You can also enable mouse control in the pause menu. It has 3 settings:</p> <ul> <li>Off = No mouse control. Keys/gamepad only.</li> <li>Steering = Mouse controls steering (left/right axis). Keys/gamepad controls acceleration/braking.</li> <li>Full = Mouse controls steering (left/right axis) and acceleration/braking (up/down axis).</li> </ul> <p>&quot;Steering&quot; mode can be quite playable if you use a large window size or full-screen mode. Use the keyboard keys to accelerate/brake as usual.<br /> &quot;Full&quot; mode is not really playable unless you're some kind of robot, but can be useful for other input devices if they can be configured to output mouse movements (e.g. a Steam controller).</p> <h3>Tips</h3> <p><strong>This is a game where you have to slow down for the corners!</strong><br /> Use the colour of the racing line to judge your speed.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/mot_grandprix p8_11.png" alt="" /> <ul> <li>Green -&gt; You are fine</li> <li>Yellow -&gt; You are close to the limit, but should be able to make the turn</li> <li>Red -&gt; You are likely going too fast for the corner</li> </ul> <p>If you're really having trouble, you can switch on &quot;Auto Brake&quot; in the pause menu. Auto-brake automatically slows you down for corners, but not to avoid crashing into other cars.</p> <p><strong>Don't be timid about muscling through traffic</strong><br /> There is no damage model. Your car is indestructible. Be fearless! :-)</p> <p>Hope you enjoy this game.<br /> -Mot</p> Tue, 21 Sep 2021 12:36:25 UTC Feature suggestion - Enhanced controller input <p>Just a suggestion, but for modern controllers it would be really nice if the extra controls could be mapped like:</p> <ul> <li>Right trigger = X</li> <li>Left trigger = O</li> <li>Right thumbstick = Mouse</li> </ul> <p>That would allow FPS games like Poom, Sorcerer to be played like a twin stick shooter on capable input devices, without actually changing Pico-8's input model.</p> Tue, 17 Aug 2021 12:48:22 UTC Variable inspector (debugging) <p>This is a cut down version of the variable inspector I wrote a while ago. It's a bit more limited, but a lot more light weight. And there's a way to use it even if you have no tokens to spare (described below).</p> <p>You use it to view Lua table variables:</p> <ol> <li>Run your game</li> <li>Press Esc to break into it</li> <li>Type: dinsp(variable)</li> </ol> <p>Then use the mouse to expand values and scroll wheel to scroll up/down.</p> <img style="margin-bottom:16px" border=0 src="/media/39676/dbg_test_0.gif" alt="" /> <p>Code snippet follows (for some reason I can't use the code formatting tags):</p> <hr /> <p>poke(0x5f2d,3)cursor()pal()clip()function dadd(n,v,i,p)add(lines,{n=n,v=v,x=type(v)==&quot;table&quot;and&quot;+&quot;or&quot; &quot;,i=i},p) end function dexp(l,p)if l.x==&quot;+&quot; then for n,v in pairs(l.v) do p+=1 dadd(n,v,l.i..&quot; &quot;,p)end l.x=&quot;-&quot;end end</p> <p>function dinp()local x,y,b,w=stat(32),stat(33),stat(34),stat(36)line(x,y,x,y+2,10)if btnp(❎) then local i=(y-10)\6+1 local p=s+i local l=lines[p]if l and (x-10)\4==#l.i then dexp(l,p)end end s=max(min(s-stat(36),#lines-18),0)end</p> <p>function dui()while true do rectfill(10,10,118,118,1)for i=1,18 do local l=lines[i+s]if l then print(l.i..l.x..l.n..&quot;:&quot;..tostr(l.v),10,(i-1)*6+10,7)end end dinp()flip() end end function dinsp(v)lines,s={},0 dadd(&quot;value&quot;,v,&quot;&quot;,#lines+1)dui()end</p> <hr /> <p>The snippet is 246 tokens.<br /> If you don't have 246 spare tokens, you can still use it as follows:</p> <ol> <li>Run your game</li> <li>Press Esc to break into it</li> <li>Paste in each of the 3 snippet lines one at a time, pressing enter after each.</li> <li>Type: dinsp(variable)</li> </ol> <p>The snippet must be entered as 3 separate lines because Pico-8 has a 255 character limit for lines in immediate mode.</p> Mon, 26 Jul 2021 07:12:46 UTC Feature request: Metronome in sfx editor <p>This is a suggestion, not a bug obviously.</p> <p>The ability to toggle on a metronome tick/beep every 4 beats in the sfx editor would be quite helpful for composing tunes.</p> Sun, 18 Jul 2021 08:41:58 UTC Trial of the Sorcerer <p> <table><tr><td> <a href="/bbs/?pid=94900#p"> <img src="/bbs/thumbs/pico8_mot_sorcerer-11.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=94900#p"> Trial of the Sorcerer</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=94900#p"> [Click to Play]</a> </td></tr></table> </p> <p><em>UPDATE: The dungeon generation logic has been revamped. Rooms are not always rectangular, and can often have a bit more cover (or hiding places for monsters). Also added a couple of new enemy types. Gold has been removed (I needed the extra tokens), but it didn't really do anything anyway.</em></p> <p>Grab your magic staff and venture deep into the demon realm to defeat Bahmott and his evil servants!</p> <p>Trial of the Sorcerer is a procedurally generated 3D first person shooter inspired by Wolfenstein 3D and Catacomb Abyss.</p> <p>Shoot monsters, collect loot, find keys to unlock doors, and try to find the exit to the next level.<br /> And don't forget to pickup the power crystals to level-up your magic staff along the way.</p> <h3>Input</h3> <p>Arrows = Move<br /> X = Shoot<br /> Z = Hold to strafe</p> <p>Or use player 2 controls (E,S,D,F) to move/strafe and player 1 controls to turn.</p> <p>Mouse input can be enabled via the pause menu (once in game), but only when playing via the Pico-8 application as mouse locking doesn't currently work in the browser version.</p> <h3>Tips</h3> <p>Doors with a small black keyhole require keys.<br /> Each door requires a specific key, so if one won't open it means you don't have the right key yet.</p> Fri, 16 Jul 2021 05:45:28 UTC Crypts of Mot <p> <table><tr><td> <a href="/bbs/?pid=94197#p"> <img src="/bbs/thumbs/pico8_mot_crypt-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=94197#p"> Crypts of Mot</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=94197#p"> [Click to Play]</a> </td></tr></table> </p> <p>Still needs quite a bit of finishing off.<br /> I'm posting it now mainly so I can play it on my phone :-)</p> <p>Levels are randomly generated. Shoot monsters, collect loot, find keys to unlock doors and reach the exit.</p> Tue, 29 Jun 2021 09:35:21 UTC Formula 1 practice lap <p> <table><tr><td> <a href="/bbs/?pid=87611#p"> <img src="/bbs/thumbs/pico8_mot_formula1-4.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=87611#p"> mot_formula1</a><br><br> by <a href="/bbs/?uid=39676"> Mot</a> <br><br><br> <a href="/bbs/?pid=87611#p"> [Click to Play]</a> </td></tr></table> </p> <p>Strap into one of the world's fastest race cars and blast around the legendary Bronzerock circuit like it's 1988!<br /> ...or something - there's not a lot of physical or historical accuracy in this game :)</p> <p>Z/X=accelerate/brake<br /> Left/right=steering</p> <p>Driving off road slows you down. Driving too fast around corners causes you to slide.</p> <p>You can use the pause menu to view your last/best lap times (my best so far is 1:43.23)</p> <p>This is work-in-progress, so some caveats:</p> <ul> <li>There are no other cars yet.</li> <li>Lots of things need tweaking/adjusting.</li> </ul> Sun, 14 Feb 2021 03:01:03 UTC