Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411490 Posts in 69371 Topics- by 58428 Members - Latest Member: shelton786

April 25, 2024, 02:13:08 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsPlumber's Smile - C64 game about pipes made in Turbo Rascal
Pages: [1] 2
Print
Author Topic: Plumber's Smile - C64 game about pipes made in Turbo Rascal  (Read 9317 times)
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« on: February 13, 2020, 02:51:29 PM »



temporary logo for temporary title Smiley
Global Game Jam 2020 entry page




Plumber's Smile is my C64 work in progress game that I started to create during Global Game Jam 2020 and now I'm developing further.

Just a month before the gamejam my girlfriend bought me TheC64 - Commodore 64 fantastic replica that revived my love for this old hardware. C64 was my very first computer on which I played games and also started my adventure with programming. I started to program in Basic and as I was quite a young lad and rather quickly I've upgraded to Amiga I didn't get a chance to learn how to code seriously for old 8bit machine... but I continued to play with programming and I'm doing that to this day making games and apps.

So naturally, after checking all games built into TheC64 (plus some more I've put on my USB) I looked for some opportunities to write my games. This would also be a great time to do some break from managing my team that makes VR games and apps - doing something simpler and do some programming on my own.

One problem was I didn't like the idea I should learn C64 assembler so I tried to look for some high-level programming solution and this is how I've found Turbo Rascal Syntax Error (yep, that's not even the full name) - work in progress fully packed IDE to program in Turbo Pascal-like language for C64 (and more!) with out-of-the-box library to handle images, sprites, characters, and sound/music playback.




So, back to gamejam, it was a natural decision to code game for C64 as I already played a little with Turbo Rascal examples and tutorials. The theme of GGJ2020 was "Repair" and that's when the idea of a game about plumber fixing paths made of pipes materialized.

I did all the graphics and coding, my friend helped me creating great theme music and short jingles for the win and failure scenarios. That's how Plumber's Smile first version was done - you can check it out on Global Game Jam entry page (the link's at the top of this post). You will find there the C64 build+sources and also online emu+game pack (not recommended - use keypad to move and keypad's dot for fire).

In the game, you move our Plumber around and use fire button+direction to kick pipes to rotate them. Your goal is to fix the pipe path in a limited time per level. In this version, there are only 5 levels (not very well designed) but a great proof of concept for me Smiley


Title screen jam version


First level of jam version


The title screen is in polish as it's my native language and it just translated to Plumber's Smile as it's the main characteristic of the game's hero I wanted to highlight as you can see on the below bad sketch that I did during gamejam (more on sketches in a future post).








I liked this side project and the not-so-final result after ~48 hours of coding. This was also a great escape from my current projects and getting things done for C64 with all its limitations is very interesting stuff. I decided I will develop it further - making better graphics, more gameplay mechanics and publishing it afterward. On this devlog, I would like to write about all things done to this day and also about all future works. I would also like to make C64 retrogaming and Turbo Rascal IDE more popular. Hope you will have fun reading all of this, playing current and future version of the game. I would also really enjoy any feedback.

Cheers!
« Last Edit: February 16, 2020, 03:57:56 PM by nosferathoo » Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #1 on: February 15, 2020, 10:13:31 AM »




The thing I wanted to show first is the way I did the character design and animation. As I already mentioned the first version of the game was made during Global Game Jam in Czestochowa, Poland. The jam site was in a small university hall and one advance was a whiteboard on which everyone could brainstorm with other teammates. As I was the only one in my "team" there wasn't much brainstorming Smiley.

Instead, I let myself test the idea to transfer graphics from the whiteboard into the GIMP and then to C64 sprites. As you can see in below picture of me there's a whiteboard in the background with one frame of animation inside the square border:


It's a meeee

The idea was to use my Android phone camera plus the Office Lens app to grab only the frame inside the square border. If you don't know Office Lens it's a software that uses auto framing, rotation, scaling and perspective correction to let you photoscan documents, whiteboards and photos of presentations into one pdf or simply save as separate JPGs. Regardless of all my graphic talent shortages, I used a combination of marker+table cloth to draw every frame of animation replacing only the changing parts. Next, I transferred the images from my phone into the computer to open them in GIMP for further processing.


Look at him go

First I scaled every picture taken using Office Lens to the same resolution because, due to different positions and angles I took adjacent frames, perspective corrected results had more or less pixel count. Then every frame had to be additionally processed to be converted into C64 sprite. C64 limits the (single color) sprite size to 24x21 pixels. C64 also limits the total count of sprites that can be used at once to 8 (without some raster shenanigans). I was willing to sacrifice 4 of them for my character so they will be displayed in the 2x2 grid. That doubled possible sprite resolution to 48x42 pixels.

The entire process was the same for every frame:
0. Pump up the contrast/brightness
1. Remove all garbage - for example, the outside frame
2. Widen the lines - Select all non-white pixels, widen selection by couple pixels and fill with black
3. Scale down to 42 pixels in height
4. Paint over the final sprite on another layer


From whiteboard to C64 sprite

As you can see some sacrifices were made in the terms of details but that's reasonable taking into account C64 sprites limitations.
After working on all frames - sometimes reusing already done parts - I've finished with all needed frames that I just had to import into Turbo Rascal IDE and export as .bin files to include them into my game.

Here's an example of a walk cycle done with just 4 frames (and one is used twice) compared to the source:


From whiteboard to C64 sprite

What do you guys think about this method and the results?

Don't forget you can already check out the gamejam version of the game - link is on the top of this page just under the title.


Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #2 on: February 16, 2020, 03:57:07 PM »



Another day another post - that's because I want to get up to speed to the current state of the game after the gamejam. So next thing I would like to show and write how I approached it is the level design. It would be best to just see the final gamejam result of one level showing the main gameplay mechanic:


The main goal of the player as I already wrote before is to fix the pipes' layout on the level. You do it by approaching the tile with a pipe that has to be fixed and kick it - this results in rotating the pipe.
The "problem" was how to present the pipe tiles and I decided I will treat pipes as background as they are mostly static. To create backgrounds on C64 I had to use char maps with graphics instead of... well - characters. I decided the pipe tiles will be built from 3x3 characters and in most cases, some characters could be reused.

Here's charset I made in Turbo Rascal built-in editor, as you can see I've also made simple font replacement for titles and scores:


Every character has a resolution of 8x8 pixels in single color mode and 4x8 in multicolor due to C64 specs. All characters have indexes that I used to build my pipe tilesets with:


So all pipe configurations were specified in code using a combination of characters that should be displayed. I also had to specify to what tile another tile is transforming when a player kicks it:


Initial level setup is kept in the array 13x8 containing the tile indexes and when a player kicks the pipe he wants to rotate I'm just changing that index to adjacent one from the table above and redraw new tile on the screen. The level setup in code:


I've also managed to add simple collision detection thanks to the not-so-memory-efficient array that describes which character has a collision with simple zeros and ones:


Ufff - this post made a heavy turn into the programming side but I hope it's somehow informational to anyone reading this and from next post I will try to show more entertaining stuff as I will focus on the post-jam changes to improve graphics and gameplay Smiley


Logged

JobLeonard
Level 10
*****



View Profile
« Reply #3 on: February 17, 2020, 06:26:42 AM »

I love that he has a wrench but does his thing by kicking
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #4 on: February 17, 2020, 03:44:17 PM »

I love that he has a wrench but does his thing by kicking

Haha - I have different plans for that wrench Smiley
Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #5 on: February 22, 2020, 04:16:42 PM »


After gamejam, the first thing I wanted to upgrade was the transparent sprite of the main character. Normal sprites on C64 are 1-bit with values that represent pixels: transparent or color/opaque. Then the color of opaque pixels can be set in the program. Each sprite can be 24 pixels wide so each line of a sprite is represented by 3 bytes.

But have no fear - C64 can show multicolor sprites and this results in 3 colors + transparency... but with some budget cuts. First and foremost - the width has to be halved as 3 bytes (24bits) has to be used to represent 2 times the data for each sprite line. The second shortcoming is that two additional colors are shared by all other sprites (there's a workaround to switch these common colors using raster interrupts). After some toying around I decided that I will use black and white colors as the common ones for shading/highlights etc. and one color can be freely configured for each sprite.


Steps to add colors to the sprite

The whole coloring process you can see above was done in GIMP. The first step was to crop all unnecessary left/right borders of the sprite to limit all wasted space. Next, I colored the sprite so the background has a neutral color and details like hat and trousers will have the color of the sprite. White color was used for other parts of the body and cloth, and black for contouring.
The next step was to scale the sprite (without any filtering/sampling) to the right width and then, finally, repair all the damage and loss of detail. I placed all frames on separate layers in GIMP so I only needed to scale everything once and then repair separate layers/frames.

After coloring I imported separate frames into Turbo Rascal sprite editor to add extra shading/details and export .bin file with all frames:


Simple shading in TRSE sprite editor

The result after repainting, scaling, importing and shading:




I did the same graphics update regarding the background - currently composed of tiles with different pipe configurations. The first thing I changed was bumping the single tile size from 3x3 characters to 4x4 because I wanted to have more thick pipes with more details. I once again repainted all required chars in TRSE and this resulted with new charset (with some leftovers from the previous one):



Finally, I've combined new pipes with new sprites and this is the current look:



What do you guys think? Are these improvements good?
Logged

JobLeonard
Level 10
*****



View Profile
« Reply #6 on: February 23, 2020, 12:23:31 AM »

Yeah, it's a nice bit of polish, and a lot more "readable" to the player for sure!
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #7 on: February 24, 2020, 03:54:27 AM »

Yeah, it's a nice bit of polish, and a lot more "readable" to the player for sure!

thanks Smiley
Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #8 on: March 04, 2020, 11:07:59 AM »




last time I've added interactive obstacles that will slow down the player after being hit by them. I don't know why but from the start I've imagined this obstacle as gooey-like boing ball that will bounce from one side of the screen to another.

To animate it I've made some research and I've found ready boing ball+animation tutorial that I used as a reference (https://medium.com/pixel-grimoire/how-to-start-making-pixel-art-3-c9eb70270fa1).

First, I've made a simple silhouette of the ball with no filling for all necessary frames.


Then I've made simple radial gradient thal will serve as shading/gloss of my boing boing ball. I've made three variants of this gradient for normal, squished and stretched phases of ball movement.


I just needed to paste these gradients into all frames:


Finally, I had to make 3 more steps:
1. Scale everything to 12x21 pixels (without filtering) - because that's the maximum resolution for one multicolor sprite in c64.
2. Fix missing outline and use a neutral color for the background (for next step)
3. Limit color count to 4 (with neutral bg) with dithering


This resulted with nice boing boing ball animation with only 5 frames plus ping pong playback:


And that's how it behaves in the wild:


What do you guys think? In the next post, I will write about its behavior and how it's done.

Logged

JobLeonard
Level 10
*****



View Profile
« Reply #9 on: March 05, 2020, 01:55:21 AM »

It's the Dark Star alien!






Nice bit of stretch and squash Smiley Also, funny enough the dither kind of feels like "too good graphics" compared to the rest of the game (I think most C64 dithering was pattern based too)
Logged
Ishi
Pixelhead
Level 10
******


coffee&coding


View Profile WWW
« Reply #10 on: March 05, 2020, 11:39:39 AM »

I've been enjoying following this - it's interesting seeing the limitations of using an older system. I also enjoy the contrast of using modern tech to help, especially using that Office Lens app to help convert whiteboard drawings into sprites. Great use of the available technology Smiley

Nice bit of stretch and squash Smiley Also, funny enough the dither kind of feels like "too good graphics" compared to the rest of the game (I think most C64 dithering was pattern based too)

I didn't think of this myself but do agree, the other graphics use a very deliberate checkerboard dither pattern, and it would be more consistent to use the same dither pattern on the ball.

Something else that could be cool to try if possible would be pausing the ball's movement while it's in the first squashing-on-the-floor frame of the animation. It would make it look like it's really connecting with the floor during that squash.
Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #11 on: March 06, 2020, 03:35:05 AM »

It's the Dark Star alien!






Nice bit of stretch and squash Smiley Also, funny enough the dither kind of feels like "too good graphics" compared to the rest of the game (I think most C64 dithering was pattern based too)

I also see some resemblance Smiley
Glad you like it. I will try to put more polish on it.
Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #12 on: March 06, 2020, 03:37:14 AM »

I've been enjoying following this - it's interesting seeing the limitations of using an older system. I also enjoy the contrast of using modern tech to help, especially using that Office Lens app to help convert whiteboard drawings into sprites. Great use of the available technology Smiley

Nice bit of stretch and squash Smiley Also, funny enough the dither kind of feels like "too good graphics" compared to the rest of the game (I think most C64 dithering was pattern based too)

I didn't think of this myself but do agree, the other graphics use a very deliberate checkerboard dither pattern, and it would be more consistent to use the same dither pattern on the ball.

Something else that could be cool to try if possible would be pausing the ball's movement while it's in the first squashing-on-the-floor frame of the animation. It would make it look like it's really connecting with the floor during that squash.

Thanks for following - it's good to know somebody likes reading what I'm writing.

And thanks for the feedback - will try to put more polish on the dithering and squashy feel Smiley
Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #13 on: March 07, 2020, 10:32:02 AM »




Let's say that our boing boing ball is ready and bounces nicely from one side of the screen to another. Now I needed to implement collision detection with the player.
Little side note - the sprites on C64 are not anchored to their top border but the bottom (that's great) and not left border but the right one - that's strange for me but not a big problem.
To detect the collision I simply calculate the difference in positions of the ball and the player and if that difference is within low margin then we have collision:


So:
dx=px-bx
dy=py-by

where for the collision to occur I decided dy must be in low range (-8,8) - in short: abs(dy)<8.
For dx I decided that I will shift X position of each sprite by offset = width/2 so it will be anchored in the middle of the bottom border:


So now I only had to check if dx is less than for example 24 pixels.
The hard part was that Turbo Rascal handles integers in a fake way so for example 4-5 equals 65535 and built-in abs() function wasn't working like I expected so I wrote my own:


That's pretty much how the whole collision detection works for me. Besides that, I also check if the ball is bouncing in the direction of the player to rule out strange situations like ball bouncing back and forth inside the player's sprite. After the detection I could for a start change the direction of ball movement:


When collision started to work I wanted the player character to react with some fall animation and bounce back a little on his butt. For this I added another frame of "animation":


To simulate the bouncing on the butt I already had some math formula (y=abs(sin(x))/x) in my head I wanted to use and checked it using google's built-in graph drawing functionality. Here's the formula with some rudimentary low-budget animation that will probably present my idea better:


All I had to do was to implement this motion in Turbo Rascal for C64. The one problem was that as you may probably know Sinus function is rather slow. To avoid it sine table is precalculated beforehand and thankfully Turbo Rascal author already implemented a sine table. One characteristic about this implementation is that the sine table has 256 one-byte values from -127 to 127 that represent quantized sinus values in the range from 0 to 2*PI:


To use my formula with this sine table I had to do some changes and finally, I ended up with this:


You may notice that I replaced abs() with mod128 as it's doing the same thing in our case as sine table values from 0 to 127 are just the same as from 128 to 255 just with a different sign. The constants that I multiply or divide with are just the result of experimentation in search of the best final effect.

Finally, I ended up with a nice bounce after being pushed by the ball:


And a little close up with the formula:



« Last Edit: March 07, 2020, 10:56:51 AM by nosferathoo » Logged

JobLeonard
Level 10
*****



View Profile
« Reply #14 on: March 08, 2020, 10:23:30 AM »

That little bouncing looks really nice!
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #15 on: March 09, 2020, 03:30:49 AM »

That little bouncing looks really nice!

thanks!
Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #16 on: March 14, 2020, 10:26:50 AM »

A little sneak peek to wrench throwing <3


What do you guys think?
Logged

JobLeonard
Level 10
*****



View Profile
« Reply #17 on: March 14, 2020, 11:51:24 AM »

Looks great! I wonder though, at this point the only high contrast black/white sprite is the plumber - everything else has shading. Maybe he needs a bit of that as well.
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #18 on: March 15, 2020, 05:11:42 AM »

Looks great! I wonder though, at this point the only high contrast black/white sprite is the plumber - everything else has shading. Maybe he needs a bit of that as well.

Thanks!
As for the main character, for now, I consider it to be cartoony but I will probably tweak it a little bit when I get to the polishing phase of everything Smiley
Logged

JobLeonard
Level 10
*****



View Profile
« Reply #19 on: March 15, 2020, 09:01:18 AM »

Yeah, to be clear it's not a critique of the design itself! It's a question of whether the styles clash or complement each other Smiley
Logged
Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic