Game Ramblings #117 – Paper Mario: The Origami King

More info from Nintendo

  • Genre: JRPG-ish
  • Platform: Switch

This one was surprising to me, but only in ways that are relevant to the recent history of the series. If taken by the original game and Thousand Year Door, this being good isn’t a surprise. Even with Super Paper Mario, we saw some capability of the series to have spinoffs that are still quality. However, Sticker Star and Color Splash introduced combat focused on really obnoxious collectibles, and it felt like the series had gone off the rails. The Origami King in that regard is an oddity. It’s sort of an RPG, or at least feels closer to one than the last couple of titles. However, its progression isn’t based on XP, it doesn’t really have turn-based battles, and to some extent battles aren’t typically all that necessary. However, the systems in place – while not working great 100% of the time – still work well enough to make this one a really fun experience.

Being realistic, I guess the place to start with these ramblings is with combat. Combat has been the major downfall of the last couple of titles. In this one, it’s at times a blessing and a curse, but it’s at least unique and not surrounded by obnoxious collection anymore. The main catch for combat is that everything is based on setting up patterns in a ring. At the start of a turn, you’re presented with enemies pseudo-randomly placed on a ring, and with a limited set of moves you’re meant to slide and twist them into either a column for jump attacks or a 2×2 for hammer attacks. Do it right and you get a big damage boost. Do it wrong and you don’t.

That little detail though ends up being a blessing and a curse for combat. You want the damage boost because it lets you avoid taking damage yourself. It also results in you gaining a significant amount more coins in finishing. The reason you want more coins is so you can buy better items, since the upgraded attack items break every few battles. However, there’s no reason to need to buy a ton of items if you aren’t really battling. If you aren’t battling, then you won’t use the items and won’t need to battle to get more coins. It’s a weird sort of pull where combat for the sake of combat often feels super rewarding, but because your goal is to one shot everything it also ends up feeling inadvertently easy. Because you don’t really need to battle, you end up avoiding battles. Because you end up avoiding battles, combat feels inconsequential.

That said, there is something to be said for how satisfying combat feels when you do engage in it. Getting your board pattern right is a big positive gameplay boost. Seeing the big damage numbers is really gratifying, and even better when you see enemies explode in a flurry of coins and particles. This is enhanced by the typical timing-based bonuses from past Paper Mario titles where timing things just right gives you damage or defense bonuses in active combat.

However, bosses flip this all around. Rather than being in the middle of the board fighting outward, you’re starting on the outside of the board and moving inwards. You push and spin the board to line up a series of arrows and attack pieces to attempt to move you into the right position for maximum damage in a turn. Everything I’d read in previews of this game seemed to indicate that these fights could be grindy and boring, but honestly I found them anything but.

Admittedly, yes they can be long fights. However, they’re generally only grindy if you make them so. Each boss has a handful of core mechanics that really give you a ton of damage. Figure these out and you’re getting through the fights in a small handful of turns. Don’t figure them out, or don’t do your board setup right in a turn, and you could be in for a world of pain, or a turn with no damage output. From that perspective, I can see where some of the criticism comes from. In some cases, the mechanics at play are probably more vague than they should be. However, it’s incredibly rewarding to figure out one of these mechanics and really lay into a boss. Seeing a third of a health bar disappear in one turn will never feel bad, and this one definitely has that happen if you’re playing your cards right.

There were also a handul of real-time combat bosses that caught me off guard in the best way. The Blooper fight above is one example, where I’m dodging and jumping over different attack patterns trying to hammer the tentacles. Another example had me fighting a gigantic Papier-mâché Pokey while driving around a desert in a boot. These little real-time segments were never necessarily a core focus of the game, but had a habit of turning up at just the right time to let the game breathe a bit. They acted as a fun little challenge to tie into some portion of the story without forcing a turn-based fight. They stretched the overworld mechanics a bit to provide something the player could hop right in without a tutorial, but still be challenged in new and interesting ways.

As far as the rest of the RPG-ish stuff goes, it’s there in small ways that provide a power curve, but remove complexity from the genre. There’s no built-in XP system, but you’re provided fairly regular health and damage upgrade bonuses to give regular power growth. There’s no real gear system, but you can buy accessories to provide battle and world bonuses. There’s no weapon upgrades, but there’s an ever increasing strength of weapon items that you can buy, which do break, but cost far less in practice than the amount of coins you gain in winning a bunch of regular battles. It’s in an interesting place where they kind of take the RPG elements that work for the game, but don’t push into all the expectations of the genre. I’d be lying if I said I wouldn’t have preferred something more akin to Thousand Year Door here, but for what it’s worth it ends up working out well, and at the very least doesn’t end up getting in my way.

The rest of the experience is core Paper Mario, and if the battle system doesn’t scare you off, you don’t need to know anything here to know you’ll enjoy it. The origami visual style is phenomenally gorgeous, and they strongly use that to differentiate the paper people from the origami enemies. The writing is top notch and often laugh out loud hilarious. You’ll see creatures and characters from all walks of the Mario life, and you’ll see them in ways that are often very different from how they’re presented in the core platformers, but again that’s no big surprise here.

End of the day there’s really just one thing here to be said about this game – pleasantly surprising. The previous two games in the series really lowered my expectations coming into this one. As much as I was being cautiously optimistic about the combat, seeing another non-traditional turn-based system had me pretty nervous about the state this one would land in. Luckily, it landed pretty well. There’s definitely some oddities around how necessary combat ever is in this game, but engaging in combat is at least fun on its own. Even better, the boss fights are super interesting with some twists on the core mechanics at play within them. Again, I’d be lying if I didn’t admit I would have preferred a more direct sequel to Thousand Year Door, but for the time being this one still leaves me pretty happy.

Programmer Ramblings – Continued Screwing with std::thread

This is a followup to yesterday’s ramblings about initial work screwing with std::thread.

In talking with Quintosh on Twitter, he asked why I didn’t go with some sort of thread pool. Frankly, it’s because I’m lazy. However, it did give me an idea. The data that I’m working on is fairly parallelizable without memory collisions. Rather than creating a thread pool where I hand work to threads, it would be a lot lower amount of work for a simple program if I let the threads directly request work themselves. This gave me a few things:

  • A unit of work could be much smaller, so cores that are running slower because of other system processes don’t present blocks.
  • Once I implement other things that scale the program non-linearly (ex: reflection/refraction), I don’t have to worry about intelligently breaking up the work into equal sizes.
  • The only member that is accessed across many threads is the piece of data controlling the work request. This keeps my actual locks to a minimum.

Much to my surprise, I also managed to get Intel VTune working completely. This helped confirm some of my assumptions from yesterday’s article, so I’ll cover that in some detail later on.

Programmer Ramblings – Screwing Around With std::thread

Being a primarily Unreal-focused developer, I don’t really spend that much time in standard C++. Ya, technically I work a lot in C++, but C++ using STL and related things is very different from the custom containers and macro-heavy nature of working in Unreal. Part of the fallout of that is that I generally miss new features of the language for quite a while. I didn’t get into working in C++11 and newer until I was off of working in UE3, and even moving into UE4 I don’t get exposed to things like STL or the the standard implementation of threads. It’s one of those things where, ya I’ve used threads and I get the concepts behind it, but creating a worker thread to offload a specific task is much different than architecting code to properly and efficiently support a threadable workload. That’s where my screwing around here comes into play.

For this screwing around, I decided to thread an implementation of a raytracer. It’s a workload that is inherently parallelizable. You’ve got a bunch of rays going out that can independently resolve themselves. Ya, you may need to have a ray spawn further rays, but that can live within the worker thread as it chews through the work. From a naive implementation standpoint, each pixel could be its own thread and run in parallel, and that’s basically where I started.

Some notes:

  • For the purposes of this, I started with a sample implementation from Ray Tracing in One Weekend by Peter Shirley. This series of books is a supremely fantastic quick look at basic concepts behind ray tracing, and gave me a quick place to get to a point where I could investigate threading.
  • For my CPU, I’m running this on an AMD 3950x (16 core, 32 thread) at stock speeds. I’m not doing anything to minimize background processes, but it shouldn’t be a huge issue for where I’m at.
  • I’m currently using Visual Studio 2019’s built-in performance profiler. I don’t particularly like it compared to other tools, but my profiler of choice on my current hardware (AMD uProf) currently has a bug on some installs of the May 2020 version of Windows 10 that prevents profile captures. The VS profiler is basic, but gets me enough information for the basics that I’m starting at.
  • This is running in release with default optimizations purely out of laziness.
  • I’ll post some code samples around. These won’t generally compile because I’m stripping out unnecessary stuff from the samples (ex: you don’t need to care about me setting image dimensions and writing it to disk).

For the purposes of my current testing, this is the output image. It’s two spheres where each pixel color represents the surface normal hit by a ray. The image is 800×400 resolution and each pixel does 100 slightly randomized rays to give an anti-aliased result. In the basic current pass, I’m not doing any bounced rays on collisions. The final image is therefore the result of 32 million ray casts. In some future tests, I’ll be adapting the rest of the book to the multithreaded version and support reflection/refraction and increasing the workload through that process.