Log In  
Follow
bikibird
Music Theory Tutorial
by
PICO DAW
by
Speako8 Speech Synthesis Library
by
[ :: Read More :: ]

Cart #daw-9 | 2024-03-16 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
11

Overview

PICO DAW is a digital audio workstation for creating PICO-8 tunes. If you've ever been frustrated by the piano style layout keyboard layout of the music editor or just wished you could draw your music, PICO DAW is for you. It's a mouse-based alternative for tune creation.

THIS CART IS A WORK IN PROGRESS AND MINIMALLY TESTED. Consider it alpha. Save early and often! Please report any bugs you find.

Quick Start

  1. Open the PICO-8 console and enter load #daw.
  2. Save the cart under a new name.
  3. Optional: Add any desired custom instruments in SFX slots 0 through 7.
  4. Edit music patterns for length, looping, channels, and SFX assignments.
  5. Edit SFX for length, speed, and filters.
  6. Run the cart.
  7. Hold down the left mouse button to draw your tune.
  8. Select active track by scrolling the mouse wheel.
  9. Left and right arrows pan the music patterns.
  10. Edit notes by right clicking on them.
  11. There are many more keyboard shortcuts and tools, keep reading to get the most out of PICO DAW.

Preliminaries

Quite simply, PICO DAW is an alternative note editor and nothing more. Therefore, you must assign SFX to the music patterns and set the SFX speed and other top level SFX settings after PICO DAW is loaded, but before you run the cart. If you plan to use custom instruments, you should load them into SFX slots 0-7.

Navigation and Layout

Editing is done one music pattern at a time. The current pattern number is displayed in the upper right of the screen and the pattern itself occupies the major portion of the screen, with a few notes of the previous and next music patterns displaying at the left and right margins.

Change the active music pattern with the left and right arrows or by left clicking in the left and right margins. Press Home or End to jump to the beginning or end of the tune.

The horizontal staff lines represent pitch values. The highest pitch is at the top and the lowest pitch at the bottom. Each note is 3 pixels in width.

The crosshair cursor indicates you are in draw mode. The dot pattern cursor indicates you are in stamp mode.

Toggle the main menu on and off by right clicking in the left margin.

Some tools require selecting a grouping of notes. Hold down the shift key while dragging with the left mouse button to select a range of notes . A selection rectangle will appear over the notes. Release the mouse button to finalize the selection. Right click anywhere in the music pattern to cancel a selection.

Saving

PICO DAW automatically saves your work every 5 minutes. You can force a save anytime by pressing Ctrl-S. Be sure to press Ctrl-S before exiting PICO DAW.

If you forget to press Ctrl-S before exiting, salvage things by entering resume, pressing Ctrl-S, and finally exiting the program.

Editing

Draw Tool

To place notes, click with the left mouse button anywhere in the music pattern.

By default note are placed according to the current scale. To place a non-scale note, hold down the CTRL key while clicking to color in between the lines.

Drag with the left mouse button held down to create a grouping of notes with attack settings applied to the first note, release settings applied to the last note, and sustain setting to any notes in the middle. (See track indicator tool for setting note defaults.)

Scroll the mouse wheel to change which channel is being edited. (See also channel indicator tool.)

Hold down the delete key while clicking on individual notes to erase them. (See also the delete tool below.)

Ctrl-Z and Ctrl-Y undo and redo editing actions. The size of the undo buffer is only limited by the size of the PICO-8 memory. please be aware that cut and insert actions are especially memory intensive operations and they tend to decrease the number of actions that can be held in the buffer.

Note Options Menu

To view or change settings for an individual note, right click on a note. Your cursor color must match the note color. Scroll the mouse wheel to change the current channel if needed.

To batch edit a range of notes, select them and then right click on a note in the range. Edits only apply to notes that are in the same channel as the cursor. Notes from other channels will be ignored.

Hover over the waveform icon and use the mouse wheel to change the note's instrument. The standard instruments are represented with the same waveform icons found from the SFX editor. Custom instruments are represented by the numbers 0 through 7.

The next icon is the effect icon. Use the mouse wheel to change the effect.

The third icon is the volume icon. Use the mouse wheel to set the volume. You cannot set a note's volume to zero; delete the note instead.

Click on the speaker icon to audition the note or range of notes.

Close the note menu by right clicking anywhere in the pattern.

Additional Editing tools

Right click in the left margin to display the main menu.

Scroll the mouse wheel in the current pattern area to change the cursor's channel. The channel indicator shows which channel is under edit.

To switch from stamp mode back to draw mode, click the channel indicator.

The channel indicator also sets the default attack, sustain, and release used for note drawing. Select a range of notes and then click the channel indicator to assign attack, sustain, and release to a channel based on the selected notes. The first note in the selection is used for the attack, the last for the release, and the second note for the sustain.

Select a range of notes and click the copy icon to copy a pattern of notes for stamping. You may also press Ctrl-C to copy. The cursor will change to the repetition/transposition cursor.


Click one of the stamp icons to stamp the previously copied notes. The stamps are: repetition/transposition, inversion, retrograde, and retrograde inversion.

The cursor changes to a pattern of dots representing the notes. Click to place the notes in the music pattern. If you click near the left or right margin any notes that do not fit the current music pattern will spill into the previous or next pattern

Note intervals automatically adjust to the scale you are currently using. Hold down the Ctrl key while stamping to ignore the current scale and stamp chromatically.

Select a range of notes and click the insert icon to insert blank space at the start of the insertion point. The existing notes of the tuen will be pushed right.

Generally, the range selected should go all the way from the top of the screen to the bottom, but if a narrower band is select, only the notes within the horizontal band will be pushed right. This can be useful if you want to isolate the notes pushed to specific channels and exclude others.

The insert key may also be used for inserting.

Select a range of notes and click the cut icon to copy a range of notes, delete those notes from the screen, and shift notes left to close up the gap.

Generally, the range selected should go all the way from the top of the screen to the bottom, but if a narrower band is select, only the notes within the horizontal band will be pulled left. This can be useful if you want to isolate the notes pulled to specific channels and exclude others.

You may also use Ctrl-X to cut instead of clicking the icon.

Select a range of notes and click the delete icon to delete a range of notes. You may also press delete on the keyboard.

View Settings

By default PICO DAW shows staff lines for the C Major scale. Clicking on the scale dial icon to select another scale. The scale selector tool displays. Ur the up and down arrows or the mouse wheel to set the scale family. Drag the outer ringer with the left mouse button to set the tonic pitch class. Drag the inner ring to set the mode. Click save to return to the editor.

Hover over the chord icon and scroll the mouse wheel to change the chord number. The staff lines for the root of the chord is highlighted in a lighter color. (When the chord number is set to 1, the root of the chord and the tonic are the same, so the chord icon may also be used to highlight the tonic.)

Press the 3, 5, and/or 7 keys to toggle on display of the e 3rd, 5th, and/or 7th of the chord. Press again to toggle them off.

Click the measure icon (metronome) to toggle measure markers on and off. By default there are 4 measures of eight notes per music pattern.

To change the measure width, select a range of notes the width of the new measure and click the metronome icon.

It's usually best to do this on the first music pattern of the tune and select the first note of the pattern through the desired width.

Click the subdivision icon (note) to display the subdivisions of the measure. By default the subdivisions are two notes wide.

To change the subdivision width, select a range of notes the width of the new subdivision and click the subdivision icon.

It's usually best to do this on the first music pattern of the tune and select the first note through the desired width.

Toggle view.
Click the view icon to toggle between channel view and spectrum view. The channel view displays the color of each note according to which channel it is in. The spectrum view displays notes according to how closely they are related harmonically as defined by the circle of 5ths. The closer that two notes are in color, the more consonant they are. The more the colors clash, the more dissonant the notes are.

Playing and Recording

To listen to your composition, press the play icon or press the spacebar. To stop playback, click the stop icon or press the spacebar.

To record to your composition, press the record icon. To stop recording, click on the stop icon or press the spacebar.

The recording saves to your desktop. If your music pattern loops, the recorder will record two loops before stopping if not stopped earlier by you.

P#143341 2024-03-16 17:22

[ :: Read More :: ]


Album is a collection of music visualizers for the PICO-8 Free Music Jam. Just add your music, cover art, and a little bit of meta-data to make your own album.

Controls

Press ⬆️ to dismiss the credit for the tune.
Press ⬇️ to see the credit.
Press ⬅️ to listen to the previous tune.
Press ➡️ to listen to the next tune.
Press ❎ or 🅾️ to replay a tune.

Suggested workflow

  • From the PICO-8 console load #album.
  • Save the album under a new name to make it yours.
  • Create your music in the cart or manually copy the SFXes and music pattern from another cart.
  • Replace the cover art and label.
    import my_image.png for album cover.
    import -l my_image.png for cart label.
  • Select the code editor and navigate to tab 2: tunes.
    Fill out the data in the tunes table, adding one entry per tune.
  • If you are using custom instruments, navigate to tab 3 to add transposition data
  • Save the cart.
  • Run the cart to see and hear your music!

Customization

Cover Art

Be default, your sprite sheet is your cover art. The cart uses map(0,0) to draw the cover art. This area of the map is occupied by the entire sprite sheet. By editing the map you can assemble a different cover based on elements of the sprite sheet if you prefer.

Properties

At a bare minimum, each entry in the tunes table must have the following properties defined: pattern, title, credit and visualizer:

{
        pattern=0,  --music pattern number to play
        title="title of tune", -- tune title
        credit="me",
        visualizer=cover, 
},

The choices for visualizer are bubble, cover, harp, piano_roll, ripples, and stars. (If you are good at coding, you can add some new ones!)

Additional properties may be used to customize the look:

{
        pattern=0,  --music pattern number to play
        title="title of tune", 
        credit="me",
        visualizer=piano_roll,
        text=12,
        outline={13,13},
        background=-1, -- for map(0,0) or color 0 through 15
        palette={[0]=0,130,141,13,12,140,1,131,3,139,11,138,135,10,9,137},
        foreground={10,10,10,10},
},

Set text to a color number, 0 through 15, to set the color of title and credit text. Defaults to 7. Supported by all visualizers.

set outline to a table of two colors, for example outline={6,6} to set the left and right outlines of the text. Defaults to {1,1}. Supported by all visualizers. outline also sets the shadow colors in the bubble, ripples, piano_roll visualizers. To omit the outline, set outline to {-1,-1}.

Set background to -1 to use the cover art in the background or to a color number to select a solid color. background defaults to black. Supported by all visualizers

Set palette to specify a custom palette for all draw operations. Defaults to PICO-8 standard palette. Supported by all visualizers. Harp visualizer expects colors 4 through 15 to form a color gradient. For example: palette={[0]=0,130,141,13,12,140,1,131,3,139,11,138,135,10,9,137} causes consonant note pairs to appear close in color, with more dissonant notes creating more visual contrast.

Set foreground to a table of 4 colors representing the 4 audio channels. For example: foreground={8,8,8,8} displays each channel in red. Defaults to light blue for ripples and red for piano_roll. Supported by piano_roll and ripples visualizers only.

You can change where the notes appear on the screen using two properties, offset and spacing. The visualizer code converts the pitches to numeric values between 0 and 64. Each successive value is one half-step (semitone) apart. C0 maps to zero and D#5 maps to 64. offset is the number of half-steps to add to the pitch value for display purposes. (It does not affect how the pitch is played.) Use a negative value to shift left and a positive value to shift right. In the case of stars and ripples every multiple of 8 shifts the display up or down by full rows.

spacing is the factor by which to multiply the pitch value for display purposes. Values greater than 1 will spread the pitch display apart. Values less than 1 will compress them. piano_roll and harp defaults to a spacing of 2. stars and ripples default to 16. Using a value of 8 for stars, will cause the night sky to appear in the top half of the screen only. Using a value of 8 for ripples will cause the puddles to appear in the bottom half of the screen.

Clever use of spacing and offset allows for optimal placement of the notes on top of your cover art.

Custom Instruments

If you are using custom instruments that transpose the pitch being played, the pitch display will be incorrect by default. You may correct this by clicking on tab three in the code editor to edit the instruments table. Enter the number of half-steps (negative or positive) to transpose the display pitch value for each custom instrument you are using.

Record Function

A record function is included for your convenience. To record a tune, enter record(pattern, repeats, fadeout) in the PICO-8 console, where pattern is the starting pattern number of your tune, repeats is the number of times to repeat a looping tune, and fadeout is the number of milliseconds to fade out a loop after is done repeating. repeats defaults to 2 and fadeout defaults to 5000. The wave file should appear on your desktop after recording is complete.

Credits

Visualizers by @bikibird
Label Art by @paraK00PA
Record function based on code by @packbat

To credit this cart when used in your own work add this statement wherever you list the credits for your project:

Visualizers provided courtesy of the PICO-8 Free Music Jam.

P#140958 2024-02-01 00:28

[ :: Read More :: ]

Cart #polardistress-1 | 2023-12-22 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

Help Santa pass his audition with the Norse Ursine Merriment Band.

Hints:

Puzzles have more than one winning solution. So, if you don't like your harmonies, try another way.

Polar bears will follow you if you get close to them. This can help or hinder.

Candy canes give Santa energy to leap across large distances automatically.

Credits:

Created for the PICO-8 Holiday Bundle 2023
Label Art by @paraK00PA
Jingle Bells by James Lord Pierpont
We Wish You a Merry Christmas popularized by Arthur Warrell
Everything else by @bikibird

P#139080 2023-12-23 15:15

[ :: Read More :: ]

ZOMG! I just realized it's October already! The PICO-8 advent calendar is just around the corner. Or, maybe not... We're still looking for tons more people to contribute a winter holiday themed PICO-8 project to the calendar. It doesn't have to be an epic masterpiece. Small games and demos are welcome. You can even reskin a game you previously released.

If you're interested, make sure you've joined the PICO-8 Discord server and then see https://discord.com/channels/215267007245975552/220602714982318081/1146905525158682665 for info on how to contribute, cuz we sure need you.

P#135215 2023-10-01 15:04

[ :: Read More :: ]

I've released the first eight lessons of my new music theory tutorial, available here: https://bikibird.itch.io/music-theory. It's designed for people who want to make their own music for PICO-8 games, but feel they don't have the skill or talent to do so.

The tutorial provides an introduction to the basics of pitch, melody, harmony, rhythm and composition within the context of PICO-8. It explores music in a decidedly mathy way through a series of interactive demos that use spatial relations to connect sound to vision.

Only the parts of music theory that are relevant to PICO-8 are covered. No prior knowledge of music is assumed. There's no reading sheet music or needing to play an instrument.

More lessons will be coming in October.

P#133862 2023-09-02 12:10 ( Edited 2023-09-02 15:30)

[ :: Read More :: ]

Cart #puffycoats-2 | 2022-12-11 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
26

You were so excited to try your brand new skates on Christmas day that you skated out to the middle of lake without checking the ice conditions. Now you are on thin ice and just want to get back to your friend on the shore.

Game Play

Control your skates with the left and right buttons. Alternate left and right to speed up. Hold to turn. You haven't exactly learned to stop yet, but if you start turning circles, you will eventually slow down. You can walk on the snow, but it is very slow.

Credits:

Music composed by Vince Guaraldi
Christmas Time Is Here arranged by @Gruber
3d effects: @Mot's Instant 3d Plus Library
Special thanks to @thattomhall for advice on the ending
Everything else by @bikibird

Created for the 2022 Advent Calendar

P#122632 2022-12-18 05:05 ( Edited 2022-12-21 00:11)

[ :: Read More :: ]

Cart #santascouts-5 | 2022-12-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
13

This is the year you find out if Santa is really real. You and your siblings are staying up late to finally get proof. The light are out, but you're not scared!

Game Play

Requires mouse. Hold down left mouse button to turn on flashlight. Drag mouse across screen to catch Santa in the act. Press ❎ to snap a picture.

Credits

Up on the Housetop composed by Benjamin Hanby
Midilib flute by @ericb https://www.lexaloffle.com/bbs/?tid=49487
Flashlight effect informed by @Krystman https://www.lexaloffle.com/bbs/?tid=46286
Fizzle fader borrowed from @DrPete https://www.lexaloffle.com/bbs/?tid=29862
Everything else by @bikibird

Created for the 2022 Advent Calendar

WARNING: SPOILERS IN COMMENTS. SCROLL AT YOUR OWN RISK.






*
WARNING: SPOILERS IN COMMENTS. SERIOUSLY, GO BACK.









*
WARNING: SPOILERS IN COMMENTS. WELL, YOU CAN'T SAY I DIDN'T WARN YOU.









WARNING: SPOILERS IN COMMENTS. HERE THEY COME.









*

P#122456 2022-12-15 04:53 ( Edited 2022-12-21 15:23)

[ :: Read More :: ]

Cart #speako8-2 | 2022-08-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
157

Add speech synthesis to your games with Speako8, a speech synthesis library for PICO-8 in under a thousand tokens! It's loosely based on a Klatt synthesizer and will remind some folks of Software Automatic Mouth (S.A.M.)

To add Speako8 to your games, copy and paste the library below:

--speako8_lib_min by bikibird
do d=split("aa=1320,1,500,4,2,0,1,2600,160,1220,70,700,130,-250,100;ae=1270,1,1000,4,2,0,.79,2430,320,1660,150,620,170,-250,100;ah=770,1,1000,4,2,0,.79,2550,140,1220,50,620,80,-250,100;ao=1320,1,1000,4,2,0,.74,2570,80,990,100,600,90,-250,100;aw=720,1,1000,4,2,0,.79,2550,140,1230,70,640,80,-250,100/720,1,1000,4,3,0,0,2350,80,940,70,420,80,-250,100;ay=690,1,1000,4,2,0,.9,2550,200,1200,70,660,100,-250,100/690,1,1000,4,2,0,.223,2550,200,1880,100,400,70,-250,100;eh=830,1,1000,4,2,0,.44,2520,200,1720,100,480,70,-250,100;er=990,1,1000,4,2,0,.41,1540,110,1270,60,470,100,-250,100;ey=520,1,500,4,2,0,.44,2520,200,1720,100,480,70,-250,100/520,1,500,4,2,0,.05,2600,200,2020,100,330,50,-250,100;ih=720,1,1000,4,2,0,.23,2570,140,1800,100,400,50,-250,100;iy=880,1,1000,4,2,0,0,2960,400,2020,100,310,70,-250,100;ow=1210,1,1000,4,2,0,.59,2300,70,1100,70,540,80,-250,100;oy=513,1,1000,4,2,0,.62,2400,130,960,50,550,60,-250,100/513,1,1000,4,2,0,.13,2400,130,1820,50,360,80,-250,100/513,1,1000,4,2,0,.13,2400,130,1820,50,360,80,-250,100;uh=880,1,1000,4,2,0,.36,2350,80,1100,100,450,80,-250,100;uw=390,1,1000,4,2,0,.1,2200,140,1250,110,350,70,-250,100/390,1,1000,0,1,0,-.12,2200,140,900,110,320,70,-250,100/390,1,1000,0,0,0,-.12,2200,140,900,110,320,70,-250,100;l=440,1,1000,0,2,0,0,2880,280,1050,100,310,50,-250,100;r=440,1,1000,0,2,0,0,1380,120,1060,100,310,70,-250,100;m=390,1,1000,0,0,0,0,2150,200,1100,150,400,300,-450,100;n=360,1,1000,0,0,0,0,2600,170,1600,100,200,60,-450,100;ng=440,1,1000,0,0,0,0,2850,280,1990,150,200,60,-450,100;ch=230,0,20,0,0,1,0,2820,300,1800,90,350,200,-250,100/100,0,100,1,0,1,0,2820,300,1800,90,350,200,-250,100;sh=690,0,20,0,0,1,0,2750,300,1840,100,300,200,-250,100;zh=1,1,250,0,0,.5,0,2750,300,1840,100,300,200,-250,100/385,1,400,1,0,.5,0,2750,300,1840,100,300,200,-250,100;jh=330,1,500,1,0,1,0,2820,270,1800,80,260,60,-250,100;dh=275,1,250,0,0,.5,0,2540,170,1290,80,270,60,-250,100;f=1,0,15,0,0,1,0,2080,150,1100,120,340,200,-250,100/660,0,25,1,0,1,0,2080,150,1100,120,340,200,-250,100;s=690,0,10,0,0,1,0,2530,200,1390,80,320,200,-250,100;k=88,0,100,0,0,1,0,2850,330,1900,160,300,250,-250,100/220,2,5,1,0,1,0,2850,330,1900,160,300,250,-250,100;p=44,0,50,0,0,1,0,2150,220,1100,150,400,300,-250,100/220,2,2,1,0,1,0,2150,220,1100,150,400,300,-250,100;t=66,0,100,0,0,2,0,2600,250,1600,120,400,300,-250,100/220,2,5,0,0,1,0,2600,250,1600,120,400,300,-250,100;g=88,0,100,0,0,1,0,2850,280,1990,150,200,60,-250,100;b=44,0,100,0,1,0,0,2150,220,1100,150,400,300,-250,100;d=66,0,100,0,0,1,0,2600,170,1600,100,200,60,-250,100;th=606,0,10,0,0,1,0,2540,200,1290,90,320,200,-250,100;v=330,1,1000,0,0,.5,0,2080,120,1100,90,220,60,-250,100;z=410,1,1000,0,0,.5,0,2530,180,1390,60,240,70,-250,100;w=440,1,1000,0,0,0,.1,2150,60,610,80,290,50,-250,100;y=440,1,1000,0,0,0,0,3020,500,2070,250,260,40,-250,100;",";")x={}for a in all(d)do local e=split(a,"=")local d,a=e[1],split(e[2],"/")x[d]={}for e in all(a)do local a=split(e)local e={unpack(a,1,7)}e[8]={}for x=8,14,2do add(e[8],{unpack(a,x,x+1)})end add(x[d],e)end end poke(24374,@24374^^32)local 𝘤,y,𝘥,g,z,𝘦,d,r,n,b,m,𝘧,s,u,j,𝘨,𝘩,𝘪,o,f,l=unpack(split"0,0,0,0,0,0,0,0,0,0,0x8000,0x1.233b,-0x.52d4")local c,w,i,h,𝘫,𝘬,k,t,p,v,q,𝘢,𝘣={}e=split"2,0x1.fd17,0x1.fa32,0x1.f752,0x1.f475,0x1.f19d,0x1.eec9,0x1.ebfa,0x1.e92e,0x1.e666,0x1.e3a3,0x1.e0e3,0x1.de27,0x1.db70,0x1.d8bc,0x1.d60c,0x1.d360,0x1.d0b9,0x1.ce14,0x1.cb74,0x1.c8d8,0x1.c63f,0x1.c3aa,0x1.c119,0x1.be8c,0x1.bc02,0x1.b97c,0x1.b6fa,0x1.b47b,0x1.b200,0x1.af89,0x1.ad15,0x1.aaa5,0x1.a838,0x1.a5cf,0x1.a369,0x1.a107,0x1.9ea9,0x1.9c4d,0x1.99f6,0x1.97a1,0x1.9550,0x1.9302,0x1.90b8,0x1.8e71,0x1.8c2e,0x1.89ed,0x1.87b0,0x1.8576,0x1.8340,0x1.810c,0x1.7edc,0x1.7caf,0x1.7a85,0x1.785f,0x1.763b,0x1.741b,0x1.71fd,0x1.6fe3,0x1.6dcc,0x1.6bb8,0x1.69a7,0x1.6798,0x1.658d,0x1.6385,0x1.6180,0x1.5f7e,0x1.5d7e,0x1.5b82,0x1.5988,0x1.5792,0x1.559e,0x1.53ad,0x1.51bf,0x1.4fd3,0x1.4deb,0x1.4c05,0x1.4a22,0x1.4842,0x1.4664,0x1.4489,0x1.42b1,0x1.40dc,0x1.3f09,0x1.3d39,0x1.3b6b,0x1.39a0,0x1.37d8,0x1.3612,0x1.344f,0x1.328f,0x1.30d1,0x1.2f15,0x1.2d5c,0x1.2ba6,0x1.29f2,0x1.2841,0x1.2692,0x1.24e5,0x1.233b,0x1.2193,0x1.1fee,0x1.1e4b,0x1.1cab,0x1.1b0c,0x1.1971,0x1.17d7,0x1.1640,0x1.14ab,0x1.1319,0x1.1189,0x1.0ffb,0x1.0e6f,0x1.0ce5,0x1.0b5e,0x1.09d9,0x1.0857,0x1.06d6,0x1.0558,0x1.03db,0x1.0261,0x1.00e9,0x.ff74,0x.fe00,0x.fc8f,0x.fb1f,0x.f9b2,0x.f847,0x.f6dd,0x.f576,0x.f411,0x.f2ae,0x.f14d,0x.efee,0x.ee91,0x.ed36,0x.ebdd,0x.ea86,0x.e930,0x.e7dd,0x.e68c,0x.e53c,0x.e3ef,0x.e2a3,0x.e15a,0x.e012,0x.decc,0x.dd88,0x.dc45,0x.db05,0x.d9c6,0x.d889,0x.d74e,0x.d615,0x.d4de,0x.d3a8,0x.d274,0x.d142,0x.d012,0x.cee3,0x.cdb6,0x.cc8b,0x.cb61,0x.ca39,0x.c913,0x.c7ee,0x.c6cc,0x.c5aa,0x.c48b,0x.c36d,0x.c251,0x.c136,0x.c01d,0x.bf05,0x.bdef,0x.bcdb,0x.bbc8,0x.bab7,0x.b9a7,0x.b899,0x.b78d,0x.b682,0x.b578,0x.b470,0x.b36a,0x.b265,0x.b161,0x.b05f,0x.af5f,0x.ae5f,0x.ad62,0x.ac66,0x.ab6b,0x.aa71,0x.a979,0x.a883,0x.a78e,0x.a69a,0x.a5a8,0x.a4b7,0x.a3c7,0x.a2d9,0x.a1ec,0x.a100,0x.a016,0x.9f2d,0x.9e45,0x.9d5f,0x.9c7a,0x.9b97,0x.9ab4,0x.99d3,0x.98f3,0x.9815,0x.9738,0x.965c,0x.9581,0x.94a7,0x.93cf,0x.92f8,0x.9222,0x.914e,0x.907a,0x.8fa8,0x.8ed7,0x.8e07,0x.8d39,0x.8c6b,0x.8b9f,0x.8ad4,0x.8a0a,0x.8941,0x.8879,0x.87b3,0x.86ed,0x.8629,0x.8566,0x.84a4,0x.83e3,0x.8323,0x.8264,0x.81a7,0x.80ea,0x.802e,0x.7f74,0x.7eba,0x.7e02,0x.7d4b,0x.7c94,0x.7bdf,0x.7b2b,0x.7a78,0x.79c6,0x.7915,0x.7864,0x.77b5,0x.7707,0x.765a,0x.75ae,0x.7503,0x.7458,0x.73af,0x.7307,0x.725f,0x.71b9,0x.7114,0x.706f,0x.6fcb,0x.6f29,0x.6e87,0x.6de6,0x.6d46,0x.6ca7,0x.6c09,0x.6b6c,0x.6ad0,0x.6a35"a=split"1,0x.fd19,0x.fa3a,0x.f764,0x.f497,0x.f1d1,0x.ef13,0x.ec5e,0x.e9b0,0x.e70a,0x.e46c,0x.e1d5,0x.df46,0x.dcbe,0x.da3d,0x.d7c4,0x.d552,0x.d2e7,0x.d083,0x.ce26,0x.cbd0,0x.c981,0x.c738,0x.c4f6,0x.c2bb,0x.c086,0x.be57,0x.bc2f,0x.ba0d,0x.b7f1,0x.b5dc,0x.b3cc,0x.b1c2,0x.afbf,0x.adc1,0x.abc9,0x.a9d6,0x.a7e9,0x.a602,0x.a421,0x.a244,0x.a06e,0x.9e9c,0x.9cd0,0x.9b09,0x.9947,0x.978a,0x.95d3,0x.9420,0x.9272,0x.90c9,0x.8f25,0x.8d86,0x.8beb,0x.8a55,0x.88c4,0x.8737,0x.85af,0x.842b,0x.82ac,0x.8130,0x.7fba,0x.7e47,0x.7cd9,0x.7b6e,0x.7a08,0x.78a6,0x.7748,0x.75ee,0x.7498,0x.7346,0x.71f7,0x.70ad,0x.6f66,0x.6e22,0x.6ce3,0x.6ba7,0x.6a6f,0x.693a,0x.6809,0x.66db,0x.65b0,0x.6489,0x.6366,0x.6245,0x.6128,0x.600e,0x.5ef7,0x.5de4,0x.5cd3,0x.5bc6,0x.5abc,0x.59b5,0x.58b0,0x.57af,0x.56b1,0x.55b5,0x.54bc,0x.53c7,0x.52d4,0x.51e3,0x.50f6,0x.500b,0x.4f22,0x.4e3d,0x.4d5a,0x.4c79,0x.4b9c,0x.4ac0,0x.49e7,0x.4911,0x.483d,0x.476b,0x.469c,0x.45cf,0x.4505,0x.443c,0x.4376,0x.42b3,0x.41f1,0x.4132,0x.4075,0x.3fba,0x.3f01,0x.3e4a,0x.3d95,0x.3ce3,0x.3c32,0x.3b83,0x.3ad7,0x.3a2c,0x.3983,0x.38dc,0x.3837,0x.3794,0x.36f3,0x.3653,0x.35b6,0x.351a,0x.3480,0x.33e8,0x.3351,0x.32bc,0x.3229,0x.3197,0x.3107,0x.3079,0x.2fed,0x.2f62,0x.2ed8,0x.2e50,0x.2dca,0x.2d45,0x.2cc2,0x.2c40,0x.2bbf,0x.2b40,0x.2ac3,0x.2a47,0x.29cc,0x.2953,0x.28db,0x.2864,0x.27ef,0x.277b,0x.2709,0x.2698,0x.2628,0x.25b9,0x.254b,0x.24df,0x.2474,0x.240a,0x.23a2,0x.233b,0x.22d4,0x.226f,0x.220b,0x.21a9,0x.2147,0x.20e6,0x.2087,0x.2029,0x.1fcb,0x.1f6f,0x.1f14,0x.1eba,0x.1e60,0x.1e08,0x.1db1,0x.1d5b,0x.1d06,0x.1cb2,0x.1c5e,0x.1c0c,0x.1bbb,0x.1b6a,0x.1b1b,0x.1acc,0x.1a7e,0x.1a31,0x.19e5,0x.199a,0x.1950,0x.1907,0x.18be,0x.1876,0x.182f,0x.17e9,0x.17a4,0x.175f,0x.171b,0x.16d8,0x.1696,0x.df50,0x.1614,0x.15d3,0x.1594,0x.1556,0x.1518,0x.14da,0x.149e,0x.cbd9,0x.1427,0x.13ec,0x.13b3,0x.137a,0x.1341,0x.1309,0x.12d2,0x.ba15,0x.1265,0x.1230,0x.11fb,0x.11c7,0x.1193,0x.1160,0x.112e,0x.a9de,0x.10cb,0x.109a,0x.106a,0x.103a,0x.100b,0x.0fdd,0x.0faf,0x.9b10,0x.0f54,0x.0f28,0x.0efc,0x.0ed0,0x.0ea5,0x.0e7b,0x.0e51,0x.8d8c,0x.0dfe,0x.0dd6,0x.0dad,0x.0d86,0x.0d5e,0x.0d38,0x.0d11,0x.8136,0x.0cc6,0x.0ca1,0x.0c7c,0x.0c58,0x.0c34,0x.0c11,0x.0bee,0x.0bcb,0x.0ba9,0x.0b87,0x.0b66,0x.0b45,0x.0b24,0x.0b03"function say(e)local p=split(e,"/")local d,e,a,n,t,f,m,j,r,v={},{}local s,b,u,w,y,g=unpack(split"1,1,0,0,0,0")for z in all(p)do local p=tonum(z)if p then local a=abs(p)local e,d,x=sgn(p),a\1,a&.99999
    if(d==1)b=1+e*x
    if(d==2)s=1+e*x
    if d==3then u=e
    if(x>0)u*=x
    end elseif z=="hh"then g=b*440elseif z=="_"then add(c,{1100*b*spk8_rate})else for p in all(x[z])do f,o,m,j,r,i,h,k=unpack(p)a,n,t,v,d,w,e,y={},{},{},f*b,e,y,k,m l=u*spk8_intonation+h*spk8_if0
    if(j==0)w=m
    if(r==0or#d~=#e)d=k
    for c=1,#d do add(a,{unpack(d[c])})local x,d=a[c],e[c]local e,a=r*(d[1]-x[1]),r*(d[2]-x[2])x.x,x.e,x.d=0,0,0if c<4then e*=spk8_shift a*=spk8_bandwidth end add(n,e/f)add(t,a/f)end if g>0then add(c,{g,2,0,1,0,1,h,a,n,t,e,s,l})g=0end add(c,{v,o,i,w,j*(y-w)/f,y,h,a,n,t,e,s,l})end s,b,u=1,1,0end end end function speaking()return#c>0end function mute()c={}b=0end function speako8()local function x()f=(5512.5/(spk8_pitch+l)+(f and f*49or 0))/(f and 50or 1)end if#c>0then w=c[1]while stat(108)<1920do for k=0,127do if w then if b<1then b,o,i,u,j,𝘨,h,𝘫,𝘩,𝘪,𝘬,𝘣,l=unpack(w)b/=spk8_rate end if o then x()t,d,p=spk8_quality*f,u/8,o*spk8_whisper if p==1then if n%flr(f+.5)==0then r,q,n=-d/(f-1),-d/t/t,0v=-q*t/3x()end if n>t then r=-d/(f-1)else v+=q r-=v end d=r elseif p>1then d=-8for x=1,16do d+=rnd()end
    if(n>f\2)d/=2
    end for n,x in pairs(𝘫)do local b,c,f,o=x[1],x[2]\10+1c=c<=#e and c or#e c=c>=1and c or 1𝘢=cos(b/5512.5)if b>0then f,o=e[c]*𝘢,-a[c]x.d,x.e,x.x=x.e,x.x x.x=(1-f-o)*d+f*x.e+o*x.d d=x.x elseif b<0then f=𝘧*𝘢 local x=1-f-s 𝘤=(d-f*y-s*𝘥)/x 𝘥,y,f=y,d,𝘧*cos(.04897)g=(1-f-s)*𝘤+f*z+s*𝘦 𝘦,z=z,g d=g end local e=𝘬[n]
    if(b\10~=e[1]\10)x[1]+=𝘩[n]
    if(c-1~=e[2]\10)x[2]+=𝘪[n]
    end d*=i/2-1+rnd(i)
    if(abs(u-𝘨)>abs(j))u+=j
    else d,𝘣=0,1end n+=1b-=1poke(m+k,d*spk8_volume*𝘣+128)if b<1then deli(c,1)if#c==0then serial(2056,m,k+1)return else w=c[1]end end end end serial(2056,m,128)end end end end

--end of speako8_lib_min

Speako8's voice must be configured prior to first use:

function _init()
spk8_pitch,spk8_rate,spk8_volume,spk8_quality,spk8_intonation,spk8_if0,spk8_shift,spk8_bandwidth,spk8_whisper=
140,1,1,.5,10,10,1,1,1
end

Warning: This application may generate loud and harsh sounds. Protect your hearing! Do not test with headphones on and turn down the volume.

Variable Range Explanation
spk8_pitch 60-230 Fundamental pitch of voice (F0) in hertz
spk8_rate .1-2 Standard rate of speech divisor— below 1 is slower; above 1 is faster.
spk8_volume .1-2 Standard volume factor— below 1 is quieter; above 1 is louder.
spk8_quality .1-2 Glottis open period— below .5 is creakier voice; .5 is modal voice; 1 is breathy voice; above 1 is weaker voice.
spk8_intonation 0-20 Degree of pitch prosody in hertz— set to zero for robotic monotone.
spk8_if0 0-20 Degree to which the inherent pitch (F0) of vowels varies (in hertz)— set to zero for robotic monotone.
spk8_shift .8-1.2 Factor by which to shift formant frequencies (F1, F2, F3)— above raises formant frequencies; below one lowers
spk8_bandwidth .5-5 Factor by which to alter bandwidth of formant frequencies (F1, F2, F3)— below 1 narrows the bandwidth of the formants; above 1 widens. When formants are shifted upward, it is recommended to widen bandwidths as well.
spk8_whisper 1 or 2 Speaking mode— Normal voice is 1; whispering is 2.

To enable speech synthesis, you must call speako8 in the _update function. Then call say with a speech string:

function _update() 

  speako8()  -- must appear once unconditionally in _update.

  if btnp(5) then --❎ button
    -- use speaking if you want to check if anything is currently being said.
    -- if not speaking() then
    say("_/hh/-1.57/eh/-1.07/l/-1.33/3/ow/-1.03/-3/w/1.27/-3/er/1.65/-3/l/-1.64/-3/_/d")
    -- end
  elseif btnp(4) then -- 🅾️ button
    mute()  --flushes the sound queue and immediately stops whatever is currently being said.
  end
end

Speech strings represent text phonetically and include prosody markup. The easiest way to create and test them is with the Declare web app. You can also try out different voice options with it.

If you are interested in learning more about speech synthesis, try googling these key words: Klatt synthesizer, formant, acoustic phonetics. It's a fascinating topic. An unminimized version of the library is included in the demo cart.

Special thanks to the gang on the Discord server for lending me their ears and keeping me motivated, especially @packbat, who did it for science. Thanks also to @IMLXH for finding the Klatt prosody rules.

P#116607 2022-08-30 19:14 ( Edited 2022-09-27 23:37)

[ :: Read More :: ]


Defy Audio Player

The Defy Audio Player plays Defy formatted audio files via PICO-8's PCM channel. It's a PCM boombox! You can also use it to create binary strings of audio data for playback in your own cartridges.

Convert almost any audio file format to .defy here: https://bikibird.itch.io/defy.

This cart is intended to run in PICO-8, not play on the BBS, which is limited to a maximum files size of 250K. Instead, open PICO-8 and enter load #defy. Then enter run.

Controls

  • Drag and drop your .defy file onto PICO-8 to play it. You do not have to wait for a file to finish before loading another.
  • Press 🅾️ (z key) to pause playback. Press it again to resume.
  • Press ⬅️ or ➡️ to switch visualizers.
  • Press ⬆️ to eject and stop playback.
  • Press ⬇️ to display title and format.
  • Press ❎ to record binary string. If you press record prior to playing the file, Defy will start recording it as soon as the file is dropped. The binary string is copied to your computer's clipboard.

Audio String Player

The library below plays Defy formatted audio strings. For support for @luchak's QPA formatted audio strings see https://www.lexaloffle.com/bbs/?tid=53933 and https://github.com/luchak/qpa-format/.

Warning: Be careful testing new audio strings. Playback with a mismatched playback mode sounds terrible. Do not test with headphones. Protect your hearing.

When record is pressed, the first 32,000 bytes of audio data are copied to the clipboard as a binary string during playback. Use the code below in your own carts to play the binary string. Be aware that only a few seconds of audio will fit in a cart. If the captured string contains too much data, you may truncate it. One second of audio equates to approximately 5500, 2250, 1840, 1125, and 690 characters for 8, 4, 2.6, 2, and 1 bit formats respectively.

  • Paste the library below into a new cart.
  • To save tokens, delete defy_play functions for any unused bit formats
do  --defy audio string library by bikibird
    local buffer=0x8000  -- required all formats
    local clips={}  -- required all formats
    local cued  -- required all formats

    -- locals required for 4, 2.6, 2, and 1 bit formats below

    local step, new_sample, ad_index,c,direction 
    local index_table = {[0]=-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8} 
    local step_table ={7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767}
    local adpcm=function(sample,bits) --adapted from http://www.cs.columbia.edu/~hgs/audio/dvi/IMA_ADPCM.pdf
        if bits >1 then  
            local delta=0
            local temp_step =step
            local sign = sample &(1<<(bits-1)) --hi bit of sample convert to 4 bit
            local magnitude =(sample & (sign-1))<<(4-bits)  -- convert sample to 4 bit
            sign <<=(4-bits) -- convert sign to 4 bit 8==negative 0== positive
            local mask = 4
            for i=1,3 do
                if (magnitude & mask >0) then
                    delta+=temp_step
                end
                mask >>>= 1
                temp_step >>>= 1   
            end
            if sign> 0 then  -- negative magnitude
                if new_sample < -32768+delta then 
                    new_sample = -32768
                else    
                    new_sample-=delta
                end
            else  -- positive magnitude
                if new_sample >32767-delta then
                    new_sample =32767
                else
                    new_sample +=delta
                end
            end 
            ad_index += index_table[sign+magnitude]
        else --1-bit
            if sample==1 then  -- negative
                if new_sample < -32768+step then 
                    new_sample = -32768
                else    
                    new_sample-=step
                end
            else  -- positive 
                if new_sample >32767-step then
                    new_sample =32767
                else
                    new_sample +=step
                end
            end 
            if sample==direction then --if direction same, try larger step. if changed, try smaller step
                ad_index+=1
            else
                ad_index-=1
                direction =sample
            end 
        end 
        if ad_index < 1 then 
            ad_index = 1
        elseif (ad_index > #step_table) then
            ad_index = #step_table
        end 
        step = step_table[ad_index]
        return new_sample\256+128
    end 
    defy_load=function(clip) -- required all formats
        add(clips,{clip=clip,start=1,endpoint=#clip, index=1, loop=false, done=false}) 
    end
    local cued=false -- required all formats
    defy_cue=function(clip_number,start,endpoint,looping)  --required all formats
        clips[clip_number].start=start or clips[clip_number].start
        clips[clip_number].index=clips[clip_number].start
        clips[clip_number].endpoint=endpoint or #clips[clip_number].clip
        clips[clip_number].loop=looping or false
        clips[clip_number].done=false
        step, new_sample, ad_index,delta,direction=7,0,0,0,0
        cued=clip_number
    end 
    defy_play=
    {   
        [8]=function()  -- 8 bit format
            if cued and not clips[cued].done then
                while stat(108)<1536 do
                    for i=0,511 do
                        poke (buffer+i,ord(clips[cued].clip,clips[cued].index))
                        clips[cued].index+=1
                        if (clips[cued].index>clips[cued].endpoint) then
                            if (clips[cued].loop) then
                                clips[cued].index=clips[cued].start
                            else
                                serial(0x808,buffer,i+1)
                                clips[cued].done=true
                                return
                            end
                        end
                    end
                    serial(0x808,buffer,512)
                end
            end
        end,
        [4]=function() -- 4 bit format
            if cued and not clips[cued].done then
                while stat(108)<1536 do
                    for i=0,255 do
                        c=ord(clips[cued].clip,clips[cued].index)
                        poke (buffer+i*2,adpcm((c&0xf0)>>>4,4),adpcm(c&0x0f,4))
                        clips[cued].index+=1
                        if (clips[cued].index>clips[cued].endpoint) then
                            if (clips[cued].loop) then
                                clips[cued].index=clips[cued].start
                            else
                                serial(0x808,buffer,i+1)
                                clips[cued].done=true
                                return 
                            end
                        end
                    end
                    serial(0x808,buffer,512)
                end
            end
        end,
        [3]=function() -- 3 bit format
            if cued and not clips[cued].done then
                while stat(108)<1536 do
                    for i=0,170 do
                        c=ord(clips[cued].clip,clips[cued].index)
                        poke(buffer+i*3, adpcm((c>>>5)&0x07,3), adpcm((c>>>2)&0x07,3), adpcm(c&0x03,2,true))
                        clips[cued].index+=1
                        if (clips[cued].index>clips[cued].endpoint) then
                            if (clips[cued].loop) then
                                clips[cued].index=clips[cued].start
                            else
                                serial(0x808,buffer,i+1)
                                clips[cued].done=true
                                return 
                            end
                        end
                    end
                    serial(0x808,buffer,510)
                end
            end
        end,
        [2]=function() -- 2 bit format
            if cued and not clips[cued].done then
                while stat(108)<1536 do
                    for i=0,128 do
                        c=ord(clips[cued].clip,clips[cued].index)
                        poke(buffer+i*4, adpcm((c>>>6)&0x03,2), adpcm((c>>>4)&0x03,2), adpcm((c>>>2)&0x03,2), adpcm(c&0x03,2))
                        clips[cued].index+=1
                        if (clips[cued].index>clips[cued].endpoint) then
                            if (clips[cued].loop) then
                                clips[cued].index=clips[cued].start
                            else
                                serial(0x808,buffer,i+1)
                                clips[cued].done=true
                                return 
                            end
                        end
                    end
                    serial(0x808,buffer,512)
                end
            end
        end,
        [1]=function() -- 1 bit format
            if cued and not clips[cued].done then
                while stat(108)<1536 do
                    for i=0,64 do
                        c=ord(clips[cued].clip,clips[cued].index)
                        poke(buffer+i*8, adpcm((c>>>7)&1,1), adpcm((c>>>6)&1,1), adpcm((c>>>5)&1,1), adpcm((c>>>4)&1,1), adpcm((c>>>3)&1,1), adpcm((c>>>2)&1,1), adpcm((c>>>1)&1,1),adpcm(c&1,1))
                        clips[cued].index+=1
                        if (clips[cued].index>clips[cued].endpoint) then
                            if (clips[cued].loop) then
                                clips[cued].index=clips[cued].start
                            else
                                serial(0x808,buffer,i+1)
                                clips[cued].done=true
                                return 
                            end
                        end
                    end
                    serial(0x808,buffer,512)
                end
            end
        end
    }   
    function eject()  -- required all formats
        clips[cued].done=true
    end
end
  • Record some audio in the Defy Player. Once the binary string is created, playback will pause while the binary string is copied to the clipboard and then resume
  • In _init() add one or more load statements to add your audio clips to the clip table. Turn on puny font by pressing ctrl-p before pasting your string. Failing to do so will corrupt the string and distort the audio.
function _init()
 defy_load"my audio string" --Turn on puny font (ctrl-p) before pasting!!!
end
  • The cue function must be called before your audio string may be played. Cue your clip in the _update function. Use whatever logic you would use when using sfx(). Cue may also be called with additional parameters: defy_cue(clip_number,start,endpoint,looping). start and endpoint are indexes into the string. looping is a boolean.
  • Add a playback mode in _update, defy_play[format](). Where format is 8, 4, 3, 2, or 1, corresponding to 8-bit, 4-bit, 2.6-bit, 2-bit, or 1-bit.
function _update()
    if (btnp(4)) then
      defy_cue(1)  -- cues clip 1 for play from beginning to end, no looping.
    end
    defy_play[4]() -- play back of 4-bit audio string.   called unconditionally in _update.
end
  • Use defy_eject(clip_number) to end a clip early or stop a looping clip.

Acknowledgements

Thank you, @luchak and @packbat, for all your sound advice. Thank you, @luchak for the antialiasing filter. Thank you, @Gabe_8_bit for feedback and your fancy oscilloscope code. It formed the basis of the simpler oscilloscope that was ultimately included. Thank you, @LazarevGaming, et al, for testing and feedback.

P#109080 2022-03-23 21:56 ( Edited 2023-09-07 14:57)

[ :: Read More :: ]

Cart #lektrik_sportz-1 | 2022-02-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

Lektrik Sportz Game

A Captain Neat-o Adventure

Let's get one thing straight. This is not Electric Football™. Doctor Lamento destroyed the football years ago because, you know, he's evil. But, I get ahead of myself. This is the story of Captain Neat-o who is far from home and falls into the clutches of Doctor Lamento.

The evil Doctor forces our hero to face off against his most formidable opponent, Neat-o himself, in a spectacle the Doctor calls Lektrik Sportz Game (because he can't spell and, you know, he's evil.)

Game Play

Run from one end of the field to the other while avoiding your opponents. You should make it home in under 5 minutes. Don't fall off.

Your teammates can help block the opponents and you can set their overall direction and confrontation style in the strategy session.

If you are using a keyboard to play, use the X key to advance to the next screen/teammate and the Z key to switch modes in the strategy session. Arrow keys select options, set direction, and move teammates.

The visiting team's strategy is randomly generated, but set for a single day. Learn their strategy over multiple plays and eventually defeat them in a single down! Then, come back tomorrow and play a new challenge.

Poetry Corner (Spoilers)

The Story So Far

Captain Neat-o floats in space,
So helpless and out of place.

His situation is dire...
Suddenly there's ray gun fire!

Freeze! Shrink! Mimeo! and Drop!
Doctor Lamento wont stop...

Pawn Neat-o battles his clones!
"Too formidable!" he groans.

"Then I will give you teammates.
Strategize while fate awaits...

I act with hostility!
Engage the utility!"

Honest Neat-o, head crowned gold,
Propels toward home. Behold...

Hero, his green band flashing,
Cuts a figure so dashing.

Lektrik electrickery!
Oh, what wicked wickery!

The End?

Stout hearted Captain Neat-o,
His story not finito,
Enlarged by experience,
Mastered fate imperious.

So, on to new adventures...
Despite the past's vast treasures,
Hidden futures still unfold
Awesome epics to be told.

Credits

All assets used in the making of this game are courtesy of Toy Box Jam 3. I borrowed @Mot's Instant 3D Plus! library and hacked it a bit to get an additional camera angle. All other code, the poetry, and the idea for this adventure are my own.

P#107707 2022-02-26 21:38 ( Edited 2022-02-28 16:26)

[ :: Read More :: ]

Cart #christmassneks2021-3 | 2022-01-01 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
10

This is the story of a hard working Christmas elf. I was never told their name. I call them Blinky. They had one last task to complete late one Christmas Eve: String some lights, plug them in, and connect them to the finial atop the tree. Easy for a smart elf like Blinky. Too bad they never finished that electrician's course...

Game Play

Connect the loose bulbs by touching them with the exposed wire from the light string. Loose bulbs are always safe, but if the string is connected to power and you touch the string to itself, some of the bulbs will explode. Electricity is powerful, but dangerous. Be careful with it.

There are three possible endings and eleven achievements to earn.

Controls

Press the Z key to disconnect the light string to/from the power outlet.

Press the X key to disconnect the light string to/from the finial.

Arrow keys set the direction of travel. If you wander off screen you will hear warning notes. Come back before you wander too far.

P#103502 2021-12-25 01:41 ( Edited 2022-01-01 01:43)

[ :: Read More :: ]

I made a web-based tool for extracting and converting MIDI file data to be played in PICO-8. It's nicely interactive and includes a PICO-8 console built into the page so that you can audition the results before you copy the SFX data. Give Denote a try and let me know what you think.

P#94001 2021-06-24 22:48 ( Edited 2022-03-27 14:08)

[ :: Read More :: ]

So, I've been working on a web based MIDI to PICO-8 converter for a while now. It was going pretty well, but today I introduced a bug, which totally corrupted the SFX data. The input was the traditional melody, Ghost Of John. The output was this:

[sfx]

Surprisingly, I like the way it sounds. I guess I composed some original music here, but it was completely accidental. I guess if you make enough mistakes, some of them are bound to turn out ok.

Now I just need to figure out what kind of game goes with this soundtrack. Any suggestions? Feel free to use this in your own projects if it fits.

P#93612 2021-06-16 17:26 ( Edited 2021-06-16 17:27)

[ :: Read More :: ]

Cart #circularthinking-0 | 2021-05-16 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
7

In my last game, I included an iris effect to transition between two scenes. I used the midpoint circle algorithm to calculate the edges of the iris. This algo avoids trig and square root functions and so is super fast. Even at 60 frames a second, there's no lag. I decided to make a more generalized version, implemented as a coroutine. I hope you find it useful for your projects.

To use:

  • Copy the iris function from the cartridge above into your own cartridge.

  • When it's time for a transition, assign the coroutine to a variable in your update function: effect = cocreate(iris)

  • In the draw function, call the coroutine: coresume(effect, 1, 128, 1, 15)

The parameters for the coroutine are starting radius, ending radius, step, and color. A positive step indicates by how much to open the iris on each frame. A negative step indicates a shrinking iris. See the code for examples.

P#92059 2021-05-16 23:58

[ :: Read More :: ]

Cart #icecreamclouds-1 | 2021-04-22 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
7

Straight from the laboratory of Professor von Stroopwafel is a modest proposal to solve global climate change. Enjoy a lighthearted romp through a speculative future. It even has bells and whistles. Happy Earth Day, everyone.

Game Play

Catch falling scoops of ice cream and toppings to fulfill as many orders as possible before the timer runs out.

Controls

Press the X key to advance to the next screen.

Left and right keys move the cone.

Use the Z key at any time to see the ice cream order. Press Z again to dismiss it. The timer is always running so try not to look at the order too long or too often.

P#90911 2021-04-22 00:31 ( Edited 2021-05-26 17:01)

[ :: Read More :: ]

I'm working on an SFX that is supposed to sound like a bicycle bell, well actually an ice cream bell. Here's what I have so far:

[sfx]

Do you find it convincing? Do you have advice on making it better? If you have a better SFX of a bicycle or ice cream bell ding, please share.

P#89978 2021-04-04 15:12 ( Edited 2021-04-04 15:52)

[ :: Read More :: ]

I made an image demake tool for PICO-8. Load any image and create a dithered image that uses PICO-8 standard colors and/or hidden colors and is reduced to a maximum width and height of 128 x128. Depict supports Ordered, Atkinson, Floyd-Steinberg, and Sierra2 dithering as well as some artistic dithers: Rivers, Streets, Rain, Wind. Drag and drop the final result into the PICO-8 sprite sheet. Free on itch: Depict

All feedback welcomed.

Mix and match standard and hidden colors, but do do not exceed 16.

Rivers dither adds horizontal ripples.

Streets dither creates maze-like artifacts.

Rain dither makes vertical steaks.

Wind dither produces slashes.

Atkinson Dither

Ordered Dither

No Dither

P#87051 2021-02-01 01:14 ( Edited 2022-03-27 14:07)

[ :: Read More :: ]

Cart #christmassneks-5 | 2021-01-02 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
7

My first Pico-8 game. Entered in Toy Box Jam 2020.

Tis the season to sing carols, drink nog, and decorate the night with Christmas sneks.

Press an arrow key to change the direction of the snek and connect bulbs to the live wire at the front of the snek to light them up. Build a long snek or a short snek. Ride the high speed rail to get around faster.

This is a mellow game with no set goals, but beware! If you touch the live wire to the snek you will create a short circuit!

When you are happy with your snek, press X to go to the forest and plant a tree decorated with your snek. Then go build another snek so you can plant another tree.

Merry Christmas and may 2021 bring you only good things.

P#85777 2020-12-25 20:17 ( Edited 2021-12-19 16:28)