How much of MYST can you run on a 4k 16k Atari 2600 cartridge?
I was doing some Atari programming and thought I'd try out Myst.
It's nowhere near a complete game, for that check out my
Apple II demake version
The game is complete! It's not the full game, but it is
enough to do a speedrun (you can beat original
Myst very quickly only visiting a tiny part of the game if you already
know all the answers).
Currently you can walk around a decent amount of Myst island.
You can flip the marker switches.
You can look at the brothers' books.
You can go to D'ni and get both endings there.
You can solve the fireplace puzzle.
You can solve the clock puzzle.
You can pick up the red/blue pages and get both endings with those.
You can go up the elevator in the library to see a hint.
This product contains trademarks and/or copyrighted works of Cyan.
All rights reserved by Cyan.
This product is not official and is not endorsed by Cyan.
Here's a longplay showing off a lot of the gameplay (version 2.6)
recorded on actual hardware:
The game engine uses ZX02 compression for each scene.
Each scene's graphcis are limited (due to various hardware limitations)
to 256 compressed bytes, which means I sometimes have
to simplify the graphics to fit. Each scene has an asymmetric playfield.
Graphics are 40x48 to simplify things a bit. Each line can be two colors,
foreground and background. We fix the background to a single color.
The foreground color can change each 4-line block. I use sprite1 as an
8-block wide source of additional color, so one extra color per line
but only in an 8-block wide column of the screen.
You also get an optional one-block wide vertical line
(missile0) which is the same color as the pointer. The engine
allows the right-side of the screen to alternate background color
every-other-line though it's unclear if this is useful or not.
When uncompressed the graphics are 448 bytes
which are temporarily stored in the 2k RAM supplied by the E7 cartridge
(by default a 2600 only has 128 bytes of RAM).
Note: these were captured with the Stella emulator.
If you want to see screenshots from the original 4k proof of concept
you can find them here
You can download the images above and run in an emulator like Stella or MAME
You can in theory play it in
on Javatari (note, until recently there was a bug in Javatari's
E7 cartridge emulation that crashes the game after a few steps.
I've contributed a fix but not sure how
long it will take to get merged and fixed on the website)
Finally you can also
possibly play in your browser at the internet archive
(as of 8/2023 you can't as the version of MAME they use doesn't
work with it)
Q. The graphics look pretty bad.
A. It takes a lot of work to make nice graphics. Each scene
is more or less a procedurally generated demo.
By default you only have a 20-bit (yes, bit) framebuffer,
and you can only draw one line a time, with only two
colors in it. Anything more than that is someone
being really really clever in 6502 assembly language.
Q. But no one in the 80s would play this!
It's completely incomprehensible unless you played
the original game!
A. I'm making this project because I think it's a fun thing to do.
I've played actual Myst before so I'm set there.
I'm not planning on taking my time machine back to the 1980s
to try to sell this as a product, so the people of the 80s
are safe from at least this particular hard-to-understand
Atari 2600 game (but you may find that there were plenty
contemporary ones that weren't much better).
Q. Are you going to do the whole game?.
A. No. Even though you can get fancy bank-switch cartridges
these days I prefer to work within the limitations of
the time. Also to do the full game requires at least
800 scenes, which would be roughly 200k, which would
be both a pretty hefty cartridge as well as a lot
of graphics to draw.
Q. How did you learn how to make Atari 2600 games in
less than a month?
A. A lot of skills I have from my Apple II hobby directly transfer.
6502 assembly, 6502 size-coding, 40x48 lo-res block graphics,
beam-racing demos. Doing beam racing is actually much
easier on the 2600 than on the Apple II due to the WSYNC
Q. How do you make the graphics?
A. I run the original game under SCUMMVM. I take a screenshot
and load it into GIMP. I crop it, raise the brighness
a bit, then size to 40x48.
I then remap to the Atari 2600 palette (no dithering).
I expand to 80x48 for editing. I then draw over by hand.
The biggest challenge is picking what color to be the
background color. It's often black or dark grey.
When done I manually split things up into two images,
background and overlay. I then have tools that convert
these PNG files into data that can be loaded into the
assembly language of the game.
Q. Why are you compressing things? Why not just use
uncompressed data and a larger ROM?
A. Each scene takes just under 512 bytes, so in theory if there
are 64 scenes you might be able to squeeze on a 32k
ROM and would probably fit comfortably in a 64k ROM.
This would also be faster as decompressing takes at least
3 frames, adding a flicker each time you move to a new
scene. This might be something intersting to explore,
but I'm enjoying the challenge of trying to fit in
16k. Also I do take advantage of having the current
level data in RAM as I patch some values on the fly.
6 August 2023 -- Release v2.6
Went back and decided it wasn't complete. Ran through things a few times
and noticed some minor adjustments were needed. Then I realized that getting
back to the dock was too abrupt, so I made a new location (at the bottom
of the gears hill). It was only 179 bytes but I had to re-arrange
and re-time a huge amount of things to squeeze it in. It looks good
under MAME and Stella, need to run through things on actual hardware.
3 August 2023 -- Release v2.5
I'm calling things complete! I just ran a glitch-free run on stella.
Next is to try it on actual hardware.
I tediously went through and made sure every scene gave 262 scanlines.
There's actually 200 bytes free on the cartridge still, but it's spread
across the ROM banks in a way that makes it difficult to do anything
useful with them. I do have a completely prepared location
(the dentist/planetarium) that's 247 bytes and so won't fit.
I still worry the 2-frame of black on scene transition (due to
decompression time) might be too much flicker for some people.
I added code so if you flip the Color/BW switch it will lengthen
the transition and maybe be easier on the eyes.
1 August 2023 -- Release v2.4
Fixing some bugs and super cycle-counting everything. Have most of
the glitches fixed, although moving the grab code to two scanlines is
enough for everything but page grab which is going to take three so I
might have to bump it up again.
Also wrote a manual of sorts
31 July 2023 -- Release v2.3
Getting close now. All four endings are implemented and you can pick
up the blue/red pages.
What remains is mostly cycle-counting to keep everything in 262 scanlines
everywhere, then size-coding to see if I can fit the last two locations
I have in.
Getting to this point was a huge amount of work, and I also wasted a lot
of time re-arranging the ROM bank layouts to optimally pack the data
with as little free space as possible.
23 July 2023 -- Release v2.2
Finally got the clock puzzle hooked up. This required more work than
you'd think. It was tricky getting the clockface to display, managed
to cram it down to only 80 bytes of sprite data with some clever packing.
In an ideal world I'd use two sprites or use sprite scaling for a better
hour hand, but in the end I just do some masking.
Once that was done
I had to make it possible to raise/lower the bridge, so had to come
up with a relatively compact way to patch the overlays on the fly.
I made this more complex than necessary so the code would be generic enough
to let me also handle the door open/shut in the library, that way allowing
the player to go up the elevator to find a clue to the clock puzzle.
We were also seriously out of room so I spent a lot of time shaving bytes
off everywhere I could to free up some space. This often involved moving
things around, which is a pain, especially if it changed timings. I also
re-did the level headers to use the div-15 position code instead of
pre-calculated coarse/fine offsets. That probably saves some space
but it meant I had to go by hand and update 56 room locations and then
play through and make sure everything looked the same as before. Not
sure if that was worth it for the 100 or so bytes saved. It did free
up room in the data structure for the overlay patching though.
Remaining plan is to properly handle the blue/red pages and get the two
bad brother endings. Then finally if there's any room left maybe
add 1 or 2 more locations.
Spent the last two weeks on vacation but also working on the Fireplace puzzle
which now works properly. The original implementation re-drew the entire
grid from scratch each frame, which was straightforward to implement
but took up 30 bytes of Zero Page and 23 scanlines, which was too much.
Optimized things to only draw one row and only when clicked. This is much
Was having issues where clicking wasn't precise, realized I was using
some simple sprite positioning code that was cheating and dividing by 16
instead of 15. Put in some proper code which actually made the code
a bit more compact as well as having the sprite0 co-ords match up with
the playfield better.
Moving things around and size-optimizing a bit. More or less out of
room in the smaller always-visible ROM area of the E7 ROM. Need
some more bytes for the clock puzzle, and I would like to eventually
have all 4 endings.
28 June 2023 -- Release v2.0
Getting unexpected press for this, which is fun, but a shame I don't
have it totally complete. The updated version adds a few more scenes,
and also lets you click on more things. You can actually "win" the game
though it's sort of meaningless as the fireplace and clock puzzles
aren't hooked up. Really starting to be pressured for space, hopefully
I can fit in all the remaining features.
27 June 2023 -- Release v1.9
Added a few more scenes, starting to run out of room. You can
actually pick up the white page now. Hooked up the green book.
Working on getting all possible endings implemented. Mixed up
the order of the directions in the data files which was a huge pain
but ended up saving 16 bytes. Maybe not worth it.
22 June 2023 -- Release v1.8
It's Mysterium time again so working on things again. Added two new
locations. Also tracked down the bug in E7 cartridge handling in
Javatari that was making things crash. It wasn't properly turning off RAM
when we switch ROM back in. I've contributed a fix upstream, we'll see
if it gets fixed.
23 December 2022 -- Release v1.7
Finally had some time to work on things again. Finally got glitch-free
(multi-frame) decompression to work, at least on Stella.
So can maybe now work on features again.
1 October 2022
Work has stalled a bit, partly because the semester has started, but
also due to being stuck on some complex code. Curently the graphics
are compressed, and decompressing them takes 3 or so frames. While this
looks fine on the stella emulator, if you go 3 frames without SYNCing the
display you'll get annoying glitches on real hardware (or at least you
do on the NTSC capture cards I have). So I've been working on having
the decompression happen in parts with proper sync happening and it's
proving to be a bit difficult.
31 August 2022-- Release v1.6
Spent a lot of time tracking down some issues with my E7 bank switching.
Should work on mame and harmony cart again.
30 August 2022-- Release v1.5
You can move around D'ni now and bug Atrus. Trying to figure how much
room I'll have to implement some puzzles.
Anyway you can make it to D'ni now, although none of the puzzles
or pages are hooked up properly.
16 August 2022-- Release v1.3
You can now reach all 8 marker switches.
12 August 2022-- Release v1.2
Now you can get to (and activate)
three of the marker switches, plus you can investigate
the red/blue books in the library. This involved making the book-drawing
code generic which was a bit of a pain.
I'd estimate the cartridge is about half full now.
10 August 2022
Now up to 18 different locations you can visit. Need to start adding back
the code that lets you grab objects.
5 August 2022-- Release v1.1
Everyone wants to see more levels, so I'm learning how to use an E7-style
bank switch cartridge (16k ROM / 2k RAM). I'm hoping I can put a decent
amount of Myst island on it. The kernel/engine I have takes 448 bytes
for each screen, but I am using ZX02 compression to fit a lot more in
(though it's tricky decompressing to the RAM). The compressed data
has to fit in 256 bytes per level, which can be tricky for complex levels.
I've got the 4k version more or less transferred over (though I had to
simplify some of the levels) and you can very barely walk about now.
It should be more interested as I find time to add new levels.
29 July 2022-- Release v1.0
Powered through and did a 1.0 release. As always there are probably
more important things I should be working on, but it's hard to
not work on things until I get at least one release out the door.
Most of the work was adding animation to the cleft and book scenes,
optimizing size down, trying to approximate the linking noise,
and work on the arrival screen. Not entirely happy with how
the arrival screen turned out but was running low on ROM so
some compromises were made.
28 July 2022
Finished the clock scene. Redid a lot of the design as I've
learned more about how the VCS works. Also put together the rocket
graphics. Trying to have a 2-scanline kernel if possible but keep
rolling over to 4-scanline as I run out of cycles.
27 July 2022
Got the linking book in decent shape. Feel like I've been decently
clever with it.
26 July 2022
Working on the star cleft. Wasted a lot of time trying to make nice
looking stars, really should look up how games like Solaris do it.
Was trying to have an HMOVE of 7 and then skipping 8 scanlines
so things were relatively prime, but didn't really work out that well.
24 July 2022
Got secret collect more or less finished so back to working on Myst.
It was too ambitious a project to start with, things are going a bit
easier now that I've learned some things.