Hacker News new | past | comments | ask | show | jobs | submit login
Documented source code for Elite on the NES (github.com/markmoxon)
243 points by ibobev on Oct 7, 2023 | hide | past | favorite | 68 comments



Many years ago, when I worked at Frontier, David Braben told me a fun anecdote about NES Elite. He said they initially got the game working using the hardware timer in the NES to keep track of real time so that the in-game physics progressed at a constant rate regardless of the frame rate, which varied. When they submitted the game to Nintendo for pre-release checks, Nintendo said they couldn't use the hardware timer because a few of the earliest NESs didn't have working ones. So Bell/Braben had to make the functions in the game maintain their own estimate of how many clock cycles they each took that frame. At the end of the frame they were all added up and used as an estimate for how much real time had elapsed.

Looking at the source github, it appears I misremembered, or likely didn't even understand what Braben was saying. elite-source-bank-7.asm has a comment saying, "Update the NMI timer, which we can use in place of hardware timers (which the NES does not support)". It looks like they somehow implemented their own real time (ish) clock by counting non-maskable interrupts.


Yes, I bet you’re misremembering something — no released NES has a “hardware timer”, in any revision.

The earliest revisions of the NES CPU do remnants of a buggy and disabled programmable interval timer on the die: https://www.nesdev.org/wiki/RP2A03_Programmable_Interval_Tim.... This was fully removed in later revisions. Perhaps this was enabled on a dev kit or something — relying on functionality that never worked on consumer units certainly would have led to Nintendo rejecting it during testing.

But even if released consoles had a PIT, it would only be very useful for sub-frame measurements for e.g. timing precise raster effects. Counting NMIs would be by far the most sensible way to measure real time. The NMI fires at the start of each video frame, which is extremely consistent at 60.0988 Hz, and not affected by in-game processing (i.e. game engine may run at a slower/variable framerate if it can’t keep up, but nothing that happens CPU-side can affect the timing of the video signal in any way; the rendering process runs off a fixed timer in hardware).

(FWIW, the audio hardware also has the ability to generate timer interrupts, and many expansion chips have scanline counters that can generate timer interrupts if you need fine-grained synchronization to the rendering process. There’s no shortage of ways to measure time on the NES if you need it).


I believe what Braben was referring to is the IRQ the APU sends when it's done playing an audio sample. This can be used as a hardware timer by playing a silent sample (all zeroes) and varying the sample length and pitch to adjust the amount of time before the IRQ happens. There's a Twitter thread (https://togetter.com/li/753345) from the programmer of Guardian Legend (a game that uses the APU IRQ for measuring when to switch from displaying the main gameplay to displaying the HUD) that mentions something similar to Braben's story. After the game came out, he started getting reports that it wasn't working correctly on a small number of consoles. It turned out out that Guardian Legend was the first game to use the APU IRQ and Nintendo had never tested that feature at manufacture. After this, Nintendo started instructing developers to not use the APU IRQ.


I randomly used that game as a test rom when I wrote my nes emulator and was pulling my hair out in why the HUD wasn’t rendering until I realized I needed to implement the APU as well.

What a fun era of development.


Yes, no hardware timers are used in NES Elite, as there aren't any.

Instead there's an NMI counter (nmiTimer) that counts every VBlank and wraps around every 50 ticks, so it's effectively a seconds counter on the 50Hz PAL version. And in the NMI handler, they keep a running total of cycles spent so they know when VBlank has finished and can stop sending data to the PPU, picking up where they left off in the next VBlank (see the NMI routine in bank 7).

They also use sprite 0 collision detection to flag when the screen redraw has reached the icon bar, so it can force the PPU to nametable and pattern table 0 (as the icon bar's tiles are only in table 0, with table 1 being used for the vector graphics). This is not unlike the original BBC Micro version's split-screen mode, just without any hardware timers (instead, the whole source is littered with macros that check the collision flag - not very elegant, but it works).

Having hardware timers would have made things a lot easier!


Interesting stuff. I'm going on a 20 year old memory of a conversation I probably didn't understand at the time, so I'm very fuzzy on the details.


> The NMI fires at the start of each video frame, which is extremely consistent at 60.0988 Hz

Wouldn’t that be different on a PAL NES? The parent mentioned that they wanted "to keep track of real time [...] regardless of the frame rate, which varied".


It is indeed different on PAL vs NTSC. The code relies on the NMI being called at 50Hz - as a result a number of timings are wrong on the NTSC version, so the music is too fast, the combat demo auto-play doesn't work properly, the time reported for completing the combat demo is wrong, and so on. The NTSC version is unfinished, and this is just one area where it shows.


I heard the same thing from Andrew Davie of BEAM Software (Melbourne House), who developed Super Glove Ball. Since Nintendo refused to provide the company with any meaningful documentation, they had to come up with various hacks for framerate calculation or something similar.

When they were trying to get approval for Nintendo for some game, it turned out that one specific version of the USA NES wouldn't work, or the game was making the system overheat (I don't remember exactly). Andrew told me that they had to fly all the way to the Nintendo's HQ to deal with this since they were on a tight window to release. It also turned out that there were fewer than a hundred of that specific version of the NES in circulation.

Ah, it was a bit different. I found the note in my (unpublished) book:

  Tests for games were not exclusive to gameplay either. Games had to be tested in each possible NES console they would be played on. Beam Software’s Andrew Davie recalls flying to Nintendo’s offices in Washington, in response to the game “The Three Stooges” causing problems on a NES system that they were testing it on. He recalls there being “something like 23 variations of the machine, with different chip manufacturers, etc.” that the game had to be tested on to pass Nintendo’s tests. Once the problem was diagnosed (the way Davie had programmed the game, due to the lack of official documentation, made the NES run too hot, which caused flickering sprites throughout the game; instead of writing the sprite data into RAM as the official documentation called for, Davie wrote the data every two seconds), the game was fixed and accepted for release; after this, the problematic NES console was removed from Nintendo’s testing line-up, with Davie being told that only around 5 consoles with that combination of chips was in circulation in the entire USA.


Curious, what was it like working at Frontier, did you want to share? I almost took a job there recently, but things didn't work out in the end.


This was a long time ago, when I was only a baby programmer. It's changed beyond all recognition since I was there. It was sort of lovely. The "office" was a farm house in the Fens. There were two dogs in the office. One was a big soft greyhound called Tigger on account of his stripes. The other was a whippet that had to be kept away from people because it was a nervous creature that would occasionally snap at people. I think there was probably about 15 people there when I started. The software development was chaotic. The chaos provided a lot of freedom and opportunity but caused some serious problems too. Suffice to say that when I left after three years to go and write Darwinia with Chris Delay, we wrote a game engine of our own over about 3 months and once we had that, I'd say we were 20x more productive at creating game content than was possible at Frontier on the Dog's Life team. That said, the Frontier tech at the time did have a nice animation system capable of relatively convincing quadruped animation. It could blend walk/trot/canter/gallop animation loops, do inverse kinematics for foot placement and I think it did vertex blending for polys near skeletal joints. And the engine worked OK on a PS2. Darwinia could do none of those things.


I had a lot of fun with Dog's Life!!

"The software development was chaotic. The chaos provided a lot of freedom and opportunity but caused some serious problems too."

Love this insight.


Any other insights about working at Frontier? Did you work on Elite 2 or 3 at all?


Elite 3 (aka First Encounters) was before my time. Braben kept wanting to get another Elite project going, but there was barely enough resource to do a decent job of the two games that were already in development at the time (Dog's Life and Wallace & Gromit in Project Zoo). Most of the staff had been promised that another Elite game was imminent when they were hired. None of us could quite understand why we were making two games about dogs when we owned the Elite franchise. I still don't understand. Probably something to do with Money and Business Deals.


> Braben kept wanting to get another Elite project going ... Most of the staff had been promised that another Elite game was imminent when they were hired. None of us could quite understand why we were making two games about dogs when we owned the Elite franchise.

... but then you realised that anyone bright enough to work it out was unlikely to have accepted the promise or the job? :)

> I still don't understand.

Mr Braben's company Frontier did not own the Elite franchise.

You were amongst many deceived e.g. "Elite: Dangerous Role Playing Game" [1]. This company ceased its false claim to own the Elite franchise some years back.

Another problem facing Mr Braben's attempts to get a publisher for a further space game under his name was his reputation in the industry. His previous attempt, "Frontier: First Encounters", was famously characterised by PC Zone magazine as a bow-wrapped turd [2]. After Mr Braben's repeated patches, a recall, a reissue and another recall, the game's long suffering publisher gave up and sued him for damages of £722,834.63 plus interest [3].

[1] Elite: Dangerous Role Playing Game (ED RPG) is the subject of an intellectual property dispute https://web.archive.org/web/20170303095150/https://www.kicks...

[2] Frontier Worst Encounters, PC Zone https://web.archive.org/web/20231007232510/http://www.eliteh...

[3] Gametek V Braben https://www.pdf-archive.com/2017/10/20/gametek-v-braben-writ...


I embarked on Elite: Dangerous, the successor game, recently. It has its share of problems, granted, but nonetheless is a pretty amazing experience.

Seeing the continuity of game elements from the 1984 version (which I also sunk hours into) is weirdly moving. Seeing the same game objects like the ships and especially the Coriolis station transformed from vector graphics on a 16K memory-mapped screen (SOTA at the time!) to fully rendered 3D at 4K/60fps was more of an emotional ride for me than I expected. Finally experiencing the detailed Coriolis interior complete with advertising hoardings, plant and docking gear moistened my eyes somewhat I don't mind admitting.

Despite current difficulties the game is a precious institution, I really hope it sticks around in some form or other!


I really enjoyed Elite Dangerous as well. Haven't played it since they dropped consoles. I really miss flying those ships with friends despite all the grinding and shallowness. Manually docking a spacecraft to the sound of Blue Danube is always a relaxing experience.

I wonder why space simulators and games always end up being so problematic. Elite Dangerous just seems to be going nowhere. Star Citizen is apparently a perpetual beta. Even KSP2 turned out to be a disappointment. Sigh.


> I wonder why space simulators and games always end up being so problematic. Elite Dangerous just seems to be going nowhere. Star Citizen is apparently a perpetual beta. Even KSP2 turned out to be a disappointment. Sigh.

Feature creep.

Everyone wants a space simulator.... then it must have atmospheric behaviour, and cities.... and well, we should be able to walk around on the ground... and shoot things.... make it a first person shooter, oh, and lots of aliens, make it a diplomacy simulator too.

And on it goes.


I don't want a first person shooter. I was very disappointed when Elite Dangerous started going in that direction. I bought the game to fly sweet space ships, possibly in formation with friends. I just want to do cool space stuff.

I think there's a case to be made for galaxy-wide sandbox gameplay. The truth is that space is empty and it's up to us humans to make it not so. The Subnautica-like basebuilding found No Man's Sky is a major source of fun in that game. It's what makes the galaxy feel alive and dynamic. Elite Dangerous lets you land on planets but there's nothing to do but admire the scenery and take screenshots when you do.

Kerbal Space Program is a single player game which also has mostly empty worlds but it's also a sandbox game. I can build and launch a space station piece by piece. I can later use that space station as an orbital refueling station to reach more difficult planets. I can land on nearby planets and set up a mining operation to refuel the station for the benefit of future space missions. It goes on and on... KSP2 was disappointing not because it didn't have FPS or diplomacy gameplay but because it launched without these features of the original as well as massive peformance regressions.


Corollary: The type of designer who likes to build space simulations also has little ability to self-regulate feature inclusion.

Solution: Never let such a designer run a project themselves, and instead pair them with a practical and empowered project manager.


The ultimate game genre has the ultimate allure.


No Man's Sky managed to pull most of that off. The diplomacy stuff is a little lacking, but it's there.


I think it's a mistake to call the game shallow, there's a deep 9-year struggle for political dominance, for example, that links up to many different game systems. If you take the time to talk with time-served veterans it's astonishing what depths are present in the game.


Well the in-game story is very interesting but the gameplay itself is rather basic. The "game system" is just a tally of points which you increase by doing little tasks and the "economy and power system" decides if you won or lost territory at regular intervals based on those points. Most people only participate in that part of the game to get the faction exclusive weapons. The real game most people play consists of buy low sell high space trucking in order to buy ships, then degenerates to seemingly endless grinding for ship engineering components. Then at some point people amass a fully upgraded fleet of ships. Then they start killing other players for fun since there isn't much else to do.

There's a functionally infinite galaxy to explore but no player run economy that lets us colonize far away systems with player or squadron built space stations. Our reward for exploration is sweet screenshots and our names on the discovery. That's awesome and I spent a lot of time doing it but it could have been so much more. I used to play with one of the biggest squadrons in the game and at the end of the day it was nothing but grinding resources or little tasks to increase numbers so the economy simulator didn't decide we lost territory or something. Would've been a lot more fun if groups could build strongholds deep in the galaxy and you had to literally attack them to take them out instead of grinding missions.


I've listened in on planning sessions for the "rather basic" "tally of points" (BGS) system, and it's far from basic, there's plenty of strategy and tactics involved and political thinking and negotiations with other player groupings are part of it - it's more like 3D Risk than what you describe.

I've listened in on discussions of relative merits of ship builds for the current anti-xeno initiative and they are deep and far-ranging.

I've watched combat streams from players who've practiced for literally a year to master the intricacies of no-flight-assist piloting.

There's a lot more to the game than "space trucking". After immersing myself over a couple of weeks in the various aspects and sub-communities it's amazing to me that people fall for the facile "mile-wide-inch-deep" truism. It's that critique that's shallow and uninformed, to my mind.


> I've listened in on discussions of relative merits of ship builds for the current anti-xeno initiative and they are deep and far-ranging.

> I've watched combat streams from players who've practiced for literally a year to master the intricacies of no-flight-assist piloting.

We agree on these points. The ships and the piloting are the game's strongest qualities. They're what I miss most.

> After immersing myself over a couple of weeks in the various aspects and sub-communities it's amazing to me that people fall for the facile "mile-wide-inch-deep" truism.

The community of players is indeed awesome. Playing with others nearly makes up for all the deficiencies of the game. It makes everything that much more fun and more emergent. The sheer existence of groups like the fuel rats is something this game deserves praise for.

Doesn't make the game itself any less problematic. The problems still exist, they just don't seem so big because you're playing with friends.

> I've listened in on planning sessions for the "rather basic" "tally of points" (BGS) system, and it's far from basic, there's plenty of strategy and tactics involved and political thinking and negotiations with other player groupings are part of it - it's more like 3D Risk than what you describe.

Nah. I've played games like Risk too and they were far more interesting than this grind. Maybe it's "interesting" to the top squadron guys but I don't see how. They're essentially maintaining territory: have everyone in the squadron do a ton of little tasks so everything will stay more or less the same. Pretty much no impact on anything but which factions control which stations which doesn't mean anything anyway. It might sound fun to sign up for the empire princess faction and imagine you're gonna help her take over the galaxy but that quickly goes away when you join a community and discover they're in maintenance mode, only occasionally gobbling up territory when some other faction gets sick of the game and stops playing or something.

Compare that to eve online and its actual player run world and it's like night and day.

> There's a lot more to the game than "space trucking".

Maybe if you've already done everything else and have meta ships you can battle other players or thargoids with. Until then it's an endless grind. Buy at station, sell at another, repeat until number is big enough to buy new ship and modules. Land on planet, shoot and pick up rocks containing common elements until their quantity is big enough to upgrade existing ships and modules.

Space trucking is the most polite way I can describe this menial busy work.


I'm sorry to be That Guy, but Blue Danube only plays when you're auto-docking.


It's a toggleable feature of the autodock computer, no? I used to always autodock my huge transport ships but fly my fighters manually. It's been a while so I'm probably misremembering.


I enjoyed X3 and X4 quite a lot. However, I didn't like the UI and lack of jump drive in X4. It also has its share of bugs and the universe can get slow when the game progresses. It's still a very engrossing game, however.


Thanks for the recommendation. I was under the impression the X games were strategy games for some reason. I'll definitely check it out.


I’ve spent a lot of time playing Elite: Dangerous since the open beta. A beautiful game, with phenomenal sound design.

Some thoughts I wrote 9 years ago: https://hypertexthero.com/elite-dangerous-education/

The Odyssey expansion is fun, too, and I hope they add EVA space walks and 0-G missions at some point!


There's also Elite - The New Kind, a C version that is mostly faithful to the original: https://github.com/fesh0r/newkind

It was done by Christian Pinder: https://www.christianpinder.com/games/

People might also want to check out Ian Bell's Elite homepage, which has a number of the original versions:

http://www.ianbellelite.com/


A shout-out is definitely due to Ian Bell and his website. This is where you can find the original source code for the BBC Micro version. Those original disks form the basis for all my Elite commentaries, including the NES project we're talking about here.

The core of the 1991 NES version (around 30% of the 128K ROM) is essentially the 1986 BBC Master version, which itself is a development of the original BBC Micro version from 1984. The Commodore 64 and Apple II versions are also cut from the same cloth (and they were developed on a BBC Micro, too).

Most of the code in banks 0, 1 and 2 is directly copied from the original BBC version, with a bit more in bank 7. There are new graphics, sound and controller routines bolted on the front, but the beating heart is still the Beeb version...


Ian Bell, author of Elite, claimed that the NES version was his personal favorite 8-bit version of Elite.

(He liked the 32-bit Archimedes port the best overall.)


The quote is:

  My greatest published achievements technically would have to be fitting BBC Cassette "Elite" into 32K of RAM including the screen, and later the Nintendo Entertainment System conversion of "Elite" that used a character mapped display and a single NES controller. The NES is my favourite published conversion and was not thought technically feasible until we'd done it.
See http://www.elitehomepage.org/archive/b5081501.htm for the full interview

I interpret this as meaning his favourite version is the BBC Micro cassette version, while his favourite conversion is the NES one. But I'm a BBC fanboy, so that might just be me being hopeful. :-)


The CHR ROM on NES Elite was actually RAM... allowing for something akin to "bitmap mode" on the TI-99/4A or C64 where they can use the CHR memory as a framebuffer in which to draw those vector graphics.


> while his favourite conversion is the NES one

favourite /published/ conversion :)


But they removed trading slaves and narcotics! :)

(I think)


Indeed - "slaves" got changed to "robot slaves", while "narcotics" became "rare species" and "liquor/wines" became "beverages". You can still trade firearms, though, so its not entirely squeaky clean...


Nintendo would have had a hell of a time censoring firearms from videogames. Nudity, slavery, narcotics, and alcohol are easy; violence and firearms form the basis of many/most popular video games.

Probotector is Contra @50Hz with all humans replaced by robots, but still lots of firearms and violence.


I never understood why UK and Europe got probotector instead of contra, maybe it was due to Germany's very strict game censorship?


Yeah, that's my guess. Violence towards humans in video games was often prohibited in Germany, so drop it for the whole region, because two releases is hard.


Arch Elite is the pinnacle for sure.


> Arch Elite is the pinnacle for sure.

Aw, blush :)

- Chris Jordan, publisher of Arch Elite.


The recent Oric Atmos fan make is pretty nice, too:

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


I like how the start of every bank contains a bank switch shim like this:

  SEI
  INC $C006
  JMP BEGIN 
Then it goes into a lot of detail about how it does this to save space, but it seems to me that the only reason the JMP is even needed is because of the instruction pipeline, which could be flushed with just a NOP. So here's my 2 byte optimisation to this code:

  SEI
  INC $FFFD ; use the C0 in the instruction vector instead
  NOP


> it seems to me that the only reason the JMP is even needed is because of the instruction pipeline

It does also make sense to a human -- execution begins in bank 7, so jump to bank 7.

Side note: on Game Boy the entry point is in ROM0, a fixed bank (at least on the common MBCs), so you don't have this problem in the first place.


Also, the JMP BEGIN approach will still work even if you move the BEGIN routine elsewhere in bank 7, so presumably it's done this way so things won't break during development when you're still trying to work out which bit of code goes where.

There are quite a few remnants of code in the NES version that do nothing - I guess with 128K of ROM, the authors didn't need to go hunting for every single optimisation, unlike the BBC Micro version...


In contrast, here's the source code for Oolite, the open source Elite clone written in Objective-C: https://github.com/OoliteProject/oolite

https://oolite.space

https://news.ycombinator.com/item?id=7894145


I played it on the C64 as an 8 year old. 30 years later I don't understand this code.


18305 lines of assembly for bank 0... I have no clue how you'd keep that in your head.


Back when I was writing 6502, you didn't keep it all in your head, you kept it in reams of tractor-fed dot matrix paper, usually with a lot of scribbled pencil notes and corrections.


I've done a bit of embedded development for 8-bit machines in the modern era, and I sincerely tip my hat to the engineers who were doing it in the 80s. Even with the best tooling available, you'd have needed an enormous amount of organisation and discipline to keep track of your code. I was doing some research about the assemblers available for the Hitachi 6303[0]/Motorola 6800[1] in the early 80s, and I'm amazed by what people accomplished with the limitations of these tools. Just to name one thing, the two assemblers I've linked to only supported SIX character labels, and no local-only labels within subroutines either. To compare, in my own work I was limiting myself to FORTY characters for the sake of being descriptive.

Having said all this, the relative simplicity of these architectures is really refreshing compared to embedded work on modern systems. There's something to be said for being able to roughly keep track of the whole system state in your head.

0: http://www.bitsavers.org/components/hitachi/_dataBooks/U24_H...

1: http://www.bitsavers.org/components/motorola/6800/exorciser/...


We were out better selves back then.

Seriously though any project of size almost had to involve large amounts of code written or printed on paper. Lots and lots of paper.


Well, it depends. On some environments such as Lucas Arts they used Unix based OSes to develop SCUMM. With grep and such, editing and porting the engine could have been a breeze.


Half joking, by the time of the NES port he would have certainly had many available options for all that , but even with access to a timesharing system with real storage and all that in the earlier 80s having at least sections on paper for easy reference against printed manuals was handy.


This code is extremely well organized and documented. I don’t know what the original code would have looked like in terms of documentation, but I imagine there was a lot of it printed on paper with handwritten notes and stuff.

Overall though, assembly programming is much like any high level language: you organize your code into functions and blocks etc. Just writing one super long wall of code with a rat’s nest of jumps throughout is asking for serious trouble.


Can anyone explain this to a modern engineer? Why would you need to hold this in your head?


Possibly lack of tools that make code search/navigation easy.


Not libre. Too bad, if I were the Elite creator I'd put all the game ports under a libre license. Anyway, nowadays you can play Oolite on a cheap netbook and have the exact same fun, if not more due to the huge addon list for it.


That's Braben being a dick about copyright. Bell on the other hand was a nice guy and released most that he himself wrote.


There is quite a lot of history around the releases that goes back several decades.

Braben et al didn't want to weaken the copyright I guess since they were doing Elite 4/Elite: Dangerous.


> There is quite a lot of history around the releases that goes back several decades.

Much generously documented by Ian Bell e.g.

David Braben sues Ian Bell for libel https://groups.google.com/g/uk.legal/c/ZmgmhpuitXQ

David Braben sues EMAP for copyright infringement https://web.archive.org/web/20160328014216/http://www.eliteh...

David Braben threatens the Elite Home Page https://web.archive.org/web/20230824005005/http://www.iancgb...


All source code should be documented as this.


Maybe someone can finally port it to run on NTSC consoles. Would still take a lot of scanlines to cut out though.


Maybe try this NTSC version from Ian Bell's website?

http://www.iancgbell.clara.net/elite/nes/


Alas, the NTSC version doesn't actually work on NTSC consoles. The NMI timings have been changed to work with some (but not all) emulators in NTSC mode, but it isn't a full NTSC conversion, it's an NTSC emulation (at least, that's what the authors call it in that version's scroll text).

There's a full list of differences between the PAL and NTSC versions here:

https://github.com/markmoxon/nes-elite-beebasm/tree/main#dif...


"NTSC Emulation" Elite was intended to be used with Nesticle only, as there was a "NES Timing" dialog where you could change the number of scanlines during vblank time.

At the time, no emulators supported emulating the PAL NES.




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

Search: