My entry for Ludum Dare 37 (theme: one room).
You're an interior decorator, and your job is to give your clients nice and shiny new homes. Take note of their demands and try to give them exactly what they want.
- a whopping 8 different pieces of furniture!
- a massive two (2) unique clients!
- almost 30 furniture styles!
- arrow keys: move cursor/select item and style
- Z (circle): new item/pick up item/place item/confirm/continue
- X (cross): finish decorating/delete item/cancel
Feel free to post screenshots of any neat rooms you decorate!
Not entirely satisfied with this one, could have gone further with it but I started losing motivation toward the end. I think it's a neat concept and I have some unexplored ideas on where it could go next, but I'm doubtful I'll keep working on it post-jam.
The cart is released under CC4-BY-NC-SA, so if you want to remix it or expand upon it (like adding more furniture or clients (or just cleaning up the spaghetti code)), I encourage you to do so.
Just uploading my #0hgame entry, made in exactly 0 hours in the timespan 2am - 2am CET.
Instructions: aim using the left and right arrow keys, wait for the toast to pop up and hit X to launch your blob of butter.
this is very dumb and ugly and i am sorry for wasting your precious time. I might be coming back to it though, I have some ideas on how to make a proper game out of it.
Recently I've been experimenting with the sfx and music editors and while they are excellent in all their simplicity, there are some areas where I would like to see it improved. I'll try to make myself as brief as possible:
The way volume is handled in PICO-8 is that it increases linearly. The problem with this is that the way humans perceive sound is logarithmic, which means that a jump from volume values 1 to 2 is a lot more noticeable than the jump from 6 to 7. Below is an Audacity recording of a square wave in the tracker going from 1 all the way to 7 displayed in both the linear and logarithmic scale and as you can see the difference in these jumps is quite significant.
Is it possible that the way volume works in PICO-8 could be fixed to ramp exponentially? I'm not sure how many people notice (or even care) but it's something that makes it hard to make natural-sounding ramps up in volume when creating sfx and music, especially on the quieter side.
2: Suggestion: Display silent notes (0 volume) in the tracker
This is a simple one: I'd like to have some sort of option (maybe in the config) that makes the tracker display note properties even if the note's volume is set to 0. As it is now all we see is "......", which can be slightly annoying when dealing with arpeggios (since they take muted notes into account). Maybe you could use darker colors to make them stand out from unmuted notes. Quick mockup:
3: Suggestion: Ability to cut sfx short (for irregular time signatures)
The way it is set up now, the only way to play in time signatures other than 4/4 is to include a sfx in your pattern with a different playback speed (for example speed 16 + a speed 12 "sync sfx" for a 3/4 time signature). I would like to be able to accomplish this without having to effectively waste a channel.
One way to implement this could be to treat sfx with their loop start index > end index as having finished played when the start index is reached. For example, a sfx with start = 24 and end = 0 would play the first 24 notes (0-23) and then stop, which could then be used for 3/4 time signature patterns.
This would mean that you are no longer limited to certain set speed values like 12 or 24, and it could also let you go much crazier with irregular time signatures than you can at the moment, like 7/8 or 29/32 or whatever insane-sounding thing you want.
Inspired by LRP's lowercase font, I made a little library that lets you print to the screen using a custom 9px variable-width font that is defined entirely in code. In other words, nice and readable text that doesn't use sprites. The cartridge includes the hastily coded example usage you see above.
init_print9 initializes font data, must be run before print9() can be used print9 str [x] [y] [col] prints to the screen using a variable-width 9px custom font if x or y are left blank it will continue printing where it last left off col is text color optionally returns the x-coordinate of the cursor, which is useful if you want to continue where you last left off (for example, when typing one character every frame) do note that print9() uses up a reasonable amount of cpu, typing out the entire lowercase alphabet uses up about 10% of the cpu @ 30fps my suggestion for longer text (i.e. dialogue boxes) is to draw to regions of the screen that are not cleared every frame and only clear when necessary is_bit_set var pos checks if the pos-th bit (including fractional part) in var is set or not used internally by print9(), but hey, it's a nice utility
With all (non-extended) characters defined, this library uses up 847 tokens. If you are desperate for tokens, it works perfectly fine to remove the definitions for characters that you don't need, for example only defining lowercase characters + punctuation can cut it down to ~450 tokens.
Explanation for how the characters are defined:
[hidden] The font data for each character are tucked away in regular Pico-8 numbers treated as bitfields. The bitfield is divided into two parts - an 11-bit header and a variable length body used as a binary bitmap. Here's what the data for the letter "e" looks like on a binary level: To be able to store more data than can be contained in a single 32-bit number we split each character up into table items, so that when we reach the end of the first item we can simply jump to the next: Let's look at the header. If the 0th bit is set, the character has an ascender. If the 1st bit is set, the character has a descender. A character that has neither an ascender nor a descender is 5px tall. A character that has an ascender extends 2 pixels upwards and adds +2px to the total height. Likewise, a character that has a descender extends 2 pixels downwards and also adds +2px to the height (a character can have both an ascender and a descender, which makes it 9px tall). The following six bits (2 through 7) are what I like to call "kerning data" and tell us whether the character "sticks" out in the top (ascender, red in the above picture), center (green) and bottom (descender, blue) regions on either side of the character: bits 2 through 4 for the left side and 5 through 7 for the right side. Let's use lowercase "d" as an example: bit 2 = 0 because the left side of the character does not occupy the top region bit 3 = 1 because the left side occupies the center region bit 4 = 0 because the left side doesn't occupy the bottom region bit 5 = 1 because the right side occupies the top region bit 6 = 1 (right side occupies the center region) bit 7 = 0 (right side doesn't occupy the bottom region) When print9() prints a character to the screen, it compares the left side of the character to be printed with the right side of the previous character. If both characters have parts that occupy the same regions (for example, "E" and "B"), there will be a 1 pixel gap between them, but if there is no match ("T" and "e") there won't be a gap (0 pixels). Let's continue looking at the header: bits 8 through 10 is simply a 3-bit number (0~7) that determines the width of the character plus 1. In other words, this means that a character can be anything between 1 and 8 pixels wide. The character "e" in the topmost image has these bits set to 011 = 3. Add 1 to that and we get a 4 pixels wide character. The body is a very simple bitmap structure that runs from top-to-bottom, left-to-right and tells print9() whether to draw a pixel (1) or not (0). Because we already calculated the height (5 px + 2 if asc + 2 if desc) and width (1 + value in bits 8-10) by looking at the header, the function knows when it's time to hop to the next vertical line and when it has reached the end of the character. If we reach the final bit of the first number we simply jump to the first bit of the next item in the table (as described earlier) (as a bonus, Pico-8 doesn't crash if we use binary operations on a nil value, meaning that if a character wraps over into a second table item but there's no data that needs to be defined in it (all zeroes from here on out) we don't need to define it and save some tokens. Woo!). To simplify, here's the bitmap for the character "e" from the earliest example and how the function treats it: That's it! That's all you need to know to create your own characters. My suggestion is to first map out your characters in the Pico-8 gfx editor, then use some calculator with a bit toggler (Window 10's default Calculator has one if you switch to programmer mode) to map it all out and get a hexadecimal number. If you want to create characters that are more than 8px wide or with heights that aren't 5, 7 or 9px you will have to modify the print9() function itself, but you can probably figure out how to do so yourself (if not, feel free to ask and I'll try to help!). [/hidden]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Licensed under [WTFPL](http://www.wtfpl.net/faq/) (Do What the Fuck You Want to Public License). Use it, modify it, trash it... do whatever you want. I'm just happy you took the time to take a look at it at all. If you use it with one of your cartridges, or make any changes to the program to optimize it or make it suit your needs better, please let me know, I'd love to see what you do with it.
You're an unfortunate flower stuck hundreds of meters below the ground and you want nothing but to see the sun again again. You might never get out, but your children may!
Shoot your seed and have it land safely to spawn a child who carries on your legacy. Shooting your seed kills you and leaves your withered body behind and if the seed is destroyed, your bloodline ends here and now.
This game uses only two controls; the left and right arrow keys.
- When idle, hit both left+right simultaneously to take aim.
- When aiming, use the left and right arrow keys to decrease/increase your shot strength, and hit left+right simultaneously to shoot.
- If on the game over screen, hit left to restart the entire game or right to restart the current level.
The game only has two levels, but I'm liking this concept so I might continue working on it after the jam.
Legacy of Flower was made entirely in PICO-8. Special thanks to @zep for making such an incredibly fun fantasy console!
Thanks for playing!
- left/right/up/down to move cursor
- Z to mark a square
- X to flip between cursor mode (0 - nothing, 1 - cross, 2 - mark)
Just uploading this stupid thing I got sidetracked with and made today. I'll probably continue with it and flesh it out, just not sure when. At the moment it has 3 puzzles (2 of which were shamelessly stolen from Picross DS (pls dont tell anyone)) and which one you get when you boot up the game is random so keep rebooting the player until you get a different puzzle.
If you don't know how to solve Picross puzzles, this page might be a good start.
- win state
- main menu & puzzle selection menu
- automatically mark numbers as rows/columns are filled in
- better controls
- tutorial (?)
- sounds, music and a plethora of juicy effects
- code optimizations to be able to fit in as many puzzles as possible
- right/left to increase/decrease amplitude
- up/down to increase/decrease wavelength
- Z/X to increase/decrease animation speed
- Q to change background
- W to change effect type
I've been toying around with my Pico-8 for the last few days and after a good amount of bashing my head against a wall I finally have something cool and somewhat presentable. It translates horizontal lines on the screen either horizontally or vertically in a sine-wave-like pattern, just like the battle backgrounds in Earthbound and Mother 3.
Thinking of making a short vertical slice of some sort of RPG with a basic battle system that makes use of it.
Here are the relevant code snippets if you'd like to use the effects in your own game:
-- horizontal distortion effect -- by qbicfeet -- -- t: time -- a: amplitude (in pixels) -- l: wavelength (in pixels) -- s: speed -- y1: first horizontal line -- y2: last horizontal line -- mode: interlaced y/n function sine_xshift(t,a,l,s,y1,y2,mode) for y=y1,y2 do local off = a * sin((y + flr(t*s + 0.5) + 0.5) / l) if mode and y%2 < 1 then off *= -1 end local x = flr(off/2 + 0.5) % 64 local addr = 0x6000+64*y memcpy(0x4300,addr,64) memcpy(addr+x,0x4300,64-x) memcpy(addr,0x4340-x,x) end end
-- vertical distortion effect -- by qbicfeet -- -- t: time -- a: amplitude (in pixels) -- l: wavelength (in pixels) -- s: speed -- y1: first horizontal line -- y2: last horizontal line -- -- note: the difference between -- y2 and y1 can not be greater -- than 111 or it will corrupt -- the draw state ram! function sine_yshift(t,a,l,s,y1,y2) local dy = y2-y1+1 memcpy(0x4300,0x6000+64*y1,64*dy) for y=y1,y2 do local yy = (y + flr(a * sin((y + flr(t*s + 0.5) + 0.5) / l) + 0.5)) % dy memcpy(0x6000+64*y,0x4300+64*yy,64) end end
Some things worth noting:
- y1 and y2 values lower than 0 and higher than 127 will likely corrupt data in the RAM and/or crash the game
- if the wavelength is set to 0 a division by zero happens, but it seems like Pico-8 handles division by zero implicitly
- you could technically get around the "max height 112" problem with sine_yshift if you copy the screen data to 0x3f00 instead of 0x4300, which will overwrite part of the sound region of the RAM but give you another 16 horizontal lines to work with
Not sure what else to say... If you have any questions or comments I'll happily answer them!
So, I noticed a lot of you are eager to start working on your own, custom Voxatron characters but don't really know where to start. I felt the same way too. Luckily, I overcame the learning curve and I'm here to make sure the same thing happens for you!
First of all, let's explain how custom characters work.
A custom character consists of 12 frames (frame 0 to 11). Each frame has the size of 15x15x16 voxels.
Frame 0 - neutral, not shooting or equipping the sword and armor.
Frame 1 - shooting, right (your character's right; your left)
Frame 2 - shooting, left (your character's left)
Frame 3 - sword and armor, neutral
Frame 4 - sword and armor, swipe 1
Frame 5 - sword and armor, swipe 2
Frame 6, 7, 8, 9 and 10 - your character's legs. I'll explain how this works below.
Frame 11 - sword and armor, drops. This is what your character will drop upon taking damage and losing the sword and armor and is purely eye candy.
*your character always swings the sword from right to left, so keep that in mind when working on these frames.
But hey, why are character's legs separate from the rest of the body? To prevent you from having to re-draw the frames over and over! If your body and legs weren't separate you would have to make walking animations for every action in the game - shooting, equipping the sword and armor... Having it set up like this saves a lot of time.
This also means that the upper body frames should not have any legs within them as the legd are positioned there automatically in-game and that you should save some space for the legs below the body.
The legs are animated in a "pingpong" movement (6, 7, 8, 9, 10, 9, 8, 7 etc.) Frame 8 is the frame where your legs are positioned right below your character. I'm sure you'll figure out the rest :]
This is an example of how a character and its frames look in the editor.
Now that you know how that works, let's get started.
Start up Voxatron and go to the editor. I assume you are already familiar with the editor. If not, hit "Esc" and type in "help". The console will tell you all you need to know.
Go to the Objects tab in the item browser. See those numbers ranging from 1 to 6 to the left of the Edit and New buttons? Those are Voxel Object Banks, or VOBs in short. These act like "folders" and can be utilized for easy organization within the Objects tab.
However, the sixth VOB gets special properties if the first object (Prop 0) is named "_char". This tells the game to use props 0 to 11 as frames for the custom character.
This is how you access VOB 6.
Now, hit the New button and start editing VOB 6 Prop 0. Before you begin, make sure to name the prop "_char", or the game won't understand that it's supposed to be used as a character. Also, don't forget to set the canvas size to "15 15 16", otherwise the animations will most likely not play properly.
All frames should have these exact properties.
Only Frame 0 is required to be named "_char" though.
There's also a third thing you have to keep in mind before you start editing: try to keep your character smaller than 5x5x10, or you will experience (harmless, but sometimes unpleasant) clipping issues with other props. Keep the character as centered in the canvas as possible.
Try to stay within this "box" to avoid clipping issues.
Once you've done that, begin unleashing your creativity! Who will be the hero of your adventure? A cyclops? A dwarf? An alien? The possibilities are endless!
A few tips and tricks:
- Frame 2 is essentially a mirrored frame 1.
- Frame 9 is essentially a mirrored frame 7.
- Frame 10 is essentially a mirrored frame 6.
- Frame 11 is essentially a copy of frame 3 with the character removed, so that the sword and armor appear to be "hovering" in the air.
- When copy-pasting (CTRL+C / CTRL+V) one frame to another, make sure that nothing is selected and that the message "copied voxmap" appears in the console instead of "copied selection". If you just copy a selection the editor will auto-crop whatever you copied which will require you to manually re-position the character and re-size the canvas. Copying the voxmap will give you exactly what you see.
If you have any questions, don't hesitate - ask me.
I uploaded a custom character template due to popular demand. Perfect if you just want to do basic recolors of the default robot character.
Also, if any of you developers happen to pass by, I'd like to propose a suggestion: custom hitboxes. This to prevent those nasty clipping issues. Just a cuboid in frame 12 or something similar which would make larger custom characters more viable. Think about it ;]