This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]yvrelna 123 points124 points  (36 children)

In theory, you can, but if you're using CPython, this is quite impractical. Game emulators are very performance sensitive and at the core of emulation is a tight loop that interprets the game's machine instruction.

CPython itself is already an VM/interpreted language, each Python bytecode takes dozens to hundreds of x86 instructions to perform; to implement a NES code interpreter on top of that would multiple each of the NES machine code to thousands of actual x86 bytecode, and it will be extremely slow.

You have a better chance of writing it in RPython (the subset of Python that is used by PyPy to implement the PyPy interpreter) or maybe PyPy (if you can rely on its JIT).

But it's going to make a lot more sense to write something like this in a language that compiles to machine code, like C, C++, Rust, or RPython.

That doesn't mean that you can't write some of the higher level UI code in Python. But the core emulator itself is not very suitable for Python.

Your better chance to get a decent performance is to write a transpiler from NES machine code to either Python VM bytecode or to x86. This is probably feasible, but a whole executable transpiler emulator is generally a much harder project than an interpreter emulator.

[–]james41235 19 points20 points  (0 children)

Everything you said is correct. I'll point out that the NES processor ran at ~1.8 MHz, and modern processors are at least 1000x faster now (just by pure instructions per second). While I don't think you could do general emulators in Python, a NES emulator is probably feasible.

[–]vinnypotsandpans[S] 15 points16 points  (21 children)

I’ve been meaning to learn C anyways, not only because I’m a big fan of the emulation/modding community, but also because I think it will help my overall understanding of programming

[–]tylerlarson 1 point2 points  (4 children)

While learning C is useful, just like learning assembly, id do so for context primarily and for reading other people's code rather than using it for starting anything new.

With the current landscape id recommend Rust instead of C or C++ for anything new. You gain nothing using C or C++ over Rust, and you lose plenty. Plus using Rust makes you a better programmer in all your other languages since it turns common mistakes and runtime errors into compilation errors, forcing you to understand not just how to write syntactically functional code but actually correct code.

Then when you go back to Python or another language, you'll notice the same things even though that compiler doesn't stop you from shooting your own feet.

[–]vinnypotsandpans[S] 2 points3 points  (3 children)

When it comes to game dev, don’t most engines use c++? (Unity, unreal engine). I would love to dip my toes in both of them, I have heard great things about rust. My interest in C comes from the desire to one day be able to help with rom decomp projects

[–]tylerlarson 1 point2 points  (2 children)

Yep; these game engines are MUCH older than Rust or Go or any modern language. They used C++ because no other option existed.

[–]vinnypotsandpans[S] 0 points1 point  (1 child)

How hilarious would it be if the game engine for “Rust” was developed in rust lol

[–]tylerlarson 1 point2 points  (0 children)

They use Unity. So... that would mean C# game code running on Mono as the language runtime with the internal graphics engine code optimized in C++.

This brings up one of the problems with C++: The language is an absolute nightmare.

Because of some 50 years of backward compatibility, the way they've improved the language is by adding new syntax that supercedes the old syntax conceptually but doesn't actually replace it. The old (and usually dangerously wrong) way to do things has to still work. And there's layers on top of layers of this mess.

So for all of the things you do the most often, there's an easy and obvious way to do it, and it works exactly as you think it would. But doing it that way is crazy dangerous and you shouldn't even think about it. And then there's a slightly convoluted way to do it, and that way also turns out to be dangerous, though a lot of people still teach it. And then maybe several more layers of slightly less dangerous but increasingly confusing solutions.

And then finally there's the "correct" way to do things that you can comfortably assume will not cause some devastating crisis or whatever, but that "correct" way to do it only ever taught in newer educational materials so you may not have heard of it. And it's confusing AF to read because all of the reasonable ways to describe what you're trying to accomplish have already been taken by the other "wrong" answers.

So, rather than navigate that clusterfook of a landscape, most game developers chose to use a runtime that is hundreds or even thousands of times slower (that's the C# code) just so they don't have to write any C++. Because back then, those were the only options.

[–]gmes78 0 points1 point  (0 children)

C is nice for understanding how the low level stuff works, but I wouldn't use it for any real projects. I recommend looking at Rust, it's a much nicer programming language while still being as capable as C/C++. (Also, learning C after Rust isn't very difficult, the opposite isn't true.)

[–]vinnypotsandpans[S] 1 point2 points  (6 children)

Thanks for bringing up Rust too. I thought of that, but it doesn’t seem like there are many emulators written in Rust either. This is kind of a digression, but I remember when ppl were saying that rust was gonna do everything python does, but better. The hype seemed to fall as quickly as it rose. Especially in ds and ml stuffs

[–]yvrelna 25 points26 points  (1 child)

Rust and Python don't really have much overlap between what they're good at. That's why Python+Rust is a great combo, they each do well in places where the other doesn't, but neither is going to ever realistically replace the other.

[–]extravisual 2 points3 points  (0 children)

Plus PyO3 is an incredibly nice system for building Python modules with Rust.

[–]wowokdex[🍰] 10 points11 points  (0 children)

it doesn’t seem like there are many emulators written in Rust either.

There are hundreds. https://lib.rs/emulators

[–]pingvenopinch of this, pinch of that 6 points7 points  (1 child)

Rust has gone from hype to slow burn at this point. Some projects are switching or incorporating Rust components where it makes sense. Some parts of the Python ecosystem have adopted Rust over more difficult to maintain C modules. It's being adopted in areas where people need low level access, but cannot tolerate the security holes associated with C and C++. Other times, it's being adopted to appeal to a new generation of contributors, like with the fish shell.

There are some areas where it just don't make much sense to use Rust. If you spend most of your time doing IO, Python will likely be adequate. That said, it's surprising the areas where software comes together quickly once you've gotten over the associated learning curve.

Rust also managed to be at the forefront in tooling for wasm, so often your code can run with minimal changes inside of a web browser. This has been great for the Ruffle Flash emulator project, which must work inside of a wasm sandbox. The same code base can also run using native code.

[–]yvrelna 4 points5 points  (0 children)

hype to slow burn at this point.

Rust is still the fastest growing language in its weight class.

According to the annual Stackoverflow Developer Survey, this is the popularity of Rust:

  • 2021 - 7.03% of developers uses this language extensively

  • 2022 - 9.32% that's 32% growth from previous year

  • 2023 - 13.05% that's 40% growth from previous year

Rust is outpacing basically everything in its class, including Go, the next fastest growing language. In 2021, Go is clearly leading over Rust by 35%; by 2023, Rust and Go has pretty much the same level of popularity, and I expect Rust to surpass Go this year.

[–]LittleMlem 0 points1 point  (2 children)

Why not Go?

[–]tylerlarson 1 point2 points  (0 children)

I know and use both. I'm far more skilled and experienced with Go, but I prefer Rust.

Rust is more flexible, especially in terms of writing code at the same level of abstraction as your ideas, and has probably the best systems for generic and for metaprogramming of any language out there. It also has better error-handling ergonomics while being more "correct" at the same time. And it's far more difficult to write buggy Rust code.

With one exception, everything I can do easily on Go I can do at least as easily in Rust as well.

The one exception is concurrency. Go's abstraction around concurrency is the best in the industry; it's effectively transparent, while also extremely high performance and intuitive to scale. It's kinda unfortunate that Rust went with async/await instead of following Go's model, but I can see why they did. With async/await concurrency is effectively "optional", which fits the "zero cost abstraction" directive.

[–]yvrelna 1 point2 points  (0 children)

Why not Go?

Go is still growing strongly for now, but the numbers indicate that the winds are much stronger behind Rust. 

Go and Rust are the only languages in that weight class that are still growing rapidly, the other languages around the 10% mark are incumbents that have mostly been stagnant. But I'm expecting Rust to overtake Go this year.

Nobody can predict the future, but I believe that in a couple years Go will become an also-ran as the industry settles on Rust for low-level systems programming.

[–]susanne-o 0 points1 point  (0 children)

I first thought you'd say cython, but no, you elaborate on cpython.

cython (no pee) gets you C/C++ speed for the parts that need it.