For this week's game, there's somewhat of a sort of a maze of crates that you can navigate and smash up.
-=-=-
As with a TON of my games, the entire level is Procedurally Generated during (and/or slightly before) play.
In this case, the maze is a series of numbered boxes scattered over a platforming environment.
Since we're working with the Calendar based system in JSE, we can use the ThisDay variable as a seed for the levels, and we'll build up our level inside the Tilemap system that JSE does fairly well.
The generator works in a number of layers.
We start by clearing out the entire level, and setting up an array to handle platform layers.
We'll also start off with some simple looking symbols for the blocks and the floor.
// Cow Pickaxe Level Method - Part One
// by Jayenkai
// Created 2025/2/10
Symbol 0,"0__;_0!;;0!;;0!;;0!;;0!;;0!;_";
Symbol 1,"0__;_0.30;;0.30;;0.30;;0.30;;0.30;;0.30;_";
Symbol 2,"0__;_03.0;;0.30;;0.30;;03.0;;030.;;03.0;_";
Symbol 3,"0__;_03.0;;0.30;;0.30;;003,0;;0.30;;03.0;_";
Symbol 4,"0__;_030030;;030030;;030030;;03.0;;0.30;;0.30;_";
Symbol 5,"0__;_03.0;;030.;;030.;;03.0;;0.30;;03.0;_";
Symbol 6,"0__;_03.0;;030.;;030.;;03.0;;030030;;03.0;_";
Symbol 7,"0__;_03.0;;0.30;;0.30;;0.30;;0.30;;0.30;_";
Symbol 8,"0__;_03.0;;030030;;030030;;03.0;;030030;;03.0;_";
Symbol 9,"0__;_03.0;;030030;;030030;;03.0;;0.30;;0.30;_";
Symbol 14,"0__B@C@";
Graphics 1920,1080,3
SeedRnd 123456 // Change this value to see different outcomes
SetTilemapSize 256,32
// Step One - Clear the Level
for x=0 to 256
for y=0 to 32
SetTile(x,y,-1) // -1 = Nothing
next
next
// Create Array to handle placements
Dim Flat(10,10)
for n=0 to 10
flat(n,0)=-1 // Reset each value to -1
next
Repeat
CLS;ResetDraw
DrawTilemap 0-MouseX()*4,0
Flip;Forever
You can run that, but you won't see anything, yet! We need to add some floors.
We'll add some platforms.
Starting on the left with all settings reset to -1, we move across and randomly spawn a platform by setting its value to something positive, and giving it a random y position.
A simple loop, really.
Stamp a platform tile when positive, or randomly respawn when negative.
// Cow Pickaxe Level Method - Part Two
// by Jayenkai
// Created 2025/2/10
Symbol 0,"0__;_0!;;0!;;0!;;0!;;0!;;0!;_";
Symbol 1,"0__;_0.30;;0.30;;0.30;;0.30;;0.30;;0.30;_";
Symbol 2,"0__;_03.0;;0.30;;0.30;;03.0;;030.;;03.0;_";
Symbol 3,"0__;_03.0;;0.30;;0.30;;003,0;;0.30;;03.0;_";
Symbol 4,"0__;_030030;;030030;;030030;;03.0;;0.30;;0.30;_";
Symbol 5,"0__;_03.0;;030.;;030.;;03.0;;0.30;;03.0;_";
Symbol 6,"0__;_03.0;;030.;;030.;;03.0;;030030;;03.0;_";
Symbol 7,"0__;_03.0;;0.30;;0.30;;0.30;;0.30;;0.30;_";
Symbol 8,"0__;_03.0;;030030;;030030;;03.0;;030030;;03.0;_";
Symbol 9,"0__;_03.0;;030030;;030030;;03.0;;0.30;;0.30;_";
Symbol 14,"0__B@C@";
Graphics 1920,1080,3
SeedRnd 123456 // Change this value to see different outcomes
SetTilemapSize 256,32
// Step One - Clear the Level
for x=0 to 256
for y=0 to 32
SetTile(x,y,-1) // -1 = Nothing
next
next
// Create Array to handle placements
Dim Flat(10,10)
for n=0 to 10
flat(n,0)=-1 // Reset each value to -1
next
// Step Two - Run left to right, placing platforms where flat(n,0)>-1
for x=0 to 256
for n=0 to 9
flat(n,0)=flat(n,0)-1 // Subtract 1 from each value
if flat(n,0)<0 and Rnd(0,20)<2 // If too low, and a random instance occurs
flat(n,0)=Rand(6,10) // This is the length of the platform
flat(n,1)=Rand(3,30) // This is the y position of the platform
endif
if flat(n,0)>=0 // If the number is positive, we'll stamp a floor tile at the given y position
SetTile(x,flat(n,1),14) // where 14 is our floor tile.
endif
next
SetTile(x,31,14) // Don't forget to add a floor to the bottom of the tilemap.
next
Repeat
CLS;ResetDraw
DrawTilemap 0-MouseX()*4,0
Flip;Forever
Run that, and you can vaguely make out the floor structure of this week's game.
Next, then, we need some of those blocks that make up the game.
We'll do another x-pass, and this time, do a secondary y loop, running bottom to top.
If the system finds a floor, it flags "block mode" and will stamp blocks up until either block mode runs out, or it hits another floor.
// Cow Pickaxe Level Method - Part Three
// by Jayenkai
// Created 2025/2/10
Symbol 0,"0__;_0!;;0!;;0!;;0!;;0!;;0!;_";
Symbol 1,"0__;_0.30;;0.30;;0.30;;0.30;;0.30;;0.30;_";
Symbol 2,"0__;_03.0;;0.30;;0.30;;03.0;;030.;;03.0;_";
Symbol 3,"0__;_03.0;;0.30;;0.30;;003,0;;0.30;;03.0;_";
Symbol 4,"0__;_030030;;030030;;030030;;03.0;;0.30;;0.30;_";
Symbol 5,"0__;_03.0;;030.;;030.;;03.0;;0.30;;03.0;_";
Symbol 6,"0__;_03.0;;030.;;030.;;03.0;;030030;;03.0;_";
Symbol 7,"0__;_03.0;;0.30;;0.30;;0.30;;0.30;;0.30;_";
Symbol 8,"0__;_03.0;;030030;;030030;;03.0;;030030;;03.0;_";
Symbol 9,"0__;_03.0;;030030;;030030;;03.0;;0.30;;0.30;_";
Symbol 14,"0__B@C@";
Graphics 1920,1080,3
SeedRnd 123456 // Change this value to see different outcomes
SetTilemapSize 256,32
// Step One - Clear the Level
for x=0 to 256
for y=0 to 32
SetTile(x,y,-1) // -1 = Nothing
next
next
// Create Array to handle placements
Dim Flat(10,10)
for n=0 to 10
flat(n,0)=-1 // Reset each value to -1
next
// Step Two - Run left to right, placing platforms where flat(n,0)>-1
for x=0 to 256
for n=0 to 9
flat(n,0)=flat(n,0)-1 // Subtract 1 from each value
if flat(n,0)<0 and Rnd(0,20)<2 // If too low, and a random instance occurs
flat(n,0)=Rand(6,10) // This is the length of the platform
flat(n,1)=Rand(3,30) // This is the y position of the platform
endif
if flat(n,0)>=0 // If the number is positive, we'll stamp a floor tile at the given y position
SetTile(x,flat(n,1),14) // where 14 is our floor tile.
endif
next
SetTile(x,31,14) // Don't forget to add a floor to the bottom of the tilemap.
next
// Step Three - Add blocks
for x=0 to 256
BlockMode=0
for y=31 to 0 step -1
i=GetTile(x,y)
// Check current tile
if i==14 then BlockMode=Rand(3,5) // If Floor, set to a random number
if i==-1 and BlockMode>0 then SetTile x,y,BlockMode;Blockmode=Blockmode-1
next
next
Repeat
CLS;ResetDraw
DrawTilemap 0-MouseX()*4,0
Flip;Forever
And that's .. more or less.. how the levels are built in this game.
Obviously things are slightly different in the final game. There's a much shorter level for starters, as I found that 256 wide levels felt too big for the way the game played. They're actually only 64 tiles wide in the final game, to help the game "feel" a little more beatable.
Also, the block counts are inverted and a little more randomness is put into their placement.
There's also the fact that, the further to the right the builder goes, in the final version, the higher the blocks tend to be, and there's also the odd line with no blocks at all, giving the player to hop up, and smash at the bottom of a pile.
But as far as a starting point goes, I hope this little example helps you understand the level layout a little better.
As with a lot of my ProcGen levels, I actually worked on the player physics AFTER building the groundwork of these levels. I've found that it's much easier to tweak player physics to fit a world I can see, than it is to try to build a level generator that works with player physics I've already locked down.
The "fun" of making this game, for me, was trying to figure out what to do within the level, once I'd placed the basic cow inside the level. Deciding on what elements do or don't work.
Things like.. Tweaking the timing of the falling blocks so that "usually" you can run under a pile if you dig fast enough, but how that doesn't always work out.
Things like.. Just how high the player should be able to jump, and whether they should be able to reach 4 or 5 or even 6 blocks high when jumping.
And then discovering things whilst playing the game, like how you were able to jump up through a gap, land in-between two higher-value blocks, and were permanently stuck, so I had to add "chippable" blocks that would reduce in value after enough hitting, so that the randomness of the levels didn't end up with the player getting into a fix.
If the building of the level is the first 10% of the game, the next 30 or 40% is figuring out the gameplay, and only once that's all in place can you start to do the balancing, and then popping all the other bits and pieces into play, like the scoring, and the sounds and whatnot.
It's not an easy job doing AGameAWeek, but seeing a simple level generator become a fully fledged game is one of the highpoints that I get to experience a ton.
And I love that bit
[verse]
It's the little bits that I enjoy,
The tweaking of the values.
Rearranging stacks of blocks,
And pickups that you can use.
Redirecting bits of code,
To make things slightly skewed.
And layering the changes,
So it's hidden out of view.
[chorus]
Making a new game. Making the fun.
Sometimes it's hard. But too often I've won,
At the game of game making, Every week.
It's the things that I do. It's the language I speak.
[break]
[Verse 2]
Typing out each wall and floor,
One by one in lines of code.
Placing enemies just right,
Danger, danger.. Might explode.
I add a goto, and return a print.
Forming floors and walls and doors,
A for loop for the windows,
While I'm building more and more.
[break]
[chorus]
Making a new game. Making the fun.
Sometimes it's hard. But too often I've won,
At the game of game making, Every week.
It's the things that I do. It's the language I speak.
[break]
[bridge]
Numbers shift, the layout bends,
Watch the blocks, where will they end?
Form worlds within the nested loops,
Then pile on lots of enemy troops.
Scrolling maps and moving doors,
lifts that rise from off the floor.
A tiny tweak, a quick redraw,
And now it plays like never before.
[break]
[chorus]
Making a new game. Making the fun.
Sometimes it's hard. But too often I've won,
At the game of game making, Every week.
It's the things that I do. It's the language I speak.
[Dave sits on his couch, playing Tetris on his old Gameboy, just like the good old days.]
Dave: [To Lady Computer] In them days, all we had was black and white. Well, Green and Dark Green, but don't say that to Greenie or he gets upset.
[Lady Computer displays a picture of a Game Gear]
Dave: Not without plugging it in. Nah, the Gameboy was awesome, because you could literally play all day.
[A small bubble floats past]
Dave: Hmm.
[Dave continues playing]
Dave: It was Tetris though. That was the big seller. That and Blaster Master.
[Another bubble drifts past, this one slightly bigger]
Dave: That's... probably fine.
[Takes a sip from his ever-present Coke can, whilst Lady Computer displays a bubble warning symbol]
Dave: It's fine, don't worry about it. It's perfectly normal to have the occasional bubble.
[A huge bubble emerges from behind the TV like an ominous monster, rising from inside a nightmare]
Dave: Though... I don't actually remember installing any bubble generators... Especially not behind the telly.
[Dave pauses his game, as another bubble floats up from under the door]
Dave: Right. Minor investigation needed. Nothing to panic about.
[Dave gets up and opens the living room door]
Dave: Let's see... they seem to be coming from... oh no...
[A myriad of bubbles float in from the hallway]
Dave: That's not supposed to be doing that.
[A larger bubble emerges from the machine]
Dave: I think there may be too much fizz!!
[Lady Computer displays "CALL GREEN"]
Dave: [shouting over the silence of bubbles] No no, this is fine! This is research! Important research! Like my cola collection organization methods!
[More and more bubbles surround Dave]
Dave: Maybe I should call Greenie!
[End Credits roll]
Views 485, Upvotes 4
Daily Blog
,
Procgen
New games every week!
Places
Archives
Site credits : This was all done by Jayenkai
(c) Jayenkai 2023 and onwards, RSS feed
88
Blog - 🐄⛏️ - 11 - Build a Cow a Level - AGameAWeek