Show HN: NES Contra (1987) port (ASM –> C and then C –> WebAssembly)
Posted by tevlon 1 day ago
Based on vermiceli's annotated disassembly of Contra: https://github.com/vermiceli/nes-contra-us. Thanks for the great work.
I ported it in two steps. First to C: the game logic is translated routine by routine from the 6502 assembly, and checked frame by frame against the original in the Mesen emulator. Then the C code to WebAssembly so it runs in the browser.
The cherry on top: online multiplayer, so two players can play co-op over the internet.
Comments
Comment by throwaway2037 1 day ago
The whole thing (all banks) is more than 10,000 lines of assembly code. When I wrote assembly code for a university computer science course, it was hard to manage even 200 lines. I cannot imagine writing and managing 10,000 lines!
Comment by zahlman 1 day ago
Comment by tevlon 1 day ago
Impressive work, indeed. vermiceli the GOAT.
Comment by throwaway2037 1 day ago
Comment by raldi 1 day ago
Comment by pipes 1 day ago
Comment by raldi 22 hours ago
Comment by hobo123 22 hours ago
Comment by tevlon 1 day ago
Comment by shinryudbz 1 day ago
Comment by tevlon 1 day ago
Comment by incr_me 1 day ago
You said in another comment:
> Then, i spent some time in building a harness and collect telemetry data in Mesen. Once, i had that: i just played the game in the emulator and asked Claude Opus 5.5 to use this as verification.
Can you comment on how this verification process worked?
You'll have to forgive me for not trying to answer these questions myself by investigating the code/git history, but... I hope you understand.
Actually, I am peeking around the code a bit and it's a bit disappointing, but it's what I should have expected having tried a project like this myself with a Game Boy game. I would like to see what an AI-produced semantic (?) rewrite of a retro game would look like. That is, what a port/rewrite that wasn't so faithful/wedded to the original ROM layout or platform architecture. For example, the agent (and you, presumably) was satisfied with writing a sort of RP2C02 emulator facade instead of doing the hard work of translating the bytes into platform-agnostic graphics rendering code. So now any customization/extensions you write to the game are fundamentally constrained to the abstractions of a specific chip from the 80s.
Comment by davesque 1 day ago
Comment by Panzerschrek 1 day ago
But I agree, that using an "AI" tool may be a serious temptation and thus way less new porting projects will be done with such care.
Comment by userbinator 1 day ago
Comment by tancop 17 hours ago
Comment by em3rgent0rdr 1 day ago
Comment by userbinator 14 hours ago
Comment by EmX_3000 1 day ago
Comment by davesque 1 day ago
Comment by tadfisher 1 day ago
Comment by pjmlp 1 day ago
Comment by Buttons840 1 day ago
Comment by pjmlp 1 day ago
When someone commissions a painting, or a sculpture, they might cut the ribbon that holds the curtain on the opening day, that is all.
Comment by davesque 1 day ago
I mean, if you insist on doing everything by hand, go right ahead.
Afterthoughts: I really just don't get why people are so weird about this AI coding thing. What difference does it make to you if someone thinks they have more to learn from high-level planning work than from low-level coding work? A lot of the time, I get the vibe from people who talk this way that they are still early on in their career and think they have to prove their coding chops. I think that's why people like Linus Torvalds couldn't give a shit if people use AI or not, as long as it's not slop and suits its purpose. If you've already spent over a decade writing code and savoring the process, maybe you're just getting a little tired of it. And maybe agonizing over code perfection even drives you slightly insane sometimes. Who the f*** knows? In any case, it's none of your business. I don't know why I'm even writing all this. Because I know you'll just come back with the same old tired gatekeeping non-arguments.
Comment by pjmlp 1 day ago
Comment by EmX_3000 19 hours ago
Comment by jkahrs595 1 day ago
Comment by gnabgib 1 day ago
Comment by EmX_3000 19 hours ago
Comment by jkahrs595 1 day ago
Comment by Buttons840 1 day ago
Comment by pansa2 1 day ago
I hadn’t heard about that - any details?
Comment by gnabgib 1 day ago
Comment by msephton 1 day ago
I used it to get games written in Lua running on SNES and in my own language/engine running on Dreamcast, Wii, Web and more.
Comment by gwbas1c 1 day ago
Are there any emulators out there that let you swap in higher resolution assets so a game can be freshened without a complete port?
Comment by vunderba 1 day ago
Comment by tevlon 1 day ago
Comment by unleaded 1 day ago
Comment by BSPtree 1 day ago
Comment by cowlevel 1 day ago
Comment by kevin_thibedeau 1 day ago
The NES supports PCM audio. It was notably implemented wrong in the title screen of Double Dribble and fixed with a patch that produces clearer audio after bit reversal into the correct encoding for the hardware:
Comment by BSPtree 1 day ago
Comment by kevin_thibedeau 20 hours ago
The DMC is typically used for instruments that are hard to reproduce well with the other generators. Double Dribble is using the DMC for the speech, not some clever setup of the waveform generators.
Comment by pantelisk 1 day ago
Comment by gwbas1c 14 hours ago
My theory is that the emulator could swap in a higher resolution tile without needing to port the game.
Comment by throwaway2037 1 day ago
Comment by gwbas1c 14 hours ago
Comment by heybax 11 hours ago
Comment by BSPtree 1 day ago
Comment by esikich 1 day ago
Comment by waltbosz 1 day ago
Comment by esikich 1 day ago
Comment by tevlon 1 day ago
For AI usage: It was all done by Claude/Codex, but it wasn't that straight forward. First: i started in April and the models weren't good enough and would make errors. You could see those immediately in glitches. Then, i spent some time in building a harness and collect telemetry data in Mesen. Once, i had that: i just played the game in the emulator and asked Claude Opus 5.5 to use this as verification. The rest was smooth.
Comment by ov3r45 1 day ago
Comment by egonschiele 1 day ago
Comment by tevlon 1 day ago
Comment by sfblah 1 day ago
Comment by tevlon 1 day ago
Comment by pmarreck 1 day ago
Comment by Dwedit 1 day ago
Comment by tevlon 1 day ago
Comment by erictheguy 1 day ago
Comment by bigstrat2003 19 hours ago
You didn't port it at all. You had Claude do it for you.
Comment by pxx 1 day ago
Comment by gosen 1 day ago
Comment by einpoklum 1 day ago
Comment by tevlon 1 day ago
Comment by smjy_studio 1 day ago
Comment by jasonlotito 1 day ago
Comment by lightedman 1 day ago
You sure you're a gamer? I've been at it since about 1986.
Comment by pjmlp 1 day ago
Comment by anonymous908213 1 day ago
Comment by literallyanythi 1 day ago
I do think you're objectively correct in your post, but I think what the grandparent meant was that "The author isn't actually interested in playing Contra on his website" which is why QoL stuff like that wasn't added and it "smells" like it should be there if you cared about playing on the thing you actually shared to HN. I know the first thing I would do would be to add wasd + mouse support to Contra, since the control scheme is the reason I don't try to play it. But at the same time I have never been interested in games that deliberately limit your controls as a form of difficulty (feels like a Japanese gamedev thing, from Resident Evil to Dark Souls)
Comment by justsomehnguy 1 day ago
Comment by em3rgent0rdr 1 day ago
Comment by justsomehnguy 21 hours ago
And this is exactly the same with ESDF.
Comment by literallyanythi 1 day ago
edit: figured out why that nostalgia happened. I was revisiting an old flash game I liked [0] and people were complaining to the dev about this exact key ghosting issue to him when it wasn't his fault but a fault of their keyboards, and in the Newgrounds description he links to a forum post [1] elaborating on the issue
[0] https://www.newgrounds.com/portal/view/547881
[1] https://board.flashkit.com/board/showthread.php?789015-wont-...
Comment by justsomehnguy 21 hours ago
Yes, by being the great equalizer. But the question is why WASD and not something else eg WSDX[0] or some shit like ASDF. And the ghosting explains it well enough.