Starting in June of 2020, I began work on recreating the arcade classic “Centipede” for the Apple IIGS. By August, I had some code demonstrating animation of some game sprites but I had a problem. I was starting to not keep up with the video beam and the animation was starting to glitch.
I turned to the Apple IIGS channel on slack. I posted some vague questions because I was planning to keep my plans secret. But people were curious and I decided to show what I had.
The community came through and I got great suggestions. But more than that, I decided that I would try to post every week with an update on my progress. There were two goals. First, I wanted to continue to lean on the community for their suggestions and support. Secondly and more importantly, I set myself a weekly deadline and I always felt the pressure of trying to have something good to show everyone when Friday would roll around.
It worked for the most part. Almost every week, you could see the changes as they changes from little animation demos to a full fledged game over the next few months.
Now, I have decided to pull that history out of slack and reproduce it here for everyone to see. I am including my original posts from back then and the videos of the status of the game at the time. Also, I am going to include links into the GitHub repository so you can quickly jump to the state of the code at the time or a set of diffs for that week’s changes.
I hope you enjoy seeing a bit of a “behind the scenes” look at the development of BuGS.
-
First Public Mention of BuGS
Well, here is a video of it running. This is 8MHz on GSPlus. It also runs well on my real HW with a Transwarp GS. But adding the centipede drawing pushed me over the edge for 2.8MHz. Until then, I had the flea, spider and scorpion drawing well. Also, I am not actually moving the centipede yet, just animating it in place.
-
BuGS Weekly Update
I didn’t get as much time this week to work on it as I wanted but I did implement some of the ideas from last week’s discussion. I changed the array of structs to structs of arrays. This was a minor win really since I did a bunch to reduce the cost of the old implementation already. The big change is that I implemented the code to redraw the dirty tiles right after the beam. I am using the vertical counter in $e0c02e and $e0c02f to do this. By doing this, the background is already redrawn by the time the beam hits the bottom and I only need to draw bugs and update game state before the next frame. With this, I am almost smooth again on 2.8MHz. This is 2.8MHz on GSPlus. I haven’t tried it on real HW yet though so buyer beware.
-
Another BuGS Weekly Update
I have written the code to animate the centipede segments at least at slow speed. Double speed centipede segments are not implemented yet. The code is also there to animate the body segments which follow the head. I used a ring buffer so whenever I figure out where to put a head segment, which way it should face etc, I keep that around in the ring buffer and body segments just update an index into that buffer and use the stuff already calculated for the head segment. Should work but ran out of time to test it so you don’t get to see that this week. This clip is running at 2.8MHz. There are a couple of odd things. At one point, a hidden mushroom appears when the centipede segment gets close. This seems to indicate a bug in the flea code. I suspect the flea left the mushroom behind but didn’t mark the tile dirty so it didn’t get displayed. Also, the head segment goes a bit nuts at the end and just cycles up and down in a couple of tile columns. Not sure what that is. So, the next step is some bug fixing of what I did this week and maybe try to display some body segments.
Oh and I haven’t coded anything to handle a centipede contacting a poison mushroom so that is to come also.
I withdraw my “hidden mushroom” issue. There is a flea dropping as the centipede passes. The flea drops the mushroom so it isn’t a mushroom appearing for no reason. I have the flea, spider and scorpion running at fast speed so the flea flashes past so fast compared to the centipede that it looked to me at first that the mushroom “just appeared”.
And I found and fixed the bug which makes the centipede drop to the bottom of the screen as though it is poisoned. The issue was one of comparing “number” versus “offset”. My check for the LHS or RHS of the screen was looking for a tile number (incrementing by 1) but I had a tile offset (incrementing by 2 to use as a word index into arrays with tile info). As soon as the centipede got low enough on the screen, every tile was considered to be the edge of the screen and it just dropped straight down thinking it always had to change direction. Adding the missing *2 in the comparison fixed it. So, no known bugs left now and on to sleep and more features for next week.
-
BuGS Weekly Update
I got the centipede animating correctly. I can animate a centipede with multiple body segments smoothly with spiders, scorpions and fleas coming continuously. The movie shows the emulator running at 2.8 MHz. There are two speeds for the centipede in the game and this is the slow speed. You will also notice that the centipede touches a poisoned mushroom and drops to the bottom of the screen as it should. Then, it moves left/right and up/down at the bottom of the screen as it does in the game. If not for the poisoned mushroom, it would have moved down row by row until reaching the bottom.
Next step is some more refinement of the centipede code. I need to support a slow centipede on screen at the same time with a fast centipede. Nothing I have done precludes that but I need to add the code to handle it. It is a bit tricky also because the slow one takes two extra frames to enter the game from the top and after those two frames, the fast centipede needs to enter. I also want to test with 12 independent centipede head segments. That is the worst case performance problem. Bodies are easier to update because they just follow the head segment. If there are 12 head segments then each frame, those 12 head segments need to be updated.
Also, you will notice that head segments don’t care if they run into and animate on top of other segments. The game doesn’t work like this. I have to add some tile information to try to detect these collisions and make the head turn around if it runs into another head or body segment.
Finally, I want to add the code to handle shooting the centipede segments and turning them into mushrooms as happens in the game. Not sure I have ever demo-ed it but I can “shoot” the scorpion, flea and spider. I use “s” to add a scorpion and then “S” to shoot the scorpion. Similarly, f/F adds/shoots fleas and p/P adds/shoots spiders. I have c set to add a fixed configuration of a centipede (single head and 11 body segments right now) and plan to have C hooked up to shoot a random segment. That way, I can test that part of the game before I add the player. So, that is where I am at this week. More centipede work to come.
The thin white lines in the middle indicate the game was re-drawing dirty tiles above this point for the next frame. There is a light blue line about 3/4 of the way down which is the draw routine for the scorpion. The other colours are for drawing the flea, spider and centipede. The orange is the final bit which is an update step where all of the active sprites are updated internally to figure out where things should be for the next frame. That tends to be at the top of the screen and after a short delay (or not), it starts chasing the beam again and redraws the dirty tiles from the previous frame with the thin white lines on the border showing the cost of those redraws.
It is just a way to visually get a sense for what is taking the most time. With the centipede at the bottom, there are lots of dirty tiles so the last few rows of tiles are pretty costly so that is much of what is seen on the screen. The border colours for drawing some of the other bugs don’t appear at all much of the time because it happens between frames entirely. The big improvement in performance was getting the tile redraw happening right after the beam so that for the most part, once the beam gets to the bottom of the screen, the background is fully redrawn for the next frame. Plus the scorpion is redrawn because it is always in the top 3/4 of the screen. Once the beam gets to the bottom, it only needs to draw the flea, spider and centipede segments and then start figuring out what the next frame will end up looking like.
Sound will be the final thing I do. I plan to have a fully playable game that is oddly silent first. Honestly, I have never done any sound programming on the GS so when the time comes, expect to see me here asking questions. Of course, I have never drawn to the screen of the GS directly and always used toolbox routines before this. And I have never done a pure assembly project on the GS. In the past, it has been pure C or C with a bit of assembly mixed in. So, this project will be a series of firsts for me.
-
BuGS Weekly Update
This video may not look too different from the last one but there are a number of new things. Note there is a 11 segment slow centipede and a 1 segment fast centipede. So, it now supports drawing two centipedes running at different speeds. Also, you will see that the single segment centipede detects when it runs into a segment on the larger centipede and it changes direction. In general, head segments will detect when they collide or are about to collide with another segment and they will change direction. Once everything is at the bottom, things are very chaotic and they end up packed into a small space so collisions are happening all the time and there is lots of direction changing but I think it is behaving correctly. Finally, there was a problem where head segments did not always detect a mushroom and change direction last week. That is fixed.
Next, I have more centipede work to do. I want to add code to support shooting centipede segments. Also, when only one segment is left, it needs to accelerate to fast speed if it was going slowly. Once a centipede segment reaches the bottom, single segments start to randomly get inserted on the side until up to 12 are on the screen. That reminds me, I did test with 12 head segments all animating independently and it worked fine at 2.8MHz which I was worried about. The other thing I want for centipede code is to be able to describe what kind of centipedes to add at the start of the level as data. Right now, the two centipede you see in the video are “hard coded” as a 11 segment and a single segment, two different speeds, entering at those points. I want it to be a bit more generic so I can vary it easily between levels. So that is next week. More centipede work.
-
BuGS Weekly Update
I worked on the ability to shoot centipede segments. I still just have keys on the keyboard tied to adding different bug types and shooting them. It randomly picks a segment and shoots it. The segment explodes and turns into a mushroom as in the real game. When only one segment is left, it goes fast again like the real game. This weeks video focuses on shooting bugs. When a scorpion is shot, nothing special happens other than an explosion. When a flea is shot, it goes faster until it is shot a second time and then it explodes. And segments are seen being shot in the video. This is again 2.8 MHz. So that is the progress for this week.
I still want to make it easier to define what segments to add with what levels. And now I could add the code to “play the game” except without any actual player. I could proceed through levels and auto-shoot bugs using the keyboard with everything game-wise just happening as it would in the real game. Then, I need to add the player, score, sound, etc.
-
BuGS Weekly Status Update
As far as coding, the only real progress was to implement the code for adding new head segments if the centipede reaches the bottom of the play area. You can see that being demonstrated in the video. I shoot all but one segment. Because it is the last segment, it accelerates and I let it reach the bottom. Once that happens, then single head segments are randomly added on the left and right side until there are up to 12 segments on the screen. There are some oddities in this video clip that I hadn’t seen before like segments passing through each other. So that is a bug to track down. But this is another piece required for the game.
Other than coding, the main thing I did this week was research. I played and recorded a number of games using mame on my Mac. And I watched some videos of other people playing the real arcade on YouTube. The goal was to try to figure out the rules around things like when do the spiders and fleas go fast, when does a flea appear, when does a scorpion first appear, and other things like that. I also read a few strategy guides for the game which had some of this info. There are multiple variants out there where these things are different, probably to play with the difficulty of the game. But I think I have all of the basic rules down for these things. I have created empty score.s and level.s files where I will start to implement some of this logic. So that is where I go next.
-
Weekly BuGS Update Time Again
This week, I only got a couple evenings to work on the code but I was able to implement all of the score code. When a bug is shot, the score goes up by the “right amount”. The score is held in two different formats. One is a 32-bit unsigned integer which is pretty easy to update. This representation will be used for things like “when the score is >= 60000, the fleas drop faster”. The other representation of course is a sequence of tiles which have digits in them. So, when an amount is added to the score, I do the add to both the 32 bit integer and I add the same amount to the tiles. I don’t try to turn the 32 bit integer into a decimal number because I suspect it is faster to just do the add twice but it does mean I could have a bug in one or the other add routine and the two representations of the score could deviate from each other. But hopefully not…
I still want to rough out all of the game logic which iterates through all of the levels and starts with the right colour and the right number of segments moving at the right speed. I can also add the logic for driving the speed of the other bugs based on score thresholds now that I have a score.
The other news is that I am the proud winner of an eBay auction for an ADB trackball and it is currently in Denver making its way to me. Once that arrives, I will suddenly have a bunch of incentive to start implementing the player…
-
BuGS Weekly Status
A longer video clip for this week’s BuGS update. I have implemented a chunk of the game logic. Now, when I press ‘g’, it starts a game and the first centipede moving at fast speed with 12 segments appears at the top. A spider is added 2 every seconds after it is killed or goes off screen which is the behaviour from the original game as far as I can tell. I can “shoot” centipede segments and spiders with ‘c’ and ‘p’ respectively and the score goes up. When all segments are killed, the game goes to the next level. The colour changes and new centipedes are added. The second level has 11 segments moving slowly and one segment moving fast. The third is the same except the 11 segments are fast. Then, 2 single segments and 10 slow segments. Then the 10 segments move fast. This pattern continues on. When 40000 points is reached, then we skip the slow segment variety of centipedes. Ultimately, you get to a level which has 12 fast single segments and the pattern restarts with a single centipede with 12 segments. All of that game logic is there.
Similarly, the logic for the spider is there. Like I said, one appears every 2 seconds after being removed for some reason. Once the score is above 5000 points, the spider moves fast. One aspect of the spider from the real game that isn’t implemented is that at certain score thresholds, the spider is restricted to fewer rows at the bottom of the screen. This is on my todo list.
Also, the scorpion is implemented. It can first appear on the 4th level and appears randomly. I don’t know the rate from the real game and I am going with 1 in every 512 frames on average so almost one every ten seconds. I think that feels about right but I can adjust that. I have also implemented another threshold from the real game. Once the score reaches 20000 points, 3/4’s of the scorpions cross the screen quickly, 1/4 cross slowly. So, the scorpion logic is fully implemented.
Like I said, I have a bit more spider logic to implement. I also need to add logic to add fleas. There are some interesting thresholds there also, like above 60000 points, fleas drop at fast speed. I want to add the ability to shoot mushrooms to test out some of that code. And I want to start tracking how many lives the player has and add a way to trigger a player death. I think I will do all of that without actually adding the player and the shot stuff. I have written some collision detection code in the sprite code for those things but that will need to be tested and hooked up. But it is starting to turn into something which looks more like a game which is really nice.
Thanks so much for all the feedback. I think when I decided to reveal my project here and then committed to providing a weekly update, it has really helped me to keep focus on the project so I have some progress to show. I am proud of the work I did this week. The last couple of weeks may have looked like big steps but they were definitely more incremental. I was hooking up existing code in many cases the last couple of weeks or tweaking some things. This week, I feel I added a good amount of game logic which makes me happy.
And I forgot to say that I am still recording these at 2.8MHz on GSPlus. I haven’t tried this build on real HW but I did run one earlier in the week and it still kept up at stock speeds. I am still hopeful that the full game will run on a standard GS. The only thing I am worried about is how costly polling the mouse will be. Can I use the Misc Toolset for reading and clamping the mouse? Or are those routines going to be too slow for a 60th of a second frame time? If anyone has any feedback about what to expect, that would be great. Thanks.
-
BuGS Weekly Update
This one is less impressive in that I have now exceeded the 60th of a second at 2.8 MHz on an emulator so probably substantially blown the window on real HW. The cause is I did add a call to ReadMouse through the GS toolbox in the game loop. You can see that when the centipede is at the top of the screen, it is often drawn too late and isn’t visible on the frame. So that makes the game that much harder with invisible centipede segments. Now, some of this is my fault. I don’t have good code yet for drawing the player. I am restricting the player to the bottom row of tiles. That way, I just have the address of the scan line of that row and add an offset to that based on the X coord of the mouse. But I don’t really know which tile(s) the player has made dirty so I am marking them all as dirty. Maybe if I optimize this and do it properly, I may recover enough to make it work with the ToolBox call but I am doubtful. What I need to do is generate a bunch of data tables so I can quickly figure out the address of the player to draw at and the 1, 2 or 4 tiles that are dirty because of that draw. If I do that, it will be slightly faster and I will be able to move in X and Y directions. But I still have more code to put in the game loop to block the player from passing through mushrooms, handle shooting and collisions etc. So, I am on the edge of this all falling apart at 2.8MHz. I probably need to go around the toolbox.
Other work this week – I finished all of the bug game logic. The flea is added based on thresholds which change as the score goes up. As the number of mushrooms disappear in the infield, the flea will start to drop. I also implemented the code to restrict the spider to lower and lower rows as the score goes up. And I added code to handle shooting mushrooms. I hooked up ‘m’ to randomly shoot a mushroom. I realize I didn’t demo any of that in this video.
The other obvious thing is the change to the LHS of the screen. I added BuGS branding, moved the number of lives from the RHS to the LHS and put player 1 and player 2 info in there. There is really not any support for player 2 yet but I have centralized all of the information that needs to be tracked per player so I have a way to add that reasonably easily in the future.
Feedback about the new display is greatly appreciated. I am not sure I like the multi-coloured BuGS branding at the top. Also, the lower case u was my own attempt at creating a tile for that so it stands out a bit more like an oddball than I would have liked. Next week, I will need to look at the mouse code. I have already perused the Firmware manual which I am guessing is the right place to go for details.
-
Weekly BuGS Update
After last weeks slapdash introduction of the player and the performance hit from the toolbox call and some non-optimized work on my part, this week that is all cleaned up. We are back to smooth operation at 2.8MHz and full X/Y motion on the player. I eliminated the toolbox call to poll the mouse and coded something based on what John sent last week (thanks!). The video shows the player moving around in all directions. But there is more work to do in this area. The player is not blocked by mushrooms. I do have collision detection code in the routine which draws the player to the screen but it is untested and not hooked up either. Shooting is still all faked out. But it kind of looks like I am playing a game. The other big change is that I used to have some C code which ran at launch which built a bunch of static tables and this took a few seconds to execute at 2.8MHz (less that 5 I would estimate). The plan always was to eliminate that and replace it with some codegen instead. I needed more tables for the mouse code so I did that work this week. There is no table generation on launch any more. Now, the tables are generated by a script which produces a couple of .s files which are assembled and linked into the project. I may need some more tables for efficient collision detection also but at least I have the scripts now for that.
The next thing I am going to tackle is the code to block the player from passing through mushrooms. This will be an interesting algorithm to code. I will need to traverse the set of tiles crossed by the mouse delta and detect non-empty tiles and block further motion in that direction. My current plan is to first try to apply a small part of the delta to end up tile aligned. Then, move in the X or Y direction based on which has the largest remaining delta one tile width unless blocked. If blocked, try to move in the other direction one tile width (or whatever remains of the delta). I also want to look at the real game and see if I can see it capping the speed of the player. It would be great if the player could only move 8 pixels in a single frame because then the player would only move into one new tile maximum in any direction making the algorithm easier. But if I do that, fast motion on the mouse would be reduced on screen and that could lead people to needing to pick up the mouse because it is physically moving in some direction more than it is virtually on the screen. Some testing on real HW will be needed to see how it feels.
-
BuGS Weekly Update
I planned to work on blocking the player from passing through mushrooms but I decided against doing that. Instead, I added the code to manage the number of lives the player has and detect collisions between the player and a bug. Also, every 12,000 points, an extra life is added. In the video above, I hide the player on the bottom left corner and then “shoot” bugs to get 12,000 points. You will see the extra life added. Then, I crash the player into bugs until all the players are used up and the game ends. Finally, I start a second game. So, the mechanics of the player’s lives is there now.
I did investigate the way the player moves in the real game. It looks like the player moves a max of 4 pixels per frame. In my code today , the player can move up to 63 pixels in a single frame or almost a third of the play width. I am considering dividing the input by 2 and capping it at 8 but I will need to see how that feels. I am concerned about requiring too much motion from the mouse.
Also missing in the above is that when the player crashes into a bug in the real game, the bug explodes but doesn’t increase the score. I need to figure out which bug the player collided with and make it animate an explosion while leaving the other bugs stopped. I will need this code anyway if I want to allow actual shooting which may be where I go next anyway.
-
Special Not Weekly BuGS Update
I am jumping the gun on the weekly update and issuing an update in the middle of the week because I have a game that works more or less. There is no sound and some weird issues to figure out. But I have been playing actual games tonight and it is kind of working. It is hard and seems harder than the original. Part of that I think is because the play field is 25×25 tiles on my version but is 30×30 on the real game. Makes everything cross the screen that much faster. But this is a major milestone in the development of the game.
I forgot to reduce my speed to 2.8MHz for the screen recording. This was recorded at 8MHz in GSPlus but I have played games at 2.8MHz and it worked fine. I tried to boot up my real GS and play it on there but my CFFA 3000 is acting up for some reason. I think maybe my CF is bad. Not sure yet but I am eager to get the machine working again and try it on real HW.
-
Weekly BuGS Update
Just a short update and no video today because not much has changed since Wednesday when I posted the previous video. I pushed pretty hard and churned out some buggy code for the video you saw so I spent some time yesterday tracking down some bugs and cleaning things up. I also decided to remove the border colour performance monitor stuff. I may re-add in the future (probably should make it build conditional actually). Finally, I put in some code to update the high score if the game completes with a higher score than any previous in the session. There is no persistence of high scores, nor is there a top 10 high score list. What I actually want to do is save the high scores to a file locally but I hope to add some code using Marinetti to send high scores to a server and have a global high score list. But I will have to ask you all kindly not to hack the high score list because it will be an insecure interface for sure. That feature is at the bottom of the list though.
What is likely in store for me next week is some more bug fixing followed by implementing the “repair all of the damaged mushrooms after death and add some more points to the score”.
-
Weekly BuGS Status (One Day Late)
I had a busy week and didn’t get too much done. I added the code to reset all of the damaged mushrooms after each death so you can see that in the attached video. Also, I added the code to restrict player movement in a single frame to a maximum of 8 pixels. This does make the game pretty much unplayable under GSPlus because the mouse movement is restricted to the size of the host machine’s screen and I was finding it difficult to deal with, even before the capping of movement. So, I used Kelvin’s awesome program Ample to get mame working. I can now launch either mame or GSPlus from my build environment. With mame, I pretty much have to run at 2.8MHz though so boot times are slow. If I run at accelerated speed, it seems like it also accelerates the vertical blank because the game is crazy fast. So, I will continue to use GSPlus for quickly booting a emulated GS and testing things out but when it comes to real play testing, I will be using mame or real HW. The video this week is captured using mame and does show the new “reset all of the mushrooms” after each of the three deaths.
Next, I should finish the work on player movement and actually implement the code for not allowing the player to pass through mushrooms. Now that capping movement to 8 pixels per frame is done, the algorithm for preventing motion through a mushroom shouldn’t be too bad. After that, it is either work on some niceties like high score lists, two player game support, ability to pause the game or maybe it is time to actually add some sound. Depends on how ambitious I feel I guess. In other good news, in order to use up my banked vacation, I will be off work and looking for something to do starting December 12th so I am hoping to focus more on it over the holidays. We will see.
-
Weekly BuGS Update
This week I finally implemented the code to prevent the player from moving on top of mushrooms. The implementation wasn’t too bad. I look at up/down first and if moving in one direction, I ask if the tile system if the tile the player is entering is occupied. If it is, then I reduce/increase Y to be a multiple of 8 so it is on the previous tile boundary. That tends to be an inc/dec followed by an and operation to be a multiple of 8 which is pretty fast. Because max displacement in a single frame is 8 pixels, that should always do it. Similarly for left/right which I handle after up/down. It does mean that if you move on a diagonal, say left and up and you are blocked in the up direction at your starting point, then you will not move up even if after the left displacement, the up direction is now clear. I could retry the up/down movement after a successful left/right movement I suppose but I think this should be OK. Other than that, I dug into two weird long standing bugs around centipede behaviour that I hadn’t investigate yet. One was related to when a segment is added on the left or right after the centipede reaches the bottom of the screen. If the point of entry is blocked by a mushroom, the change direction code would turn the segment around, facing away from the game screen which was bad. I now ignore obstructing mushrooms when a segment is entering the game screen. The second one was a bug where slow moving head segments did not correctly detect collisions with other centipede segments and change direction. This lead to weird problems where two slow moving head segments could end up stacked. You might think you only had one segment left but there were two stacked. That is now fixed.
I don’t have any other known serious bugs right now and game play is basically complete. The remaining items are high scores, two player and of course sound. I did some searching for samples from the original arcade but I couldn’t find anything online yet. Worst case, I think I can capture some audio samples using mame. But that will have multiple sounds playing concurrently during normal game play so isolating the flea, spider, scorpion, etc sounds will be tricky and annoying. Suggestions definitely welcome. I also spent some time reading docs about sound on the GS. Should I use the Sound Toolset? Or do I need to go right down to hitting the sound GLU registers for performance reasons. Again, wisdom about game sound programming on the GS definitely appreciated.
-
Weekly BuGS Update
BuGS is not silent any longer although sometimes you might wish it was. There is sound now when you fire, when you die, when you kill a bug and when the mushrooms are refreshed after you die. There still needs to be sound added for the background “beat” which plays during the game, the spider, flea and scorpion sound and the “extra life” sound. I have the sounds for the “beat”, spider and flea but I am not playing them yet. I am still looking for a source of the scorpion and extra life sound. The big problem I have is with stopping/starting sounds. I am using FFStartPlaying to trigger sounds that I have already loaded into DOC RAM but there doesn’t seem to be a way to stop them from playing. As per @fatdog‘s recommendation, I am using 5 generators for the fire sound and when there are many shots in close succession, I use a different generator. But that just leads to multiple sounds overlapping in time and it sounds pretty bad. If I use FFStopSound seems to unload the sound. I tried to change the volume of the sound to “turn off” the previous shot but it seems you cannot change the volume while the sound is playing, at least at this level.
So, I am coming to grips with the need for going around the sound toolbox routines and hitting the ensoniq registers myself to do what I need. That is probably where I need to go next.
-
Weekly BuGS Status Update
This week, I got rid of the calls to the free form synthesizer functions in the sound toolbox. I am still using the sound toolbox to load the waveforms into DOC RAM. But to setup the Ensoniq registers and stop/start playback, I am using the ROM routines for reading and writing to the registers that you get from GetTableAddress. I decided not to hit the GLU soft switches directly but I am programming the Ensoniq itself now. I think the sound is better, especially the rapid fire which stops and starts quickly. I have sound working for firing, killing bugs, player death, refreshing mushrooms after death, the background “beat”, the spider sound and the extra man sound. I still need to add the flea and the scorpion sound. I have a bit of sound RAM left but may need to do some optimization to fit in the scorpion sound and I don’t have a source for it.
Next steps include adding the flea sound which involves adjusting the frequency over time, finding the scorpion sound and adding it. I am on the trail of a crashing bug which sometimes happens at the beginning of a 2nd, 3rd, etc game. It does seem like some memory which is used to track segments on the screen is overwritten with $70 $02 $70 $02. I saw it once and added some debug to find out what is happening and got to this memory corruption. I need to keep pushing this backwards to find the source so I will be adding some more debug to validate things to try to find when this happens at the earliest point.
I would also like to do some work on stereo. Right now, everything is coming out the left. I want to build another table which maps a tile number to a L/R volume. Then, I can have a couple of oscillators playing a bug sound or something like that and adjust the volume on each accordingly. That way, a spider entering from the left or the right has sound which enters from the left or right. Shooting from the left will play a firing sound on the left, etc. I think it shouldn’t be too bad to implement.
Oh, and there is a bug which I am not sure is in the sample above. If you die just as the spider enters, the spider sound may keep playing. I think the bug is that the spider can enter at all actually. I will put it on my bug list right now. Yes, BuGS has a BUGS.md file in the repository which is a bit confusing.
The other bug which is in BUGS.md already is that when the player dies, sometimes the “can shoot indicator” doesn’t get cleaned up. If you look closely at the beginning of the video, you can see a pixel or two of “garbage” on the lower RHS. That is the “can shoot indicator” not getting cleaned up from the previous game when I was making this video. A round of bug fixes needs to come soon too.
I have decided to make the GitHub repository for BuGS public. So if you want to look at the code or try to compile it yourself, go for it – https://github.com/jeremysrand/BuGS
Not sure I will be taking any pull requests right now. Maybe once I declare v1.0, I will be more open to something like that. But if you want to browse the code and send me feedback, I would definitely appreciate it.
In terms of the build, I am using the infrastructure here: https://github.com/jeremysrand/Apple2GSBuildPipeline
I think the pre-requisites are ORCA/C, ORCA/M, Golden Gate, ProFUSE, make and perl. Now, I am only doing builds within Xcode on an Intel Mac. I have some feedback that with some minor changes to some scripts and makefiles, this build infrastructure can work on Linux but I haven’t in general ported those fixes into BuGS. Those fixes are in the above GitHub repository so if you want to build outside of MacOS, those may help get it working. And I would probably accept a pull request to fix the BuGS build for non-Mac platforms if you or someone else happened to have one. At the moment, it isn’t a priority for me but in the medium/long term, it would be ideal if the build wasn’t tightly coupled to any one platform. Let me know if there are other questions or problems when trying to build the code.
And yes, I used perl to generate code. I was planning on using python and to be a “modern coder” who learns the new fangled stuff (not that python is all that new fangled). But when the time came and I needed to implement the code generation, I decided to take the easy path and use a language I have worked with in the past. In my defence, perl is quite good at text processing…
-
Weekly BuGS Status Update
This week, I fixed up some bugs I mentioned last week with the “can shoot” indicator leaving some dirty pixels behind and the spider misbehaving on player death. But I also did a fair bit of play testing and added more issues to my bug list. I also worked on sound. I have sound for the flea and the scorpion working now and you can hear them in the video. Also, I added code for stereo. The sound of the spider, scorpion, flea, player shot etc is panned left to right based on their position on the screen. I found quite a bit of inconsistency about whether channel 0 is left or right. The emulators I am using (GSplus and mame) say 0 is left but Apple’s docs say the opposite. Specifically, GS tech note 19 says that even channels should go to the right and odd to the left. The documentation for the 4soniq also says that 0 is left. It seems like my ancient sound card though treats 0 as right. I may have to take a soldering iron to it. Is there real inconsistency out there among the sound cards? Maybe I need to make L/R configurable which is annoying.
And as a Christmas present to everyone on the appleiigs channel, here is v0.9 of BuGS. This is not a bootable image, just the executable. If you are using an emulator, I suggest using mame. I am using “apple2gs -skip_gameinfo -mouse -window -resolution 1408×1056 -ramsize 4M -sl7 cffa202 -hard1 <boot image>” as my arguments to mame and that is working for me. It does work under GSplus but the mouse control isn’t ideal and you will probably find it frustrating. I haven’t tried other emulators. I have tested this on real HW and it seems to work there although the sound is decidedly more “muddy” than I get on emulators. Keep in mind this is a pre-release build and there are known bugs that are documented here: https://github.com/jeremysrand/BuGS/blob/master/BUGS.md
My next step needs to be some more bug fixing and some more play testing!
-
Weekly BuGS Status Update
This week, I fixed a number of bugs, including a crash that was possible in the release I sent out last week. Not many known bugs left in the code but I am sure there are lots to find yet. Beyond that, I implemented code to pause the game. Now during a game, any key press will pause the game. This will bring up a prompt saying to press Q to quit or any other key to resume the action. Sound is also suspended and resumed during a pause. There was some discussion around the lack of a clear standard for left/right audio on the GS and there may be different hardware out there which reverses these things. So, I implemented an option to swap the left/right channels. While doing that, I added code to load/save a settings file where this option is stored so it is persistent across restarts. Finally, I have added a top ten scores to this settings file and added the code to insert scores into that top ten. What isn’t there yet is code to prompt for initials. For now, it is hardcoded to my initials (yes, my initials are JSR) but everyone should be good with that, right?
Next step will be to actually add the prompt for the players initials. I would also like to finally implement two player games. Once I have that, I think it could be called feature complete. But I would like to add some support for a global high score list. Whenever you get on your own local top 10 score list, I think the game should send that high score to a DB out on the Internet of the best scores. Then, if you are on a GS with an Internet connection, you would see local and global high scores. Basically, the project is getting to the point where nice to have features and bug fixing is about all is left. I am hoping to do an official release in February, maybe January if things go very well.
-
BuGS Status Update
Here is v0.9.1 of BuGS. It addresses many of the issues from the previous build. It also adds the ability to swap L/R channels in stereo if your stereo card is standard/non-standard. It saves your setting across restarts of the game. And it now keeps track of the top 10 high scores and you can enter your initials. These should load across restarts also. I am not aware of any crashing bug in this build but I also had seriously weird problems when I loaded it on my real GS. There were weird graphics artifacts appearing, especially when a flea would drop near the middle of the screen. I can’t reproduce it on an emulator yet though. If you get graphics weirdness, I would appreciate a picture of the screen to see if it is the same as I was seeing. There is a possibility the problem is somehow with my HW.
This also has the new icon thanks to @fatdog.
Note that the instructions says to press 2 for two player, however that isn’t implemented yet. If you press 2, you get a single player game – for now…
-
BuGS Status Update
I found the crashing bug I was experiencing and I believe it is fixed with this build. And I believe it also explains the other crashes people saw on other configurations. The problem is that the sprite code is in a different bank from most of the other code. The player and shot sprites try to write to a pair of words to describe a collision if any is found during the draw. These were defined to be in the same bank as the sprite code but the data bank register was incorrect. So the writes happened to the wrong bank and what happened to be there got corrupted whenever a player or shot was drawn. On my machine, that was tileBelow data. I have fixed the writes so they happen to the correct address and I can no longer reproduce the crash and the code looks right to me. So, this build should be better. Thanks for everyone’s help.
The wrong bank was leading to the flea smearing across the screen. What was happening for me was the the tileBelow array was getting corrupted. The flea animation uses tileBelow to figure out what tiles need to be marked dirty and need to be redrawn based on the flea’s changing position. Because tileBelow was corrupted, the wrong tiles ended up being marked dirty. That meant that the flea was not being erased anymore between frames so it smeared down the screen. Worse, the flea detects it has reached the bottom of the screen when the tileBelow says that it is an invalid tile offset. Because the tiles that the flea is tracking are no longer correct, it doesn’t detect the bottom of the screen and the flea continues animating beyond the bottom of the screen, corrupting the SCB. Basically @digarok nailed it when he said that there was off-screen writes happening. I just needed to figure out why that was happening because the flea code should make it impossible, as long as the tileBelow data was correct, which it wasn’t.
-
Weekly BuGS Status
I don’t think I will post a video this week since visually, there isn’t too much new to see. And there is a pretty good build out there so if you want to see what it looks like, give it shot. Of course, the big effort this week was to fix the mysterious crashing bug I had and thanks to the support here, I believe it is addressed. I have started work on two player support since then. When you use ‘2’ to start a game now, two players are initialized and internally there is a playerNum value which tracks which of the two players is playing. If I force that value to be set to player 2 at the beginning of the game, I can play through a game as “player 2” and the right score and lives counters are now updated. But this work isn’t done. I actually have to implement the code to swap back and forth between the two players, prompting whose turn it is, handle the case where one player dies quickly while the other player perhaps has multiple extra lives and continues to play for a while after the other is done.
Work is threatening to get much more busy so I am considering deferring the online high score list for a follow-up v1.1 or v2.0 release and declare v1.0 without that feature. I worry that I will end up distracted and not able to finish if I don’t focus on achieving v1.0. Once that is done, if work doesn’t distract too much, I can try to implement the online high scores and my daughter has offered to do the server side work and that is good experience for her.
Changes – none since last status update
-
Weekly BuGS Update
I have some bad news that my prediction that work was going to distract me has come true. I only got one evening this week to work on the game and I pushed forward with support for two player games. But I don’t really have anything of substance to show this week – just work in progress. And my schedule looks pretty full this weekend.
I am committed to getting a v1.0 though. I will negotiate a deal with my spouse to get one or two days next weekend to try to focus on it assuming that my evenings continue to be burned during the week. Thanks for your patience.
-
BuGS v0.9.4 Beta Available
The primary change is a fix for how sound samples are started. Prior to this, I thought the sound was “muddy” on real HW. The root cause was that I wasn’t ensuring that the DOC was free when trying to write to it and now I am also doing a read check to make sure that the change made it under most circumstances. That ensures that both left and right channels are started and the sound is much better.
The only bug I know of which I am tracking is the “mysterious appearing mushroom” bug. There are times when a mushroom seems to appear out of no where. I added some debug code to try to find a situation where a mushroom exists in the tile data but not on screen which is one way this can happen. But the debug code was never triggered so I don’t think that is happening now. I can’t reproduce it reliably and see this once every 5 or 6 games. But if you see it have any idea of how this is happening, it could help me find and fix this bug. Thanks.
I believe I have found the mysterious appearing mushroom bug last night. The problem was that a centipede segment which is mostly offscreen was supposed to be marked as occupying an off-screen tile. And that should ensure that collisions are not handled and some other things like that. But, I messed up the offscreen tile. I have tile numbers which are in increments of 1 and tile offsets which are in increments of 2. I should have put in a tile offset but I instead used a tile number. That meant that the offscreen tile actually mapped to the middle tile on the game board (it was half of what it should have been). Then, if you happened to “shoot” an off-screen segment right as a level is starting, it would lead to a mushroom appearing on the centre of the screen. By fixing the tile offset of the offscreen segments, I was no longer able to reproduce it. The next beta build should have that fix in it.
-
BuGS v0.9.5 Beta Available
This release should fix the “magical appearing mushroom” bug from the previous beta. I have written a Readme file which is part of the distribution which describes issues with emulators, track balls, stereo cards, etc. It also includes support for Speccie’s Versions application to make network based updates possible.
I think this is a v1.0 candidate and feedback definitely appreciated if you find any issues that should be fixed before that milestone. Thanks everyone!
-
BuGS v0.9.6 Beta Available For Testing
The changes since v0.9.5 address some typos in the readme. Also, @roughana suggested adding borders on the left and right side of the screen to delineate the play area from the rest. I have added those and I think they look pretty good.
Still racing towards a v1.0 at this time I think so feedback definitely welcome.
-
BuGS v0.9.7 Beta Available For Testing
This version has a change that preloads the sounds from resources into main memory after the initial screen is shown. It used to do that at the beginning of the first game which introduced a long delay when starting that first game. Now, responsiveness is better. Also, there is more in the readme with a number of acknowledgements.
-
BuGS v1.0 Is Now Released
http://www.rand-emonium.com/2021/02/11/bugs-version-1-0-released/
BuGS
Thanks everyone for all your support here on this channel!