raulboo [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=54921 Miditron - The first midi to picotron conversion tool! <img style="margin-bottom:16px" border=0 src="/media/54921/miditron_01.p64.png" alt="" /> <p>(Access it from BBS with <code>load #miditron-0</code>)</p> <h1>Miditron!</h1> <h3>The first midi-to-picotron conversion tool!</h3> <p>This tool allows you to convert .mid or .midi files into .sfx files used by the Picotron synth tracker.<br /> Just drag and drop the desired midi onto the window, and voila! Your midi is transformed into a .sfx file, conveniently placed onto your sfx folder in your current cart~</p> <p>Beware!! The tool is pretty barebones though! And far, <em>far</em> from perfect. So you might encounter glitched tracks and have to manually adjust patterns and tracks to fit the desired results.</p> <p>Some handy tips for adjusting your midi files for an optimal result would be:</p> <ul> <li>Use only 2/4, 3/4 and 4/4 meters; These meters are the most optimally supported by the tool</li> <li>Avoid odd-numbered sections of the song (sections are separated by time signature change or tempo change)</li> <li>Avoid using .midi with too many simultaneous notes/instruments (Picotron only supports 8 a time)</li> <li>If need be, check the Ignore Tempo Changes checkbox (some midi files are weird and change tempo every note, and miditron will identify it as a section change, and will mess everything up)</li> </ul> <p>I worked really hard on this tool, and I've learned a lot! I'm really proud of it and I'm happy to feel like I'm contributing to this wonderful community &gt;w&lt;</p> <p>Cheeeers 🌟🌺</p> https://www.lexaloffle.com/bbs/?tid=141566 https://www.lexaloffle.com/bbs/?tid=141566 Tue, 09 Apr 2024 00:43:36 UTC ❤️ starry trip 🌟 - 3 free to use music tracks for pico-8 games <img style="margin-bottom:16px" border=0 src="/media/54921/5_coverlexa.png" alt="" /> <h1>~ ❤️ <a href="https://naramel.itch.io/starry-trip">starry trip</a> 🌟 ~</h1> <p><em>a musical journey through the stars</em></p> <p><em>by ral schutz</em></p> <h3></h3> <p><em>my submission for the <a href="https://itch.io/jam/pico-8-free-music-jam">free music jam</a></em></p> <p><em>containing 3, free to use original tracks</em></p> <p><em>under the <a href="https://creativecommons.org/licenses/by-sa/4.0/">cc by-sa 4.0 deed license</a></em></p> <h3></h3> <h3></h3> <p> <table><tr><td> <a href="/bbs/?pid=142281#p"> <img src="/bbs/thumbs/pico8_starry_trip_1-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=142281#p"> starry_trip_1</a><br><br> by <a href="/bbs/?uid=54921"> raulboo</a> <br><br><br> <a href="/bbs/?pid=142281#p"> [Click to Play]</a> </td></tr></table> <br /> <table><tr><td> <a href="/bbs/?pid=142281#p"> <img src="/bbs/thumbs/pico8_starry_trip_2-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=142281#p"> starry_trip_2</a><br><br> by <a href="/bbs/?uid=54921"> raulboo</a> <br><br><br> <a href="/bbs/?pid=142281#p"> [Click to Play]</a> </td></tr></table> <br /> <table><tr><td> <a href="/bbs/?pid=142281#p"> <img src="/bbs/thumbs/pico8_starry_trip_3-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=142281#p"> starry_trip_3</a><br><br> by <a href="/bbs/?uid=54921"> raulboo</a> <br><br><br> <a href="/bbs/?pid=142281#p"> [Click to Play]</a> </td></tr></table> </p> <h3></h3> <p><strong><em>1 - stargazing on the star train 🌟</em></strong></p> <p><em>(uses channels 1, 2 and 3 | 4 custom instruments 0-3 | uses total 45 sfx )</em></p> <h3></h3> <p><strong><em>2 - adventure on the garden planet 🍃</em></strong></p> <p><em>(uses channels 1, 2 and 3 | 4 custom instruments 0-3 | uses total 52 sfx )</em></p> <h3></h3> <p><strong><em>3 - burning core of a star 🔥</em></strong></p> <p><em>(uses channels 1, 2 and 3 | 4 custom instruments 0-3 | uses total 46 sfx)</em></p> <h3></h3> <p><em>have fun :3 ✨</em></p> https://www.lexaloffle.com/bbs/?tid=140467 https://www.lexaloffle.com/bbs/?tid=140467 Fri, 01 Mar 2024 21:15:39 UTC [WIP, help much appreciated!] ToriEngine, ECS Engine for Metroidvanias in PICO-8 <h1>ToriEngine - ECS Metroidvania Engine</h1> <p> <table><tr><td> <a href="/bbs/?pid=132836#p"> <img src="/bbs/thumbs/pico8_toriengine-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=132836#p"> toriengine</a><br><br> by <a href="/bbs/?uid=54921"> raulboo</a> <br><br><br> <a href="/bbs/?pid=132836#p"> [Click to Play]</a> </td></tr></table> </p> <p>I'm building an Entity-Component-System engine-thing to make platforming metroidvania games like Cave Story on Pico-8. I was initially building it for a Jam game, Tori Tower, but the engine fell out of scope x.x</p> <p>I have run into some issues as I was building the code, and I'd really appreciate if anyone would like to help me here and there ^^</p> <p>I'll start by explaining how the engine works, so it all becomes easier to digest later:</p> <h3>Architecture</h3> <p>An ECS (Entity-Component-System) is an architecture for games in which the <strong>World State</strong> is populated by <strong>Entities</strong>, which are simply containers (tables) who store values. These values are called <strong>Components</strong>, and each entity has its own set of components, which its own values assigned.</p> <p>Entities hold no functions. The logic is handled by <strong>Systems</strong>, which are functions that make changes in the World State every frame. A system does so by <em>filtering out the entities in the world who have components relevant to the system, and executes the function upon each entity selected</em>.</p> <p>Example: Moving system<br /> A moving system moves every entity that is movable each frame.</p> <p>So, the system <code>_move</code> will filter out the <code>world</code> table, so that it only selects the entities who have the <code>move</code> and <code>pos</code> component. Those components look a bit like this:</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>entity_that_moves={ pos = {x=30,y=64} --position component move = {vel_x=1,vel_y=0,max_vel_x=3,max_vel_y=2,acc_x=1, acc_y=3, friction=0.8} --movement component }</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Filtering out these systems, it'll run the logic for movement:</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>function(ent) ent.move.vel_x=mid(-ent.move.max_vel_x,ent.move.vel_x+ent.move.acc_x,ent.move.max_vel_x) ent.move.vel_y= --yadda yadda yadda you get the point 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>With that said, I'll explain how my engine is working.</p> <h3>The Core</h3> <p>The core is simple and compact, and credit goes to <a href="https://www.lexaloffle.com/bbs/?uid=24591"> @selfsame</a> for creating the system, and <a href="https://www.lexaloffle.com/bbs/?uid=10816"> @alexr</a> for building upon it:<br /> <a href="https://www.lexaloffle.com/bbs/?tid=30039">https://www.lexaloffle.com/bbs/?tid=30039</a></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>-- basic function _has(e, ks) for n in all(ks) do if e[n]==nil then return false end end return true end function system(ks, f) return function(es) for e in all(es) do if _has(e, ks) then f(e) end end end end --extras function tag(e,k,v) if (not v) v=true e[k]=v end function untag(e,k) e[k]=nil end function filter(es,k,v) local res={} for e in all(es) do if e[k]==v then add(res,e) end end return res end function find(es,k,v) local res=filter(es,k,v) if (#res&gt;0) return res[1] return nil end function filter_tagged(es,t) local res={} for e in all(es) do if e[t]!=nil then add(res,e) end end return res 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>Basically, the function <code>system(ks, f)</code> returns a system function, that when called passing the <code>world</code> as the argument, executes function <code>f</code> upon the entities in the world that have all the components dictated in <code>ks</code> (a table of strings)</p> <p>The other extra functions are pretty self explanatory. Tagging just means adding a component to an entity that didnt have it before.</p> <h3>Entities and Components</h3> <p>Entities are all stored in the <code>world</code> table, and are made in factory functions, such as <code>mk_player(x,y)</code>, that returns a table with all the components of a player, to be added to the <code>world</code>.</p> <h3>Systems</h3> <p>Update systems are called in the <code>_update60()</code> function and rendering systems are called in the <code>_draw</code> function. These are the ones currently implemented:</p> <p>(credit to @matthughson for the collision system, on this cart: <a href="https://www.lexaloffle.com/bbs/?tid=28793">https://www.lexaloffle.com/bbs/?tid=28793</a>)</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>function _update60() -- these are the updater -- systems we need (for now) _animate(world) --_behaviour_system(world) _ai_behaviour(world) _move_input(world) _jump_input(world) _atk_input(world) _gravity(world) _grounded(world) _movement(world) _map_collisions(world) _ent_collisions(world) _damaged(world) _death(world) end function _draw() palt(11,true) palt(0,false) cls(5) colorize(128,133,141,134) map() -- these are the render systems -- we need (for now) colorize(129,2,15,7) _animspr(world) _camera(world) pal() _ui(world) -- just debug stuff if debug then _debug_vectors(world) for p in all(debug_collision_pixels) do pset(p[1],p[2],p[3]) 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> <h3>Custom Handlers</h3> <p>Collisions are handled in separate functions, because their logic was too extensive to handle in a single system function.</p> <p>They're separated into two types: colisions with the <em>map tiles</em> and collisions with <em>other entities</em>.</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>-- update systems _map_collisions = system({&quot;pos&quot;,&quot;size&quot;,&quot;mcoll&quot;,&quot;jump&quot;}, function(e) collide_side(e) collide_roof(e) if collide_floor(e) then tag(e,&quot;grounded&quot;) else --self:set_anim(&quot;jump&quot;) untag(e,&quot;grounded&quot;) end end) _ent_collisions = system({&quot;pos&quot;,&quot;move&quot;,&quot;ecoll&quot;}, function(e) for typ,tg in pairs(e.ecoll.all) do local es=filter(world,&quot;type&quot;,typ) for e2 in all(es) do if e2!=e and overlaps_box_box( e.pos,e.size, e2.pos,e2.size) then --entity collided will become --e[tg] if (not e[tg]) tag(e,tg,{by=e2}) end end end end ) -- custom handlers function collide_side(e) local offset=e.size.x/3 for i=-(e.size.x/3),(e.size.x/3),2 do --if e.move.vx&gt;0 then if fget(mget((e.pos.x+(offset))/8,(e.pos.y+i)/8),0) then e.move.vx=0 e.pos.x=(flr(((e.pos.x+(offset))/8))*8)-(offset) return true end --elseif e.move.vx&lt;0 then if fget(mget((e.pos.x-(offset))/8,(e.pos.y+i)/8),0) then e.move.vx=0 e.pos.x=(flr((e.pos.x-(offset))/8)*8)+8+(offset) return true end -- end end --didn't hit a solid tile. return false end --check if pushing into floor tile and resolve. --requires e.move.vx,e.pos.x,e.pos.y,self.grounded,self.airtime and --assumes tile flag 0 or 1 == solid function collide_floor(e) --only check for ground when falling. if e.move.vy&lt;0 then return false end local landed=false --check for collision at multiple points along the bottom --of the sprite: left, center, and right. for i=-(e.size.x/3),(e.size.x/3),2 do local tile=mget((e.pos.x+i)/8,(e.pos.y+(e.size.y/2))/8) if fget(tile,0) or (fget(tile,1) and e.move.vy&gt;=0) then e.move.vy=0 e.pos.y=(flr((e.pos.y+(e.size.y/2))/8)*8)-(e.size.y/2) landed=true end end return landed end --check if pushing into roof tile and resolve. --requires e.move.vy,e.pos.x,e.pos.y, and --assumes tile flag 0 == solid function collide_roof(e) --check for collision at multiple points along the top --of the sprite: left, center, and right. for i=-(e.size.x/3),(e.size.x/3),2 do if fget(mget((e.pos.x+i)/8,(e.pos.y-(e.size.y/2))/8),0) then e.move.vy=0 e.pos.y=flr((e.pos.y-(e.size.y/2))/8)*8+8+(e.size.y/2) e.jump.jump_hold_time=0 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> <h3>Databases</h3> <p>These are for data sets that are repeated among many entity constructors, or those that are unique<br /> to each entity. Things such as animations and enemy behaviours.<br /> There's a better description of each in the code :3</p> <h3>Backlog</h3> <p>[X] ECS</p> <p>Gamemodes<br /> [X] Overworld<br /> [ ] Cutscene<br /> [ ] Boss Fight<br /> [ ] Title Screen<br /> [ ] Game Over Screen</p> <p>Entities<br /> [X] Player<br /> [X] Enemy<br /> [ ] Item<br /> [ ] Moving Blocks/Platforms<br /> [ ] Breakable Block<br /> [ ] Boss</p> <p>Update Systems<br /> [X] Movement<br /> [X] Solid Collisions<br /> [X] One-Way Platform Collisions<br /> [X] Entity Collisions<br /> [X] Walk Input<br /> [X] Jump Input<br /> [ ] Get Item<br /> [X] Take Damage (any entity with HP)<br /> [ ] Knockback<br /> [~] Die<br /> [~] Enemy Behaviour<br /> [ ] Gameover<br /> [ ] Scriptable Overworld Cutscenes (Toriscript)</p> <p>Render Systems<br /> [X] Sprites<br /> [X] Sprite Animations<br /> [X] Camera<br /> [X] HP UI<br /> [ ] Current Item UI<br /> [ ] GFX<br /> [ ] Textbox</p> <p>Custom Handlers<br /> [ ] Change/Load Room<br /> [ ] Story Event Handler<br /> [ ] Save Progress</p> <h3>Current Progress [Aug 07 2023]</h3> <p>I'm currently having issues with implementing the unique entity behaviour. If you see the _ai_behaviour() system and the db_bhvr table, you'll see what I'm talking about.<br /> There's been weird behaviour like this one - the enemy is only supposed to avoid walls and pits; I'm not sure what's causing it .w.</p> <img style="margin-bottom:16px" border=0 src="/media/54921/tori-enginev5 p8_0.gif" alt="" /> <p>Any help will be sincerily appreciated~<br /> Cheers!</p> https://www.lexaloffle.com/bbs/?tid=53684 https://www.lexaloffle.com/bbs/?tid=53684 Mon, 07 Aug 2023 16:15:44 UTC