u/InfrastructureGaming

▲ 207 r/rct

"Cursed Balloons"

I have no idea if this has been posted before, so apologies if I'm sharing old info...

For all of my years playing this game, I've always wondered what's up with the balloons. Sometimes a guest will let go of one, and it'll float up into the sky... where you can click it to satisfyingly pop it.

...usually.

But once in a while, there's one- JUST ONE- that flat out refuses to pop. You click, it dodges your cursor. You click again, it dodges again. It's like this thing KNOWS you're trying to pop it and it's just gleefully rage-baiting you along. Ever since I was a kid, I've wondered: is this a bug? Is it intentional? Was it accidental behavior that Chris Sawyer just left in for laughs?? WHY??

While exploring the codebase this morning, I stumbled across this little gem... it's 100% intentional, and it's straight from Chris Sawyer's original code (OpenRCT2 ported it faithfully). Here's the actual function, Balloon::Press() (entity/Balloon.cpp:73):

void Balloon::Press()

{

if (popped != 1)

{

// There is a random chance that pressing the balloon will not pop it

// and instead shift it slightly

uint32_t random = ScenarioRand();

if ((id.ToUnderlying() & 7) || (random & 0xFFFF) < 0x2000)

{

Pop(true);

}

else

{

int16_t shift = ((random & 0x80000000) ? -6 : 6);

moveTo({ x + shift, y, z });

}

}

}

There's even a comment spelling it out. But the mechanism is the beautiful part, and it's hilariously sneaky:

The dodge is keyed to the balloon's identity, NOT the click!

The pop condition is (id & 7) || (random & 0xFFFF) < 0x2000. Read that as two kinds of balloon:

- id & 7 != 0 → 7 out of 8 balloons. The first term is already true, the || short-circuits, and it pops on the very first click, guaranteed, forever. These balloons can never dodge.

- id & 7 == 0 → 1 out of 8 balloons (the ones whose entity sprite-index happens to be a multiple of 8). For these, the first term is false, so it falls through to the coin flip: (random & 0xFFFF) < 0x2000 is 8192 / 65536 = 1/8. So a "cursed" balloon has only a 1-in-8 chance to pop on each click, meaning it dodges 7 out of 8 clicks.

So it's not that any balloon randomly resists sometimes. A balloon is born either instantly-poppable or stubborn, decided by which entity slot it got allocated (its id). The stubborn one will fight you every single time you meet it; because you're not up against a 5% fluke, you're up against a 1/8-per-click coin that keeps landing the wrong way!

When it resists, moveTo({ x + shift, y, z }) literally jumps it ±6 units sideways (the sign is pulled from the random's high bit). So it doesn't just refuse... it hops left or right out from under your pointer. Combine that with Balloon::Update() drifting it up a step every 3 ticks, and a cursed balloon you can't land your 1/8 on will jitter sideways and float off the top of the map (z >= maxZ → Pop(true)) before you ever get it, escaping clean.

For a stubborn balloon, pop-chance is 1/8 per click → a geometric distribution with expected 8 clicks, but a fat tail: getting 15–20 dodges in a row is entirely normal. That's exactly the "click over and over and it keeps dodging" experience.

So: not a bug that survived, not an accident... it's a deliberate little cruelty Sawyer baked in, preserved bit-for-bit ~30 years later. Some balloons are just built to get away :) 🎈

reddit.com

Tilt-A-Whirl (improved)

After the largely positive reaction to my last post, I figured you'd want to see the ride actually running. So, here it is, doing a full cycle in a large park I use for ride testing.

After receiving feedback that my sprites looked "flat", I incorporated a two-stage dithering process that utilizes an optimized Floyd-Steinberg algorithm on the static ride frame and a content-aware Atkinson algorithm for the animated parts (riders are never dithered). We also refined the color remapping process to provide control over the catch tolerance for each zone, which gives us much more precise results with essentially zero artifacts.

This one sits on a 7x7 base, just because I wanted the extra space to offset it on the platform. I filled in the back area with landscaping to make it look like it's on a 6x6.

We've also deeply redesigned the custom ride system that these rides are running on; it's way more refined and robust now. [CUSTOM_FLAT_RIDE_GENERIC] is becoming an immensely versatile and powerful architecture that supports pretty much endless ride designs. The limits now are the global sprite pool limit of 1,000,000 and the nuances of paint functions that play nice with huge sprites. I misspoke about the large sprite format pre-existing in the engine earlier- it's actually an extension I created of the existing small sprite format. Apologies for that.

...I know some people have strong opinions about what I'm doing, and that's completely fine. I'm just having fun making stuff; I'm on my own custom fork, customizing this game, trying new things to see what sticks and what doesn't. Let me know what you guys think, I welcome critiques (just please don't be a d**k about it) and I'm legitimately curious to hear if this is a project people would be interested in. What rides would you want to see?

Thanks so much for all the kind comments last time, they really motivated me to refine the design and animation for this ride. I'll post my Chance Freestyle next, if that's something you'd like to see- it's got a pretty cool sequence.

Cheers :)

EDIT: Video compression kind of nuked the dithering. It's in there, I promise! Video doesn't really do it justice.

u/InfrastructureGaming — 9 days ago
▲ 94 r/openrct2+1 crossposts

Custom Ride #1: Tilt-A-Whirl

https://preview.redd.it/e7glqsjthw7h1.png?width=1280&format=png&auto=webp&s=0d9453970a69e65db9c0f7ef26865eaa538ce13a

I've wanted to expand the selection of flat rides in RCT since I was a kid. Decades later- here we are.

Modeled after the classic Sellner design seen across US fairgrounds for over 100 years, I did my best to reverse-engineer this ride to be as accurate as possible. Built largely to-scale on a 6x6 base, and with a capacity of 14 riders, it's a centerpiece for the park and a long-overdue addition to the RCT roster!

Excitement: 3.44 (Medium)

Intensity: 2.80 (Medium)

Nausea: 3.80 (Medium)

Yes it's real, yes it works. The ride supports full paint customization (2 colors), and the number of rotations per cycle can be adjusted (like the Twist).

Working on a heavily-modified development fork. Modeled & rendered in Blender, packaged & deployed with a custom-built pipeline I've been working on.

Curious to see what everyone thinks! Cheers :)

u/InfrastructureGaming — 18 days ago