This is my take on an io game. You’re a big blob competing to become the biggest blob. Doesn’t that sound wonderful? To spice things up, I also added a few powerups. You can grow faster, move faster, jump higher or activate a magnet.

The game is written in Unity and C#, born out of playing with the randomly colored spheres example. I use the Epic Games Online Services for matchmaking. I even integrated it further, you can log in with your Epic Account and invite friends to join you. This doesn’t mean you have to use an Epic Account, you can also play without logging in or even on the local LAN. This wasn’t easy to accomplish, much less as easy as it is now for the user at the tip of a finger.
If you’ve used Mirror before, you’ll know each of those requires a different Transport. Each one should be on a Don’t Destroy On Load object and the NetworkManager needs a reference to it; so why not put all three of them on the same Manager?
Well, because it’s three different things, they require different setups. For example the Epic Games Transport requires Epic Application Details, and finding other players on the local LAN requires a NetworkDiscovery component. So I made three different NetworkManagers and dynamically switch between them. It’s unfortunately slightly hacky because statics are involved, Transport.active is cared for by the active Transport and NetworkManager.ResetStatics() does the rest. To abstract this away, I made a Manager interface and a struct that’s used to join lobbies. My script also handles dependent GameObjects like the friends UI and loads the player name. To solve initialization issues with the Epic SDK all managers start active, then all but the first one are disabled.

start menu

While I appreciate the free service Epic provides, I hold a slight grudges against the way the Epic SDK has to be used. Let’s say we want to get a friend list. We first have to call QueryFriends and pass a callback. In this callback we can then check for success and store the result of GetFriendsCount. Equipped with that, we can now loop over all friends and call GetFriendAtIndex to get the friend’s EpicAccountId. This allows us to QueryPresence and then, in a callback again, save the status. Finally, we can QueryUserInfo and then, in another callback of course, copy it into our garbage-collected code. All of these calls do not take simple arguments, no, they take a <function name>Options struct each. Did we forget to check any callbacks for a successful result, by the way?
In my opinion, this is quite a lot of boilerplatey code for something pretty simple. I’d rather have a simple GetFriendList call that returns a list of Friend objects with a Presence and UserInfo property.

game lobby with player character and options

The lobby provides lots of customization options. Select one of five maps with different looks and paths to the treasure and 13 cute wobbling player models you can color in the entirety of RGB. Of course a proper lobby allows managing players, invite your friends with the integrated friends list and watch their avatars pop up in your game.

small yellow blob in front of staircase with forest skybox

Now for some actual game mechanics, you can move around with WASD, jump with space and use the mouse to steer the camera. PowerUps are activated with the number keys and come with different cooldowns, so use them wisely. On mobile two joysticks are used for movement and camera. You can grow by eating the colored objects or smaller blobs. For extra points activate the double multiplier or master the obstacles to get the treasure at the top. The treasure is worth a lot of points, but needs to recharge. There’s no official ending for now, just a message when a player reaches 10k points. If you get eaten, you can leave the game and rejoin or spectate; a slight caveat: the host should not leave because that would end the game for everyone.

big yellow blob on top of staircase with forest skybox

There’s no demo to test it right in your browser because the EOS SDK does not support it, but the game and source code will be eventually available via GitHub.

Comments