Embracing changes with MVVM

Experimenting new ways to make great games together

etermax technology
Published in
6 min readJul 29, 2021

--

In etermax one of our main pillars is Gaming, where we create multiplatform games. It all starts with an idea, then they become sketches and when those two parts are consolidated, we bring it to life with Unity.

We are encouraged to use any tool we want to build our code; we have a lot of freedom to make the best code as we see fit. But we are not alone, we work with artists and other professionals who improve the content of the games in the same Unity project.

In January, our team was trying to find a solution to an everyday problem we had in the past, which is the dependency between artists and developers when building the game and then modifying the assets or flows within it.

What we found was that our MVP architecture was limiting our artists’ freedom because it was not easy to change the flow of the game from the Unity editor; developers had total control of this flow and that created some kind of dependence between the two parties, which wasn’t good for anyone, because we need them to integrate visual effects, animations, prefabs, designs, whatever. And they need us to bring those things to life, but if developers are in a hurry, the work done by the artists will not see the light of day in that sprint, or maybe ever.

  • MVP: Model View Presenter
  • Sprint: It’s the name of each cycle or iteration within a Scrum project; in our case it’s 2 weeks.

Finding a solution

So we started to investigate what kind of solution would work with the team, to provide that freedom that we had but that we were taking away from others, and we discovered that making our game data oriented was the initial step to make that flow easy to modify. To be able to do this, we implemented a basic MVVM in Unity with custom components and editor tools.

Supporting an easier way to build our game, even more so in Unity, was a journey we wanted to embark on.

Our inspiration for how to integrate editor tools with this new data-driven flow was a Fruit Ninja Devblog.

Wait, MV… what?

MVVM diagram (https://www.developer-experts.net/)

MVVM (model-view-viewmodel) is a pattern that facilitates the separation of graphical interface development from business logic development.

  • Commands: it’s the mechanism the View has for letting the ViewModel know about an interaction.
  • Data Binding: It’s the way to synchronize the data between a ViewModel and the View.
  • View: It’s the View, components in Unity.
  • ViewModel: It’s responsible for exposing properties and commands, it also transforms the model to represent it through the properties mentioned above.
  • Model: It’s our domain, where our business is.

Recognizing risk

But we also had more questions than answers about how we were going to make everything work with this architecture in Unity and how we would make the game easier to build for non-developer teammates.

Starting to experiment

We tried to follow the basic architecture that anyone can find for MVVM (see diagram above), but that didn’t work for us. We found that the way that was the most faithful to that diagram was not easy to use from the Unity Editor, it was very easy from the code, but that would be giving in on the main purpose for which we ventured on this journey: to democratize the way in which the game is created, for any team member to be able to create a button that triggers a command and updates something on the screen for that run.

After some testing with the new game, we discovered that what was working for us was to use Scriptable Objects (SOs) to contain our commands, our ViewModels are also SOs and we added something extra that we call DataSources, they are just SOs that contain data objects.

Scriptable Objects: is a data container that can be used to store large amounts of data, regardless of class instances.

The difference between ViewModels and DataSources is that we use ViewModels to expose properties that are easy to consume by Views and only contain primitive types. On the other hand, our DataSources contain richer data in terms of their structure.

DataSources: It is where we keep the data structures, when a command executes an action, a datasource provides the data object and at the end of the operation in the domain, the result of that operation is saved in the DS updating its state and generating notifications for the associated ViewModels to react.

The flow of changes starts with a button in Unity that runs a command, that command will execute an action domain [Business UseCase] that will change the state of the game, then the new state will be set to a DataSource, and the DataSource will notify the ViewModel indicating that the data structure it is observing has changed, and from there, the ViewModel will notify our Bindable Components in Unity that are linked by the properties of the component in Unity with the properties of the ViewModels.

Will this be scalable?

The main concern we had was how this would work on a real device, would we have FPS drops? Maybe performance issues?

We had those questions, but we didn’t have a game big enough to have a real picture of that. In March we reached that level, our game grew to a point where we were able to measure the FPS and get that answer: the game was 58 -60 FPS all the time, including transitions between screens, it worked without any problems and very fluidly.

How did we do that?

Let’s talk about what’s under the hood of our framework; of our Binding Components, these are the most basic scripts we use, but the most powerful ones. These receive a ViewModel like SerializableField and with reflection a property of that ViewModel is joined with a property of the Unity Component we choose.

But reflection is slow, you’re probably thinking. I have to say you’re right about that. We use reflection only to link the component; after doing so, we create a subscription between the Unity Component and the ViewModel property from which we want to receive the new changes.

Learning

That was our journey using MVVM in Unity. We can say we had tough times trying to change the way we approach features with MVP and how we needed to approach features with MVVM, but now we have that data oriented factor that allows us to move prefabs from one place to another without breaking anything and it’s really easy to add new features. Is our framework ready? No, it has the minimum to cover the features that the product needs. We must deliver a game, not an MVVM framework.

It took us about two months to discover the pieces that are needed, the workflow, and teach the rest of the team how to use this implementation of the framework. In our case we have a very good technical team so the learning curve was not so big, but we have proven that this works and that the potential is great.

--

--