Live data from Hacker News

The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

larstofus.com

141–150 of 186 posts

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#141

> The same trick can also be used for the other direction to save a division: NewValue = OldValue >> 3; This is basically the same as NewValue = OldValue / 8; RCT does this trick all the time, and even in its OpenRCT2 version, this syntax hasn’t been changed, since compilers won’t do this optimization for you . (emphasis mine) Not at all true. Assuming the types are such that >> is equivalent to /, modern compilers w…

That whole section is kind of weird. The mention of operator overloading also seems out of place, since the operator is not overloaded here at all.

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#143
> The same trick can also be used for the other direction to save a division:

> NewValue = OldValue >> 3; > This is basically the same as

> NewValue = OldValue / 8;

> RCT does this trick all the time, and even in its OpenRCT2 version, this syntax hasn’t been changed, since compilers won’t do this optimization for you.

The author loses a lot of credibility by suggesting the compiler won't replace multiplying or dividing by a factor of 2 with the equivalent bit shift. That's a trivial optimization that's always been done. I'm sure compilers were doing that in the 70s.

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#144

> The same trick can also be used for the other direction to save a division: NewValue = OldValue >> 3; This is basically the same as NewValue = OldValue / 8; RCT does this trick all the time, and even in its OpenRCT2 version, this syntax hasn’t been changed, since compilers won’t do this optimization for you . (emphasis mine) Not at all true. Assuming the types are such that >> is equivalent to /, modern compilers w…

Yeah. I'm surprised this along with the money thing are listed in the article at all. These are the sort of things you learn within the first month of writing assembly, and were widely used across the industry at the time (and times prior). The bit shifting optimization is performed by GCC even at -O0, and likely already was at the time, as it's one of the simpler optimizations to make. It's like calling "xor eax, ea…

"XOR AXAX" was my license plate in the 90s.

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#145
This is a fun read, its one of my favorite games growing up by far, countless hours sunk into it. I didn't need this write-up to know that Chris Sawyer was god among men and that the open source version is a huge labor of love, but its a good reminder :) I will need to give OpenRCT a try some time, I've tried a little OpenTTD and really enjoy it, but RCT was always my jam.

For the lesson here, I think re-contextualizing the product design in order to ease development should be a core tenant of modern software engineering (or really any form of engineering). This is why we are usually saying that we need to shift left on problems, discussing the constraints up-front lets us inform designers how we might be able to tweak a few designs early in order to save big time on the calendar. All of the projects that I loved being a part of in my career did this well, all of the slogs were ones that employed a leadership-driven approach that amounted to waterfall.

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#147
post #137

Earlier quoted context omitted.

> Numeric characteristics are absolutely still a consideration for game designers even in 2026, one that influences what numbers they use in their game designs. The good ones, anyways. I used to think like this, not anymore. What convinced me that these sort of micro-optimizations just don't matter is reading up on the cycle count of modern processors. One a Zen 5, Integer addition is a single cycle, multiplication 3…

> A cache miss is going to mean anywhere from a 100 to 1000 cycle penalty. That blows out any sort of hit you take cutting your cycles from 3 to 1. A good example of this is using std::vector vs. std::vector in the debug build vs release build. vector is much slower to access (it's a dynamic bitset). If you have a hot part of the code that frequently touches a vector , you'll see a multiple X slowdown in the debug bu…

Fascinating, that's counterintuitive. I'd think the point of using vector is because the compiler would optimize it to be a bit field which is fewer bits and thus smaller and thus faster than using vector . How did you come to figure that out?

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#148

>the game was written in the low-level language Assembly Surely it wasn't all assembly. There is little to be gained in performance from writing non-bottleneck parts of the code in assembly.

> > What language was RollerCoaster Tycoon programmed in?

> It's 99% written in x86 assembler/machine code (yes, really!), with a small amount of C code used to interface to MS Windows and DirectX.

https://www.chrissawyergames.com/faq3.htm

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#149

>the game was written in the low-level language Assembly Surely it wasn't all assembly. There is little to be gained in performance from writing non-bottleneck parts of the code in assembly.

> > What language was RollerCoaster Tycoon programmed in? > It's 99% written in x86 assembler/machine code (yes, really!), with a small amount of C code used to interface to MS Windows and DirectX. https://www.chrissawyergames.com/faq3.htm

Wow. It reminds me of those guys who run a marathon carrying a fridge. Impressive, but ...

Re: The gold standard of optimization: A look under the hood of RollerCoaster Tycoon

#150
post #137

Earlier quoted context omitted.

> A cache miss is going to mean anywhere from a 100 to 1000 cycle penalty. That blows out any sort of hit you take cutting your cycles from 3 to 1. A good example of this is using std::vector vs. std::vector in the debug build vs release build. vector is much slower to access (it's a dynamic bitset). If you have a hot part of the code that frequently touches a vector , you'll see a multiple X slowdown in the debug bu…

Fascinating, that's counterintuitive. I'd think the point of using vector is because the compiler would optimize it to be a bit field which is fewer bits and thus smaller and thus faster than using vector . How did you come to figure that out?

I dont know how it's implemented by the standard/compiler (not my domain). The performance differences are well documented though.

I've used both in my pathing code and tested each in debug/release.

Even if the std:: implementation was as fast as possible, you're still adding bit manipulation on top of accessing the element, so it will be slower no matter what you do.

Post reply on HN