Penguin Action Toolkit (PAT) empowers action game development, in ways even beyond people’s imagination. This was our headline when we were pitching the project. Truth is, PAT never ceased to surprise us, the developers, throughout the process of coding and testing. A few changes in the Unity Inspector transforms a Soul-Like game into a resource management game where your character loses HP when moving. The players are running and dying at the same time, how exciting is that? What’s even more exciting is that we never intentionally designed PAT for this specific use case, yet the toolkit enables playtesters and game designers to bring their whim and inspiration into reality. Because of that, we believe these enlightening moments must be recorded, and they shall not be forgotten just because this project will eventually come to an end.

Introducing: Beneath the Feathers (a nod to Dota2’s Between the Lanes) — a new blog feature where we review certain cases from our development, and try to bring all those decisions, aspirations, and technical details of PAT to the public. Share the problems solved and the moments sparked. We hope that these stories, as entertaining as the video games themselves, can be a part of PAT. Whether you will be using PAT to create your own action game or not, you might find joy in reading those posts.

“Does our framework support multiplayer?” That’s a very interesting question. During past internal tests, we implicitly assumed the toolkit is built for classic single-player games. From there, we had a rabbit running over the moon and a robot diving into Castlevania. A single player controls a single character.

When the question was asked, we could not immediately give an answer. PAT adopts a unique input system. An input from the player is presented to the Player Component that controls the character, and it will turn the signal into a special Input Tag in order to trigger different Action States. How do we differentiate various inputs and assign them to the correct charaters? That’s the problem we needed to figure out. We didn’t want to ignore the possibility, where two penguins — or even more penguins — can hold their hands (or flippers) and march forward together on the same screen. We wanted to give it a shot. Perhaps someday, someone will use it for some fun ideas. So we spent some of our spare time verifying whether PAT supports the use of two controllers.

Naturally, we started with the attempt of finding a usable API that sets a corresponding player for each Input Action. If Unity provides something like that, then we use it, and problem solved. We had no luck even after diving deeply into Unity’s source code. But we did manage to find some very interesting comments:

It was a good reminder for us: even Unity has features still in development. The engine developers of Unity are just as confused and tortured by all kinds of problems. The fate of humanity was united, from that perspective.

Giving up on searching for APIs, we turned to a more formal pipeline. Unity actually has this pipeline for multiplayer game controlling schemes. Two Components, Player Input Manager and Player Input, allow us to differentiate inputs and bind them to different characters. We did not use this pipeline until now. What we used is a Script called Input Manager that exists on some Game Object. It decides everything for us. This was a habit from our past experience of making indie games and game-jam games. After all, if there is only one player, Input Manager seems good enough.

So, how difficult it is to adapt our system to this formal pipeline? It wasn’t hard to do the basic movements. It didn’t take long before we had two robots running left and right in the Castlevania world. However, making the second character jump and attack? Not so easy.

This is where we need to bring up how Unity’s Player Input Component actually works. The component has four behavior options. Send Meesage, Broadcast Message, Unity Event, and C# Event. The first two Message behaviors require us to provide functions named after required names. Any modification to the names will cause the system to fail without any warning or error from Unity. We have also been avoiding Unity Events because they move tasks that should be handled in code to the Unity Inspector, resulting in chaotic logic chains that are difficult to manage. So, the only option left was C# Event.

C# Event has its own disadvantage: we will have to do String comparison for the inputs. Every time we detects an input, we need to compare the Action name to the Actions that exist on its Action Map. We were not the biggest fans of String comparisons, but at least the Strings that were used are from the Action Asset — it makes it a lot more stable than using Messages. Perhaps there exists a more elegant solution, but none of the four behaviors is perfect, so we have to settle for less. With some extra code, inputs other than moving were passed to the correct character with String comparison. Finally, two robots were taking their adventures together.

Or, they might be locked in a duel.

This change of Input System pushed PAT forward in two directions. First, it now has the capability to support multiplayer. Second, the structure of our Sample Scene is more formal, at least from Unity’s own perspective. Developers using PAT can now appreciate the standardized structure demonstrated in our sample. Ultimately, after a series of attempts, we confirmed that PAT supports multiplayer. It surpassed our expectation, again. Will someone use it to build a multiplayer game? Who knows. Maybe we do it ourselves.

Hopefully these paragraphs and pictures brought you some joy. It is an exploration over PAT. What can it do? What should it do? We keep asking ourselves those two questions. The former demonstrates its capability, the latter guides us to improve its design. In the next update of Beneath the Feathers, we will probably discuss the latter question: What is PAT designed for?

Author: Harry

Revision: YC & Wuji

Tags: