Show older

I have a really hard time imagining anyone but me enjoying working this way, but at least there's one person

Streamlined level 2 a bit - in my head forever referred to as "the hellmaze" - but it's still pretty hellmazey. Mostly I ended up getting rid of doors. It's a Neut-centric level anyway so it feels basically the same. There's still a pointless switch & door I could get rid of but it'd mean getting rid of the fun "how will I turn on multiple switches that are next to each other" surprise.

It's definitely a lot easier to work with a real map editor!

whooops level 3 has enough text in it that the code spills into video memory 😬

Bad: code immediately gets overwritten when I draw the screen and I then tell the game to try to execute graphics

Good: Interactive execution from my editor still works - it just draws over a random part of the screen with code and then executes it

The thing about Neut Tower is that every damn level adds a new mechanic. I'm up to level 5 (of 6!) Drawing the maps is so quick and so easy, and then it's like "oh I guess I need to write a some code to make this actually work now." It never ends up being _that_ much work but it still kinda makes me tired sometimes.

Fun retroprogramming pattern: repeatedly ask yourself “am I over-engineering this?” until there’s nothing left but your actual problem

huh, I've managed to get five levels in without needing to implement less than / greater than in my VM

gave in and implemented < for level 6, but I refuse to implement full 16-bit multiplication. math routines requiring a loop?? unthinkable. I'll use a weird encoding and a fixed number of bitshifts instead.

Almost got the boss key in. It works, but there is a lot more flashing text than I expect. Laid it out visually in VisiCalc, and then wrote a little fennel routine to generate the bytes.

Haha fun, loading the boss key screen into the second text page breaks the tape loader, so I have to load it into main graphics memory instead, which means it now appears while the game is loading

Have reached the point where I don't have much work left to do except figure out how to put my game onto a floppy disk, so I'm reading about ProDOS. Will probably end up writing some Fennel code to inject files into a blank disk image, because this dumb project is about nothing if not rewriting my own tools from scratch instead of using other peoples'

I've injected a BASIC program into a ProDOS disk image! The disk no longer boots for some reason, so some more investigation is needed, but this is a big first step.

Fun story: at one point a minor bug caused my “insert a new file into this disk image” program to actually be a “recover a deleted file from this disk image” program. Naïve undelete is so trivial on these old file systems I did it by mistake!

It’s so refreshing that the best documentation for how all this stuff works at a low level was published in the 70s and 80s directly by folks who worked on it and with it, instead of textfiles describing incomplete, haphazardly reverse-engineered guesses, decades after the fact

... huh. It looks like maybe I uncovered a ProDOS bug in 2.4.2? The blank disk image I was using, which was the stock ProDOS 2.4.2 release except that I manually deleted a bunch of files from within ProDOS, had a block marked as free which was actually part of the boot loader. So when I injected my file, I overwrote part of the operating system with my "hello world" program.

Welp, I wrote a little routine to look for blocks that are incorrectly marked free and fix them, and now the disk boots. Wild!

Realized as I was going to sleep last night that I’m reading the free block list backwards, so it’s a bug in my code after all

FINALLY implemented level transitions, by just loading all 6 levels into RAM at once. Turns out the whole game - code, graphics, text - currently fits comfortably into 32kb. (It won't quite run on a 32kb Apple like this because a big chunk of that is reserved for graphics and stuff, but 48kb is not an unreasonable target.)

Somehow this broke hot code reload? 😬

Tooling bugs aside, this means Neu] [ower is officially completeable now!

I still don't have a .DSK image to put anywhere, but the end is in sight!

I have successfully generated a disk image that boots into Neut Tower in an emulator!

My Apple ][+ is still acting up but I’m able to boot my game from a floppy on my Apple IIgs! A shame that my most convenient video option is OBS on my laptop but hey.

Retro game development is just the process of writing a series of barely-usable custom paint programs. Now I can draw full-screen bitmaps (and I have a separate editor for editing "brushes"), because a game needs a title screen, right?

Reworked my disk loader so it boots to a stub that only knows how to load the title screen and then rest of the game. My code to make ProDOS calls worked flawlessly first time, shockingly. ProDOS has good docs!

I ought to start putting disk images online, now that I’m finally producing working disk images

Neut Tower is a puzzle game with no undo - there should not ever be any way to get yourself stuck.

Doing some polish work and I just discovered a way to get yourself stuck on room 4. Whooooops

There are a bunch of open-source Apple ][ emulators that run in the browser, but the only one set up for the use case of "embed this on your webpage to boot one specific game" is MAME on the Emularity and Apple ][ emulation in MAME has unpleasant crackling sound issues :/

Game music on the Apple ][ has a great variety of interesting sounds and polyphony. By comparison, DOS games with PC speaker music uniformly have the same single-channel square wave beep. But it's the same damn 1-bit speaker. What's the difference?

PC: Has hardware dedicated to generating a square wave at a given frequency.
Apple: Has no such hardware. To make a sound at all, you must do all of the timing on the CPU to generate a square wave. This means you can trivially try other wave shapes.

On the PC, techniques to play digital audio samples out of the 1-bit speaker were advanced wizardry; you had to use all of your CPU power to do it.
On the Apple, the same thing is basically true, but that's just how making any sound at all works, so you might as well play with your harsh-sounding beep routine and try to make it sound more interesting.

A related question is how did Tim Follin get 5-voice polyphony out of the ZX Spectrum's 1-bit speaker? The answer appears to be "the Spectrum's CPU was about 4x as fast as the Apple ]["

Seriously, listen to this. AFAICT there's no technical reason this couldn't have come out of a low-spec DOS PC. youtube.com/watch?v=UUpvQEfMJs

Thought about implementing a random number generator to make white noise... then realized I could just generate some random bytes from Fennel and put them inline in my program

the period is a little shorter than a proper LFSR but it still sounds fine

Big reorganization of my booting / loading routines this morning, so the game code and the initial loader code can use the same virtual machine and disk access routines. In my head I was like "this is going to save so much memory!" but my VM is quite small -- 936 bytes!

I almost called it "tiny" and then I remembered the SWEET16 VM Woz wrote for Apple II Integer BASIC. That one's only 393 bytes, and Woz wrote an article that's like "PS here are the parts you can delete if you don't need 'em."

Wrote a 1-bit tone generator that assumes a “short blip / long pause” waveform and now there is a part of my brain that kinda wants to try writing a two-voice 1-bit music driver

I... think I might be done Neu] [ower? I just put in the introduction sequence, implementing a touch I never bothered with in the MS-DOS version - starting the room with no broken furniture and then slowly knocking stuff over. I'll need to play through it and see if there's anything else I want to polish, but the game is all there, start to finish.

I've added cheat codes, which has led to the discovery that warping _backwards_ to a level you have already played has... some strange side effects. I never reset the state of the level, and in fact currently have no way to do so. I don't _think_ there's any way to crash the game, but, it's definitely weird.

I have a few options to deal with it and I'm not sure which one I like best, so, poll!

Follow

Alright, I'm calling it -- Neu] [ower is done! spindleyq.itch.io/neut-tower-a

You can download the disk image and play it on an emulator / real hardware, or you can play it directly in the browser.

Let me know what y'all think! It's been a fun journey to put this all together.

Sign in to participate in the conversation
gamemaking.social

Hi! Game Making Social is a part of the Fediverse dedicated to being a well-moderated, cosy, friendly place to talk and share stuff about amateur videogame making, and everything surrounding that.

It's kinda an offshoot of Game Making Tools, which is a wiki(+) for a similar audience.

Game makers, game writers, game curators, etc. etc. most welcome!

I also try to maintain a list of not-jerk game-making communities on the wiki, which you might find interesting.

Please read the rules before signing-up :)

PS: We have Animal Crossing, LSD, and Klik & Play emoji :3