I guess, what I'm wondering about is twofold...
Do you think rollback netcode can be implemented in a cart without consuming a ton of it's resources... and do you think a cart with that level of netplay (within the remaining resources) has an audience it would appeal to? Granted, this is major feature-creep territory for any project scaled to P8 in the first place, but again, that's why it's a theoretical discussion...
Still chipping away at sound design and _update() sections of my other projects. Little by little, they're going somewhere, or so I'm telling myself.
But this season hit some high traffic at work, as expected, so in light of having any real concentration-allowing downtime, I started visuals on what I'm hoping may turn into a "fundamentalist Terraria" project I'm simply calling Terra.
This little 32x16 chunk; sprites 126-127, is the biome metamap which defines the whole 416-screen world:
While some of these screens will be packed solid, or have little notches of ore carved out of them, a good chunk of screens will also be tunneled/mapped by applying variants of these other (lower end) tiles; often meant to mash in some treasure hunting and world structure. I'll probably also have to use some manual scripting to input minecart tracks and space for their use.
The top section is the player and basic objects/platforms in the game, and the middle section is enemies/creatures. I'll probably put some more "player head" variants in there for humanoid enemy types. I'm hoping to make four boss creatures, one for each corner of the map area (??); and maybe a 3-minute day/3-minute night cycle. Something you can mash through in a 15-30 minute sitting, but still full of surprises and exploration, you know?
DISCLAIMER: This isn't a replacement or a diversion from my ongoing projects. I'm at sound design and update functions on many of those now (trickling away little by little); this is either aimed toward a future project, or a thing you can just take on yourself should you choose to.
But in this thread!
I'd like to toss around some ideas for a modular "escape room" cart. Ways to use stuff like creative recursion, math and word and logic puzzles and so forth to make a dynamic mystery adventure that's really just layers of solving things; but concise enough to fit in a PICO-cart.
If you've never done an escape room before, or have played anything like the Zero Escape games: An escape room consists of a network of intermingled puzzles and clues... so that the solution to one puzzle results in acquiring information or items that are then used to solve additional puzzles. Typically there are 3-5 "layers" of these puzzles of varying breadth - with each "layer" consisting of 1-4 types of puzzles - and then later layers of puzzles can reuse elements of the earlier puzzles in new and different ways - or the rewards for solving those puzzles can.
https://lockpaperscissors.co/craft-1st-escape-room
Integrating this into PICO-8 in a modular fashion is the part that may make or break this. Clearly, it'll have to use a distinct set of puzzle types that are fun to play in PICO's controls and scope; as well as code/hint generation tools... then having some cohesive theme and plot generation in play. It might also be possible to integrate some basic-stripped versions of typical video game play as part of the excitement!
There's also the choice to make this (primarily) sidescrolling, top-down-adventure interactive, or menu-driven. Each comes with upsides and tradeoffs, and there's no reason each one couldn't work nicely.
So... let's spitball! What kinds of puzzles, themes, and approaches do you think would be best for this kind of project? Do you think making a "video gamey" version of this could do something unique?
I am an idiot that needs to move on to BGM stuff, basic AI, and update code. Still got a fair amount of coding on all of my projects to do, and for some reason, I've recently been jamming out a PICO-8 demake of Spiral Knights, or at least the base stuff of it. Don't know if I'll ever get the online multiplayer aspect of it, but the semi-random Zeldalike quality of the game is more than enough to make fun. Sprites and a fair chunk of map data done, code isn't even started yet.
Infinitroid has been a great inspiration to simplify and revisit Gentroid, where now instead of having code try to write a Super Metroidy world, has really been simplified to a handful of environments that are mostly horizontal in nature with isolated elevator rooms, item rooms, and maybe miniboss rooms. And now that I've learned you can recolor/tint sprites, I've revised many of the repeated items to make more creatures. All in due time, I suppose...
I've been plucking away, a function or two a day, or a SFX, or a handful of sprites, etc. Still just mashing on my days off and lunch breaks. Starting to see some little tidbits of going somewhere, at least.
Anyways, I ran into a thing I could use someone with a little deeper expertise in dealing with.
I'm devising a kind of proc-gen DDR game/song generator, using four hex-character seeds to implement 12 randomizable sequencers*, which are then used to pull table data and plant music data structurally (and then apply stepchart logic to that). The part in particular I'm needing help with is making a few functions that can universally change the speed, octave, and instrument choice of a selection of SFX (32-62, in fact - 00-31 only need speed adjusted since they're bass/percussion layers), maybe one to change the speed of one SFX in particular (for multiplied-speed layering after that).
I'm not 100% sure where the "poke" ranges I need to target for that kind of thing are.
This is some really good stuff, certainly worth a dig. It's the kind of thing I've been trying to get into with dynamic level generation, eventually. There's a lot of ways to apply these principles, too!
https://www.rockpapershotgun.com/2017/03/10/how-unexplored-generates-great-roguelike-dungeons/
Was running through some theoretical stuff in my "idearrhea" at work the other day - it does seem like the idea behind P8 structure is creative recursion. So, while a few things I've worked on have been tiled up as you'd expect in the map editor... I got to thinking about a thing and how it could be implemented.
The thing I think I want to pull off is to commit the second two pages of sprite data to pixel-point maps of tiles, and then to put THOSE in the map editor. So, instead of rendering realtime maps, it could read each pixel of the map data, and then generate a tile based on the color of said pixel... in order to make a map that's 32x the size of the map data!! Bonus: then the "pause" button can be used to simply display the pixelled data, and you get an instant minimap!
Sure, you'd have to get a bit creative in how the data itself is interpreted - maybe a chunking out squares of biomes where the same tile data is interpreted differently (or upon game start, probabilistically), as well as manually adding some objects after that on a per-scene/screen basis... but it's more to the effect of creating bigger gameworlds.
I guess eventually I'd like to pan this idea out into something Terraria-like? But way more simplified. I'm really just making this post to put the idea out there, though... because I think this is ALREADY how the map data in the cart works to begin with... so then decoding map tiles into sprites, and THOSE sprites into additional grids of sprites...
YO, DAWG.
I HEARD YOU LIKE FANTASY CONSOLES. SO NOW WE PUT A FANTASY CONSOLE IN YOUR FANTASY CONSOLE, SO NOW YOU CAN PLAY YOUR FANTASY CONSOLE IN YOUR FANTASY CONSOLE!!
...and THEN you can put THAT in VOXATRON, TOO!!!
IT'S CONSOLECEPTION!!! XD
For reals, though: I'm astonished at how simplifying constraints EVEN FURTHER has resulted in considerably more games being produced, what looks like considerably more rapidly!!! Just... WOW.
I love you crazy bastards!
PS: So... how long until we integrate this with Splore, to make a game about playing all these games?
Alright. I'm finally getting somewhere with my level code, physics, and... well, I'm still WORKING on my composition stuff, too. But now I'm also starting to work on enemy AI. And here's another spot I'm kind of fresh to.
See, past projects I've worked on include fighting games - which are essentially just really big FSMs, and the AI uses some conditions like player distance or input to determine appropriate responses (some MegaMan bosses do this, too)... and music games, which is really just about lining up targets with precise timing and that's really all there is to it. Making shots doesn't seem any different than making fireballs in SF, either. But making enemy AI for platformer and top-down-adventure games is kind of a different thing; and I could use some guidance - heck, maybe even outright collaboration with.
There's four titles of enemies I'm trying to reasonably replicate here:
200X - a MegaMan knockoff.
Concert of the Damned - something between Zelda II and SotN, maybe a little Shovel Knighty too.
Gentroid - Yet Another Metroid Fangame (there's a good grip of these, it seems - and Cow has the physics/feel to that DOWN! Perhaps I should just step aside...)
...and an as-of-yet-to-be-determined title that's in line with Zelda 1 and/or Gauntlet; maybe a bit Isaacy, but certainly not Isaac. Save for maybe boss influence, we'll see where that goes.
How do some of you do your enemy AI? I know really simple stuff could be handled by my "MakeTarget()" code, but not stuff that depends on terrain contact. "MakeTarget()" is mainly about making basic movement patterns - lateral, vertical, sine-waved values, diagonals, circles or semicircles, that kind of thing.
function maketarget(obj,scr,x,y,xrange or 0,yrange or 0,speed or 0,loop or 0) --x/y position relative to map obj.p.x=((scr\5)*16+x) obj.p.y=((scr/5)*16+y) --set sine motions to control local movex=2*sqrt(xrange)*speed local movey=2*sqrt(yrange)*speed --reverse direction! if (movex=xrange or movex=-xrange or xrange<0) movex*=-1 if (movey=yrange or movey=-yrange or yrange<0) movey*=-1 --diagonals or curves if loop=1 then movex=xrange elseif loop=-1 then movex-=xrange end |
So, I'm going for some modular map usage, and in the interest of map management, I need to learn of a way to make "scroll cuts" and "jump cuts" between segments. For instance, the "Concert of the Damned" map is broken up into pathways that exit to the left and right, and the top and bottom. The "green blocks" indicate doorways that will jump the character into the next scene upon collision. But don't let the layout fool you! Since the map is modular, each of these scenes doesn't just connect to it's neighbor, they're designed to cross-script to one another. 200x on the other hand, scripts gameplay mechanics into the segments and warps between them, but I also need to preserve the scrolling within each scene, while not scrolling to the other scenes in visible range (perpindicularly). The screenshot for it shows horizontal corridors, but I have a section of vertical ones as well; so it's not just as simple as only scrolling on the X-axis.
What I need is a way to cut the scrolling at the ends of the screens, and jump-cut to another segment of the map; while preserving the scrolling in the segments themselves. Any code monkeys care to give me a little tutorial on that?
So... I guess what I'm aiming for is a back-calculating method for controlling player movement, via globals. So, let's say I'm wanting a typical jump-to-same-level duration to be 90 frames; and for it to go up 3.5 "tiles" of 8 pixels apiece; with a 0.8x accel/decel rate (gravrate). I define the jumpheight as 28 (pixels) and the jumptime as 45 (ground-to-apex; so half of 90), and then use that to calculate jumpvelocity.
My usual go-to is jumpvel=2sqrt(gravity tiles * gravrate), and then letting the typical gravity accel/decel take over from there. "gravity" is seperate from gravrate, in case I want to disable it (by making it 0) reverse it (by making it -1), or reducing it (making it a decimal, usually between 0.5 and 1).
Also, working on a similar accel/decel for horizontal walk/runspeed... so let's say I'm aiming at 0.3 px/frame to be the max speed (18 pixels a second, or a little over 2 tiles, so you can jump four across, level-to-level)... I still want a 20-frame accel and 10-frame decel delta to that, to give some fluidity to the player's motion, it's not all "everything or nothing." So the actual velocity is like "0.3 - (0.015 * runframes, if less than 20)" and then at release, setting that value to 20 and reducing it 2 at a time so that the calculation still affects the movement speed.
...
I think I'm losing my mind though, so am I still doing this right? >.>
I'm increasingly forgetting stuff, and when I'm working and calculating, it's interfering with my work - and THEN when I'm off, I'm no longer calculating, and everything's kind of getting messy. Dammit!!
So, election and holiday season both got pretty crazy up until last week. So most of my PICO-dev has been during lunch breaks and to/from work or in little spurts on days off. That said... I probably get about 16-32 sprites, or 4-8 screens of map writing done, maybe a function per toss. That said, a fair number of these can reuse some code I use, which is a good thing; because I can concentrate most of my code into one project, iterate it to working condition, then copypaste and adapt it to other carts. All things considered, I still wish I could've been getting more accomplished by now; maybe it's just impatience talking... I see a fair number of good carts being pushed, maybe that's the thing.
These include Concert of the Damned (really, I've only reworked the maps so far), 200x (pictured above... if 20xx was the proc-gen response to MegaMan X, this is me trying to do that with MegaMan Classic or Xtreme, if it were meshed with MM9's Endless Attack mode), Gentroid (same approach but more Classic Metroid inspired), a simply-titled "PlayThing" (just an experiment for learning various things in PICO-8; where I'm currently focusing my code for the time being), "Race to Riches" (a simple speed platformer inspired by David Newton's "Treasure Tower"), and "Shirley Nutt" (a nut-collecting demake of Sonic, but where you can shoot nuts forward to control space ahead of you, and with none of the asinine plot or buddies or loop-de-loops, or even bosses).
Matter of fact, I have two experimental "Playthings." XD I started one on my PC, and a second, different-but-similar sort of one on my PocketCHIP. There's some ground they have in common but I have to kind of match up the factors and really make one do something.
So... one of the things in my tinkering cart that I'm playing with is sprite complexity. The idea here is to associate the player position with the body, then draw the head relative to the player position, and finally, layer the expression on top of the head (unless it's facing up/away), and recolor as appropriate. It's not just the player that'll be using the build, but many enemies and NPCs as well, of course, so I'm trying to plan a "DRAWBODY(..)" function to draw the whole thing in one swoop.
So far, I'm thinking important factors are:
-x and y positions
-body frame
-colors of body
-relative head x/y
-head color/sprite
-eye expression/color
-facial expression/color
...but I get the feeling I might be forgetting something here?
So, in between lunch breaks, I've made tiny-but-significant progress in my level generation code. It's part of a "bigger picture" thing, and meant to be useful across multiple projects; since I'm kind of digging into proc-gen core gaming. Even this little project is a proof-of-concept of a major undertaking, depending on if I can squish this into tokens available.
The idea here is to take a number of levels "LV" and make each one a 15-plus-one table - the first 15 being a kind of "perlin noise" function used to script "rooms" into the level, and the last being a control variable "BIOME" which influences the level's colors, themed elements, etc. I'm planning on coupling this with horizontal and vertical "targets" - ones to collect, ones to avoid, ones to attack, etc. Well, a "target" can be oriented both vertically and horizontally, and in varying speeds (more on this after my next WIP major chunk of code, "MAKETARGET()").
So MAKELEVEL(3) would generate 3 "output" tables:
LVL1={n1,n2...n15,biome}
LVL2={n1,n2...n15,biome}
LVL3={n1,n2...n15,biome}
...and then these tables will define the 5x3 screen map of each level.
I'll have to add "biome control" in later scripting, depending on the kind of game it generates, after the level generation. The "doorway" table definition occurs BEFORE it runs... for instance, it makes sense for a platformer to limit "doorways" to being {0,4,5,9,10,14}, where in top-down adventure or RPG games, it could be anywhere.
That said... still checking this for proper P8 syntax, and to see if it can be simplified. Being intermediate-level at best, I have the suspicion this can be streamlined a little bit still. Maybe even a lot.
function makelevel(lv or 15) if (lv>15) lv=15 winlevel=lv for lv>0, do "lvl"lv={} level={scr1=0,scr2=0,scr3=0,scr4=0,scr5=0,scr6=0,scr7=0,scr8=0,scr9=0,scr10=0,scr11=0,scr12=0,scr13=0,scr14=0,scr15=0,biome} -- create sequence of 16 doors -- we don't have to use them all doorshuf={rnd(1,6),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5)} ezpath={} hdpath={} d=0 n=1 for n=1 to lv do d+=doorshuf(n) add doorlist (return doorways,d) n+=1 end --each exit makes a short, --high-risk way, then a long --low-risk alternative for n=1 to lv do stdoor=doorlist(n) endoor=doorlist(n+1) --vertical paths? vstep=(stdoor/5)-(endoor/5) if (vstep<0) vstep*=-1 --horizontal paths? hstep=(stdoor\5)-(endoor\5) if (hstep<0) hstep*=-1 --add values to paths for n=vstep to 0 do if (stdoor/5)<(endoor/5) then add ezpath "5" add hdpath "5" else add ezpath "-5" add hdpath "-5" vstep-=1 end for n=hstep to 0 do if (stdoor\5)<(endoor\5) then add ezpath "1" add hdpath "1" else add ezpath "-1" add hdpath "-1" hstep-=1 end end add ezpath {"1","-1","5","-5"} if (#hdpath<3) add hdpath{"1","-1"} --shuffle ezpath/hdpath order shuf(ezpath) shuf(hdpath) --read paths, edit level table local pos=stdoor for i=#hdpath,2,-1 do local step={ -1=(makelevel(pos)+=18,makelevel(pos-1)+=4,pos-=1), 1=(makelevel(pos)+=20,makelevel(pos+1)+=2,pos+=1), -5=(makelevel(pos)+=17,makelevel(pos-5)+=8,pos-=5), 5=(makelevel(pos)+=24,makelevel(pos+5)+=1,pos+=5)} end local pos=stdoor for i=#ezpath,2,-1 do local step={ -1=(makelevel(pos)+=2,makelevel(pos-1)+=4,pos-=1), 1=(makelevel(pos)+=4,makelevel(pos+1)+=2,pos+=1), -5=(makelevel(pos)+=1,makelevel(pos-5)+=8,pos-=5), 5=(makelevel(pos)+=8,makelevel(pos+5)+=1,pos+=5)} end --return generated results as a --list of "lvl1,lvl2" tables... return "lvl"lv{}=level{} end end |
Proposing a DKC inspired cart, based mainly on the funner parts that DKC is known for. Priorities: Barrel Cannon sequences/mazes, mine cart levels, rocket barrel levels, maybe bird buddy / flying or fish buddy / swimming stages... and then maybe after all that, if there's space left... we can squeeze in some platforming.
Takers?
Well... trying to make some dynamic level generation script - it's a thing I've been digging into, lately... and kind of fuzzy on implementing it.
So, the idea is that the main playmap area is 3 screens tall, 5 screens across; and ultimately, represented as a table like:
LVL1={/leveltype,scr1,scr2,scr3,scr4...scr15} (where scr1 for instance, is a perlin noise variable that indicates where it joins with other screens... so if it were "4," it would open to the right (up=1, left=2, right=4, down=8). LVL1-LVL15 each do this.
I have a table called DOORWAYS={1,6,11,5,10,15} ...these are the screen IDs that can contain doorways. And then one that's DOORSHUF={RND(1,6),RND(1,5),RND(1,5)...} - the idea is that the starting door from level 1 is the first variable, and it references "DOORWAYS" to place the appropriate door - then every door thereafter is made by adding the next "n" of DOORSHUF to the previous one, and if need be, subtracting 6 from it until the table finishes, and returning those values to a DOORLIST table that should end up looking like either (16 values of 1 through 6, to reference DOORWAYS) or (16 values of DOORWAYS that always alternate).
From there, I'm aiming at taking THAT table, and having each of 15 levels take that sequence, and concoct a "fast road" that's high risk, rewarding, but very direct toward the next door; and a "slow road" that's safer but winding (at least 7 "screens" in sequence)... the two paths can cross, too. The path generation basically adds the appropriate openings to scr1, scr2, etc. (and doesn't really matter which way it generates, since that's just the openings on the screens); and calculates via +/-1s and +/-5s (trying to devise a way to prevent calculative wrapping... so "5 to 6" has to do a "+5" and 4 "-1s" rather than a +1... so that too)...
Anybody else here mess with this kind of thing and get it to work right, by chance?
In progress:
DOORWAYS={1,6,11,5,10,15} FUNCTION MAKELEVEL(BIOME,SCR1=0,SCR2=0,SCR3=0,SCR4=0,SCR5=0,SCR6=0,SCR7=0,SCR8=0,SCR9=0,SCR10=0,SCR11=0,SCR12=0,SCR13=0,SCR14=0,SCR15=0) --CREATE SEQUENCE OF 16 DOORS DOORSHUF={RND(1,6),RND(1,5),RND(1,5)...} D=0 N=1 FOR N=1 TO 15 DO D+=DOORSHUF(N) ADD DOORLIST (RETURN DOORWAYS,D) N+=1 NEXT |
Well, THIS was a surprising side of myself to find coming to life while messing with PICO-8. Little as I've been able to really sit down and focus, I've actually started getting more into hardware and Linux now as a result of my exposure to it! I've already built a "Picade Console unit," and got that loaded up with some games... for some weird reason, Emulation Station still having trouble launching PICO-8, even though it can see the games there for it. I've done the "sudo chmod +rwx pico8" thing too. But nevertheless, the controller/unit was FUN to build, and that's something I really haven't done in a good ten years now. I'm up and playing a bunch of cool classics with it, too! I'm probably gonna get a full Picade Cabinet kit when they become available again, too! :D
Also, after MUCH delibration, my PocketCHIP finally shipped as well! It's only been a day now, and I had to do some calibration to the touch screen, but developing for PICO with it is still fun and solid! The somewhat nonstandard punctuation is a little tricky at first; but once you get acquainted a bit, it's pretty solid. I didn't have as much trouble hitting diagonals as I expected to have, from what I've heard here - but getting my right thumb back on the 0/+ keys (the Pocket edition equivalent of o/x or z/x) usually involved me looking away from the screen for the placement. It also felt weird trying to compose sound with "Q 2 W 3 E 4 R T 6 Y 7 U" since the number keys THEMSELVES were in a piano-like arrangement at the top of the screen (that might be one version difference worth considering); but once I popped up an octave and stuck to "Z S X D C F V B H N J M," it wasn't so bad. Then if I needed the top octave, I'd just change that bit in the tracker view. Editing sprites, maps, and even code felt natural as feck, though. And it's kind of a neat touch that it boots in Splore mode... but I can understand why the regular version doesn't do that.
It also feels REAL DAMN GOOD to have my first entire weekend off since June. T.T But I suppose without that intense grind, I wouldn't be swimming in all the cool nerdy wares I have going on now! And it's all 100% thanks to the PICO-8 community.
A PICO-8 social game that revolves around the two things PICO-8 lovers love to do:
-Making PICO games
-Playing PICO games (ala "Splore"?)
Now, granted... there should be a fun game within this itself, too. So, you're a Pico in some PicoSpace that you can deck out (a general Pico theme, maybe a Migli/Celeste/Classic Arcade/couple other themed sets of assets?), maybe a set of background tracks you can buy as singles and swap to in your pad - which will become the default BGM there... or on the go, with headphones (to overwrite the in-game track with the one of your choice)... and the two meaty parts of the game: going to the "Splorecade" to run an arcade-simulator version of Splore, and the Game Store, which lets you "buy" (IE: download) P8.PNG carts to run on your home Pico-88 system, or later your portable PicoBabe system!
Now, how do we make this social? How do we make feedback to each other with this, and/or share our PicoSpaces with each other? I know we can save a few simple strings like "what we're working on," "a game we played recently and really like" - or maybe we can just check our hearts/stars database here through the internet to get that data on the fly! Or what kinds of things we're have trouble with, so we can get/give development advice to one another. Also, there should be some way to play in each other's PicoSpace too, so we can leave each other notes and so forth.
Talk with me here. What do you think we could pull off, like this?
"Feature Creep Talk:"
I'd like to pull off customizable fighting~platforming movesets and powerups; so internal minigame segments can be like little competitive platformer games, fighting games, simplified beat'em ups (think GaiAttack from Retro Game Crunch), and side-scrolling shmups. Some kind of in-game puzzle or pinball game may be cool too (especially because the pinball elements can coincide with platforming somewhat), but that might be getting into "too crazy" boundaries, given "tokens vs. scope" and all.
"GaiAttack" here:
[youtube]a2dlB2EAgNQ