I've bundled up my improvements for the gamepad problems in HTML exports I described over in another thread as a plate.
- Full Dpad support.
- Gamepads are only assigned to players when they first press a button. This way if you have multiple gamepads you aren't stuck with whatever order the browser decides to assign them to P1, P2, etc.
- Download the release of Nettie's Gamepad from github.
- Go to the PICO-8 plates folder. (Run FOLDER in PICO-8 to open the carts folder, go up one level, the plates folder should be alongside.)
- Copy netties_gamepad.html into the plates folder.
- Load up your game in PICO-8.
- Export with EXPORT YOURGAME.HTML -P NETTIES_GAMEPAD
I've got two big frustrations with gamepad support in HTML exported games and the BBS. The following is based on testing in Chrome on Windows and Mac using an XBox 360 Wireless Controller and a Nintendo Switch Pro Controller. I'm using this test app for everything following.
D-pad does not function as direction inputs
When exported to HTML or uploaded to the BBS, d-pads are either ignored or treated as extra pause buttons. (It seems they are ignored on the HTML export and behave as pause buttons on the BBS?) The gamepad browser API supports other controller layouts but is designed around common modern controllers, and it has a concept of the "standard gamepad" canonical device, which allocates buttons 12, 13, 14 and 15 to up, down, left and right. I would be great if the D-pad was supported here, by mapping these buttons to player direction inputs, either in addition to or instead of the analog stick.
Controller assignment cannot be changed in the browser
Controller assignment cannot be changed. Not even by unplugging and replugging controllers. I think controllers are assigned indexes by the browser when it first encounters them, and you need to restart the whole browser to get them re-indexed. This is generally untenable. PICO-8 games have some capacity to work around this, since they can see up to eight controllers, but they are hampered because they can't actually tell the difference between a player using the keyboard and one using a joystick, which renders the common best practice in this area rather player-unfriendly: to prompt for player input and then assign the first active controller as player 1, etc. Even if they can work around it, I think something could and should be done at the HTML exporter and BBS level, if not in the core of PICO-8 itself.
PICO-8 has a joystick model based on the classic consoles and arcade machines, where a fixed number of joysticks (or at least joystick ports) were present, and clearly identified by position. This is a fine model in many cases, but it begins to break down when where there are many controllers, controllers of different types, or wireless controllers, all connected to one machine. It might well be that all the controllers are not equally suitable for a given game. It might be that it's not easy to figure out which one is player 1, it might be that it's not easy or even possible to remove unwanted controllers.
As a single example, whenever I try to play an HTML-exported single player PICO-8 game, I find that none of my gamepads is player 1. Why? Well it turns out my keyboard also registers itself as a gamepad, and a pretty useless one at that. (It acts as a single-axis wheel... don't ask.) And since it's always there, it always ends up being gamepad #1. I can't unplug the keyboard, because... it's my keyboard, I need it to use the computer.
Now, there's a best practice to handle this situation! Games can wait on the title screen for a player to press a button on a controller, and then make that controller player 1. This works pretty well. But PICO-8 struggles at it because it deliberately abstracts away controllers entirely from the game code. The game doesn't know that
you're using a controller or playing with the keyboard. If you follow this method there's a risk a player unfamiliar with PICO-8 will first hit one of player 2's keyboard controls, activating player 2's awkward controls and deactivating player 1's. In trying to make the game behave better on gamepads you risk making it more confusing on keyboard. Trapped inside PICO-8's machine abstraction, there's not a lot a game can do about this.
And of course, most developers don't even try. If you're just developing a single player game, PICO-8 encourages you not even to think about other players - if you never specify a player index to BTN or BTNP you'll only ever see player 1. And honestly, maybe they shouldn't have to! It would be nice if they didn't have to worry about it. It's hard to force everybody to fix their games to handle a problem many of them will never encounter.
I'm not sure I want to advocate for any specific intervention here. Right now I just want to highlight the problem and say that it is pretty painful for me. A full controller remapping interface in the browser might be helpful but is probably overkill. I think mapping gamepads to player 1, 2, 3 etc. on first observed button press would probably be an improvement from where we are currently. I.e. after PICO-8 has loaded, the first time any unassigned controller presses a button, it gets assigned to the first unassigned player slot, starting at 1. (The main problem I can see with this is if you want one player on keyboard and one on gamepad, although that's already a problem at the moment.) It might also be helpful to have some way as a player or as a developer to force all gamepads to be player 1, to handle the most common case of single-player games.
I'm uploading this as a quick and simple joystick tester, largely to have something to point to when discussing issues with HTML5 joystick support. It just visualises the control state for all 8 possible players.
This is a demake of the infuriating "Beaver Bother" minigame from Donkey Kong 64. The minigame was a particular source of torment to Hbomberguy, a YouTuber who recently ran a wildly successfully charity livestream of him completing Donkey Kong 64 to raise money for the UK charity Mermaids, who support trans children and their parents. I created this to celebrate.
For everyone unfamiliar with PICO-8, the [O] button is Z on the keyboard and the [X] button is X.
It's still not quite there, but it's playable and almost as frustrating as the original so I think it's worth sharing.
- Sound. I'm really bad at music, so my attempts so far have been pretty miserable.
- Z-sort the mobs.
- Beaver self-preservation. Beavers should try to avoid the hole when not being chased.
- Make "scaring" useful. It's currently purely cosmetic. (Although it's unclear what function it plays in the original either...)
- Visual effects for beavers appearing.
- Better visual effects for beavers falling down the hole.
- Actually draw the walls of the barrel, rather than just lots of black circles.
- Make the beaver spawn rate more consistent so you can't just get unlucky with it.
Tutorial levels (v1.4)
Hard levels (v1.4)
Old Version 1.3:
Old Version 1.2:
Old Version 1.1:
Guide Linton the devil as she gathers the riches of the underworld. Her goal on each level is to collect all gems, collect the gold cup, defeat all serpents and finally enter the portal. Some gems are locked inside safes that open with a key. Others are sealed inside tombs and will only be released when a wandering ghost is returned to the tomb. Beware of falling rocks - Linton can support a stationary rock, but a falling one will crush her. Use rocks to your advantage to crush serpents, or to help guide ghosts. Remember that rocks will roll off surfaces that aren't level.
- Collect a clock to reset the timer. If you run out of time, you will lose a life.
- If you become trapped, you can choose "give up" from the menu to lose a life and respawn.
- Press the X button to view the map and your progress. The game is paused.
- Your best time for each level will be shown. If you haven't beaten a level yet, your highest number of gems collected is shown instead.
- Ghosts always follow the wall to their left. Once you learn their pattern they are entirely predictable.
This is a fan remake of Repton 3, with new graphics and a new set of 8 original levels. The Repton games originally featured on the BBC Micro, and in recent years have been re-released as a PC version. If you like my version, you might also be interested in the official release. And if you don't like my version, the official one has a lot more levels with a much more reasonable difficulty curve! (I have no affiliation with Superior Interactive and they don't endorse this game.)
This version is intended to be compatible with the original, i.e. if you take a level created in the original game's level editor, it should play just the same here. There are a few differences:
- The game plays a bit faster overall.
- Various graphical changes: spirits replaced with ghosts, cages replaced with tombs, skulls replaced with mines, fungus replaced with mushrooms, crowns replaced with cups, monsters replaced with serpents, Repton (a green lizard) replaced with Linton (a red devil).
- You can play any level in any order without passwords.
- Rock behaviour is very close but there are still one or two corner cases involving rolling rocks and priority of movement that I think aren't quite the same.
- Mushroom growth probably isn't quite the same rate and is more predictable.
- Ghosts and serpents appear on the map.
I actually created these levels about ten years ago in a BBC emulator. I recently found them on an old hard drive and was inspired to create this remake. I could not remember most of the solutions. The levels "oppression" and "burial" were particularly tricky. I think "pressure" might be my favourite. I chose the name "Linton" because it is a the name of a village in Derbyshire, as is "Repton".
Be warned, these levels are hard! While I'm not sure they quite match the hardest levels from Repton 3, they are certainly all on the difficult end of the spectrum. You will die a lot trying to figure them out. (That's one reason I didn't bother with progression through the levels, as it seems unnecessarily cruel.) I may add some sort of a tutorial/guide and some training levels in the future, but I've been working on it long enough and wanted to get something out! If you complete some or all of the levels, please let me know! I'd love to see some highscores.
There's not much gameplay here at the moment - just wander around the maze. It's mostly an exploration of some procedural generation. I might yet try to build a proper game around it, but I thought it might be of some interest on its own.
- 16x16 room maze generated with Kruskal's algorithm plus some extra connections to make it more interesting.
- Basic random room generation so that each room has connections to adjacent rooms that match up.
- Automatic wall borders.
- Textures assigned by randomly combining a selection of 3-colour palettes with a number of different wall, floor and border textures.
- Basic texture transitions between rooms.
- Transition textures and borders are assembled into pre-combined and paletted tiles on entering a room, saving a lot of time in rendering each frame.
- Basic shadows under the player and walls to give a bit more depth, with some hacky code to render quickly.
- Each room has a few extra walls scattered around to make it a bit more visually interesting, but there are no constraints and it occasionally clogs up an exit.
- Sometimes there's a flash of garbage textures on entering a room, because the texture assembly works by rendering every tile combination to the screen, then it's memcpy'd back into sprite memory. This could probably be avoided by drawing straight into sprite memory in the first place, but it needs more custom code.
- Some of the colour palettes clash pretty badly, and there's no constraints to try to prevent the walls and floors being the same or clashing colours. Some rooms are utterly garish, and the transitions don't look great.
- There's only about 20% CPU free even with the optimizations. Any further decoration probably can't cover much of the screen.
- The code is pretty incomprehensible right now. I've not yet made a major effort to clean it up and try to improve the identifiers and comments. If you're curious about any part let me know and I can try to explain it.
It currently uses 4020 tokens, but I think that could probably be reduced a fair bit by stripping out redundant code.