Log In  
Follow
BenWiley4000

For games, I do programming and music/sfx. For money, I do web development (mainly JavaScript lately).

@BenWiley4000


If you port your PICO-8 game to any European languages other than English, you might want to include some character accents, which doesn't work by default since PICO-8 only supports ASCII characters (plus some special ones in the unused range between ASCII and ISO-8859-1).

My work here is based off of Zep's post from a couple weeks ago about Latin accent printing (by including special characters in front of plain ASCII characters to indicate accents). My code goes a step further by offering a way to save your strings with the real accent characters included, and then encode them so they can be printed properly. This way your text is a bit more readable in the source file.

I slightly modified Zep's original print function by changing the : control character to @ since I needed : in my printed text. The general rule, if you want to add new encoded characters to this system, is to pick a control character that won't be needed in the actual printed text.

[ Continue Reading.. ]

2
0 comments



I wrote this library to cut down on the number of tokens taken up by large tables with string data, e.g. for dialogue text/translations/etc. Most helpful if those tokens are using a lot of your tokens (i.e. more than 150), since the library itself takes up 139 tokens. But all your table declarations can be reduced to 5 tokens each!

Here's an example of what your code can look like.

Before:

my_table = {
  hello='world',
  nested={
    some='data\'s nested',
    inside_of='here'
  },
  'and',
  'indexed',
  'data',
  { as='well' }
}

After:

function table_from_string(str)
  local tab, is_key = {}, true
  local key,val,is_on_key
  local function reset()
    key,val,is_on_key = '','',true
  end
  reset()
  local i, len = 1, #str
  while i <= len do
    local char = sub(str, i, i)
    -- token separator
    if char == '\31' then
      if is_on_key then
        is_on_key = false
      else
        tab[tonum(key) or key] = val
        reset()

[ [size=16][color=#ffaabb] [ Continue Reading.. ] [/color][/size] ](/bbs/?pid=64776#p)
4
6 comments



Here's a simple tool I made for converting PICO-8-style Lua syntax into standard Lua syntax which allows you to run code analysis tools created for Lua. It's a thin wrapper around a converter function I took from PICOLOVE.

https://github.com/benwiley4000/pico8-to-lua

1
0 comments



Cart #51655 | 2018-04-16 | Code ▽ | Embed ▽ | No License
18

Sk8Border is a collaboration by Leif Halldór Ásgeirsson, Marc-André Toupin and Ben Wiley for the Anti-Fascist Game Jam.

Works in mobile browsers!

Hold Z or X to crouch, release to jump (Ollie). Do a tail or nose grind with Z or X. Rack up a nice combo to take down the wall!

More details and play instructions are at the game's official site. We recommend playing it on mobile there since we have specially tailored controls, and vibration support!

The game is "finished," but comments are always welcome.

18
8 comments



Here's a repo with the code and more details on GitHub

PICO-8 has a GPIO interface supporting 128 pins, each of which can store a 128-bit unsigned integer (0-255). However Raspberry PI and CHIP only support consuming each GPIO pin as a single bit (0 or 255), and only have pins for a small subset of the 128 virtual slots. The Pocket CHIP only has 6 fully-exposed pins (indices 2-7).

This means that if you want to pass GPIO information that can be used easily with any platform that runs PICO-8, you only get six on-and-off slots, which doesn't sound that great. Until you consider that you can still use those 6 slots to encode an integer up to 6 bits (-32 to 31 signed, or 0 to 63 unsigned!). Even a 3-bit int (0-7 unsigned) can often be enough to encode meaningful state information for many games, which can be used to trigger vibrations, color lights, etc.

The trouble is, taking a decimal value and encoding it as binary with PICO-8's built-in GPIO functions, then reading it again later, is not simple. PICO-8 Messenger provides utility functions which abstract away the bit-shifting and let you just read and write numbers.

Usage

Copy the functions you need from pico8-messenger.lua into your .p8 file.

-- included definition for write_gpio
-- included definition for read_gpio

-- write the number -1 to bits 2 through 4
write_gpio(-1, 2, 3)

-- print out the number stored in bits 5 through 7
print(read_gpio(5, 3), 8, 8, 7)

[ Continue Reading.. ]

2
0 comments



The fact you can read and write PICO-8 GPIO values from the web wrapper is awesome - it means you can do things like emit vibrations according to game state, change the site theme to match different in-game levels, or maybe even develop a brand new input scheme.

However the API for reading these values is a bit basic... PICO-8 writes GPIO values to an array, and it's up to you, the developer to check those values periodically to see if they're different. What if you could just tell JavaScript to let you know whenever the GPIO pins get updated with new values?

Voilà:

var gpio = getP8Gpio();
var unsubscribe = gpio.subscribe(function(indices) {
  console.log(
    'New values at indices ' + indices.join(', ') + ': ' +
    indices.map(function(i) { return gpio[i]; }).join(', ')
  );
});
// unsubscribe later if you want...
unsubscribe();

This uses JavaScript setters under the hood to watch each index in the array, which means the watching part is shoved into a native background thread (== faster!). No need to write once-a-frame JS iterator loops or anything like that. Whenever PICO-8 writes to the GPIO array, you get notified immediately.

Of course you can also write back to the GPIO array:

gpio[3] = 255;
gpio[4] = 0;

[ Continue Reading.. ]

11
3 comments



I want my web export to support mobile. But if you're like me, you might find the API for controlling touch button inputs from a web page a bit esoteric, and not super easy to read/write. Why not write a tiny API wrapper that makes this much easier?

If you have a page that looks like this:

<!-- ... cart stuff -->
<button id="left"> < </button>
<button id="right"> > </button>
<button id="up"> /\ </button>
<button id="down"> \/ </button>
<button id="o"> O </button>
<button id="x"> X </button>
<! -- ... -->

Include this in your page...

(function() {
  var __btns = {};

  function update_btns(playerIndex) {
    pico8_buttons[playerIndex] =
      Object.keys(__btns[playerIndex]).reduce(function(val, btn) {
        return val | (__btns[playerIndex][btn] ? Math.pow(2, btn) : 0);
      }, 0);
  }

  function registerP8Btn(domElement, btnIndex, playerIndex) {
    playerIndex = playerIndex || 0;
    window.pico8_buttons = window.pico8_buttons || [];
    pico8_buttons[playerIndex] = pico8_buttons[playerIndex] || 0;
    __btns[playerIndex] = __btns[playerIndex] || {};
    domElement.addEventListener('touchstart', function() {
      __btns[playerIndex][btnIndex] = true;
      update_btns(playerIndex);
    });
    domElement.addEventListener('touchend', function() {
      __btns[playerIndex][btnIndex] = false;
      update_btns(playerIndex);
    });
  }

  window.registerP8Btn = registerP8Btn;
})();

[ Continue Reading.. ]

1
1 comment



Cart #19773 | 2016-04-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12

Cart #19696 | 2016-04-10 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12

As Scathe noted over here, there's not a proper/easy-to-use Timers API built into PICO-8. Turns out it's not too hard to build one, though, so I took up the task.

The cartridge which you can play above just counts to 10. I've reproduced all the code here:

-- start timers code

local timers = {}
local last_time = nil

function init_timers ()
  last_time = time()
end

function add_timer (name,
    length, step_fn, end_fn,
    start_paused)
  local timer = {
    length=length,
    elapsed=0,
    active=not start_paused,
    step_fn=step_fn,
    end_fn=end_fn
  }
  timers[name] = timer
  return timer
end

function update_timers ()
  local t = time()
  local dt = t - last_time
  last_time = t
  for name,timer in pairs(timers) do
    if timer.active then
      timer.elapsed += dt
      local elapsed = timer.elapsed
      local length = timer.length
      if elapsed < length then
        if timer.step_fn then
          timer.step_fn(dt,elapsed,length,timer)
        end  
      else
        if timer.end_fn then
          timer.end_fn(dt,elapsed,length,timer)
        end
        timer.active = false
      end
    end
  end
end

function pause_timer (name)
  local timer = timers[name]
  if (timer) timer.active = false
end

function resume_timer (name)
  local timer = timers[name]
  if (timer) timer.active = true
end

function restart_timer (name, start_paused)
  local timer = timers[name]
  if (not timer) return
  timer.elapsed = 0
  timer.active = not start_paused
end

-- end timers code

-- start app code

function _update ()
  update_timers()
end

function _init ()
  init_timers()

  local last_int = 0
  print(last_int)
  sfx(last_int)
  add_timer(
    "timer1",
    10,
    function (dt,elapsed,length)
      local i = flr(elapsed)
      if i > last_int then
        print(i)
        sfx(i)
        last_int = i
      end
    end,
    function ()
      print("done!")
      sfx(10)
    end
  )
end

-- end app code

[ Continue Reading.. ]

12
13 comments



I was discussing with a friend how to deal with complex music arrangements (all 4 channels) alongside sound effects. He alleged that the GameBoy used all its channels for music at times but would cancel one of its channels (perhaps the percussive one) to play sound effects, then resume when sound effects had elapsed.

Current PICO-8 configuration, as far as I understand, is to have music channel masks take precedence over sound effects. This is good in theory but can be bad if you want to do something like the above. A possible solution could be to allow music channel mask modification mid-playback - is this doable? It would require some way to save or lookup a currently playing track (not yet in the API as far as I know), and then we pass that track's value to a function that could reset the channel mask to fewer channels, before playing a sound effect. Then we would do it again with the previous channel mask and expect the muted track component to come back.

I'm not familiar with the tech powering sound playback for PICO-8 and I don't know if this is the sort of thing that could have a simple implementation, or if trying to be able to modify variables for already-playing songs is totally out of the question. I can begin to imagine why it would be complicated or non-performant, but I'm not sure, so I thought I'd ask.

Thanks!

3 comments



I want to write a song that's in 4, but has swinging notes - so I'm just writing tracks that fill up 24 of the slots instead of all 32. But in order to make it work in sequence I need the track to stop playing after the 24th slot and move on to the next segment in the song immediately. Is there a way to tell PICO-8 to do that? Of course I could just use all 32 slots and changing the measure's starting place depending on where I am, but I'd rather be more organized.

1
3 comments



UPDATE: Since I created this I've updated the script to apply all transforms with Python by default. The JavaScript method of shuffling elements is enabled only if 1) you lack the dependencies required by Python or 2) you specifically flag the program to use JavaScript. The advantage of doing it all with Python is that you don't have to wait until page content loads to see a responsive layout - it's already there. I've also created a comparison of the responsive and default web player layouts. And check out the README to see what Python packages you'll need to do the full HTML transform in Python.

~original post~

The default webplayer page format that gets exported from PICO-8 is great, but not quite excellent, since it only provides one display resolution. I decided to work with the structure and style a bit (using flexbox styles and media breakpoints) to make the canvas render at 290px, 580px, or 1160px wide based on what real estate is available. Also, the buttons collapse into multiple rows once the display gets small enough.

I came up with this.

[ Continue Reading.. ]

2
3 comments



So after completing the (very helpful) Squash/Pong tutorial in the first pico-8 zine, I decided to go about setting up a class-based object-oriented framework for implementing the same game - one where relevant data is contained within an object, and the object has callable methods that let the object act on its own data rather than other members reaching in and changing values. The _update() and _draw() functions in turn just call _update() and _draw() methods contained inside game objects.

Here's what I came up with: http://hastebin.com/agasogijet.lua
The code at the top is mine, and the section at the bottom contains the original code (more or less, I made a couple of changes).

It's good if you follow the tutorial from the zine (https://sectordub.itch.io/pico-8-fanzine-1), but if you don't, you should be able to paste the code into the pico-8 editor and run it. The health meter sprites won't show up, and you won't get any sound, but everything else will work.

[ Continue Reading.. ]

3
10 comments