Unreal Match 3, our newly released app for Android and iOS, began as an Epic Friday project back in April of this year. The game was created primarily by a few of us on the learning resources team — a small group within Epic that is focused on creating training materials.
Many of our smaller learning resource samples were Blueprints-only, and while they're still really valuable, we understood the need for more C++ samples to round out the resources. While we were brainstorming, Tom Looman was kicking off his survival game in C++, so we wanted to go in a different direction both in the style of the game and the engine features shown. Using a puzzle game like Match 3 meant that we had established rules we could use, which let us focus on showing how to implement those in Unreal Engine.
Our initial brainstorming list includes a few features that didn't make it into the initial sample, like AI and Data Tables. We do intend for it to be a living sample, though, with new functionality added over time. Some of those features might end up in other samples we do, instead.
Coding Unreal Match 3
After Richard and I came up with our project starting point, we began adding code to my original prototype. As we wrote code, there were three main rules to which we adhered.
The first was to keep code as generic as possible. My original grid code assumed a square grid and that we'd only want to have a Match 3 mode. The final Unreal Match 3 game code has parameters that let you create non-square grids or ask players to match 4, 5, 6, or more tiles. During development, we even considered multiplayer support, although we finally made the scope call to remove it from the sample.
The other two code design decisions we made were about object-oriented programming in Unreal Engine. We wanted to use framework classes like Game Instance, Game Mode, and Player Controller for their strong suits. Our Game Instance class handles saving of the whole game, as well as sending information to mobile services, while Game Mode keeps track of the Match 3 rules, such as the amount of time left on the clock. We wrote these C++ classes while trying to keep in mind what designers would want to hook into in Blueprints, although later on when we got to the art pass, we came back and extended our Blueprint API even further.
After about two months of on-and-off coding in between our other work, we had a fleshed out game, complete with the art I'd borrowed from other learning resource samples, along with a free Marketplace pack.
Note the lack of HUD art and landscape mode. Our bombs were actually boxes!
The Art Pass (and Beyond)
This is about the time we started to add to the team. All told, by the end of the project, we had six people working on Unreal Match 3 part-time over a period of about six months. Our artist, Mike, created new textures for the game within a few days, and our audio engineer, Joey, knocked out awesome sounds in a two-day turnaround. It was really remarkable to see the art and design pass transform the project into something that began to feel more and more like a real game.
As the team grew, we became very glad that we'd kept our game logic in multiple C++ classes (and also multiple Blueprints). This way, for example, Wes could work on the Bomb Bar Widget Blueprint, while Alan worked on the explosion effects for all the different tile types, and we rarely ran into issues where someone needed to pause and check in their work to unblock someone else.
There are two examples from this art and design pass that show our goals for how setting up the inheritance and class breakdown.
- In C++, our base Tile class handles tasks like storing whether or not it can explode, the animation for when tiles fall, and reporting back to the game grid when they've been selected. Our Blueprint Tile class inherits from that, and adds on base effects like spawning the floating score display. Finally, we have Bomb, Gem, and Block Blueprint Classes that add specialized visual effects for each of those tile types. This way, visual or audio effects are primarily handled in Blueprints, while base game rules or things that happen frequently (like the tiles animating) are in C++.
- We used Blueprint Native Events and Blueprint Implementable Events throughout the project. For example, after most of the audio pass was done, Joey mentioned that he'd like to do a sound effect for the tiles landing. I added a Blueprint Implementable Event that was called in code when the tiles landed, and he was able to quickly wire the effect up in Blueprints and test it out.
Along with the design and visual pass on Unreal Match 3, we hooked up mobile services like achievements, leaderboards, ads, and in-app purchasing. We also began testing across a range of mobile devices.
These areas brought up some interesting and tough questions for us. We ended up going with a cosmetic overhaul of the level for our in-app purchase, because we wanted to illustrate the flow of the purchase process in the final project without impacting gameplay. The nighttime skin ended up being one of my favorite parts, by the way, because it really shows how a different art and audio style can change the whole feel of the game.
For leaderboards and achievements, we originally had a setup where the online service had authority, and in a full-fledged game where you want to maximize the security of your high scores, that is an ideal setup. But, after a lot of back and forth discussion, we went with a system that is forgiving to people who play offline by using the highest score or achievement level between the local and online systems.
Finally, on the mobile device front, I'm really glad we tested across a wide range of devices, as it uncovered some edge case scenarios we hadn't considered earlier. We used device profiles pretty heavily to try to get as much performance as possible on a wide range of devices without sacrificing the look of the game.
What Went Well
Unreal Match 3 has been an amazing project to be a part of, and I hope that anyone working in Unreal Engine finds it useful as a learning tool. While it is a mobile sample, the C++/Blueprint split, the event-driven UI, and the Paper 2D setup can be applied to many projects.
- We used what we had available, and scoped the project to the skills of the team. Being more on the programming side, I leaned toward the 2D game style when planning the project, and the rest grew from there. Since we were a small team doing this on the side, keeping the scope small and achievable really helped in the long run.
- Working on Unreal Match 3 was jokingly called the "stone soup project" for a while, in that everyone contributed where they could to get the project one step closer to being done. The learning resource team was the primary team working on it, but we collaborated across the company on art, sound, and testing, and that was an awesome experience.
- Alongside making the game, we put together livestreams and written documentation to explain the project setup, from our UI design to force feedback.
- More than that, though, creating a complete project like this helped us find the stumbling blocks in development, and how best to work two features together. We'll incorporate those lessons in a lot of other learning resources we create going forward as well.
- I like how Wes put it, so I'll quote him shamelessly: "This was also a learning process for us. None of us profess to be the end-all-be-all when it comes to Unreal Engine 4, and we are learning more and more every day, just as you are. Building this project allowed us to get more exposure to the engine and exposed some things on the engine side that we are already taking steps to improve the process and pipeline for. The best way to learn is to set out to build something, then build it – learning along the way if need be! "
- Everyone pitched in when and where they could on this project. We didn't have defined roles as much as primary skill sets, and while this caused some hiccups at times, it also contributed to the team feeling a sense of ownership over the whole project.
What We'll Learn From
Even though this is a learning resource for the Unreal Engine community, it's safe to say we learned a lot while making it, too.
- Because we didn't have defined roles going into the project, it was sometimes tricky to resolve gameplay design decisions, art style questions, and other discussions. Everyone having a voice is definitely great, but sometimes an executive decision is needed to keep the project rolling. A game design document helps a lot with this too – while we had one on the teaching side of things, we could have used more detail on the plans for overall gameplay.
- While we got the game to a playable state fairly early on, the last (big!) push of bug fixing and testing caused a small drop-off in enthusiasm as we got closer to shipping. This definitely isn't unique to this game or this team, and is something to keep in mind when you think that there are "just a few things left to do before shipping."
- UI Scaling is an area where we spent a lot of time with fixes and testing. Part of the reason for this is because we made some changes for individual devices first, rather than starting with general fixes and then narrowing down device-specific fixes. Much like optimization, UI scaling (and device-specific fixes in general) is an area to work from general to specific, and proceed with small steps.
- Mike, the artist who created a lot of our tile art and UI textures, was also really busy with other projects, and so while we would have iterated more if we'd had more time, we ended up adapting the game to the art instead of the other way around. The main thing we learned here is that when collaborating outside the team, communication is key, because your team's shorthand/internal expectations might not always translate.
Unreal Match 3 Trivia
- Number of games played by Samples QA: 1,979
- Number of games played by unofficial QA/Unreal Match 3 Fan Club: 101,979
- Number of bundt cakes consumed during development: 20 (4 gluten-free)
- Most popular Match mode overall: Match 2
We hope you enjoy this project as much as we've enjoyed working on it to bring it to you. It's the first time we've done a major sample with so much accompanying documentation, and ended up with a game that is pretty fun to play along the way!
Check it out in the Learn tab, on Google Play, and soon on the iOS App Store, and let us know what you think in the forums.