Created so I could learn how to handle tracker and maps (sort of...)
Inspired by tjheslin1's Interstellar I took yet another try to learn how trackers work and I just had to choose my favourite tune from Terminator 2!
Made in Pocket C.H.I.P. where I coudn't manage to make a screenshot so tips would be appreciated!
This is also my introduction to Pico-8 community!
Cheers everyone!!

For the game I'm working on I built a super tiny tweening system for making it easier to move things around. This cart demonstrates a few different easing functions that plug into the system.
Tweening is a way of moving an object from point A to B. You specify where you want the object to go, and how long you want it to take to get there, and the tweening system takes care of the motion. I find it super useful for making games, especially for adding little bits of polish to your game. It's easier to just say "move the ball to x=104 in 60 frames" than it would be to calclate the required speed every time. You can also use an easing function to tell how it should get there, allowing it to accelerate slowly or bounce or spring back.
Tweens have four parameters: the property we want to update, the value we want to end up with, the length of time we want it to take to reach the target value, and the easing function. We'll store those values in a table, and each frame we'll look at each entry in the table and update the target property as needed.
The tween function begins tweening a property:
function tween(target, property, destination, duration, func)
local tween_info = {
target = target,
property = property,
base_value = target[property],
change = destination - target[property],
duration = duration,
elapsed = 0,
func = func
}
add(tweens, tween_info)
end
|

As of Voxatron 0.3.4
The visibility option asks for two numbers:
The first number is meant to represent the "Host's" line of sight, and 72 degrees for every 0.1 (0.5=360).
The second number represents the "Actor's" line of site, it uses the same number system as the first number.
If the host can "see" the actor, and the the host is within the actor's line of "sight", then the modifier activates.
Red is at 0.2, 0.1 (Visible within 144 degrees, makes a cone of 72 degrees)
Orange is at 0.35, 0.05 (Visible within 252 degrees, makes a cone of 36 degrees)
Yellow is at 0.5, 0.02 (Visible within a full circle around you, makes a cone 14.4 degrees).
If you have a controller for Voxatron, then use it for this level, it makes the effect look less rigid
[b]WARNING

So I've been looking for a quick and portable developer environment for me to gamedev on the go, and I thought pico-8 was it; but after trying for a while I'm not entirely sure....
I've already gotten a pocketchip and pico8 on pc >_>. But it feels really confusing after using Unity, gamemaker, and other more graphically based programs. I've tried making a sort of starting point for quick deving with objects and built in collision detection but its really difficult....
Any suggestions on where to start again or if there's a different programming environment I could work with?
EDIT:
I'm asking because I was trying to find a very quick and portable developer environment and that seems to be very hard to find and I'm not sure if this is right for me because I want to dev on the go >_<

I recently made a program that can translate (some) MIDIs to PICO-8 tracker format and I thought I'd also make a fun visualizer to show it off :)
The music you see (and hear) above is J.S. Bach's Sinfonia 15 in B minor (BWV 801). It was translated from a MIDI file (that I found on the internet somewhere) into PICO-8 tracker format by the aforementioned tool:
https://github.com/andmatand/midi-to-pico8
This visualizer takes a simple approach of displaying whatever notes it sees are currently playing each frame (if any notes changed) so it may skip notes if the notes ever change faster than the FPS (this cart runs at 60). A more robust visualizer could be written, but I just wanted something that could display most normal songs for fun :)
You can use this visualizer to display your own music by downloading this cart and uncommenting one or both of these lines in the _init() function (and changing the path string appropriately):
-- load the music and sfx data from another cart --reload(0x3100, 0x3100, 0x1200, 'othercart.p8.png') -- permanently store the music and sfx data loaded above --cstore(0x3100, 0x3100, 0x1200) |

This is a simple one - it's an over-engineered Pico-8 version of this Commodore 64 BASIC program:
10 PRINT CHR$(205.5+RND(1)); : GOTO 10 |
It's a random maze generator, and some folks wrote an interesting book about it

Or you could read that subject line as, "No Objects For Noobers."
For those of you confused or confounded by Object-Oriented programming, you might be happy to know that PICO will also accept the standard spaghetti-code variety. That is where there are no system interrupt or timing routines.
How do I use a single tile to create a perfect black outline around a sprite that is already 8x8 pixels in size ? You'll have to look at the code to find out. :)
Based on DittoSlash's test cart.

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.
What's included:
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
|

Posting this for anyone who wants to use it. I had made this as practice awhile back and I hate to see the graphics go to waste. Originally I thought maybe I'd make a LITTLE COMPUTER PEOPLE clone (if you remember that for the C64) or some sort of sidescrolling adventure game, or even maybe as a "cheerleader" for a shooter/puzzle type game (she could react to how well or badly you're playing.)
If you download the cart, you'll see that there are 2 sprites with blank faces, a lot of faces for front and profile view (demo only uses 1 face), and a ground tile set, and a flower accessory sprite, and a walking sprite which does have a face.

As I'm getting deeper and deeper into my PICO code, I am finding a few things, and perhaps suggesting some additionally.
Allow FUNCTIONS to be below main code. Many programming languages do not care where you write your functions. It's convenient for me to have them beneath my main code which is the opposite of what PICO requires currently.
Are parentheses really necessary for commands that will always start as the first code ?
PRINT
CLS
I understand it takes two "=" for a comparison. I can think of several programming languages that do not do this. You might keep it as deprecated code, but also allow "=" in a comparison. Quite simply, there should be no need to set a value while making a direct comparison, so "=" could be done this way.
Are parentheses really necessary for other commands ? GFA and BlitzMAX, ONLY used parentheses for functions that return a value or if you wanted to change the order of the operands in a mathematical calculation or a logical comparison. Incidentally, () would never be used except to describe the parameters of a function that does not return a value.
A=ADDUP(16)
CHECKADD A
A=(B+C)*D
CLS clears the whole screen yet ignores CLIP().
A command CLSCOLOR() would be nice to set the CLS color so when it is called, instead of always BLACK, you could have a different color.
Option for LOAD and SAVE state when playing a game from SPLORE. Then you could leave one game, play another. Then go back to the other game at the same position you left it. This would not be cheating as once you SAVE state, you exit that game back to SPLORE.
Only when you load the game again in SPLORE do you have an option to LOAD state and set for the ability to SAVE STATE again. During the game you CANNOT use LOAD state, it is only to recover your position optionally when playing a game.
Instead of an error message stating what line # it occurred on, show an error dialog, perhaps go directly to the editor on the line and column where the error took place along with a dialog box.
Ability to FOLD functions. That is, if you are on the first line of a FUNCTION, you can press F10 or some other select key and it will fold up - not showing the contents and only the name and arguments for it.
FUNCTION ADDUP(N)
RETURN N+1
END
FUNCTION CHECKIT(N)
IF N==0 THEN RETURN -1
END
(2 folded functions)
FUNCTION ADDUP(N)
FUNCTION CHECKIT(N)
Ability to have split edit. That is, you can have one frame above which is at a particular line # in your code and an edit frame below that which can be at an entirely different line #. Useful for debugging complex functions and their calls to main code.
Force readable coding. That is, do not permit this or any other way to convolute coding:
IF (A==5) B=3
Instead it could be:
IF A=5 THEN
B=3
ENDIF
Allow ENDIF as a possible command. END can also be used as a deprecated command, but ENDIF only with an IF statement.
Same with FOR, have a NEXT. Variable name not needed for NEXT, however, unless operating in STRICT mode. (That is something else).
Add a new command, DBUG:
With it, it will choose the top-right-hand corner of the screen and show the variable name + value, updated every time screen is updated:
DBUG A,B,C
A=1
B=A+2
C=10
Display in top-right-hand corner of the screen right-justify flushed during runtime shows:
A=1
B=3
C=10
It could also update every time you call FLIP()
Either that or create a new small panel to the right of the enlarged 128x128 screen and with legible Truetype font and text so it does not interfere at all with the game display.
Use NODBUG to remove a viewed variable during runtime. Exiting a program removes all DBUG variables. Your code MUST have DBUG in order to view them again.
When using UP ARROW for command history when in FILER mode, you could skip over repeated entries. I.E: here is the history
PRINT A,CLS, RUN, CLS, RUN, CLS
Pressing UP will reveal CLS, RUN, but if it is CLS again seeing a repeated pattern, then it will just skip to PRINT A. In fact, there is no reason to save copies of the same command set in history if it is already listed at least once there.
Naturally a repeated command will prompt it to appear at the bottom of history so it is recalled first as it was the last item entered.
NONE of the keys from the keyboard currently work in the PICO editor from NUM-LOCK: HOME, UP, PGUP, LEFT, RIGHT, END, DOWN, PGDN, DEL. I use these all the time in other programming lanuages.
The INSERT KEY is not being used at all. You could use it like SPACEBAR to move typed commands to the right, but instead of the cursor moving additionally, it would stay in the same position, so in effect it just PUSHES what is typed to the right by one-character.
Thus, where the uppercase letter represents the position of the cursor to start, and _ represents the same position of the cursor after pressing INSERT.
ripeApple
ripe_apple
Some commands that I believe would be useful that are not included with PICO:
CHR$(), ASC(), VAL(), STEP, SUBROUTINE, ENDSUB, ENDFUNCTION, PRINT USING,
MKL and CVL to convert 4-bytes to and from a single variable value
PEEKWORD, PEEKLONG, POKEWORD, POKELONG. There may be others.
FILL(X,Y,PaintColor,EdgeColor)
If Paintcolor is not chosen, it uses default color. If Edgecolor is not chosen, it uses any color that is not PaintColor.
add options to CIRCFILL and RECTFILL thus:
CIRCFILL X,Y,Radius(,FillColor,OutlineColor,ThicknessOfOutline)
RECTFILL H,V,X,Y(,FillColor,OutlineColor,Rotation,ThicknessOfOutline)
XRECT H,V,X,Y(,FillColor,OutlineColor,Rotation,ThicknessOfOutline)
(where X & Y are not ending coordinates but pixels across and down)
Same with LINE.
LINE H,V,X,Y(,C,Rotation,Thickness)
XLINE H,V,X,Y(,C,Rotation,Thickness) (where X & Y are pixels across and down, negative for left and up)
LINETO X,Y(,c,Rotation,Thickness) (where the line is drawn directly from the last line drawn and X & Y in this case are not coordinates but pixels adjusted from the last plotted position.
So if you draw a line FROM 50,25 to 100,75 and then used LINETO 0,-10 , the last line drawn will be a vertical one 10 pixels above 75 giving you vertical coordinate 65.
Also add:
OVAL and OVALFILL:
OVAL X,Y,RadiusX,RadiusY,OutlineColor,Rotation,ThicknessOfOutline
OVALFILL X,Y,RadiusX,RadiusY,FillColor,OutlineColor,Rotation,ThicknessOfOutline
Might have ROUND and ROUNDFILL as well, to create Macintosh-style rounded frames.
CurveStep is # of pixels to draw a curve. Zero is none (same as RECT), 1 is 1-pixel, etc. 3 would yield a nice Macintosh style curve.
-- -- -- -- -- -- -- -- ## ## -- -- ## -- -- -- ## -- -- -- -- ## -- -- -- |

PICO-8 v 0.1.9.
I'm using sprite page 3 in my game. I was cleaning up some mockup art by pasting an all-black sprite over the top of the mockup in the sprite editor, but when I flipped back over to the map editor and moved the viewport around, the sprites reverted:
This happens every time I repeat this sequence. The sprites revert if I paste over 1 or all of the mockup.
This doesn't happen when I use the pen tool on the sprites in page 3, nor does it happen when I paste an all-black sprite onto a sprite in page 0:

The new printh() does not sanitise its second argument (the filename) and can thus create or modify user-owned files anywhere on the filesystem. For instance the following code could be put in a cartridge and run on Linux:
printh("echo 'lol'", "../../../.bashrc")
|
It will cause the command to be executed the next time the user logs in (provided they use bash).
A similar technique works on Windows:
printh("@echo lol", "..\\..\\microsoft\\windows\\start menu\\programs\\startup\\script.bat")
|
Many variations of the above are possible and potentially devastating.

This code works as expected:
debug=false
(debug and printh or print)("hello")
print("success")
|
But this gives a runtime error “attempt to call a nil value" at line 4:
debug=false
(debug and printh or print)("hello")
print("success")
(debug and printh or print)("hello again")
|
Confirmed in both 0.1.8 and 0.1.9.






2 comments



