Gruniożerca 3 - The Great Cavy Clean-Up!

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233404)
Image

Guinea pigs Grunio and Dzidzia have been left home alone, and their toys are scattered everywhere! Their owners could come home any minute, so it's time for these cuddly cavies to get their clean on!

Overview

With Dzidzia's guidance, help Grunio clean up 24 increasingly messy rooms one-by-one. And don't worry if you're the frustrated type, Dzidzia can be rather generous if you're willing to beg.
Twenty-four stages not enough? You can even play as Dzidzia herself in Survival mode and see how many rooms you can clean while keeping your piggie toes off the carpet.

Controls & Accessibility

Although standard input conventions (A to accept, start to pause, etc.) have been followed, additional input methods are also accepted to allow for the entire game to be played with one hand.Typically, pressing right can confirm most selections. In fact, the only time a player *must* reach across the controller to the face buttons is while the game is paused, to restart a stage.
An inverted control scheme has also been included to allow players who either need or want to exclusively use their right hand to play more comfortably with a standard controller.

Credits & Background

Łukasz Kur programmed Gruniożerca 3, I provided the graphics, and Chip Jockey composed all original tunes for its soundtrack.
We were initially inspired by the core mechanic of the Bomb Disposal minigame of Codemasters' Ultimate Stuntman, but hope that we've expanded upon and improved on that concept enough that our title stands on its own.

Play Suggestions

Please download and enjoy yourself.
Testing on major clones and other hardware is appreciated.
The game automatically detects not only NTSC and PAL regions, but Dendy as well, and adjusts itself accordingly.
If you're playing on an emulator, we strongly suggest Mesen.
(Some features won't display as intended in other emulators, even FCEUX.)
And—as always—feedback is both welcomed and encouraged.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233405)
Ah now I can play it ^^
Oh first thing I did was to go to the credits screen and I'm sitting there for some time. The text is glitching a bit on some frames.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233408)
This was the one I was hoping for. :beer:
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233425)
Thanks for the show of enthusiasm. Updated the OP with a suggestion to use Mesen if playing on an emulator.
Some timing-based stuff and specific usage of emphasis bits, which works fine on hardware, don't in many other popular emulators.

Also, nesrocks, thanks again for your input on the car animation.
(nesrocks' style of cars seen in Super Hiking League heavily influenced my design of that scene, and direct feedback nesrocks provided via pm improved its final animation.)
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233426)
I'm not good at puzzle games but tried it this morning. Look good as usual ;)

On the title screen, there is 1 line a the top that doesn't seems part of it. I looked at the PPU viewer and everything was fine so I'm not sure why it does that. Is it on purpose? Since it will be in the overscan part it may not be an issue but still, if you're curious like me I'm sure you want to know why (or maybe you know about it already :lol:).

edit:

The music is great too ;) Looks like Tcheco is in the car in the credit :D
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233427)
@M_Tee: And it turned out totally awesome!
By the way did you try it on everdrive? I'll test it on mine ^^

Also, Chip Jockey made a song for SHL and though I liked it, I ended up closing the game's OST with someone else. I see now that he improved a lot, these songs are great!
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233430)
@Banshaku
Thanks, I'm glad you're enjoying it. The folks in the car are actually Archon and Neko, the guinea pigs' owners. Archon previously showed up in the G2 ending.

Speaking of Tcheco though, Macbee made a solid contribution to the game by suggesting a fairly complex combination of palette changes and emphasis bits being set for the transition fades. It looks great on hardware and Mesen displays it pretty accurately, but FCEUX doesn't. ㅜㅜ

The row of garbage pixels at the top is intentional, and is in all of the games we've made so far. We render our picture starting one row of pixels lower. I'll have to let Łukasz chime in on the specifics, but from what I recall, it makes sprite drawing more convenient in some way.

It'll definitely be covered up by overscan (even on a PAL system from what I've been told). I'm actually a little disappointed that Mesen, by default, displays the PAL overscan rows even when region is set to NTSC (as it makes it difficult to suggest the emulator for casual players who would be more reluctant to adjust the setting).

Anyway, I suggest setting the overscan to 8 pixels at both the top and bottom via Options-->Video-->Overscan for all games.

@nesrocks
Yeah, Chip Jockey's really talented. About half the BGM tracks in CG2 come from the Electro Body 2 album—which is from 2014, and extremely good as well.

Edit: Talking about region made me update OP with region detection information.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233431)
M_Tee wrote:
The row of garbage pixels at the top is intentional, and is in all of the games we've made so far. We render our picture starting one row of pixels lower. I'll have to let Łukasz chime in on the specifics, but from what I recall, it makes sprite drawing more convenient in some way.

It's because the PPU displays sprites one scanline lower than the actual value set for their Y coordinate, so if you also lower the background by 1 scanline, you get a perfect match between sprite and background coordinates, sparing you the trouble of compensating for that 1 scanline in collision checks and the like. You can probably make it look less glitchy if you set the scroll to 239 instead of 255 though, because you'd at least get valid NT data instead of AT data interpreted as if it were NT data.

Quote:
It'll definitely be covered up by overscan (even on a PAL system from what I've been told).

I was under the impression that all scanlines were visible in PAL.

Quote:
I'm actually a little disappointed that Mesen, by default, displays the PAL overscan rows even when region is set to NTSC (as it makes it difficult to suggest the emulator for casual players who would be more reluctant to adjust the setting).

Heh, I'm the exact opposite! As a developer, I like to see the entire picture by default, and I hate that FCEUX crops 8 scanlines from the top and bottom by default!
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233432)
M_Tee wrote:
I'm actually a little disappointed that Mesen, by default, displays the PAL overscan rows even when region is set to NTSC (as it makes it difficult to suggest the emulator for casual players who would be more reluctant to adjust the setting)
It used to cut the top/bottom 8 pixels by default, then people said they wished it didn't, so I set it to 0 instead. And now we've got the opposite problem. I wish I had a simple solution here - would be convenient if the header could be used to specify stuff like this (if only for homebrew's sake), but I imagine a lot of people would be opposed to changing this.

Beyond that, other than adding it as a database entry in Mesen's own DB (not a great option) or having it load a config file next to the ROM (e.g myrom.cfg) or something akin, I can't really see any real solution. :|
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233434)
tokumaru wrote:
I was under the impression that all scanlines were visible in PAL.
PAL (both 2C07 and UA6538) displays 252x239 pixels. Left and right two pixels, and top scanline (where sprites couldn't appear) are all black instead.

Sour wrote:
I wish I had a simple solution here - would be convenient if the header could be used to specify stuff like this (if only for homebrew's sake), but I imagine a lot of people would be opposed to changing this.
Would a usable compromise be to display 224 scanlines normally, but all 240 when any of the various Debug windows are open?
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233438)
M_Tee wrote:
@Banshaku
Thanks, I'm glad you're enjoying it. The folks in the car are actually Archon and Neko, the guinea pigs' owners. Archon previously showed up in the G2 ending.

Speaking of Tcheco though, Macbee made a solid contribution to the game by suggesting a fairly complex combination of palette changes and emphasis bits being set for the transition fades. It looks great on hardware and Mesen displays it pretty accurately, but FCEUX doesn't. ㅜㅜ


Since I never saw the ending of the second one (I suck at puzzle, mention it often :lol:) it just looked line Macbee's character to me. As for the palette fade, he gave me the same information too for my project, which makes it smoother, I do agree. I wasn't aware that FCEUX didn't support it though. I mostly test in mesen and very fast on FCEUX.

M_Tee wrote:
The row of garbage pixels at the top is intentional, and is in all of the games we've made so far. We render our picture starting one row of pixels lower. I'll have to let Łukasz chime in on the specifics, but from what I recall, it makes sprite drawing more convenient in some way.

tokumaru wrote:
It's because the PPU displays sprites one scanline lower than the actual value set for their Y coordinate, so if you also lower the background by 1 scanline, you get a perfect match between sprite and background coordinates, sparing you the trouble of compensating for that 1 scanline in collision checks and the like.


That's why my sprites where always off by 1 pixel and I though I did something wrong or something, I didn't know! :lol: I just feel better now and know that I was not crazy after all for that 1 pixel off thing.

M_Tee wrote:
Anyway, I suggest setting the overscan to 8 pixels at both the top and bottom via Options-->Video-->Overscan for all games.


I don't mind that line, I leave the overscan on to make sure I don't show weird stuff in that particular part. For my current project, it is important to confirms it. I just mentioned that line since I thought it could be a bug (but chance were low since the game was very well done) but it was not the case so everything it fine.

I will try do to an effort and reach later level but knowing myself, I'm not confident in my skills :lol: For some reason some of the artwork gave me a konami vibe but I don't know why. Maybe just my imagination.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233440)
@Banshaku
No harm done, any comparison to Macbee's work is a compliment in my book. Anyway, try dying or restarting a single stage too many times. Dzidzia might offer to help out if you're struggling with some of the puzzles. This game is more forgivig than our last in that aspect. :)

@sour
I hadn't noticed you were the developer of Mesen. I've been using for about a week now and love it, but haven't dug too deeply into its features. Thanks for your work on it.

EDIT: I realized I almost never explore the NESemDev subforum, so I found your thread in there and trimmed the section I had originally written about overscan to post there instead to keep thread on topic.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233454)
edited because my memory failed, the story didn't go like that.

M_Tee wrote:
Speaking of Tcheco though, Macbee made a solid contribution to the game by suggesting a fairly complex combination of palette changes and emphasis bits being set for the transition fades. It looks great on hardware and Mesen displays it pretty accurately, but FCEUX doesn't. ㅜㅜ

When I started making my first asm program that ran on a NES, one of the first things I did was a fading effect. It was only palette based. I showed it to Macbee and he mentioned it was possible to make it smoother by using emphasis bits. I went to to add it to the program! My code must be horrible, but I needed to have it.
If you want to check the horrible code, it is here https://nesrocks.com/blog/nes-homebrew-source-code/
It is in utils/fade_pal.asm

I tried the game on the everdrive and mesen. Something must be slipping past vblank that shouldn't.
Also, I got to level maybe 10 or something and the game crashed (sprites scatttered and then the game froze with the bg still visible). Could have been a bump in the console, but I'm not sure.

Aside from these, the game is awesome, and it shows what you get when you have 3 people who excel in their areas. I wish to one day work on a NES project in this fashion. :beer:
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233457)
Thanks for checking it. I got your twitter message as well. Łukasz mentioned being aware of the Credits glitch but just not having time to fix it prior to submission.

We spent the last week or so frantically compressing things while also adding other things. I'll either let Łukasz post about the various ways we fit stuff into the ROM. I found some of the ways he achieved things remarkably interesting.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233467)
M_Tee wrote:
@Banshaku
No harm done, any comparison to Macbee's work is a compliment in my book. Anyway, try dying or restarting a single stage too many times. Dzidzia might offer to help out if you're struggling with some of the puzzles. This game is more forgivig than our last in that aspect. :)


Macbee is helping a lot of my current project so I'm very grateful about it. I learned about Tcheco after trying his game (still need to finish it, it's hard :lol:) thus the character felt familiar in some way. I will try to play the game without using the help and see how far I go.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233471)
Got to level 12 or so. Very nice that you included solutions to everything.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#233747)
Hi, thank you everyone for the input.
Just to confirm: Yes, the top line is intentional. It doesnt renderI do this in my games for two reasons.
First is just like tokumaru has stated
Second is to actually incentivize emulator developers to improve their emulation.
You can read a bit of discussion regarding this in Cowlitz 2 topic.

Did anyone beat the game yet? Im happy with how the ending turned out, Mtee and Chip Jockey surpassed my expectations :)

As Mtee mentioned, we spend last days compressing stuff.
At some point, we run out of space to both finish Ending and Polish text translation. We decided compress the maps.
At first, I considered going from 2x2 MetaTiles to 4x4(2x2) MetaTiles, but quickly dismissed it give how many different ones would be introduceds in later stages.
Next, I turned my attention towards a method I used waaay back in Inversion, the Object based compression.
After assessing some later lavels, though, I gave up on it as it wouldnt be as effective as I hoped for.
Finally, I decided to use variable bit compression.
Quote:
Map starts with 8bit RAM offset for starting location.
The stream starts with a 2 "control" bits.
0-move with bits. Read bits to move in given direction. Next 3 bits for tile ID, more 5 bits is amount of moves.
1-small move with bits. 3 for tile and 3 for amount of moves
2-Sets Exit MT on player position. Proceeds to literal draw.
3-Carrot mode. EOR a carrot flag. This flag always starts as 0. Code fetches next control bits.

Once game finishes command 0 or 1, game will start asking for movement. Each move is 2 bits.
0-up
1-down
2-left
3-right
Once all move bits are processed, another 2 "control" bits will be given.

If code lands on tile 1F, it will replace it with currently selected MT.
If code lands on tile 0x1,0x2,0x4,0x5,0x7,0x8 it will be upgraded to higher level.
If Stair MT is selected, the MT id to be placed will include direction offset, allowing for some bit savings.
This will continue until amount of movement ends.
If Conveyor tile is selected, It makes a mini loop similiar to mode 0\1.
After amount of moves in given mode, game also expects 2 extra bits for direction in which place first Tile.
Later on the order of moving pointer and placing tile on map is reversed in the code.
The code still fetches directions as normal.
If Teleporter is selected, the amount of moves is not asked for. Instead a 8bit offset is asked.
After which, selected mode restarts.
if 8bit ofset is equal to 255, extra 4 bits will be asked.
These 4 bits will be interpreted as delay. 64 frames for single value.
These are for playing the solution and will indicate a number of frames to wait in between the moves.
This 255 offset will also *not* place a teleporter on the map.
Note: Carrot mode is turned off when control bits are fetched.
Note: Mixing 1, Explosive and Regen tiles is possible(no need to change type is tile was already placed)
Meaning, crossing regen tile while with 1 tile will upgrade regen instead of replacing.

;literal draw;
In this mode, game assumes you finished placing tiles normally.
All left are tiles that Grunio cant reach. Like ones destroyed by explosions.
Code intereprets bit stream in following manner:
6 bits - tile to place
3 bits - how many of them put on the map
8*repetition bits - map offset to put selected tile on.
Once all tiles of given id are placed, code rolls back to 6 bits for tile.
If tile ID is 0x3F, map loading is finished.

Some maps would ask too many Bytes to pathc in literal mode.
If tile ID is 0x3E, code shall ask for 8bit value for map offset and then jump to control code interpretation.

;Saving on bits;
Our MT table has 0x42 MTs. This means we need 7 bits to access all of them.
-To cut on this, we can limit our selection by MTs that are used for welldone screen.
Doing so saves us 1 bit.
-On entire 0x1X line is not required. If we create an ID list in ROM, with which we can reference
our true MT IDs,we can limit our selection to 0x1F MTs max.
Doing so saves us another 1 bit.
-If we use only 0x0F as exit, we are only 6 tiles shy of saving another bit.
If we make the code to actually upgrade tiles(when possible) instead of just placing them,
we can cut lv2 and lv3 versions of upgradeable tiles.
This allows us to place remaining 6 tiles in their place.
And so, another 1 bit was saved.
You could also remove Exit and Start points, but it has no benefit....or does it?

The ROM table should look like this:
0x01,0x04,0x07 ;These are upgradeable. Normal, Explosion and Regen
0x00,0x28,0x29 ;Stool, Start point and Carrot box
0x24,0x25,0x26,0x27 ;Stairs. Up down left right
0x0a,0x0b,0x0c,0x0d ;conveyors. up down left right
0x0e,0x0f ;teleporter and exit

-Now, we have 16 Tiles to choose from. At first, cutting down to 7 seems impossible but let us try...
We can remove Start tile(0x28) for free since its placed only at start of the level.
We can also remove (0x0F) tile as it is placed only once at end of the map.
This cuts us to 14 tiles...which doesnt saves us a 1 bit yet.
-By observing Stair tiles, we can notice that they always have to be placed in same direction to where player is moving.
If we make a control MT for Stairs instead of having all 4, we can offset correct MT by using the movement direction.
That shaves off 3 MT from our table....and shortens map bit stream a little.
-Same logic as above can be applied to Conveyor belts(with small exception, see above).
That saves another 3 MT from table.
With that, our table can be 8 MTs long, and thus can be adressed with 3 bits only.

The ROM table looks like this:
0x01,0x04,0x07 ;Its important to have upgradeables first, to make code bit easier and faster.
0x00,0x29 ;cant be upgraded, are not "special" cases.
0x24,0x0a ;special numbers for Stairs and Conveyors
0x0e ;teleporter


The great thing about this is that we also got "free" map solution reading(which would not be in game otherwise!)....so when Dzidzia is giving you a solution to the map, it reads back actual map data.

But later on we run out of space. Again.
Text was compressed with dictionary compression.
I decided to combine it with bit stream.
This one was much simpler...and I did go for bit stream compression again.
While our font is less than 64 symbols, we still have to use 6 bits to represent a single symbol. That is good, but it could be better.
First, I created two sets of symbol tables. One with very common symbols and other with less common ones. This allowed us to reduce symbol size to 5 bits.
Then, when a symbol is pulled from bit stream, it is compared to one of special cases:
Quote:
0x1F End of stream
0x1E Newline
0x1D Swap symbol table
0x1C Pull a word from dictionary
Up to 64 words. Pulls next 6bits from bitstream as ID of the word in dictionary.

This saved a good chunk of ROM too.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#234587)
I just had a chance to place this game last night, and it is an absolute blast! I love how the fun personality of the characters is reflected in the portraits and animations. My wife even had fun watching me play it, and she's not really in to games. I only had time to play half the levels last night, looking forward to checking out the rest later. :D
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#234824)
I played through a couple weeks ago. My only criticism is that it should've came out about 25 years ago so I could've played it as a kid :) . It's so well polished, the puzzles are a great mix of challenging without being frustrating and there are a lot of little things that put it over the top (like the one hand controls option or the endless mode).

As a second opinion, I brought it to my brother's house last weekend (he's less of a gamer than me but still has nestalgia). He a. demanded that I show my dad (who used to play puzzle games like lolo) and b. our wives got home and his asked him to help with something around the house... he pulled the "just one more try at this level" card, which snowballed into another 20 attempts and 30 minutes later his wife yelling at him :) which I would consider high praise. GG.
Re: Gruniożerca 3 - The Great Cavy Clean-Up!
by on (#238350)
Image

https://chipjockey.bandcamp.com/album/g ... ean-up-ost

I should have posted this a while back, but Chip Jockey released an album of the game music, including a (very good) track not in the competition build.