Few days ago I started working on new game called Nemezyro, which (as usual) contains some significant features/technologies which I never used before.
So what is Nemezyro about?
It is relaxing logical game which requires fast responses. There are randomly generated colored tiles scrolling from right to left and player’s job is to eliminate those tiles as long as possible until they reach left border of playfield. Tiles are eliminated by pointing at them with cursor controlled using joystick and pressing fire. All adjacent tiles of same color are eliminated as well. There is one special feature when we speak about adjacent tiles, because also first and last line of tiles are adjacent to each other – this fact sometimes causes that you might think those tiles are eliminated without your action :).
Lets speak about how it’s done and what challenges I had to overcome…
I started working on this game on 20th of august, unconventionally my first task was to set name of this project. I had several thoughts of its name, but then I found nice name generator online, so after several hundreds of generated names my eyes stayed on Nemezyro. Then I started coding, first was scroll engine, then I took graph2font where I designed colors and DLI. Afterwards I exported them and used generated DLI routine in my coding. Back then game contained 4 types of tiles, but later I removed orange one during fixing some graphics issue and I decided not to bring it back.
After pause that lasted 3 days I told myself that it is time to proceed with this project so I started adding player interactions quite furiously.
I was quite worried about timing, how will system respond to 4 color changes inline when using normal-width playfield, but curiously it worked smoothly without any glitch.
Next day was free and then I started working on game logic and some special feature. I was searching online for some quick and easy floodfill algorithm, but then I realized I have no other choice than rely on myself so I coded my own simple buffered (w/o using stack) floodfill algorithm. It had some tiny issues, related to bottom-to-top adjacency, but basically it worked:
I got in touch with Poison – I am big fan of his music – so I asked him if I might use some of his music in my upcoming project. Unexpectedly he responded very quickly, he just finished new music, which was originally created for Fandal’s new multijoy4 game, but Fandal refused it because it was stereo. Of course music was excellent so I decided to add it into game. Poison composes his tunes in SDCMC which states for Stereo Double Chaos Music Composer created by Datri. It is a modified version of classic CMC which uses 8-channel stereo and mysterious double mode. I will deal with this “jewel” later…
Recently almost every Atari game uses tune created in RMT (Raster Music Tracker), which has nice SFX support. I don’t know about such thing in CMC, I slightly remember that it might have something like sfx support, but documentation is quite hard to find, so I thought of something quite innovative.
What could be innovative on Atari? – It is unexpected, but from time to time something special appears in our Atari world and in this case I was thinking about using keyboard beeper as SFX generator. Sound of keyboard beeper is not handled by Pokey (audio) chip, but by GTIA, which is also responsible for PMGs, graphics modes with fat pixels of many colors and function buttons like Start and Select.
It was not long ago when XXL created GTIA sample player that plays music modules as they were samples. To play such sound, you need frequency modulated signal (amplitude cannot be changed). Whole trick of playing sound trough GTIA is in alternating writes of two values into CONSOL ($D01F), magic is in frequency of those writes.
After couple of tries I understood that I cannot play anything nice during VBI time so I at least created sort of buzz generator for VBI. Problem is that you need to perform CONSOL writes in significantly much higher frequency than 1/50th of second. I also contacted XXL to be sure that I am doing it right, but I realized that I cannot perform any sorcery using this technology in my project, so I left that buzzer as it was…
Big change happened on 30th of August quite close to deadline. I added high amount of content, but only single one code version was committed to SVN. After I added ingame music I realized that GTIA buzzer has no place in this game anymore. It was not even noticeable when Poison’s beats were kicking so SFXs were completely rejected. Day before that I was working on other special feature. It was RastaConverter, genial creation that can display unexpected amount of colors in static picture without flicker. Trick behind this is utilization of hill climbing algorithm to iterate color changes of PMGs and bitmap graphics to find closest match to desired picture. This incredible tool is authored by Ilmenit (man, u are the boss!), some time ago (like 2 years ago or so) there was quite alive discussion about RastaConverter at AtariAge, but I really cannot remember single game that uses such picture. “Challenge accepted, I want Rastaimage as title screen!”. I spent some time figuring out how it should look like, finally I chose colored grid with title in the middle.
I created several versions, I mostly tuned the title (size and font face), but then I found combination that brought impressive results. I spend almost whole day with this task, I was changing colors, dithering algorithms, .. and some other variables …. this logo was generated after 160 million iterations and I took about 4 hours on my quadcore Elitebook… but result is really impressive.
Madly gigantic code (more than 20kB) generated by RastaConverter was added to game together with music and I was unpleasantly surprised that SDCMC replay routine in double mode cannot fit into VBI so it interfered with display of title logo. Result was glitchy (especially during drum parts) and sometimes music got slowdowns.
In the meantime Poison provided slow version of music for SLOW game mode. I had to ask him to remove drums from this song and to tune it for normal (non double) mode. I hoped that this kind of tune will not interfere with timing so logo as well as music would be nice and stable.
Now it looks, like everything went very well, but reality was quite different. All this happened after very strong “bleeding” which was caused by SDCMC player. I discussed it with Fandal, I really have to thank him a lot, because I might not make it work without him. He wrote twice about SDCMC on his blog and every time he described unpleasant experience, so this time I tried it on my own. Player routine as it is plays music in normal mode. This version of CMC player has one special flag that has to be set in order to play music in double mode. Double mode runs alternate replay routine which takes much more CPU time than normal one, but listener is rewarded with much better sounding drums. It is something like when you run RMT on TMC player twice a frame, but this one is run just once. Funny thing is that one sound channel plays total jibrish in double mode and also one part of replay routine reads some data from addresses which have no relation to music ($FF00). Fandal warned me about these facts, so I fixed some bugs with his patch, but I could not fix this weird reading from last memory page. Then I fixed it by trial and error method so I changed 1 byte of music to different value. Btw this issue caused that song refused to loop so when replay routine reached end of last songline it just went silent. Second “funny” thingie about SDCMC is its integrated Disk Manager where “load” function works only on second try and “save” works only when using Atari800winPlus (I believe that also SIO patch has to be also disabled). You might get totally lost when using Altirra, no disk write possible – funny. This fact really “amused” me because I use Altirra exclusively and I had to discuss this issue with Fandal again… after 25th unsuccessful disk write attempt.
31st of August came, the day of deadline. Status: title screen worked, music caused glitches (see screenshot below with enabled frame blending), game logic was not really implemented at all yet, it was possible to click on tiles, but nothing was eliminated or animated yet.
Poison prepared new version of SLOW tune without drums in non-double mode, which really did not cause title screen glitches anymore, nice nice. I was still fighting with error I did not mentioned yet. How to describe it… simply …sometimes it just somehow lost screen synchronization, display started to flicker and then it turned black. It would not be nothing unusual if game would not behave like nothing has ever happened. Man would expect interrupt break, execution of illegal opcode and crash… but no such thing happened, everything seem to work but display.
I have never dealt with such issue. As I was in great despair, I sent binary file to Fandal, to check how it looks to him and he replied that he did not see any issue. “It was not very well synchronized, but otherwise quite ok.” – he must have been joking or something. Fandal as an oldschool coder (he does not use macros like MVA,MWA,SUB,ADD,PLR,PHR and also .PROC and .LOCAL) primarily uses old (non updated) emulator Atari800WinPlus4.1. I am using Altirra for almost 3 years and it was quite surprising that my binary worked on Atari800WinPlus quite stable (with display), it almost blew my head off. I was searching for error according to incorrect symptoms … whole time.
I managed to fix this issue, eventually. HSCROL was responsible for such behavior. I tried to write whole program without any silly screen-synchronization loop like LDA:CMP:REQ 20, apparently it caused change of HSCROL during scrolling in kind of “weird/forbidden” time which caused Altirra to lost its control.
Ok, nice, picture was not mangled anymore, but more than one person would suffer from epilepsy when playing this game. Horrible flicker appeared during one of 8 frames exactly in moment when fine scrolling turned to coarse scroll and whole videoram needed to be shifted. I believe that it could fit into one frame, but in my case I was redrawing whole scene one tile after another. So I started to work on double-buffer and surprisingly it took less than hour to make it nice and smooth. It was alternating video ram destination and synchronizing it with DisplayList changes. I was excited because finally I did some serious progress so I could focus on actual game not just fixing stupid glitches, flickering and other broken video stuff.
The only problem was that it was already 8PM so just 4 hours left to the deadline.
I swiftly created fonts, added simple (but I think quite nice) ingame logo and some lines to make ingame screen more classy. I did not know what to do next, there were so many things to work on and I just started to lose faith that I could finish game at least as fully playable beta version till midnight.
Suddently my cellphone beeped and PG wrote me that he sent game to Abbuc only one minute before deadline…. “say what?” he must misunderstood the rules, deadline must be at midnight as usual… nevermind, I checked rules online and I could not believe my own eyes, deadline was at 10PM!
It took me some time to think what to do, but I decided to act quickly. I took game as it was, attached it to email and sent to Sascha Kriegel (skr) who is responsible for software compo and I wrote him simple game description as well as information that I did not know that deadline was shifted 2 hours this year.
I stayed confused for couple minutes, but then I decided to continue working on game, at least I could release it sooner. I started working on relocations sometime near 11PM. You know, coding something for emulator is quite nice, but real HW has one solid limitation in case you need to load data under ROM. In emulator, you can do this directly, but on real Atari you have to load data temporarily somewhere in RAM, then turn off ROM and move this temporary data under ROM address space. You should know that ROM (among other things) consists of disk loading routines, so these routines are not present if you turn it off… in case you try to use them with ROM off, system crashes immediately. That is not anything new, I am dealing with this in every project since Summertime demo. Problem is that crazy Rastaimage eats more than 22kB of memory and it is not trivial to cleverly stick it under OS ROM or Basic ROM. I planned spending 1 hour to relocate all data to make game runnable on real Atari … “Oh, what a horrible underestimation!”
I gave up standard approach, it was not working at all and it is quite frustrating when you literally destroy functional game the way that you cannot run it successfully after one hour of relocations tuning. So I reached for 2nd approach, use of runtime packer to perform relocations. I use TeBe’s SuperPacker, but I was not able to make it work even after 10 tries of various packing sequences. “Ok, it is too late, I really do not have nerves for this.” – so I reverted my code back one hour from my SVN repo and I put relocations on hold.
I continued with development and simple score worked sometime after 1AM, then I was working on difficulties and game modes. I went to get some sleep near 1:30 after fixing bug that caused occasional “reverse movement” of tiles.
Next morning (1st of September) I found email from Sascha Kriegel. I was reading and again I could not believe what I saw, Nemezyro was successfully registered as part of compo, Sascha required description and working playable version till deadline, and that is what I provided. Deadline was shifted further. It was not very clear how Sascha meant it, so I discussed interpretation with MaPa. Eventually deadline was shifted to 3rd of September… and it was also possible to send bugfixes till 7th of September.
This caused wind in my sails, so I began to finish game for Abbuc SW contest. I bled on relocations since morning till 3PM when I eventually make it work. I tried to relocate code generated by RastaConverter (so foolish), but then I got enlightened. I left code at same place where it was built and I put video data under ROM. Well, man has to learn all time, unfortunately sometimes on same mistakes… when he forgot about them from previous project.
Then I was working on Options screen design to have 3 gameplay modes. I played with design a bit and then I nailed it with infinite loop of writing random values into background color. It reminds me decompression visualization, I hesitated whether remove it or let it there, but then I decided to keep it…
I worked on game cycle and statuses that defined when to move from title screen to options screen, then to game and how to get back after game is over. I finally fixed recalculation between PMG cursor position and tiles in the evening, this recalculation was quite imprecise before… my testers reproached me of this quite a lot :). Options screen was finished close to midnight and it contained last score and best score. I tuned various game parameters for each of game modes and I added reload time parameter which prevents player to perform fast tile elimination without delay in between. Cursor just turns orange and after some time it turns back white and after that player may perform another elimination. It again required difficulty tuning, then I went to bed close before midnight.
Next day (3rd of September) was final day of my work on Abbuc game Nemezyro. I started finishing game at the evening, again lots of difficulty tuning and I had to add time (stopwatch like) into game to tune difficulty even better. Final build was done at 10:40PM and I sent it to Abbuc right after I built it.
It was quite a challenge once again, always new surprises, it is hard road to take but I like it this way…
P.S.: I wrote this blogpost in 2 evenings and 3 more evenings took me to translate it to english. It was more like 1hour of translation each evening, but I was not quite sober all time, so I hope you can still understand my thoughts and writings ;).
Awesome game as usual from you 🙂
Thanks for sharing your story.
Quite confusing this shifting of the “dead” line. Sascha, what’s going on with you? 😉
A very vivid, enjoyable chronicle… and as a result of your effort, an even better game.
A nice read – glad to see someone else under that deadline pressure!