Log In  

Cart #zelda1_dungeon_2021_10_17-0 | 2021-10-17 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#98785 2021-10-17 12:03

Cart #gb_zelda1_dng-0 | 2021-10-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Press X to add/remove the low health beeping sound which layers on top of one of the music channels. I have many memories of hearing it that way, so I added it in, haha.

Edit - This was created with respect to this post from earlier:

P#98560 2021-10-13 01:24 ( Edited 2021-10-13 01:37)

Cart #ndarwyi-0 | 2021-03-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#88446 2021-03-03 13:55

Cart #procedural_fire-0 | 2021-02-26 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#88203 2021-02-26 15:13

Cart #ch_func_demo-0 | 2021-02-26 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

I was thinking of ways to decouple code flow from a standard procedural design and more towards what I call a chaining queue. Basically, the queue starts off with a single function. This function would then add itself with some modified parameters to the call queue via a table {func, args...}. This would closely resemble JavaScript's setTimeout() function.

This demo only uses a 1:1 call (it calls itself once, and that's it), meaning that the queue will never overfill.

I ended up making some really cool-looking color demo accidentally!

P#88200 2021-02-26 13:48

Cart #sonic2_emeraldhillzone_2-0 | 2020-12-18 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#85548 2020-12-18 07:32 ( Edited 2020-12-18 07:35)

Cart #wip_ma_20200905-0 | 2020-09-05 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Just in time for GBJAM8.
I had to remove the breakable pots to conserve tokens.
I am literally at 8192 tokens even after making even more optimizations!
I had to add the key and door to exit the stage.

P#81517 2020-09-05 11:31

Cart #wip_ma_20200902-2 | 2020-09-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Hey again. Goober here.

This revision has me REALLY looking in every little nook and cranny I can find
to get precious tokens. I've had to resort to utilizing SECRET SPECIAL tricks
to making sure I can load as much data as possible while not using very many
tokens at all. In the beginning of my code I've created a special function:

-- handy token-saving function
glb     =_𝘦𝘯𝘷
function vars(...)
    local a={...}
    local b=split(a[1],",")
    local c=2
    for i in all(b) do

Pair this with one of my modules - the dialog module, for example:


This will allow me to assign multiple global variables while saving about 1/3
of the tokens. A lot of data is being converted to strings in order to save
more and more tokens. Data which doesn't need to be written to very often
may also be stored together in strings, but I haven't really gotten to that
point yet.

What will PROBABLY happen is that I'll start looking into using peek/poke
for reading and writing data. One of the problems with using poke, though, is
that each call to this is 4 tokens. [poke ( offset , value]. The ending brace
doesn't count. Peeking is about the same. Even with shorthand peeking, it takes
four tokens to assign a value.

But, there are some features added to this version!

  • When attacking and killing bats, their spheara (currency is souls) is sucked
    in by the magic lantern. When the lantern takes the soul, it glows bright for
    a split second.

  • It's now possible to die. While it's not possible to be hurt by the bats
    right now (fixed this), you can die from spikes or falling into the water at the bottom of
    the stage. This results in a neat effect! Also, when you die, a password is
    displayed. While this password doesn't serve any purpose right now, I'm planning
    on allowing players to input their password upon startup.

  • You still can't end the level yet. The key actor has not yet been implemented.
    Because I'm out of tokens right now, I'll need to save some more before I can
    implement this. It's in the works!

I think that's it for now. See ya!

~ Goober

P#81473 2020-09-03 11:04 ( Edited 2020-09-03 12:05)

Cart #wip_ma_20200831-0 | 2020-08-31 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Hey again. Goober here.

I've made some impressive changes to the cart! Here's some of the neat things
I added:

  • You can attack and kill the bats and pots in the level! For now they both
    add 10 to your score. It also makes this neat little explosion when you
    defeat them, with a cool sound effect.

  • The magic lantern in the cutscene now shows up in gameplay! This lantern
    is the basis of storing your currency, which is called Spheara. It glows
    faintly as it travels with you. The spirit of the hero's brother Coji also
    resides in this lantern.

  • You still can't die, but I'm working on it. If you're on the bottom level of
    the map and you fall through the water below, you'll have to reset.

  • There's still some oddities with the map looping and actors not really
    behaving like it's a seamless loop, but at least the foreground and background
    map tiles do!

  • The map was simplified to make it easier to build levels via 8x8 chunks.
    This does limit the amoutn of variety for now, but it's a fine placeholder
    for building as many maps as I would like.

  • While not implemented, there exists a password system hidden in the game's
    code which will be utilized at some point later in development.

Again, I'm topped off on tokens, which means I'm gonna have to find ways to
save some somewhere.

Tokens: 8190 / 8192
Characters: 43954 / 65535
Compression: 90%

Believe it or not, compression was actually hassling me too. I lessened this
by replacing the detailed map from a prior version to a chunk-based one. The
string size is MUCH less than the former.

While adding stages is absolutely no hassle at all (really only adds a handful
of tokens each level (like.. 9?) adding content for the game is proving to be
very difficult. I don't want to remove anything that is currently in place,
and I'm already scrubbing every nook and cranny I can find for any amount of
tokens I can save. I still have a lot I need to do as well:

  • Implement the other 4 abilities (Water, Ice, Lightning, Wind Magic)
  • Make it so Makeii can get hurt and die, and also get a game over.
  • Implement charged up abilities
  • Utilize an ability-changing menu when holding down and Z
  • Make a shield appear when Makeii is holding down and X.
  • Implement more enemies so I can make use of the sprites I made for them.
  • Implement key + locked door mechanic so you can leave the level.

I really REALLY wish that we had the ability to test games even if they go
over the token/char limit. While it is possible to still test carts over the
compression rate of 100%, it would be much easier to first implement all
of the content I need to and then compress and optimize whatever I can. I may
need to resort to a minifier to get everything to fit in there. Identifiers
which are substituting for numbers could probably be optimized that way.

That's all for now!

P#81391 2020-08-31 08:19

So I was thinking about how charming it would be to make a password system for my current game in progress, but I'm not entirely sure where to start on it.

I guess the first thing I would need to do is determine which values need to be saved to the password, determine the ranges in which these values are valid, determine the base for each character in the password, and then encrypt the password which displays to the player when they want to quit the game.

Let me make a small hypothetical data set that needs to be saved in the password:

HP-LV  (min 0, max 6, 3 bits)
MP-LV  (min 0, max 6, 3 bits)
SCORE  (min 0, max 99999999, saves in multiples of 100, so real range is 0-999999, which means 20 bits)
STAGE  (min 0, max 7, 3 bits - stage saves as 0-7)
INV.   (bitfield of 10 items, 15 bits (5 items have level-2 upgrades, one bit each))

TOTAL: 44 bits (move this up to 48 to increase non-possible pw combos)

Possible PW Character Set (base 32):

48 bits / 6 bits per character = password length of 8.

Possible password attempt:
QQQQQQQQ (Solar Jetman fans, word up!)

per character:
010000 010000 010000 010000 010000 010000 010000 010000

per assignment
010 000 01000001000001000001 000 001000001000001 0000

This equates to:
SCORE: 266305+00
INV.:  2 items obtained (level 0), 1 passive item
ERR BITS: 0 (pass)

So, I need to figure out how to encrypt this password to be harder to interpret, as well as utilize the error bits at the end to further keep players from typing in random passwords and getting "cheat passwords". Any ideas on how I can go about this?

P#81281 2020-08-28 05:07

Cart #wip_ma_20200824-0 | 2020-08-25 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Well, this version definitely had me scraping every little inefficiency
I could think of to save tokens. There's still a lot that can be saved, but
right now I'm pretty much fighting against the token limit to try and add
more and more features.

tokens: 7885 / 8192
chars: 48853 / 65535
compression: 97%

To start, I had to start doing variable recycling for scenes. Because the dot
operator counts as a token, it's more efficient to keep data on the global
namespace than to utilize containers. Because of this, scenes are using generic
variables like "sc_1" through "sc_7" at the moment. As a strangely positive
consequence, my game runs much more efficiently and uses a lot less CPU.

I was originally concerned about doing it this way, but it turns out that I
have a lot of RAM to spare. I think PICO-8 allows up to 2048 KB? The game's
debug stats seem to show that I'm only using 250 KB or something.

I'm watching my code sort of merge into a less elegant but more efficient style.
It's more efficient to use expressions than branches, but it's still good to
use functions instead of GOTO branching. as far as I know. It doesn't save any
tokens to GOTO branch if I recall.

Because comments affect the compression percentage of the cart, most of them
have been removed. I'm expecting the code to become less readable as time goes
on, but I'll have a good amount of knowledge about the code I've written for
each section.

Anyway, in this version, the first (non-killable) enemy is seen! There's bats
flying around the place now, but I have to fix the fact that they'll fly off 
the edge of the map because their position doesn't wrap around like the player's
does. If I set their solid flag to true, I can ride on them! It was turned off
in this version, however.

There is another actor that was made, but it's indistinguishable from the
foreground tiles it represents. I've added pots to the game, which eventually will
be breakable in order to get stuff like healing items and game currency. They
will respawn like enemies do when you change vertical layers, so it may be an
efficient way to farm things you will need.

You may also notice in this version that a very weird noise plays when you
step on spikes or lava. This was me testing harmful tiles while making sure
that they don't hurt the player if they're still standing on the ground. The
noise still plays when you're standing NEXT to spikes though, so I have to fix

So far I haven't needed to sacrifice any of the content I've made for the game
so far. I've only needed to compress their information or made their modules
more efficient. I'll need to find clever ways to beat the token limit, which
is my current adversary in development. Maybe I can implement a tiny string
parser which can ease the load? It will cost CPU to add an interpreter on top
of an interpreter (Lua) but if it means saving valuable tokens, then I'll
start working on one.

- Goober
P#81152 2020-08-25 06:39

Cart #wip_ma_20200821-0 | 2020-08-21 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Hey again.

Some new things in this update!

* Platforms work! It took a little bit of code to get them to work as expected,
  but now they function to impede downward motion for entities while encouraging
  non-opacity for upwards velocity. In short, they do what platforms do.

* While there's no enemies or hurtful terrain to worry about, there is a full
  four-layer stage to explore! Each stage will be somewhere around this size.
  I'm barely beneath the compression cap (which I didn't know was a thing until
  tonight) which will cause me to have some serious issues with optimizing

  Platforms use sprite flag 6, or [& 64]. The use of sprite flags have made it
  much easier to handle map collision data by associating the sprite IDs with
  these attributes. While there's only 8 flags to work with, they can be used
  as categories for further fine tuning with actual sprite IDs. Sprite flag 0
  always serves as solid collision detection on the map.

* Stage layers are decompressed (foreground and background) from a cheap and
  simple compression method which simply states [tile][amt] in hex. For example,
  the first stage layer starts off with "1204 b108" which means from the topleft
  of the stage area, it first places four tiles of ID of 18 (blank transparent).
  It then places adjacent to it eight tiles of 177 (bricks).

  This compression method, while simple, cuts the level data down to 1/3 of the
  usual size, mostly. If there's lots of the same tiles banded together
  horizontally, the compression method works extremely well. Stage 1-4's BG
  layer uses a gradient which makes it looks like this when compressed:
  This covers the entire 56 by 8 tiles of the background (16 by 8 tiles are
  not saved because the first and last 16x8 tiles for both the foreground and
  background are exactly the same to give the illusion of the looping mechanic).

* Current cart stats:
  8103/8192 tokens
  49955/65535 chars
  98% compressed size

  As you can see, I've pretty much hit the limit on both tokens and compressed
  size. I didn't think that I would need to worry so much about the third one,
  but it looks like even comments add to this percentage. I could very well
  be at the limit of the cart's virtual space and will need to look for some
  compression methods. This is the fun part! There are a lot of things which
  could be simplified.

* One thing I didn't think I would have is extra map space. I'm actually not
  using much of it at all. A lot of the space was going to be used for world
  slices and make maps out of those. It may be something to resort to in the
  future, though.

  I want to keep all the data on a single cart and not feel like I need to load
  anything from an external file. However, should I need to utilize multiple
  carts for this game (kind of like multiple CDs for games back in the day),
  it may be an option.

That's all for now!
- Goober
P#80999 2020-08-21 11:27

Cart #wip_ma_20200817-0 | 2020-08-18 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Okay! Quite a few changes in this version.

You can walk the player around on a flat solid terrain (the world collision
isn't put in yet so the only solid tiles are the ones on the very bottom). I
made sure to make the movement of the player feel smooth when jumping, yet
tight when walking left or right. It kind of works like Megaman a little bit.

Pressing Z will jump, and pressing X will attack with a little magic slice.
The player, who's name is Makeii, is a spellsword who has the ability to
change his weapon since it's made of mana. The game's weapon mechanics have
been simplified a lot (only one item slot on the top now). Holding down X will
charge Makeii up. When at full charge, he can spend an AP (the triangle meter)
to use the spell in his item slot. There aren't any spells coded in at the
moment, so all it does is reduce AP by one point.

Because there aren't a lot of buttons to use to map to things, ducking is
considered Makeii's defensive position. I'm planning to allow the two buttons
to activate a shield or to use defensive magic after charging, allowing
each spell to have two different uses. Still in the works.

I'm at 7488/8192 tokens, though. I'm going to have to find a way to compress
and save tokens as I build the game more, but the token cap isn't deterring me
from this goal. With each wip version, things get shifted around, more code
gets added, and code already added gets optimized to save tokens. It's expected
to hit and exceed the token cap in the near future, so cutting out some stuff
or making things a little more efficient will need to happen.

I found out that a pair of parenthesis counts as a single token () and
multiplying is also one token, so functions which do things like multiply
a variable by a number seems to be fine. For example, I'm using a function
called "TL(x)" which acts as a multiplier for a tile size, which all it does
is return (x*8). Three tokens for the definition of this function, and two
tokens everywhere else. I could instead use the literal pixel value, but I 
feel like that's going to happen during the late optimization phases.

Finally, comments don't add to the token count, only the char count. This is
good because a lot of variables have abbreviated names due to the small screen
space working with pico-8. I've already tripped up on some of my own variable
names which don't make a lot of sense without context.

- Goober
P#80901 2020-08-18 03:13 ( Edited 2020-08-18 04:59)

Cart #wip_ma_20200812-3 | 2020-08-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Howdy again.

Here to give you some updates on the game so far.

I've managed to save a fair amount of frames by not worrying so much about
keeping information in tables and moving data to the global namespace. What I
mean by this is instead of something like "nested.table.variables" instead
I go with "global_namespace_variable". Using the latter method will save
me lots of tokens. I've managed to add content and I'm actually lower than
my last count in the previous post (5931/8192).

The intro is pretty much done, so now all that's left is to work on gameplay.
Currently there's a test stage. You can't control the player just yet, but
it's next on my todo list. Instead you can pan the camera across the stage.

I was aiming for a huge overworld with a map you could check on, but I guess
instead I'll make it simple and keep the game stage-based, which should help
keep my token count within reason. Each stage can have multiple rooms of
varying length. I may even see about making the rooms loop horizontally, since
the game takes place in a tower.

The test area is currently manually mapped out just for visual purposes.
The parallax looks okay, except when moving slowly. In this test you can see
that I had some trouble lining up the building interior with the foreground,
but it really doesn't look all too good even if it is lined up right. I could
probably do some coding magic to alter the background tiles to interior, or
maybe I just won't be bothered to go to that extent.

Oh, also, there's a secret if you hang around long enough on the "MAGUS AORA"
title screen. :]
P#80709 2020-08-13 13:21 ( Edited 2020-08-13 13:36)

Cart #wip_ma_20200811-0 | 2020-08-11 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Some new things in this WIP since the previous version:

* Added compressed slide data and slide module. This can fill the playfield
  with a static slide. The slide data is kept as a hex string, so each char
  can hold two pixels (with values 0-3). The playfield is 112x64 pixels,
  meaning that each slide is 3584 characters long. Decompressing and drawing
  the slide once to the screen probably takes more than a whole tick, but I
  was expecting it to be a lot slower. Win win!

That looks like this, for no one asking:


* The code's been slightly overhauled in the backend. Some minor speed
  improvements and token saving. I'm really worried about hitting the max
  token amount because I'm already at 6020 / 8192. I'm nowhere near the
  character limit, so the slides mentioned above can hold lots of data while
  barely affecting the token limit.

* Attempts to keep things as modular as possible is saving me from duplicating
  a lot of code for no reason. There's always going to be exceptions, though.

* IF/ELSEIF/ELSE branches are slow when you use them frequently on every tick,
  so plans to swap those out for function references are in the works.

* Sorry for no actual gameplay. I plan to use cheap point-in-rect collision
  detection for whole-pixel movement and not worry so much about subpixel
  stuff. Velocities for actors will still retain floating point precision,
  but actors will "inch" pixel by pixel for the amount they need to move, and
  stop moving if they happen to collide with a world tile. It's simple and
  effective when moving small distances. Since the screen's resolution is
  already pretty small, and things won't move faster than 2-4 pixels at a
  time, I believe this is a great route to take.

* I want to maintain a constant 60 FPS throughout the whole experience, so
  there are going to be some corners I'll need to cut later on. The HTML5
  version chugs pretty bad on my Android device when I'm using per-pixel
  shading (the diamond effect, additive strips on the main menu and intro,
  etc). This causes the drawing FPS to drop to 30 FPS while logic is still
  kept at 60, and it's pretty evident that this can cause some issues with
  areas of the screen that don't clear/update frequently.

S'about it for now.
P#80622 2020-08-11 07:36

Cart #wip_ma_20200807-0 | 2020-08-07 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

No gameplay yet, but the main menu and stuff looks
pretty much complete for now.
You can access the cheat menu with cheat code
"< > < > O X O X" when the "MR.GOOBER" screen comes up.
There's no gameplay once the intro cutscene and dialogs play.

I'm really superstitious about showing off my work to people prematurely
because it could chance me not finishing this, but I felt like doing it
because I thought it looked cool.

I went for a 4-color style game with changeable palettes in the options
menu. I want to not use the START menu because it breaks immersion.

I'm already halfway at the token limit so I'm going to need to find some
optimizations in the code later on, I'm sure. I'm already out of sound
space, and I was really hoping to make more music for the game.

Anyway, hope you all like it.

  • Goober
P#80445 2020-08-07 07:29 ( Edited 2020-08-07 07:30)

Follow Lexaloffle:        
Generated 2021-10-21 21:45:40 | 0.091s | Q:65