Hacker News new | past | comments | ask | show | jobs | submit login
How Prince of Persia Defeated Apple II's Memory Limitations [video] (youtube.com)
250 points by weare138 on March 22, 2020 | hide | past | favorite | 57 comments



Accompanying article is here: https://arstechnica.com/gaming/2020/03/war-stories-how-princ...

Which links to the transcript: https://cdn.arstechnica.net/wp-content/uploads/2020/03/princ...

And his journals from the time, which are now being published: http://jordanmechner.com/journals


TL;DW: Memory constrains prevented the inclusion of enemies in the game (due to the space taken by rotoscoped images), so he got the idea of xor-ing frame pixels together to get the outline of the main character, kind of a shadow, and made that the enemy. He also squeezed a bit more memory from an "auxiliary" memory unit to animate guards.

Kind of light on details, though :)


If you want to delve into the details then the Apple II source code is on github: https://github.com/jmechner/Prince-of-Persia-Apple-II

Along with technical documentation: http://jordanmechner.com/downloads/popsource.pdf


Hi, saw this thread and wanted to jump in. It's a good question not answered in the 20-minute ArsTechnica video: since Shadowman was born out of the necessity of being squeezed for memory on the Apple II, how was I then able to add guards, skeletons, and a Vizier?

To refresh my own memory (which is more than 48K, but often foggy), I checked my journal. Part of the answer is in this entry from 11/20/1988:

"...Put in footsteps, and improved the chomping jaws. But the real breakthrough this week was invisible: I moved a bunch of stuff around so the main game code can use the auxiliary language card. Basically, I've just freed up an extra 12K. That gives me some breathing room I'll sorely need if I'm going to put in all this sword fighting."

And a few months later, on 2/16/89: "A lot of heavy work, most of it invisible, but which will make it much easier for me to implement the enemy guards in their flowing robes and turbans."

The journal doesn't give more technical detail than that (if I'd imagined anyone would be interested in this stuff 30 years later, I'd have written more!) but the code is on github, so anyone who's motivated enough should be able to reconstruct how the final code uses the auxiliary memory. In my recollection (foggy, as warned -- it's been a while), the "auxiliary language card" was an extra 16K of RAM that Apple had squeezed into the latest generation of Apple II computers, but that was difficult to use because it wasn't contiguous with the rest of RAM. I seem to recall it shared addresses already used by the main memory, so you had to flip between which part you were using. In November '88, seeing how much Shadowman and swordfighting and Shadowman improved the game motivated me to invest the time to rewrite/strategically relocate a bunch of existing code to free up 12K that I could use to implement enemies.

As for the multiple enemies, I'm pretty sure that each level contained exactly one enemy, whose shape table was packaged with the level load. The floppy disk access (very quick, thanks to Roland Gustafsson's magical 18-sector routines) when the level was loaded would swap out the previous level's enemy with the new one. That's why you'll notice that the levels containing the "special enemies" (skeleton, Jaffar, and the Fat Guard) had no normal guards in the rest of the level -- they couldn't.

Hope this helps. Thanks for your interest!


Such great memories of playing PoP in my teens! I wish I could get as excited about some new game/software as I did back then. In those days there really were some titles that would come along and just knock your socks off. Doesn't happen much anymore...a sign of the times I guess.

Thanks for taking time to share!


I can't reply to the parent anymore, but I just went back to HN after a week of busy work: thanks a lot for the details, jmechner, that's quite interesting :)

I don't have enough time on my hands to dig into the old source code (nor I am particularly interested in the Apple II), but I'm glad to know it's available, should I or some others be suddenly curious to dig in. I much prefer such code to be opened than to be lost to history!

So, it's a bit like register banks [1] or an MMU, where you have to page in and out part of the address space, I guess? I've seen some people [1] argue that we needed less powerful machines and to break backwards compatibility, for people to get creative again. Maybe there is some truth to that?

[1]: http://www.keil.com/support/man/docs/c51/c51_le_regbankspec....

[2]: https://fosdem.org/2020/schedule/event/generation_gaps/


Accompanying article is here

It really seems to be a trend these days for new accounts to submit the YouTube videos that were embedded in previously popular HN articles as new HN articles. I've seen this several times in the last week or so.


I heard about this video directly and didn't know there was an accompanying text article. It's reasonable to assume the submitter thought the same.


Didn't change the trend. Does ask for a different call to action. No need to be upset on people submitting auxiliary videos. Would be nice to have a feature linking the video to the article. Is there already metadata to make this discoverable?


I’d suggest that the article is the auxiliary content to the video.


I actually hate consuming video. So perhaps complimentary? :)


Media preferences aside, the article is essentially a watered down commentary on the video. If I came across this while I was at work, I would also prefer to consume the article. But I think the video is where the value is in this content.


I even saw this video on /r/TheMakingOfGames/ last week


I enjoyed the video a lot, but it feels a bit fictionalised. The first fifteen minutes talking about how hard it was to get another character, then immediately after adding shadownman the vizier is added, then unmentioned but shown at 16:21 there's a new skeleton enemy which is clearly a completely different bitmap from any other character.

That's a heck of a lot of space to suddenly find when adding a single extra character was seemingly untenable.


It's because the video is an ad for his book, "The Making of Prince of Persia".


Loved the video, and loved Prince of Persia growing up. It might have been my first PC game, back on our old 286. I'm saying might be, because we also had Monkey Island and Alley Cat!

Now that I'm older, I really appreciate the relentlessness of the vision. "I'm just gonna do rotoscoping! I'm gonna film my karate teacher and my brother!". I have to say it's really rare these days in the tech industry to see this kind of insane vision. It's even more rare to see someone pull off a cohesive product out of it.

I wish the interviewer had asked for more elaboration on the techniques used. It went really quickly from:"I ran out every single byte of memory with this Prince guy, how do I create an antagonist? I know, palette shifting!" to "then I added sword fighting, and enemy guards". Still, really love to hear these tales of optimization.


And he did it on an Apple 2. Those machines were good programming workstations, in the day, fast storage, lots of tools, and so forth, but high resolution graphics were hard to do fast.

And it is not even palette shifting. The Apple has absolute colors. He literally made another draw routine that performed the XOR operation.

For a modern day example of similar dedication, check this out:

https://m.facebook.com/LawlessLegends/

Python scripts create in line assembly for the ray caster, PLASMA byte code interpreter, big world, animations, and excellent use of the 6 colors and artifact art.

A game this big would have been epic in the day. The team has been grinding away at it for some years now.

It will end up being an exemplary example of an RPG, and on the Apple, that kind of game is in the sweet spot.

What Jordan did was not really considered possible. PoP amazed many people!


Not just absolute colors, but absolutely bizarre Rube-Goldbergesque colors!

https://en.wikipedia.org/wiki/Apple_II_graphics


The big complication was 7 pixels per byte. Artifact colors work on even "bit boundaries" aligned with the colorburst.

On pretty much every other computer, the same bit patterns resulted in the dame artifact colors, but the Apple had even and odd byte patterns, because the repeat took two bytes, not one like other machines.

On the other hand, having that high bit shift the pixel clock a little meant 6 colors, plus black and white.

Because of how artifacting works, that is actually enough to do anything. Until the PC and some machines like the color computer 3, artifact colors were limited. Red blue, kinds of things.

The secondary complication was the screen addressing, which cost a table lookup. Had it been linear, overall draw speed would have been a bit faster.


Right, within every even/odd group of seven pixels, the even/odd colors for each of those pixels were reversed. With the high bit switching between different sets of colors. And on top of that the vertical scan line interleaving.

So many levels of owch! And punching through all that with an 8 bit 6502. It's really hard to appreciate how fucking hard any Apple ][ game that uses hires graphics had to work just to put a dot on the screen.

https://en.wikipedia.org/wiki/Composite_artifact_colors#Appl...

Even more amazing were the text/hires graphics adventure engines that stippled together different colors to get a wider palette. It was so hard for the poor 6502, that part of the visceral pleasure of the game was just sitting there watching it draw each scene.

And all the visible text (IN UPPER CASE OF COURSE) must fit in the characteristic four lines at the bottom. Since it drew the scene so slowly, there was enough time to read the text before it scrolled off the top. Talk about making lemonade out of lemons, due to technical limitations!

Hi-Res Adventure #4: Ulysses and the Golden Fleece for the Apple II

https://www.youtube.com/watch?v=QTFNKbkxeY8


Not to mention that the HGR screen was also interleaved, rather than linear. Also, if you factor in DHGR, you remove the half-pixel shift, but instead you operate like you do in 80 column text mode, with the even columns of 7 pixels being in the normal high-res memory map, and the odd columns being in the auxiliary 80-column memory, on top of the normal HGR interleaving. Certainly a lot to wrap your head around as compared to other video subsystems.

http://www.appleoldies.ca/graphics/dhgr/dhgrtechnote.txt


When your only registers are a 8 bits X, Y, and A, the hires screen memory was practically encrypted!

It felt so fucking amazing to finally have a computer with a normal 1 pixel : 1 byte memory mapped display.

But before that, I played around with the Sun CG1 graphics board (on a Sun 2: I mmap'ed /dev/cgone0, but maybe it was actually a cgtwo card, not sure), which was kinda but not really memory mapped.

http://www.sunhelp.org/faq/FrameBufferHistory.html

It had 8 bit color mapped pixels, and it had an implicit read position and write position, such that you could address a row and column of pixels at a time, one pair for reading and one for writing ("rop mode memory").

When you accessed a column of the row block of memory, that set which column you could address in the other column block of memory. When you accessed a row of the the column block of memory, that set which row you could address in the other row block of memory!

As it turned out, that just happened to be useful for drawing lines and filling trapazons and performing raster operations, but it made random access quite inefficient, and was a huge pain in the ass for anything else.

(Although nowhere near as painful as Apple ][ graphics, but a lot more expensive!)

I think the early X10 and X11 servers actually supported it (SunView [SunTools at the time] certainly did), but it was really really slow.

I learned later than John Gilmore had written weird union structs the .h file to describe the memory mapped registers, when he was at Sun in its early days:

https://donhopkins.com/home/archive/forth/cg/cg2reg.h

Here's some Forth and 68K code I wrote to play around with that card (notice how register offsets gr_x_select / gr_y_select, 68k code xsel / ysel, and Forth words lineaddr / coladdr work together -- yes Forth can mmap device registers, and that is RPN 68k assembly code, with opcodes at the end of the line!):

https://donhopkins.com/home/archive/forth/cg/cgone.f

    : getfb
      0 bytes/fb [""] /dev/cgone0 mapin  >fb !
    ;
https://donhopkins.com/home/archive/forth/cg/cg.f

    code xsel ( x --- addr )
      >fb l#) d0 long move
      gr_x_select gr_update + l# d0 long add
      d0 sp ) add
      next
    c;

    code ysel ( y --- addr )
      >fb l#) d0 long move
      gr_y_select gr_update + l# d0 long add
      d0 sp ) add
      next
    c;
https://donhopkins.com/home/archive/forth/cg/fline.f

https://donhopkins.com/home/archive/forth/cg/iline.f


Did it use double hires graphics? That was even harder to do correctly. Half the graphics memory was in the first 64K of memory ($2000-$4000) and the other half was stored in the second bank switched 64K of memory.


The only double hires was on the title screen. Maybe the princess scenes too.


It's possible that Mechner did go into further detail and it was cut for this video. Keep an eye on this channel; recent videos in this series (Rand Miller and Lorne Lanning) had the full un-cut interviews posted, which go on for hours and are well worth it if you're into this stuff.


Along the same lines, there's a wonderful series of forum posts detailing the progress (right through to completion) of a fan-made Prince of Persia port to the BBC Master here: https://stardot.org.uk/forums/viewtopic.php?f=53&t=13079


It's very good. Official page here:

https://bitshifters.github.io/posts/prods/bs-pop-beeb.html

Click the "Emulate" button at the bottom to play in your browser.


This War Stories series from Ars is really great. The episodes are generally geared for the gaming audience and not necessarily a technical audience, but they often touch on a wide range of topics involved in producing video games that also end up being applicable in wider software development.


Yeah it's really good, though one minor issue is that they seem to be keen on fitting a certain structure (cutting in with "The Problem", "The Solution" when it doesn't really fit well) when really it's just entertaining hearing people like Jordan Mechner, Sid Meier and Lucas Pope talk for a while about an interesting mechanic or issue.


Download a copy of the original Apple II disk for an emulator https://archive.org/details/wozaday_Prince_of_Persia You can kinda play it in the browser but the sound was a little odd and I couldn't figure out the controls.


The the Apple II version the game is actually very playable with the keyboard (easier than using a joystick) but it would be hard to figure out without some guidance.

At the title screen, hit the space bar to start the game.

After the game starts, hit Control+K to enable keyboard controls.

It uses the standard I,J,K,L + U,O layout for up, down, left, right and jumping. Note that you can't press two of these keys at the same time, but you can hold one of them down.

The Option/Alt key modifies the behavior of these keys, and you will use it often:

- Option+J/L: step slowly rather than run. Use this to safely walk up to the edge of a ledge.

- Option+I: Jump up and hang on to a ledge. Hold 'I' to climb up the ledge.

- Option+K: Drop down and hang on to a ledge. Release Option to let yourself drop.

Use 'U' and 'O' to leap left or right over a ledge. This can be done while running or from a standstill.

Use 'Option' to pick up objects and drink potions.

Use the space bar to see how much time you have left.

There is a lot of trial and error at first, as you discover what things can kill you. When you die you can back to the start of the current level. Some tips:

- You can only safely fall one story. Falling two stories will reduce your life. Falling more will kill you.

- You can safely step into spikes that have popped out of the ground. If you run into them you will die.

- You can jump straight up to see which floor and roof tiles are loose. Run over floor tiles that are loose. Jump up underneath a loose ceiling tile to reveal hidden areas.


You da real documentation mvp. Thank's, I've tried playing this in the past, but got lost on how the controls work.


I see that ijkl is the arrow keys, but I can't hold left and jump, so I can't make him run and jump yet.

I'd recommend dosbox for replaying prince of persia!

https://www.freegameempire.com/games/Prince-of-Persia/Run-in...


Why wasn't the "auxiliary" memory the actual solution? Most of the video was about not having enough memory to add guards/monster for combat but guards were added anyway after finding extra memory and yet that fact was largely glossed over.


Path of least resistance. Also, if he would have used that part for the "evil self" there would have been no guards because that memory would be in use now.


The evil self was suppose to be (according the video) the "genius" work around to not having guards and combat in the game due to memory constrains. Guards and combat being added anyway really undercuts the narrative of the video.


It was such a let down to hear that after all that work, apparently the ports are what made PoP successful.


One point that Jordan Mechner makes is the limitations made the game better. The whole idea of the mirror guy as an antagonist was inspired by these limitations. Here's someone who is actually in the game world (not just in cutscenes or a final boss battle) that would manipulate the environment to frustrate your efforts to escape.

And then some extra memory was found so guards were added, and the ports had even less limitations and could reach a larger audience. But the original limitation inspired creativity that might otherwise never have been.


Well the video implies that the Apple II was on its way out when the game was launched.

I remember playing the PC version of it. At some point, the port was probably easier to do than the original game.


Any port in a storm during the A][ Winter.


combat, combat, combat.

Not so long ago I shared a small video of his young brother doing the jumps and walks that he uses to create the animations for his game. Awesome work, awesome video. Inspiring.


I'm trying to imagine his coworker, telling him this every time he was bragging about some feature he managed to squeeze into the game.

Torches on the wall. Super. Why didn't you use that surplus for, and I'm just spitballing here, say... combat?


The answer would likely be along the lines of torches using a minimal amount of memory, while combat would involve adding multiple large sprites for the player in combat as well as many large sprites for the the combatants's combat and motion. Given that the game was already pushing the limits of computer graphics with it's art style, it was likely desirable to differentiate the appearance of at least some of the combatants, pushing the memory requirements even higher.

Then there was the author's lack of desire to make another game focused upon combat.

Which is the beauty of the shadow character. Since it is based upon a computational trick, it added a minimum to the resources required. At the same time, it afforded a twist in the plot that allowed the author to accept and integrate combat into the game. It changed the nature of the combat and of the player's decisions, permitted the antagonist to exist long enough to have it's own story, and got rid of the cheap feeling of a clone army (i.e. reused sprites).


Related, the video How Myst Almost Couldn't Run on CD-ROM[1] is actually more fascinating and entertaining in my opinion.

[1] https://www.youtube.com/watch?v=EWX5B6cD4_4


I would like to see Jordan getting out there and making stuff again. From this outsider's perspective, he's been in a largely quiescent state for 15+ years. I'm sure he's got more good stuff inside his brain and I want him to set it free.


He designed a completely re-imagined Karateka in 2013. The iOS version died during the great 32 bit apocalypse.


He posted some "making of" videos when he remade the iOS version of Karateka.

I really enjoyed this video explaining how he got around making the gameplay easier (not just 1 life) but also made it make sense to the story.

You have 3 lives... but 3 different lives:

https://www.youtube.com/watch?v=Vq31IwKZkt0


Their video on Crash Bandicoot has some more technical trick to squeeze performance out of a finite resource, where I think this one was mostly conceptual. Both enjoyable though.


Is "Shadow Man" the origin story of Nega Scott?

'Nega Scott is a reference to the "Shadow Doppelganger" stock character present in many games and anime & manga.'


Maybe, but I feel there's a great chance it inspired Shadow Mario, the main antagonist in Super Mario Sunshine.



There's a related set of blog posts[1] that go into some details of the memory limitation problems when making the C64 port.

[1] http://popc64.blogspot.com/2011/10/part-one-why-hell-would-a...


For some reason I initially read this as "Prince Charles." And thought that I was totally ignorant of Prince Charles' programming exploits, as though he were a Lee Hsien Loong.


I always wanted to play "Prince of Persia" but I was too busy writing code for a living. Is it possible to play this game in a current platform, may be in Ubuntu ?


The PC version is available via abandonware. You can play it in dosbox.


Or here, right in the browser (via Dosbox)

https://archive.org/details/msdos_Prince_of_Persia_1990


This was awesome. Thanks!!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: