Sunday, 22 March 2020

Two Level Demo

It's been a difficult couple of weeks for everyone (and by that I mean the entire World) with the onset of Covid-19 across the globe.

Therefore, to spread a little bit of love and cheer, I've decided to release a 2 level demo version of Chiller 2!

First a word of warning!  The game has not undergone extensive play testing yet by anyone else other than me, so some may find it a little hard!  After the play testing is complete, there are lots of tweaks that can be made to make things easier if required.  It has already been discussed that perhaps energy will be reset between levels and/or energy being 'topped-up' during play somehow.

This demo aims to give a little taster of the type of game it will be!


On the title screen, select either to play as the boy or the girl by pulling left or right on the joystick.  The boy is ' stronger' than the girl so can take collisions and lose energy a little slower than the girl.  However, the girl is a little lighter than the boy, so when jumping will stay in the air just a fraction longer making it easier to cross larger gaps or reach higher platforms.  Choose carefully, then press fire to play!

The aim of the game is to collect 20 crosses on each level to progress to the next level.  Each cross collected adds '1' to the cross counter in the middle of the status panel at the bottom of the screen and '100' to your score on the left of the status panel, as in the screen below.


Move your character around the level using the joystick, left and right to move.  A single fire button press activates 'jump'.  Holding down fire enables a double-jump; some 'platforms' may initially appear too high to reach with one fire button press so holding down the button and double-jumping means the character will jump up to the platform and then jump again.

Gravity is always active in the game, so walking off the edge of a platform will result in your character falling down the screen.  There is no limit as to how high you can fall from and no energy is lost.

If your character touches an enemy or certain parts of the scenery such as mushrooms, then energy is lost from your energy bar at the very bottom of the status panel.  Collision with enemies is quite 'loose' so they can often be passed without energy loss even if a few pixels are overlapping.  Mushrooms will only drain energy if they are walked over or fallen on.  You can jump up through or past them without energy loss.

A few tips!

Although the player character can move relatively quickly, rushing about is a guaranteed way of losing energy very quickly, ending the game.

Each level has been purposefully designed to be a type of 'puzzle' with some routes through being more optimal than others.  Take your time and plan your path; there is no time limit so you can stop and think.  Use strategy!  There are safe places on the levels where you can stand without fear of enemies crashing into you!

While stopping, watch and learn the enemy patrol routes.  Timing your jumps between and over them will result in more success!

The game ends when you run out of energy.

Please have fun, but more importantly, ensure you and your loved ones stay safe during these troubled times.

To play the 2 level demo, you can download it here...

You can also download the game preview from CSDb here...

TRIAD have released a cracked version which you can download from CSDb here...

Next diary entry coming soon...

Friday, 6 March 2020

Machine Detection Intro

I've spent twenty minutes today adding a *tiny* (and simple) little intro screen to the game before the main title screen appears.  This intro displays information about the type of machine the game is being played on as detected by the code added yesterday in the previous diary entry here...

This intro informs the user the machine type being used (PAL or NTSC) and the fact that the music and sound was designed for an 8580 SID chip.

It also gives me a chance to use the 'Cosine' sprites that I designed months ago and that have been languishing in the sprite bank unseen and unused up until now!  The sprites and messages look a little like this when running in WinVICE using NTSC...


Obviously, the message changes to PAL if such a machine is being used.

I'll own up to hacking my own code a bit!  The game essentially uses two 'modes', title screen on or title screen off, which is stored in a label called 'title_mode'.  When title screen is off, the game is in play - the two modes use slightly different code branches.  For example, the colour washing of text on the title screen is handled in one of my IRQ splits, but when the title screen mode is off, the colour washing code is skipped.

However, for this little intro and for various reasons, I need to run a little portion of title screen code and a little portion of game screen code, so there is now an intro check to skip or add certain elements and I admit to doing this in a quite hacky, yucky way!  It works, but I may need to recode this as it's stirring my OCD tendencies!

Next diary entry...

Thursday, 5 March 2020

NTSC

I'm guessing that this little game of mine will mainly appeal to people in Europe (hopefully!), but since I'm part of a C64 group (Arkanix Labs) that is U.S. and therefore NTSC based as well as a U.K. and PAL based group (Cosine Systems), I would feel a little disloyal towards my American cousins if I didn't include compatibility for NTSC systems.

If you don't know anything about NTSC, then do some research possibly by starting here...

Basically, NTSC machines run at 60Hz instead of 50Hz as on PAL.  Also, they have fewer display scanlines, 262 versus 312.  For my game, this means that my blue top border I wanted for 2 levels and which works nicely under PAL (see diary entry here...), starts waaay too early on NTSC and appears at the bottom of the screen, something like this...


To combat this, I've included an extra IRQ split in the top border.  Thus, the first IRQ split colours the background (therefore border area) black to eliminate the blue at the bottom of the screen under NTSC and the second IRQ split, which starts just as a PAL machine begins displaying the visible area of the top display, then colours the background blue.

Miraculously, this seemed to work!  Well, in WinVICE at least - I'll have to wait for my NTSC friends to test on real hardware for me and report back to be sure!  At present, it now look like this under NTSC in WinVICE...


Adding an additional split did have a knock on effect on some other timings; since the NTSC display has less screen time to execute in it seems, the title screen code was over-running and everything was slow and flickery.  A little rearrangement of some of my IRQ code later and all was back up to speed!

The other NTSC issue is the music.  Since NTSC machines run slightly quicker, the music was playing too fast and sounded awful.  Therefore, I've coded up a timer/counter that skips calling the music driver every few frames thereby slowing it down.  Of course, the game needs to know what type of machine it is running on, so I've now included a check at the start of the code to do this.

I've used a modified version of code that was posted on CSDb so thanks to all those involved in that discussion and who shared code, which you can find here...

Next diary entry...


Wednesday, 4 March 2020

Player Characteristics

I still need to calculate coordinate locations for crosses on many levels and seem to be putting this off at the moment, mainly down to the fact I find it rather boring...

However, I'm putting this task off by actually tweaking and/or adding code to other sections!  Honest!

The girl finally became 'properly' selectable/playable the other day and until now has shared characteristics with the boy.  But no longer!  I've altered certain variables so that when the girl or boy are selected they handle slightly differently.

The boy is slightly 'stronger' than the girl - he can be in contact with enemies or dangerous parts of the scenery for just a few milliseconds longer before experiencing an energy drain.

The girl is slightly 'lighter' than the boy - although she can jump no higher, she can stay in the air just a few milliseconds longer than the boy, making it a tiny bit easier to successfully make the longer jumps between platforms on some levels.

Those differences above are only subtle, but does give the player some choice as to how to play - do you choose easier jumps or more strength?  No doubt the variables will be altered further once play testers get their hands on the game and maul my efforts to death, but it will be easy for me to change in the code now since it's all handled by a couple of labels.

I've also finally got round to moving my screen splits slightly to accommodate the fact that on two of the levels (Level 3 - The Apartments and Level 7 -  The Park, if you're interested!) I've used a blue background.

I wanted to 'extend' the blue sky background into the upper border, an easy task since the top border is open, but not-to-hot looking because the split was in the wrong place, therefore the blue colour 'bled' too far down the screen.  Also, the blue was appearing on levels where the background and top border should have been black.

It was simple fix in the end - the two levels needing a blue top border set a flag telling my top border split to colour itself blue, otherwise colour itself black.  The result on Level 3 looks like this...


Next diary entry...

Saturday, 29 February 2020

Let it Snow!

After designing Level 9 (The Log Cabin) a few weeks ago (read here...), I've been looking for ways to improve the on-screen look as the level has been looking rather plain - currently, there is quite a lot of background moment (animated chars) used in the levels before and after Level 9.

I did ask on various forums for ideas because I was fresh out of them and a couple of people suggested perhaps animating (glowing) eyes, or wisps of smoke coming out of the log cabin chimney.  I did try these and, although they looked quite nice, I was still disappointed with the amount of animation on-screen compared to Levels 8 and 10.

Yesterday, I had a brain-wave!  I already have rain in some levels, so why not have some snow?

Today, I loaded up the Xmas demo level that was completed for FREEZE64 fanzine (see here...) to see how I made the Level 1 forest look all icy and Christmassy, took ideas from that and incorporated them into Level 9.  Then I had to make it snow.

I started quite simple.  The log cabin background was plastered with a single 'snow' char that depicted a few pixels and that char was then slide repeatedly downwards using a simple bit of code.  That was quite effective, but I wanted more.  I added a little more code to slide the snow char left after the downwards movement and now there was quite the little blizzard blowing, with snow falling diagonally down/across the screen.

To cut a long story short, I spent most of the rest of today experimenting with variations of snowfall - the snow char itself, the speed of 'fall', patterns of fall (including zig-zag patterns) and so on.

In the end, I decided on one of my simple patterns that, although (a lot) less complex than some of the other patterns, works well in the context of the level - there is lot's of movement on screen, but it's not too distracting; some of those more complex patterns drew the eye away from the player sprite and enemies!  Also, it saves me some chars since only 2 are used for the effect!  At present it looks a little like this...


It's quite a subtle pattern that may not even be noticed.  If you look closely, the snow is actually falling in 2 alternating strips (each strip made of one char), perhaps best highlighted in the static image below...


As mentioned, there are only 2 chars being used, each drawn in downwards strips, alternating across the screen - the first char strip is highlighted using a red line in the image above, the second char strip is highlighted in pink.

For this level, the code then animates (slides) the 2 chars downwards, but not at the same time.  Every time the snow routine is called, only one of the char strips is slid downwards, with the other char strip being slid the next time the routine is called.  As a result, you end up with a slight 'jutter' that breaks up the snowfall a little in an attempt to make it look more natural.

The code was quite simple in the end.  I have a variable that remembers whether strip 1 or strip 2 should be moved each time the subroutine is called, the appropriate char is then 'slid' downwards and to finish the strip variable is changed to make sure the alternate strip is slide next run through.  Finally, there is a jump to a small piece of code that resets the background animation timer - as with the majority of the background animations in the game, the snow doesn't fall every 'frame' and on this occasion the snow slides down every fourth frame.


; snowfall anim subroutine  
   
 snow_anim  
           lda snowstrip                 ; which snow strip should move?  
           cmp #$01                      ; strip 2?  
           beq snow_fall2                ; yes? do strip 2 then!  
                                         ; no? then do strip 1!  
 ; move snow strip 1...  
 ; shift snow char 196 a pixel down!  
 ; (char location $2620 to $2627)            
   
 snow_fall1                              ; move strip 1                 
           lda $2627                     ; load up the last byte of the char  
           sta chardown_temp             ; put it in a temporary byte store  
   
 snow_move1  
           lda $2620-$01,x               ; now shift each byte down  
           sta $2620,x                   ; until 7 of the bytes are done  
           dex  
           bpl snow_move1  
        
           lda chardown_temp             ; now put the byte that was originally  
           sta $2620                     ; last into in the first byte of the char  
             
           lda #$01                      ; next time, do snow strip 2!  
           sta snowstrip  
             
           jmp reset_bkgrd_anim_tmr            
   
 ; move snow strip 2...  
 ; shift snow char 197 a pixel down!  
 ; (char location $2628 to $262f)       
   
 snow_fall2                              ; as above, but for snow strip 2!  
           lda $262f  
           sta chardown_temp  
             
 snow_move2  
           lda $2628-$01,x  
           sta $2628,x  
           dex  
           bpl snow_move2  
             
           lda chardown_temp  
           sta $2628  
             
           lda #$00                      ; next time, do snow strip 1!  
           sta snowstrip  
   
           jmp reset_bkgrd_anim_tmr
  

This code can be compacted by using only one slide routine for both strips, inserting the appropriate memory locations for each char as necessary, but as written above, it's nice and easy to read!

Next diary entry...

Friday, 28 February 2020

More Whoosh Hair

Waaayyyy back in August last year, I added a 'jump' sprite for when the player was jumping left or right (see diary entry here...).

It's always bothered me, however, that when the player jumped straight up and/or fell straight down, only the static 'standing still' sprite was displayed.  Well, I've spent some time today fixing that!  I've pixelled up a jump/fall sprite for both the boy and girl and added a tiny bit of code to check whether the player was jumping/falling (gravity is active or it isn't!) and if the gravity is active, the jump/fall sprite is displayed.

In practise, it looks a little like this; very simple, but quite effective I think...?


I've been intending to do this for a while, but have been concentrating on other things such as level design.  Now the jump/fall is done, I have now also fixed a slight movement issue whereby after a left/right jump, the walking animation didn't reset and the jump left/right sprite remained making it look as though the player was sliding everywhere.

If you're wondering why the sliding issue took so long to fix (it's been this way since August last year!), that's simple because after a joystick movement, the player movement routine checks what current sprite is being displayed and makes decisions on what sprites to display next based on that.  Since the jump up/fall down sprite has only just been done, now was the time to fix it!

I regard the control system in Chiller 2 quite simple, but it's still a bit of a maze of checks and conditions!  Please spare a thought and admire games with much more complex control systems!

Next diary entry...


Tuesday, 25 February 2020

Dangerous Scenery

Another piece of the gameplay puzzle has finally fallen into place!

It's not really been necessary to do it until now since some gameplay mechanics just get in the way of testing and debugging, but I have now coded the, er, code that detects 'dangerous' scenery around the player and drains energy if touched.  The main 'obstacles' in the various levels are mushrooms and pools of green slime and if they are walked upon, energy is subtracted.

I've tried to be fair however; the detection is quite 'loose' and you can jump up near or through such scenery without being penalised, with the energy drain only occurring if the player directly walks on such scenery.  However, on some levels the mushrooms may be 'reversed' chars and appear only as silhouettes amongst other scenery; they can be quite difficult to spot in the heat of the action and will probably annoy those who go charging around without stopping, looking and thinking!

Here's how it looks in action (the animation below also showcases the first outing of the girl player, who is now selectable from the title screen!):



The scenery collision detection reuses values calculated from the gravity subroutine so checks what is underneath the players feet.  There is a bit of a cheat going on - the subroutine is not checking the mushrooms directly, but 'special' chars underneath the mushrooms that trigger the collision!

Next diary entry coming soon...

Saturday, 22 February 2020

Level 10 Design

To wrap up my short break from work, late last night I completed the design for Level 10, set down in a basement.  As ever, the design is likely to change slightly once proper testing begins, but it already look and 'feels' good to me!

The level includes some pipework and conduit; anyone who knows me knows my love of 8-bit pipes in games!  The pipes pump out some green slime which drains your energy on contact.  Also new to the scenery are some wooden boxes and some wall chains.  I may well add some extra detail later on, depending on whether I have many chars left.

The basement looks a little like this at present...


Although I still need to work out the cross locations for Level 4 onwards, I've have now added all the enemy paths and pattens for all the levels, including Level 10.  Here is Level 6 (The Cinema) with it's enemies inserted...


Next diary entry...

Friday, 21 February 2020

Level 7, 8 and 9 Design

I've been away for the week, but took my laptop with me so I could carry on designing more levels for Chiller 2!  Take pity on my long suffering wife!

Level 7 is set in a park and features the rain from an earlier level expanded to fill more of the screen.  I do intend to go back to this level and add a bit more silhouette detail once I've designed further levels - I don't want to run out of chars too early!  The park level looks a little like this (excuse the lower quality screen-grab as I'm getting worried about sharing too much of the game)...


Level 8 is set underground in a sewer!  This level features an expanded version of the slime pools from the cemetery level, with additional slime 'falls'.  As with the park, more detail may be added later when I get a better idea of how many chars I will have remaining after the majority of the levels have been designed.  The sewer looks like this (although some modifications have been made since this grab)...


Level 9 is set outside and features a log cabin.  All the best horror films have a cabin in the wood scene don't they?!  The great thing about this level is that it was pixelled using practically all existing chars, leaving me chars for future use!  The log cabin looks like this...


I've also already started designing Level 10, which is set in a basement and will feature more slime oozing from a feature I have a slight fetish for - 8bit pixel pipes and conduits!  More on this soon!

Next diary entry...

Saturday, 15 February 2020

Level 6 Design

Hot on the heels of designing Level 5 a couple of days ago (read here...), I've only gone and designed Level 6!  This level is set inside a cinema and is a call-back to the original game, which also had a level inside a cinema.

The original Chiller level had a slightly odd perspective, with a screen in the distance and chairs that decreased in size the closer to the screen.  When static, that kind of looks fine, but when your character sprite approaches the never changing cinema screen, the sprite stays it's original size and things tend to look all strange then.

In Chiller 2, I've drawn a screen at the top of the display and chairs on platforms all around, with no perspective tricks tried at all.  I have reused, albeit with different colours, some of the staircase chars from Level 4 (The Haunted House) for some variety. And to combat the original game having a cinema screen that never changed, my cinema screen will have a very simple animated noise effect, with flickering black and white pixels - truth be told, this is already coded and working!

Here's what the level looks like in my editor, ChillED...


As an aside, I've now altered the code slightly so that each level can have it's own 'timer' for the background animations.  Up until now, all the background animations (flame, rain, slime, etc.), have shared a timer and been updated every fourth frame, which has been fine until the cinema screen 'noise' was coded up and ended up being too slow.  Thus, each animation has now been tweaked to a more suitable speed for what it's displaying.

Also, I cannot tell a lie.  I've installed a cheat mode whereby pressing up on the joystick skips to the next level!  Hey, the game is getting bigger now and it's the only way I can check that everything is working properly!  This cheat will be removed before release!

Next diary entry...


Thursday, 13 February 2020

Level 5 Design

In the diary entry called 'Level 4 Design', I described that level as 'the toughest so far'.

Forget that!

I've just designed Level 5, set outside in a cemetery and it's an absolute pig of a level!  Virtually all of the enemies are in your path constantly, the platforms are quite far apart and are peppered with mushrooms ready to drain your energy AND now there is a new introduction to the gameplay - small pools of green slime that, although can be walked on, drain your energy just like the mushrooms!

I've already added the enemy paths and just need to enter the cross locations in hex.  I really may need to make this level a little easier; it may not look that hard but playing it is something all together different, particularly if your energy is low!  At the moment, the cemetery looks a little like this...


Next diary entry...

Friday, 7 February 2020

Level 3 Crosses

Another Friday rolls around and I treat myself to another 'feet up in the office, drink coffee and work on the game' day.

This time I've worked on the coordinates for the crosses that will appear on Level 3 (The Apartments).  Even these days in this world of technology, there is something therapeutic about working on paper! 

Later this evening, these hex coordinate locations will be typed into the data table for Level 3 crosses!  There are actually more locations here than the required 20, but that just gives me more choice!


Next diary entry...

Tuesday, 4 February 2020

SFX

I've been thinking about how to incorporate sound effects in the game since, when writing the music recently, I've kept the in-game music to two voices to enable this.

After reading my digital copy of Compute's 'Mapping the 64 and 64C', specifically the sections relating to the SID registers, I thought it might be easy to shove some data into said registers and see what happens!

After a bit of fiddling, low and behold, I made noise!  It really was as simple as writing a short routine that inserted some previously created values for the waveform type, pitch (note), attack/decay and so forth into their associated registers and then changing those values over a short period of time using another small routine.  It did sound a little like Paradroid to start with though!

Next, I inserted these little routines into my Chiller 2 code and called them when certain actions were performed, in this case when the player jumps or when crosses are collected.

It worked!

But... problem...

It seems that, even though I had kept a voice free on SID (in this case voice 3) for the effects, the GoatTracker music driver still writes values to the voice 3 registers, effectively neutering my sound effects.  Damn...

After a bit more reading around, it turns out that GoatTracker has a sound effects routine built in.  I've read the GoatTracker help file a few times over the years, so how the hell have I ever missed this information about sound effects!?!?  So I investigated this and within about 20 minutes, had sound effects playing using this GoatTracker routine!

The process goes a little like this:

When exporting your music file from GoatTracker as a .prg to include in your code (press F9), there is an option to enable the SFX player. Do this and once saved the SFX module is now part of the overall music file.  This does add about 150 bytes to the overall file size.

You then create your SFX exactly the same way as creating instruments in GoatTracker.  These instruments are then saved from within GoatTracker.  The instrument file is then converted to a sound effect using a tool bundled with GoatTracker called 'ins2snd2.exe', which gives you a text file with the associated hex data for the sound.  There are a couple of rules to follow for the tool to be able to convert the instruments to effects, but you'll have to read the GoatTracker help file yourself for those!

Currently, the data for my jump and collect SFX look a little like this...


; sfx data (lower the sfx data, the higher play priority it has)  
   
 sfx_jump  
     !byte $38,$F6,$04,$A0,$21,$A0,$A0,$A6,$A6,$A6,$20,$A9,$A9,$A9,$A2,$A2  
     !byte $A2,$A6,$A6,$A6,$A9,$A9,$A9,$A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9  
     !byte $A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9,$00  
       
 sfx_collect  
     !byte $00,$89,$04,$A2,$41,$A2,$A2,$A6,$A6,$A6,$40,$A9,$A9,$A9,$A2,$A2  
     !byte $A2,$A6,$A6,$A6,$A9,$A9,$A9,$A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9  
     !byte $A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9,$00 


To play the effect, you then insert a small simple piece of code that is triggered when, for example, the player jumps or collects a cross.  Something like this...

  
 lda #<sfx_jump       ; start address of the effect  
 ldy #>sfx_jump  
 ldx #$0e             ; 0, 7 or 14 for channels 1-3 (channel 3 use here, or $0e)  
 jsr music+$06        ; music = memory location where music is stored in memory  
                      ; sfx player is at +$06!


So Chiller 2 finally has some sound effects!  I've purposefully kept the sounds quite low in the 'mix' (quiet) currently, since both the jump and collect will be played quite frequently and I don't want to annoy the game player!

Sound effects... TICK!

Next diary entry...


Thursday, 30 January 2020

Sounding Off

I'm still immersed in the depths of GoatTracker!

Since the last blog entry a few days ago (read here), I've completely rewritten my 'get ready' tune so it now sounds more 'urgent' and suspenseful.  Well I think it does...

I've also written four more level tunes to accompany the one written the other day!  I was originally going to make them spooky sounding, but found that style didn't actually suit the gameplay.  More 'driving' bass lines are needed to motivate the player along.  Each tune is between 40 and 60 seconds long before repeat; I've deliberately made them short so I can have more tunes in memory for more variety for each level.  As mentioned in the previous blog entry, these tunes are written using only two voices, leaving the third free for sound effects.

Along with the level tunes, I've composed a really rather jolly game complete tune!  A bit premature maybe as I don't even know if I'll have a game complete screen yet, but it gives me options further down the line.

What?  You want proof I've actually written some music?  Below should be a player containing a test recording of the music currently assigned to Level 1 (this was recorded using SidPlay64 on my 8580 equipped C64c playing through my Dolby amp).  If the player doesn't appear from some reason, hear it on my SoundCloud page here.





Next diary entry...

Saturday, 25 January 2020

Sound Start

After another busy week in work I've fancied a change from level designing, so yesterday evening I started work on some music for the game.

Now I will be honest, I did start writing some music quite a few months ago and by that I mean the first 10 seconds of the title screen music, along with some place-holder notes for the 'get ready' screen so I knew that the music was being called/initiated and played correctly for the sequence of screens from the title screen, through the get ready screen to the game screen.

After yesterday's bout of composing, I have now refined my first 10 seconds of title screen music, modified my get ready music and added a (very) short piece for game over.  The biggest addition though is a brand new piece that is currently around a minute long that I'm using for the in-game music.

Of course, all this music will be refined, extended or even deleted and composed again from scratch as time goes on.  At present, I don't really want to aurally share the music in it's current state, but here is a screen dump of GoatTracker in action:


When being assembled, the code is loading the music to $0900, with the next block of memory being used by the charset at $2000.  This gives me just under 6K of memory for music at the moment.  Quite a bit!

I've decided that I may do short, simple repeating tunes so that each level has it's own music.  To this end, I did dive into the code and add a short routine that can detect the level number then initialise and play a different tune for each level.  Naturally, this code will be removed if I run short of memory in the future and only end up with one in-game tune.

I've written the first in-game tune with only 2 channels, keeping the third free.  I'm toying with the idea of having some sound effects too in the future, maybe for jumping or energy depletion.  Maybe...

Next diary entry...

Saturday, 18 January 2020

Level 4 Design

Off the back of sorting the cross locations for Level 2 yesterday, the evening saw the beginnings of me tentatively designing Level 4.  As stated in a previous blog entry (see here), I never intended to have levels set in exterior and internal locations alternatively, but since I've seemed to set off down this path, it shall continue!

Thus, after Level 3 being set outside, we're back indoors for Level 4 and most of today has been spent creating the inside of a haunted house!  This gives me a chance to save some characters in the charset by reusing some used in level 2, as well as adding new chars specifically designed for this level.  I need to do this after blowing five chars on the rain in Level 3!

New chars and features for this level include a wooden staircase that can be used to reach higher platforms, a stone fireplace (so as to reuse the animating flame char from Level 2) and a rather ominous looking rope and noose!

Since this is now Level 4, I'm assuming the player is getting better at the game, so platforms in this level are deliberately further apart to make them harder to cross, with gaps below that the player falls down if the jump is 'missed'.  Along with avoiding the planned to be fast moving enemies, this level should be the toughest so far. I hope!

What does the level look like?  On this occasion, I've done a time-lapse animation showing the build up over the course of the day it took to design.  Of course, things will probably change as the enemies and crosses are plonked into place and the level tested.



Next diary entry...

Friday, 17 January 2020

Level 2 Crosses

I've had a difficult week in work for one reason or another, so I set Friday aside to sit in the office, put my feet up and drink coffee!

Whilst taking it easy, I also decided to grab a screen-dump of Level 2 and work out some collectible 'cross' locations; since Level 3 is now in the game (see this blog post here), I don't want to end up with a load of levels in the game without anything to collect in them!

So, as well as the enemies, the crosses are now in for Level 2 and to prove it, here is my scrappy piece of paper with hastily scribbled hex number coordinates, along with some notes about slight modifications to the actual screen layout...



Next diary entry...

Monday, 13 January 2020

Level 3 Insertion

A fair few months ago, I started to design Level 3 for the game (see blog post here).  Up until yesterday, it only existed in my screen editor, but I've finally exported the screen and colour ram data and inserted it into the game, along with the code to set-up and call the level.

Since this level has been languishing for a while, I thought it deserved some habitation, so I've also added some data to the enemy table for this level and there are now various baddies crawling and flying around.  I still need to add some x and y data for the cross locations; currently the data table contains my stand-by data that only contains 2 locations that strobe back and forth.

Once it was all up and running, I wanted more screen action, but in a subtle way.  I've seen a couple of games recently that have rain in the background (it seems fashionable to have rain in your game at present and, at time of writing, appropriate given the weather outside) so I decided this level shall have rain!

I must also admit to having watched Simon Jameson's Twitch channel the other night where he demonstrated how he had implemented rain in his game and this also provided the idea and motivation for me to include rain in Chiller 2.  However, I wanted a much simpler solution for my game compared to Simon's code, so decided to go with the 'copying char data around' route rather than the pixel plotting through a char route he demonstrated.

So, to start I set aside 5 sequential chars that will be used for the rainfall and plotted a 1,2,3,4,5 repeating sequence in columns using these chars.  In the editor to begin with, the rain looked a little like this...


I did my very best to ensure it looked 'random', with columns of chars that were near or adjacent to each other not having identical numbers that were in-line (1's in line with other 1's, 2's next to other 2's and so on) - not doing this would have resulted in very unnatural looking rainfall methinks!  Once I was happy with the layout, I cleared the chars themselves of the numbers, knowing the chars were still actually in place on the screen.

I then designed a simple raindrop, not in the editor, but on a scrap piece of paper which I then turned into a table of hex bytes.  If you're interested, that table of data looks a little like this within my code...



 ; raindrop pattern  
   
 rain_patt     !byte $ff,$ef,$ff,$ff,$ef,$ff,$ef,$ff  


And then it was time to code a very simple rainfall by copy my raindrop pattern above into each char sequentially.  The code I came up with looks a little like this (please note, this is wholly unoptimised at present but was written this way to ensure it could be followed in the future by me!):


 l3_bkgrd_anim                          ; level 3 rain  
   
 ; clear all raindrops first  
   
           ldx #$00  
           lda #$ff                     ; char needs to be solid!  
 clear_rain            
           sta $2400,x                  ; raindrop 1  
           sta $2408,x                  ; raindrop 2  
           sta $2410,x                  ; etc  
           sta $2418,x  
           sta $2420,x  
           inx  
           cpx #$08                     ; all 8 bytes of each char cleared?  
           bne clear_rain               ; no? branch back  
             
 ; now check which raindrop should be drawn! 
   
           lda raindrop                 ; which raindrop are we on?
             
           cmp #$00                     ; drop '0'?
           bne *+$05                    ; no? go and check drop '1'
           jmp draw_rain0               ; yes? go draw rain0!
   
           cmp #$01  
           bne *+$05  
           jmp draw_rain1  
             
           cmp #$02  
           bne *+$05  
           jmp draw_rain2  
             
           cmp #$03  
           bne *+$05  
           jmp draw_rain3  
             
           cmp #$04  
           bne *+$05  
           jmp draw_rain4                                     
             
 draw_rain0       
           ldx #$00  
 rain0_loop  
           lda rain_patt,x            
           sta $2400,x  
           inx  
           cpx #$08  
           bne rain0_loop  
             
           jmp draw_rain_dun  
             
 draw_rain1       
           ldx #$00  
 rain1_loop  
           lda rain_patt,x            
           sta $2408,x  
           inx  
           cpx #$08  
           bne rain1_loop  
             
           jmp draw_rain_dun  
             
 draw_rain2  
           ldx #$00  
 rain2_loop  
           lda rain_patt,x            
           sta $2410,x  
           inx  
           cpx #$08  
           bne rain2_loop  
             
           jmp draw_rain_dun  
             
 draw_rain3  
           ldx #$00  
 rain3_loop  
           lda rain_patt,x            
           sta $2418,x  
           inx  
           cpx #$08  
           bne rain3_loop  
             
           jmp draw_rain_dun  
             
 draw_rain4  
           ldx #$00  
 rain4_loop  
           lda rain_patt,x            
           sta $2420,x  
           inx  
           cpx #$08  
           bne rain4_loop  
             
 draw_rain_dun  
           lda raindrop  
           inc raindrop  
           cmp #$04  
           bne reset_bkgrd_anim_tmr  
           lda #$00  
           sta raindrop
  

What's happening?  Well, when this routine is called, first of all I'm clearing all five rain chars to erase any previously drawn chars (this could be optimised to clear only the last previously drawn char!).  Then, using a 'variable' that stores which raindrop we're on (it starts with '0'), the code determines which char should be drawn to next and jumps to the drawing code for that char and copies the raindrop pattern data pattern into that char's memory location.  The code then jumps to a label called 'draw_rain_dun' which increases the raindrop variable and then checks to see if all five chars have been drawn to in sequence.  If they have all been drawn to sequentially over the course of the routine being called a few times (i.e. the fifth raindrop char was last drawn to), the code resets the raindrop variable to '0' so next run through the raindrop pattern is drawn to the first char again.

Hopefully that makes sense?!  Of course, this code is also inside a timer that executes it (at present) once every 4th frame.  Without the timer that rain would, er, rain too fast!

To be honest, if this code was applied to the whole screen and not just the top of the buildings as in my level, it would probably look pretty jerky.  However, in the context of my level and game, it has a nice cartoony feel that I'm very happy with!  What does it look like?  Something like this...


Next diary entry...

Sunday, 12 January 2020

Level 2 Enemies

Late last night, I finally got round to 'plugging' some data into the movement table for the enemies on Level 2 (The Church).

On this level, the platforms extend quite high, so for the first time the player is able to 'jump' up into the top open border.  Therefore, it makes sense to have an enemy 'patrolling' this upper border making it more difficult to collect any crosses that appear there.  In conjunction with this top border enemy, there is another enemy patrolling the platform just below, so this should mean the player has to carefully time their jumps between the two enemies, while avoiding floor mushrooms (which zap the players energy) and any floor openings.

I can see quite a few crosses being placed up there to collect!


Next diary entry...

Friday, 10 January 2020

Unsung Routines

I've been working quite a bit of what I've come to call 'unsung routines', as opposed to the 'hero routines' such as the all important sprite and background collision detection or the gravity and animation routines.

These unsung routines have no apparent visible effect on screen but are important to keeping the code running in a modular way so it's easy for me to add more features.

An example of this is my 'process background animations' subroutine.  When this was routine was coded originally, it was done only for the animating torch flame character (see this blog entry for more about animating chars) that appears in the current level 2 (the church).  Since this routine was called from the main game loop code, it meant that the flame char animation code was executed for every level, even if the flame wasn't present on the level!

What a waste of processing time!  How lame!

So, my background animations subroutine has now been restructured and had some code added so that it can handle multiple levels - it now checks the level the game is currently on and only executes the animations needed for that level.  If the level has no character animations at all, the animation code is skipped completely, so no processing time is wasted!

Of course, I had always originally intended to do things this way, it's just that I've only just got round to it!

Another example of making things more modular is the variables and code I've added for background colours.  I had originally set the background colour to black and had intended for every level to have a black background.  However, when designing level 3, I chose to have a dark blue sky just to make the level look different to the previous two levels (see this blog entry for more about the level 3 design).  The background is still actually black, but blue characters are used to represent the sky.

This created the problem of the sky being blue, but the top border being black and seeing that the borders are 'open' and the player sprite can jump up into the top border, it looked a little strange with the sprite moving over blue then into black 'sky'.  So the solution was, quite simply, to make the top border (now controlled by the background colour register since the border is open) blue.  Now there is a nice extension of the blue sky right to the top of the visible screen.

Problem - all other levels now have a blue top border, when not needed, including the title screen and intermediate screens!

To overcome this and returning to the idea of making the code more modular and flexible, the colour of the top border part is no longer hard coded, but controlled by a 'variable' that is changed for each level as part of that levels set-up code.

To be honest, these are the sort of things that more seasoned coders probably do right from the start, but since this is my first 'real' game, I'm still coming to terms with such things!

Next diary entry...

Wednesday, 1 January 2020

Enemy Movement Delay

A small diary entry to celebrate the New Year!

In my haste when coding the the enemy movement code (see previous diary entry), I didn't think to include a timer to 'activate' the code.  Basically, when the enemy movement routine was called every enemy sprite position was updated *every* frame.  This had the effect of every enemy only being able to move 1 or 2 pixels (set by the sprite speed table) because any bigger movement made the sprite move too fast, which looked rather silly on screen.  Also, because there were only 2 speed choices, the movement looked a little 'unnatural', with too many enemies moving in-sync because of their same speeds.

I've now enclosed the enemy movement routine within a timer, so it only activates every so many frames set within the code.  Currently, the routine now runs every other frame, which means I can now have sprites that move 3 pixels without looking ridiculously fast.  This means that the screen now looks much more 'natural' with enemies moving seemingly at their own pace.

As the game progresses, I'll play more with the timer and enemy speeds to see if I can introduce even more natural looking movements.

Next diary entry...