Approaches For Multiplatform UI Design Adaptation: A Case Study

There is no winner in the battle between iOS and Android, and we all know that. If a product succeeds on one platform, it will undoubtedly be ported to the other. Sometimes app developers don’t even bother waiting, and release apps for both platforms simultaneously. For designers this means only one thing — they will have to adapt an application’s UI and UX to another platform while ensuring a consistent design language across the product.

There are three different scenarios for UI multiplatform adaptation: retaining brand consistency; aligning with the conventions specific to the platform; and seeking a balance between the two. We decided to analyze these three approaches by looking at the most popular apps out there so that you get some insight into what method might work best for you.

The Brand-Oriented Approach Link

Sticking to the brand and ignoring “parents’ rules” is the fastest, easiest and most cost-efficient approach, but only in relation to UI design, not software engineering. Custom UI is rather complex in implementation, so development effort would cost you more if compared to the price of building standard components.

Furthermore, choosing brand as a priority in UI design can be a pretty dangerous approach to take. I call such apps “teenagers” because they don’t feel at home, don’t follow the rules, and can be pretty annoying sometimes. They think they’re different, but really they’re the same as everybody else at their age. There are exceptions though.

VSCO CAM LINK

Visual Supply Co.’s first VSCO Cam app for iOS came out in 2012. A year later, the popular photo editing product was ported to Android. The Android version of the app copied the iOS version’s interface almost entirely. Interestingly enough, neither version of the VSCO Cam app correlates with the standards specific to the platform it was designed for.

VSCO Cam iOS and Android
VSCO Cam iOS (left) and Android. (View large version)

Dropping platform guidelines in favor of brand identity is well justified in this case. The VSCO Cam’s founders deem creativity as massively important, which explains their vision of the product they’re building. They developed an app to be part of the brand and the brand to be part of the artistic community, which is why the creative integrity of the brand is more important for VSCO Cam.

VSCO Cam
VSCO Cam. (View large version)

INSTAGRAM LINK

Like the VSCO Cam app, Instagram was launched in the App Store way before it became available for Android. The iPhone app, which strongly corresponded to iOS guidelines experienced huge success; in this case, the typical UI for Apple devotees became Instagram’s distinctive feature. This explains why Instagram’s creators didn’t spend a lot of time creating a unique UI for Android. Even though the app’s overall aesthetics don’t conform to what Android users have come to expect, Instagram garnered over 1 million downloads from Google Play on day one.

Instagram iOS and Android
Instagram iOS (left) and Android. (View large version)

The current iOS and Android versions of Instagram do look like twins, but there are still a few elements that set them apart. For example, the search bar looks native to both platforms. The camera interface in the latest Android version is also a bit different from the iOS version. What’s more, Instagram’s logo is located in the center of the navigation bar on the iPhone app, but was moved to the left of the tool bar in the Android version.

Instagram search interface iOS and Android
Instagram search interface iOS (left) and Android. (View large version)

The Instagram app for Android fails to comply with the platform design standards, but it still feels convenient to users.

Instagram video interface on iOS (left) and Android
Instagram video interface on iOS (left) and Android. (View large version)

WIRE LINK

Co-founded and backed by Skype’s creators, Wire is another messaging app. It doesn’t differ much from its counterparts, except in one thing — it has a strikingly beautiful user interface which never fails to leave an impression, especially on the hipsters who use it. Wire’s designers used non-standard gesture-driven solutions, the main purpose of which is to hide as many things from the user’s eye as possible.

We are building an elegant and useful tool to communicate across all modalities — text, voice, video and media. Media is at the core of the Wire experience, so we have chosen to reduce chrome and remove any unnecessary clutter in favor of the content. We also put a lot of effort into typography and readability.

—Priidu Zilmer, Wire’s head of design

It takes quite a bit of guess work for a user trying to navigate through the app for the first time. But on the other hand, Wire uses lots of micro-interactions which make user experience more fun and engaging. A simplified contact search, nice color palette, the option to choose a background image, and color all contribute to the uniqueness of Wire in a world where online communication is ruled by Telegram, WhatsApp, Viber, and a bunch of other typical-looking messaging apps.

Wire iOS and Android
Wire iOS (left) and Android. (View large version)

We invest a lot in design, and we could not do it three radically different ways (for Android, iOS, desktop/web), especially as the platform conventions themselves are often moving targets. Getting too close to them means you can suddenly look out of sync — much like when iOS 7 and Android L shipped.

At the same time, we know the risk of not following familiar platform conventions. Therefore, we are constantly working to find the right balance by iterating and adjusting so that our design can be simple enough to translate well across the platforms.

—Priidu Zilmer, Wire’s head of design

The iOS and Android interfaces of the Wire app are absolutely identical, including UX design and icons. Wire apps lack any reference to the original guidelines (except for the size of the clickable elements). This app is another example of the user interface design being given more weight than platform requirements.

According to Zilmer, the Wire’s design team did not feel that elevating how users connect to and share with the people in their lives could be done staying purely within the conventions.

Wire
Wire iOS (left) and Android. (View large version)

VSCO Cam, Instagram, and Wire chose to focus on brand in the interface design. But does this mean that a smaller mobile startup that follows in their footsteps can become just as successful? There are a few situations where I believe following a brand-oriented approach can be a winning strategy.

WHEN SHOULD I FOLLOW THE BRAND-ORIENTED APPROACH? LINK

The same user accesses your product from multiple channels (desktop, iPad, iPhone, Android)Link

Quite often, brands that employ multiple channels to interact with customers follow a brand-oriented approach. However, this is only reasonable if the same user accesses a product from different platforms and device types (iPad, Android phone, web). For example, the same user ofiBroadcast, a music service, accesses it from iOS and Android devices, and even desktop. The app’s versions look similar everywhere because the highest priority for iBroadcast is creating a smooth transition from one platform to another one so that a user doesn’t feel any difference.

Our service has people bouncing between the website, the iOS app, and the Android app. We want to make the transition as consistent as possible so it is easy for our users.

—Rod Collen, co-founder of iBroadcast

The iBroadcast app for iOS and Android
The iBroadcast app for iOS (left) and Android. (View large version)

In case your app falls under this description even if it’s a multiplatform product, you might want to think twice before taking a brand-oriented approach. For instance, Facebook (which we’ll consider a bit later) follows a mixed approach to multiplatform UI design adaptation. The thing is that Facebook’s users tend to interact with the social network using one or the other platform (iOS or Android), not both of them.

Custom UI components provide intuitive user interactions, and are eye-catching at the same timeLink

One research study suggests four components of intuitive interaction: gut feeling, verbalizability, effortlessness, and magical experience. The combination of these components allows designers to create seamless user experiences regardless of whether they follow a platform’s guidelines or not. After all, some custom components can provide a superior presentational or interactive experience than platform standards.

It’s also worth noting that the differences between platforms can be the reason why an app might feel convenient to use on one platform, but inconvenient on another.

The creators of HowAboutWe, a dating app, argue that the only way to truly ensure style and layout consistency across various Android OS versions, manufacturers, screen sizes and densities is to use custom UI solutions. Native UI components do have some limitations, but you can always innovate to improve user experience with your product.

For example, an Android budget managing app, Receipt, has quite unusual drop-down animations that ignore the platform’s guidelines but manage to engage users.

I wasn’t happy with how the guidelines suggested implementing certain features and thought I could come up with better solutions.

Generally, I’ve only ignored the guidelines when I thought there was a clear advantage to doing things my way, such as providing better feedback to the user, removing unnecessary steps, or preventing workflow interruptions. Replacing modal popups or unnecessary screens with inline elements are a big part of this.

—Bogdan Mihaiciuc, founder of Receipt

Unless unique and beautiful UI solutions in an app complicate user experience, they make a great first impression on users and draw them into a product. One of the reasons why users feel attracted to My Day countdown app is its uniquely designed interface, identical on both platforms.

Excellent UI design in Citymapper makes the app stand out across all platforms, including web.

For us it was always about the balance. Feeling familiar in the behaviour of our UI but also making a clear and unique statement about who we are as a brand.

I think the value of a unique design language is often underestimated… You mean Citymapper? Yes “The green one.” That in itself is hugely valuable.

Sometimes designers can be too precious about the pixel-perfection and “correctness” of their designs. Life’s chaotic, and so is building a product. So why hide that fact? We’re in this together — the people who build a product, and the people who use it.

— Gilbert Wedam, lead design at Citymapper

When adapting UI to another platform, you should put yourself in the user’s shoes regardless of the approach you use. The ability to create frictionless user experience while keeping brand consistency is one of the virtues of a great designer.

The Platform-Oriented Approach Link

Contrary to the brand-oriented approach, following platform-specific standards requires significantly more time and money (if we speak about UI design exclusively). When you port design, many UX and UI elements need to be recreated from scratch to align with the conventions of the target platform.

In this case, the focus shifts from brand identity to familiar user experience, since users are accustomed to the platform conventions. They have an intuitive grasp of the design rules around their platform, which you can use to your advantage — which is exactly what Telegram and WhatsApp did very well.

TELEGRAM LINK

Telegram is a popular messaging app co-founded by Pavel Durov, the man behind the biggest Russian social network, Vkontakte. Telegram has a minimalist design style and supports a secure encryption protocol for private messaging which gives the app a great competitive advantage.

Telegram launched on both iOS and Android at the same time, and chose to focus on functionality rather than looks. Therefore, its designers decided to stick to a platform-oriented approach.

The iOS and Android versions of one and the same product are as different as typical iOS and Android apps can be. The iOS version fully follows Apple guidelines, and looks exactly like an app designed for iOS 7/8: on the right of the navigation bar there is an icon for typing a new message and on the left there is a button for editing; at the bottom of the screen there is a tab bar with sections, and on the top you can find the name of the current section.

Telegram for iOS and Android
Telegram for iOS (left) and Android. (View large version)

The Android version of Telegram complies with Google’s Material Design guidelines. It has a hamburger menu for navigating through the app’s sections, a simple search button at the upper right, and a floating button — the heart and soul of material design.

Telegram
Telegram contacts list in iOS (left) and Android. (View large version)

The apps use platform-standard controls and UX interaction elements. I bet Telegram’s designers were guided by the most general principles of usability when creating the app.

Telegram 2
Telegram settings interface in iOS (left) and Android. (View large version)

WHATSAPP LINK

We’re going to stick to the theme of messaging apps for a while. Another candidate we’ll look at is the so-called evangelist of messaging — WhatsApp, now Facebook’s property. The iOS app was released back in 2009, followed shortly after by versions for BlackBerry and Symbian. The WhatsApp app for Android hit the market only in 2012. It looked exactly like an app Android users would recognize and love.

Since WhatsApp is available on almost every platform, it’s natural that it sticks to the platform-oriented method. The iOS and Android versions of WhatsApp look completely different from each other. Its designers did a great job on the multiplatform adaptation. They changed everything from the UX to the message look to the icons to the location of elements and menu items.

WhatsApp for iOS and Android
WhatsApp for iOS (left) and Android. (View large version)

At present the iPhone app version corresponds to iOS 8 standards. The version for Android? You guessed it …received a material design visual refresh in the latest update.

KOMOOT LINK

Komoot is the go-to app for hikers and bikers that belongs to a startup from Germany. The first app’s version came to iOS in 2010 and a year after it was followed by the Android version. Both old versions of the Komoot app have nothing in common with the current products of the startup.

komoot for iOS and Android
Komoot for iOS (left) and Android. (View large version)

The iOS and Android apps compile through guidelines and best practices for designing apps for their respective platforms. The apps contain a lot of travel content including topographic maps, turn-by-turn navigation, recommendations on cool places, and much more. All this functionality has to be easily accessible for a user.

We decided to stick to each platform’s rules since native user interface is more predictable and is therefore easier for a user. More than that, Apple and Google give preference to the apps that follow their requirements for UI design. This can be really important for promotion on Apple’s App Store and Google Play.

—Dmytro Prudnikov, UI and UX designer at Komoot

Komoot has been repeatedly featured in Apple’s App Store. It was named one of Google Play’s Best Apps of 2014, and is currently one of the top apps in Google Play in Germany.

Now we’re through with these exemplary apps, let’s discuss when sticking to a platform’s rules can be the most reasonable method.

WHEN SHOULD I FOLLOW THE PLATFORM-ORIENTED APPROACH? LINK

A highly competitive market environment prompts you to make a fast launch and rapidly grow a user baseLink

Even though you need to spend time redesigning an app’s concept entirely, a platform-oriented approach allows your software engineers to implement your idea much quicker. Once an app has been launched, users who download it will find interaction patterns familiar. More than that, you don’t need to wait for inspiration to design something special. All you should do is follow the guidelines.

A super-smart branding move on Google’s part leaves us with a single choice: if you port an app from iOS to Android, it’s almost a must to profess material design as your religion. But this hot trend has also been attracting glances from iPhone users. As a result, we can see some iOS apps featuring material design style UI. I only mention this to emphasize the importance for an app to align with design trends, even if that means occasionally disregarding a platform’s specifics. By the way, here is a great piece from InVision on how to avoid looking like Google but still take its material design principles into account.

Your app has complex functionality and user interfaceLink

Any mobile app has to be as simple to use as possible, even if it has a load of functions. Following a platform-oriented approach makes a lot of sense for apps with rich functionality and a lot of content. To illustrate, Accent Kit, an app we developed for the UK’s leading accent and dialect coaches, contains a wide variety of features, from audio playback to recording to text and images all aimed at helping actors learn accents. When Yalantis had to port the app to Android, we didn’t consider any other method, but the one that’s oriented to the platform. Otherwise, users would’ve had a hard time trying to figure out all the useful features the app provides.

The Accent Kit app for Android and iOS
The Accent Kit app for Android (left) and iOS. (View large version)

Sticking to platform conventions and providing users with experiences native to their platforms allows us to meet their expectations.

Where some apps succeed, others may not. A platform-oriented approach isn’t always so awesome for companies that want to retain the strength of their own brand. After all, it’s the brand that makes you a living, so try not to make your app just another “teacher’s pet” who follows all the rules but doesn’t receive much love from its classmates.

The Mixed Approach Link

With a little ingenuity we can achieve sufficient correspondence to platform specifics while remaining true to a brand’s values. This mixed approach to multiplatform design adaptation is a balanced combination of the two approaches mentioned above, and it’s also the most complicated one.

In this case, you need to take into account two types of users: those familiar with your product, and those who have never used it before. The former adhere to a brand, while the latter are accustomed to the particularities of their platform. Designers who choose the mixed method are diplomats whose job is to represent the interests of the brand, as well as promote friendly relations with users. They need to figure out what UI elements make a product stand out, and also find platform-specific solutions which won’t hurt the brand.

Let’s see how SoundCloud, Facebook, Airbnb and Viber have handled this challenge.

SOUNDCLOUD LINK

A well-known audio streaming app, SoundCloud came out on both markets at the same time. Even though SoundCloud’s designers adopted the design for each platform specifically, they made a significant effort to maintain the brand’s integrity.

On mobile, we aim to strike a good balance between users’ familiarity with their iOS and Android devices, and the patterns that are specific to our product and reflect our brand. For example, skipping along a track on our signature waveform player (which we call scrubbing) operates differently to any other comparable services.

—Sylvain Grande, VP product, creators & monetization at SoundCloud

Among the platform-specific features, there is iOS’s standard tab bar at the bottom of the screen (with some design modifications), and a search bar at the top. The Android version has a typical tool bar at the top of the screen, a hamburger menu on the left, and a search icon which expands the search bar. Both the iOS and Android versions of the app use platform-specific interactions.

SoundCloud for iOS and Android
SoundCloud for iOS (left) and Android. (View large version)
SoundCloud
SoundCloud play screens on iOS (left) and Android. (View large version)

FACEBOOK LINK

Facebook’s mobile incarnation started with HTML5, but it was a big mistake, as the company’s founder Mark Zuckerberg admitted. Eventually, Facebook decided to work on improving the native mobile experience on iOS, Android and other platforms.

On the one hand, Facebook’s brand has a huge impact. On the other, it’s a multiplatform network with an enormous number of users. That’s why the mixed approach which harmoniously combines brand identity and platform was the most appropriate for its situation.

The iOS and Android versions of Facebook’s app look similar, but also feel quite native to users of both platforms. Facebook follows Apple and Google design guidelines for the sake of their users. Since content is the key feature of the Facebook app, its creators chose a minimalistic design style to leave more room for the app’s content.

Facebook for iOS and Android
Facebook for iOS (left) and Android. (View large version)

The iOS version uses a typical iOS navigation bar at the bottom of the screen and a standard search bar. In the Android version switching between sections is done with the help of a tab bar, which is located at the top just like the majority of Android apps.

AIRBNB LINK

One of the fastest growing startups, Airbnb managed to gain a strong position on the market, largely because of its simplicity and fantastic customer experience.

Airbnb’s designers chose the mixed approach when transporting their service to mobile. The brand itself is unique and attracts the attention of people all over the world. However, it’s the content that makes this app work. Therefore, Airbnb’s creators made their product convenient for the users of both platforms.

We want our apps to feel familiar for all our users, which means taking on conventions they are accustomed to. But we also want to make sure they experience one Airbnb.

Coherence between platforms — mobile, web, email, etc. — is important to the confidence and trust we build, and therefore our decisions can’t solely be driven by the norms of various platforms. The thread of continuity unifying the experience is brand.

—Katie Dill, head of experience design at Airbnb

At first sight, the main difference between Airbnb’s iOS and Android apps is the location of the navigation bar: bottom in the iOS version and top in the Android.

Airbnb for iOS and Android
Airbnb for iOS (left) and Android. (View large version)

If not for this small but crucial particularity, I would’ve considered Airbnb among the apps which use the brand-oriented design approach. However, if we look closer, the difference between the iOS and Android apps becomes more apparent.

Airbnb search screens
Airbnb search screens on iOS (left) and Android. (View large version)

Given the simplicity of Airbnb’s functionality, a fuller correlation with the platform specifics would have complicated the app.

Airbnb 2
Airbnb navigation on iOS (left) and Android. (View large version)

VIBER LINK

We almost forgot one more incredibly popular messaging app! I believe Viber is the best representative of the mixed design approach.

Unlike WhatsApp and Telegram, Viber’s designers perfectly complied with the brand identity while following platform requirements to the app’s UI. The mixed approach allowed them to make the app both recognizable on any platform, and convenient for any user. In other words, users won’t mix up Viber with any other messenger, neither they will have any difficulty trying to figure out how to perform a given action.

Viber for iOS and Android
Viber for iOS (left) and Android. (View large version)

Compliance with the brand identity is achieved by using custom colors and icons identical on both platforms. To make the iOS and Android apps easy to use, the navigation between the apps’ screens is platform-specific.

Viber
Viber contacts lists in iOS (left) and Android. (View large version)

Despite strong adherence to the brand, Viber perfectly meets user expectations in the interface and interactions, and pays a lot of attention to the functionality.

WHEN SHOULD I FOLLOW THE MIXED APPROACH? LINK

When you’re incrementally developing and refining your product’s design based on feedback and evaluationLink

The mixed approach implies continuous work on user experience which is one basis of iterative design methodology. This means you should analyze metrics to understand how a user is interacting with your product, roll out regular updates and improvements, analyze the metrics again, and maintain growth rates. Iterative design represents a form of research carried out within a cyclic process of prototyping, testing, analyzing and refining each successive version of a product.

The mixed approach is a singular case where you let the experience speak for the brand. I believe it’s the best path to the ideal multiplatform adaptation. It allows you to stay true to the platform, brand and user. Besides, using this approach lets a designer alter the balance either in favor of the brand or the platform guidelines, and as a result deliver a great product.

The only disadvantage of the mixed method is that it’s close to impossible for small startup companies that can’t afford investing that much time and money into enhancing their app’s design. Moreover, making the right guess in the first version of an app without testing UI features on users is a matter of luck, I’d say.

Which Approach Wins? Link

Even though the mixed method seems to be the way to go, I’d say none of the approaches mentioned in this article is perfect.

Sometimes choosing brand identity over the platform standards leads to specific user experience problems, no matter how beautiful your app is. After all, users decide how a menu should slide in, where to swipe to access a certain function, and how to go back to the profile page.

The apps that use platform-oriented approaches risk acquiring a look that’s too standardized and doesn’t work well for the brand. But on the other hand, you’re most likely to succeed using the platform-oriented approach, especially if your app is full of features, and targets a large user audience.

The apps I used to illustrate the mixed approach are great examples of successful multiplatform adaptation. Such cases are pretty rare. However, it doesn’t mean you shouldn’t try to achieve the same results.

When we design apps, we should always remember that we do it for real people to use on real devices in the real world. In fact, it’s not a brand, or a platform, or even your creativity that’s important. The only thing that matters is users. They don’t care about approaches you applied in your multiplatform UI design adaptation. Whether we like it or not, all that users are interested in is their overall experience with a company — and when it’s positive, a company succeeds.

We’d love to hear your opinion about UI multiplatform design adaptation and which approach you think is the best. If there are any other apps that you feel are good examples in each of these three approaches, please share them in the comments.

Hey Designers: Stop Being An Afterthought

There are reasons you’re still saying the same thing after all these years — still talking about how it always seems likedesign gets tacked on to the end of the process. You should be at the concept meeting, you say, where you can make a real difference.

I’ve been hearing it for 15 years. I once had a job where I got to say it myself a few times. I got tired of that pretty quickly. I don’t say it anymore. You shouldn’t either.

Primarily because it’s not true.

There is no such thing as a project that goes off well without some level of planning. You’re just not the one doing it. You can keep wondering why, keep complaining, or you can change it. The front of the bus is a crowded place, but that doesn’t mean the people there are smarter than you. You’re a designer, which means you’re capable of imagining a better version of the world than the one you’re living in. And yet there you are, stuck at the back.

Here are some of the reasons it happens. And how to stop being an afterthought.

Semantics Link

Possible cause number one: Design.

You use this word practically every day. You might not know how much trouble it’s causing.

In the web industry, it means a lot of things. There’s visual design. There’s web design — whatever that means these days. There’s the end result — “the design.” Then there’s the version of design where you plan things out before building them.

That last one’s key. Because “design” actually means “to plan.” And because another word for “plan” is “strategy.” And because no one but a designer thinks of strategy as being equal to design. They are not the same thing. Your boss does not think of them that way. You’re “the designer,” not a strategist.

And that’s your problem. Semantics.

There are several definitions of design, and the people around you all think you do the other one.

Design is strategic by nature. You can’t prescribe an experience, you can only influence it. A designer’s job is to determine in whatever ways possible what kind of experience a user should have, how a design might achieve that and what outcomes would be best for everyone involved. You research, you consider, you devise a plan and then you act on it. Design is a planning exercise. It’s all strategy. There is no design without intention.

Until you connect “design” to “strategy,” you will never move from one to the other. Until the people running the project see that design is strategy, your name will continue to be the last one called.

Designers need to educate in order to stop being an afterthought
Designers need to educate in order to stop being an afterthought. (Image: Markus Spiske)

WHAT TO DO LINK

Two things. First, educate.

In every meeting, find an excuse to talk about planning rather than design. Mention how much you love planning. Because to design is to plan, and that’s the best part of your job. The part that has the most effect.

Secondly, start using the word “strategy” in your conversations.

Human beings are susceptible to a lot of persuasive tricks. One of them is repetition. Say something over and over again (according to a strategy) and people will often start to believe it, whether it has any merit or not. It’s how presidents get elected. It’s how wars are started. It’s how an entire company can be convinced, rightly so, that design matters.

Manipulative? Heck yeah, it’s manipulative. Manipulation is a good thing. It’s a necessary tool. Call it “persuasion” or “influence” if it makes you more comfortable. Just wrap your brain around it. Treat it well and it will serve you well.

Just note that repetition also reinforces your own beliefs. The more you say something, the harder it is to change your own mind about it later. Be careful about what you repeat. You can give gravity to your own bad habits and ideas.

The Deception Of Lousy Work Link

Possible cause number two.

The people at the helm of your projects are executives, outside stakeholders, project managers. They are people whose job it is to think about quarterly revenue, user-base statistics, numbers — lots and lots of numbers. They’re not designers.

Sometimes, they’re bad at strategy and it shows. Other times, they’re great at strategy, but you can’t tell because all you see is the tiny sliver of the big picture they show you.

Sometimes, they’re terrible at design. They look at what competitors are doing and copy it. They look at user complaints and prescribe Band-Aids no matter the cause of the wound. They invent solutions to non-problems so that they can stand out from the crowd. Whatever the case, they’re working according to their own world view and not yours. Then they tell you about it.

To you, no matter what’s been done or how well, it looks like design is being tacked on at the end of the process, because when strategy is done badly or is badly communicated, it looks like it hasn’t been done at all. You wonder, why this solution? Why this feature? Why this way? You want to sort out something better. Instead, you’re left to push pixels.

WHAT TO DO LINK

See the previous answer. Turn yourself into a strategist.

Ask why — all the time. When they bring you a bad idea, a non-idea, an old idea, ask questions. Why this? What problem? Is this the best way to achieve the result you’re after?

Ask enough and you’ll often find that no one knows the answers. There’s your chance. Help them see the vapor behind the mandates. Suggest a new way. Plug insight into a process where only opinion existed before.

Don’t be pushy. If you’ve never done strategy work, you might be terrible at it for a while. Learn, then assist, then do. Go slowly. You and everyone else and your products will get better.

And, of course, remember that sometimes people are doing good strategic work. It just isn’t what you would have done. (Respecting other opinions lets people like you more the next time around.)

Self-Awareness Link

You won’t like this one: You’re just not there yet, and you’re the only one who doesn’t know it.

The reason you’re not involved in strategy is that somebody is already doing it and you weren’t invited. You haven’t proven yourself to be a strategic thinker, and you’ve failed to realize it. You complain and demand and expect, but you don’t offer value. You’re fresh out of school and ready to change the world, but you don’t know how much you don’t know. Or you’re a veteran designer but still haven’t figured out that complaints are useless and annoying, that insight matters, that insight gets you places, or even what “insight” means.

WHAT TO DO LINK

Take a good hard look at your skills, your actions, your words. Look at what people say about you. Has anyone ever suggested you’re more useful than you think you are? Or are you the only one who thinks that?

If planning is not part of your job, then you are not a designer. You may be called a designer. By definition, you’re not. You’re contributing in some way. You must be. But not the way people need. Not the way you want.

To become a designer, start planning. Start researching. Define goals and success metrics. Map your ideas to them. Ask for feedback on them. Then put them to work. Track them. Iterate.

If your “design” work has no definable objectives, it’s not design. It’s decoration. You’re doing the wrong work. Change that and you’ll change the way people see you. To be seen as a strategist, be a strategist.

There’s another possibility: You’re actually great, but no one knows you want to do this stuff.

So, tell them. Sometimes it’s just that simple.

Strategy Hogs Link

Possible cause number 75.

Type A personalities. You know the ones. Control freaks. In charge, in everyone’s way, un-provably right about everything, suffering from self-induced anxiety because they can’t let anything go, living under the belief that they’re better than you.

Control freaks are strategy hogs
Control freaks are strategy hogs. (Image: Faramarz Hashemi)

They won’t let you do the work. You never even get close to it until they’re too buried in something else, and that never happens because strategy is their favorite part.

Despite your qualifications and interest, other people want to do it themselves and refuse to invite you into the process so that you can improve your skills and grow as a designer.

WHAT TO DO LINK

I’ve answered this one before. Read the section titled “Let Them Improve.”

Good UX leaders give you chances to grow. If you’re not getting them, get out. Your career is more important than your job. Your work is more important than their product.

Stop letting bad managers be bad. Force them to change by losing their staff.

That’s all I’m going to say about that.

The Cost Of Design, Good And Bad Link

Last one I could think of. And it’s common.

Startups, companies with revenue shortfalls, small businesses, guys with a basement and a dream — they all have a good reason for not letting design in on the action earlier. So they think.

They’re broke. They can’t afford design.

The reason you’re not involved in strategy is because afterthought design is all they can afford. They do their best, make their best guesses, do as much as they can with as little as they have. Then they call you to hedge their bets. To get a second set of eyes. To hopefully clean up a little before the thing goes live. You get a week. Two days. Three hours. Just do a quick evaluation and let us know what you think.

Design always has a cost
Design always has a cost. (Image: Steven Depolo)

WHAT TO DO LINK

Sometimes this is all you can do. They really don’t have a budget. They really don’t have time. They really are going live next Tuesday.

Do what you can.

If there is time, if it is early, if there is a budget, here’s your argument.

Bad design costs a lot more than good design. There’s research, I’ll send you some of it. Let me be involved earlier in the process so that I can at least make some good guesses up front so that you don’t get tripped up by giant UX problems after launch. It costs more to rebuild than to build.

There’s evidence in the company where you work. They’ve done it. They’ve failed at something and rebuilt it. They’ve learned hard lessons they should’ve known before. They’ve been hijacked by big problems you could’ve helped to prevent.

There’s evidence in other companies. Look at the ones that have failed. Look at why. Look at the companies that stole customers through better design — enough customers to pay for the problems you aren’t solving now, enough for new development rather than repeat development.

Design is an investment. They can either make it now or later. It costs less now.

There’s your argument.

Be patient. Persist. Evaluate your skills and actions and words. Do the work.

Stop being an afterthought. Start being the right kind of designer.

 

Principles Of HTML5 Game Design

Visual effects in games define their overall look and feel, and gameplay. Players are attracted to high visual quality, which generate more traffic and reach. It’s key for creating successful games and providing a lot of fun for players.

In this article I want to present a few ideas of how to implement different visual effects in <canvas>-based HTML5 games. These examples will be based on effects we made in our game, Skytte. I will explain the basic ideas supporting them and provide the effects used in our work.

What You Will Learn Link

Before we get going, I want to set out the things I hope you’ll learn from this article:

  • Basic game design
    We’ll look at patterns that are commonly used to make games and game effects like: game loops, sprites, collisions, and particle systems.
  • Basic implementation of visual effects
    We will also explore the theory and some code examples supporting these patterns.

Common Patterns Link

Let’s start with some common patterns and elements used in game development.

SPRITES LINK

These are simply 2-D images that represent an object in the game. Sprites can be used for static objects, but also animated objects, when each sprite represents a frame of sequential animation. They can also be used for making user interface elements.

Usually games contain between dozens and hundreds of sprites. To reduce memory usage and the processing power needed to handle these images, many games use sprite sheets.

SPRITE SHEETS LINK

These are used to group a set of single sprites in one image. This reduces the amount of files in the game, resulting in reduced memory and processing power usage. Sprite sheets contain many single sprites stacked next to each other in rows and columns, and like the sprites they contain can be used statically or for animation.

Spritesheet example
Sprite sheet example. (Image credit: Kriplozoik)

Here’s an article from Code + Web to help you better understand the benefits of using sprite sheets.

GAME LOOPS LINK

It’s important to realize that game objects don’t really move on screen. An illusion of movement is achieved by rendering a snapshot of a game world to the screen, advancing the game time a small amount (usually 1/60th of a second), and then rendering things again. This is literally a stop-motion effect and is used in both 2-D and 3-D games. A game loop is a mechanism that implements this stop-motion. It’s the main component needed to run a game. It runs continuously over time, performing various tasks. On each iteration it processes user input, moves entities, checks for collisions, and renders the game (preferably in this order). It also controls game time that’s elapsed between frames.

Below is a very basic game loop in JavaScript:

var lastUpdate;

function tick() {
  var now = window.Date.now();

  if (lastUpdate) {
    var elapsed = (now-lastUpdate) / 1000;
    lastUpdate = now;

    // Update all game objects here.
    update(elapsed);
    // ...and render them somehow.
    render();
  } else {
    // Skip first frame, so elapsed is not 0.
    lastUpdate = now;
  }

  // This makes the `tick` function run 60 frames per second (or slower, depends on monitor's refresh rate).
  window.requestAnimationFrame(tick);
};

Note that the above example is very simplistic. It uses variable delta time (the elapsed variable) and it’s recommended to upgrade this code to use fixed delta time. See this article for more details.

COLLISION DETECTION LINK

Collision detection refers to finding the intersections between objects. This is essential for many games because it’s used to detect if a player hits a wall or a bullet hits an enemy, and so on. When a collision is detected it can be used for game logic; for example, when a bullet hits the player, the health score is reduced by 10 points.

There are a lot of collision detection algorithms, and because it’s a performance-heavy operation, it’s important to choose the best method wisely. To read more about collision detection, algorithms and how they can be implemented, here’s an article from MDN.

PARTICLES AND PARTICLE SYSTEMS LINK

Particles are basically sprites used by a particle system. In game development, a particle system is a component that consists of a particle emitter and particles assigned to that emitter. It’s used to simulate various effects, like fire, explosions, smoke, and rain effects. Particles are emitted over time and each emitter has its own parameters to define various variables used for the simulated effect, such as velocity, color, a particle’s lifetime or duration, gravity, friction, and wind speed.

EULER INTEGRATION LINK

Euler integration is a method for numerically integrating the equations of motion. Each object’s position is calculated based on its velocity, mass and force, and needs to be recalculated for each tick in the game loop. The Euler method is the most basic and useful for games like side-scrolling shooters, but there are also other methods like Verlet integration and RK4 integration which are better for other tasks. Below I’ll show a simple implementation of the idea.

You need a basic structure to hold an object’s position, velocity and other movement-related data. We propose two identical structures, but each with different meaning in the world’s space: point and vector. Usually game engines use some kind of vector class, but the distinction between points and vectors is very important and greatly improves code readability (for example, you calculate distance not between two vectors, but two points, which is more natural).

PointLink

Simply, it represents an element in two-dimmensional space with x and y coordinates which define where the point is located in that space.

function point2(x, y) {
  return {'x': x || 0, 'y': y || 0};
}
VectorLink

A vector is a geometric object that has length (or magnitude) and direction. In 2-D games vectors are used mostly to describe forces (e.g. gravity, air resistance and wind) and velocities, as well as proscribing movements or how light reflects off an object. Vectors have many uses.

function vector2(x, y) {
  return {'x': x || 0, 'y': y || 0};
}

The above functions create new two-dimensional vectors and points. Internally we don’t use the new operator in this case in JavaScript to gain a lot of performance. Also note that there are some third-party libraries available that you could use to manipulate vectors (glMatrix is a good candidate for this).

What follows are some very common functions used on the two-dimensional structures defined above. First, calculating the distance between two points:

point2.distance = function(a, b) {
  // The x and y variables hold a vector pointing from point b to point a.
  var x = a.x - b.x;
  var y = a.y - b.y;
  // Now, distance between the points is just length (magnitude) of this vector, calculated like this:
  return Math.sqrt(x*x + y*y);
};

The magnitude (length) of a vector can be calculated directly from the last line of the above function like this:

vector2.length = function(vector) {
  return Math.sqrt(vector.x*vector.x + vector.y*vector.y);
};
Vector length
Vector length. (View large version)

Normalization of vectors is also very handy. The function below resizes a vector so it becomes a unit vector; that is, its length is 1, but its direction is maintained.

vector2.normalize = function(vector) {
  var length = vector2.length(vector);

  if (length > 0) {
    return vector2(vector.x / length, vector.y / length);
  } else {
    // zero-length vectors cannot be normalized, as they do not have direction.
    return vector2();
  }
};
Vector normalization
Vector normalization. (View large version)

Another useful case is to have a unit vector whose direction is pointing from one location to another:

// Note that this function is different from `vector2.direction`.
// Please don't confuse them.
point2.direction = function(from, to) {
  var x = to.x - from.x;
  var y = to.y - from.y;
  var length = Math.sqrt(x*x + y*y);

  if (length > 0) {
    return vector2(x / length, y / length);
  } else {
    // `from` and `to` are identical
    return vector2();
  }
};

The dot product is an operation on two vectors (usually unit vectors), which returns a scalar number representing the relation between angles of those vectors.

vector2.dot = function(a, b) {
  return a.x*b.x + a.y*b.y;
};
Vector dot product
Vector dot product.

The dot product is a length of a vector a projected on a vector b. A returned value of 1 means that both vectors point in the same direction. A value of -1 means that vector a points in the opposite direction of vector b. A value of 0 means that vector a is perpendicular to vector b.

Here’s an example of an entity class, so other objects can inherit from it. Only basic properties related to movement are described.

function Entity() {
  ...
  // Center of mass usually.
  this.position = point2();
  // Linear velocity.
  // There is also something like angular velocity, not described here.
  this.velocity = vector2();
  // Acceleration could also be named `force`, like in the Box2D engine.
  this.acceleration = vector2();
  this.mass = 1;
  ...
}

You can use pixels or meters as the unit in your game. We encourage you to use meters, as it’s easier to balance things out during development. Velocity, then, should be meters per second, and acceleration should be meters per second squared.

When using a third-party physics engine, you just store a reference to a physical body (or set of bodies) in your entity class. Then, the physics engine stores the mentioned properties, like position and velocity, inside each body for you.

Basic Euler integration looks like this:

acceleration = force / mass
velocity += acceleration
position += velocity

The code above must be executed in each frame for each object in the game. Here is a basic implementation of the above in JavaScript:

Entity.prototype.update = function(elapsed) {
  // Acceleration is usually 0 and is set from the outside.
  // Velocity is an amount of movement (meters or pixels) per second.
  this.velocity.x += this.acceleration.x * elapsed;
  this.velocity.y += this.acceleration.y * elapsed;

  this.position.x += this.velocity.x * elapsed;
  this.position.y += this.velocity.y * elapsed;

  ...

  this.acceleration.x = this.acceleration.y = 0;
}

elapsed is the amount of time in seconds that has passed since the last frame (since the last call to this method). For games running at 60 frames per second, the elapsed value is usually 1/60 of a second, which is 0.016(6)s.

The article on delta time mentioned earlier also covers this problem.

To move objects, you can change their acceleration or velocity. Two functions shown below should be used for this purpose:

Entity.prototype.applyForce = function(force, scale) {
  if (typeof scale === 'undefined') {
    scale = 1;
  }
  this.acceleration.x += force.x * scale / this.mass;
  this.acceleration.y += force.y * scale / this.mass;
};

Entity.prototype.applyImpulse = function(impulse, scale) {
  if (typeof scale === 'undefined') {
    scale = 1;
  }
  this.velocity.x += impulse.x * scale / this.mass;
  this.velocity.y += impulse.y * scale / this.mass;
};

To move an object to the right you could do this:

// 10 meters per second in the right direction (x=10, y=0).
var right = vector2(10, 0);

if (keys.left.isDown)
  // The -1 inverts a vector, i.e. the vector will point in the opposite direction,
  // but maintain magnitude (length).
  spaceShip.applyImpulse(right, -1);
if (keys.right.isDown)
  spaceShip.applyImpulse(right, 1);

Note that objects set in motion stay in motion. You need to implement some kind of deceleration to stop a moving object (air drag or friction, maybe).

Weapon Effects Link

Now I’ll explain how certain weapon effects are made in our HTML5 game, Skytte.

PLASMA LINK

Plasma weapon in Skytte.

This is the most basic weapon in our game, just one shot each time. There are no special algorithms used for this weapon. When a plasma bullet is fired the game simply draws a single sprite that’s rotated over time.

A simple plasma bullet can be spawned like this:

// PlasmaProjectile inherits from Entity class
var plasma = new PlasmaProjectile();

// Move right (assuming that X axis is pointing right).
var direction = vector2(1, 0);

// 20 meters per second.
plasma.applyImpulse(direction, 20);

BLASTER LINK

Blaster weapon in Skytte.

This weapon is a little more complex. It also draws simple sprites as bullets but there’s some code that spreads them out a little and applies a random speed. This gives a more devastating feeling to this weapon, so players feel they can inflict more damage than with the plasma weapon and have better crowd control when among enemies.

The code works similarly to the plasma weapon code, but it spawns three bullets and each has a slightly different direction.

// BlaserProjectile inherits from Entity class
var topBullet = new BlasterProjectile();  // This bullet will move slightly up.
var middleBullet = new BlasterProjectile();  // This bullet will move horizontally.
var bottomBullet = new BlasterProjectile();  // This bullet will move slightly down.
var direction;

// Angle 0 is pointing directly to the right.
// We start with the bullet moving slightly upwards.
direction = vector2.direction(radians(-5));  // Convert angle to an unit vector
topBullet.applyImpulse(direction, 30);

direction = vector2.direction(radians(0));
middleBullet.applyImpulse(direction, 30);

direction = vector2.direction(radians(5));
middleBullet.applyImpulse(direction, 30);

Some math functions are needed for the above code to work:

function radians(angle) {
  return angle * Math.PI / 180;
}

// Note that this function is different from `point2.direction`.
// Please don't confuse them.
vector2.direction = function(angle) {
  /*
   * Converts an angle in radians to a unit vector. Angle of 0 gives vector x=1, y=0.
   */
  var x = Math.cos(angle);
  var y = Math.sin(angle);
  return vector2(x, y);
};

RAY LINK

Ray weapon in Skytte.

This one’s interesting. The weapon shoots a laser ray but it’s procedurally generated in each frame (this will be explained later). To detect hits, it creates a rectangular collider that deals damage every second for as long as it collides with the enemy.

ROCKETS LINK

Fig. 8: Rockets weapon in Skytte.

This weapon shoots guided missiles. The rocket is a sprite with a particle emitter attached to its end. There’s also some more sophisticated logic, like searching for the nearest enemy or limiting the turn value for a rocket to give it less maneuverability. Also, rockets don’t start to seek for enemy targets immediately – they fly straight for a time to avoid unrealistic behavior.

Rockets in Skytte move toward their nearest neighbor. This is achieved by calculating the proper force needed for the projectile to move in any given direction. To avoid moving only in straight lines the force calculated shouldn’t be too big.

Assuming that Rocket is a class inheriting from the Entity class described earlier.

Rocket.prototype.update = function(elapsed) {
  var direction;

  if (this.target) {
    // Assuming that `this.target` points to the nearest enemy ship.
    direction = point2.direction(this.position, this.target.position);
  } else {
    // No target, so fly ahead.
    // This will fail for objects that are still, so remember to apply some initial velocity when spawning rockets.
    direction = vector2.normalize(this.velocity);
  }

  // You can use any number here, depends on the speed of the rocket, target and units used.
  this.applyForce(direction, 10);

  // Simple inheritance here, calling parent's `update()`, so rocket actually moves.
  Entity.prototype.update.apply(this, arguments);
};

FLAK LINK

Flak weapon in Skytte.

Flak was designed to shoot many small bullets (something like a shotgun), which are little dot sprites. It has some specific logic to randomly generate the position of these dots within a cone-shaped area.

Flak weapon bullets cone area
Flak weapon bullets cone area.

To generate random points in a cone-shaped area:

// Firstly get random angle in degrees in the allowed span. Note that the span below always points to the right.
var angle = radians(random.uniform(-40, 40));

// Now get how far from the barrel the projectile should spawn.
var distance = random.uniform(5, 150);

// Join angle and distance to create an offset from the gun's barrel.
var direction = vector2.direction(angle);
var offset = vector2(direction.x * distance, direction.y * distance);

// Now calculate absolute position in the game world (you need a position of the barrel for this purpose):
var position = point2.move(barrel, offset);

The random.uniform() function returns a random floating point number between two values. A simple implementation could look like this:

random.uniform = function(min, max) {
  return min + (max-min) * Math.random();
};

ELECTRO LINK

Electro weapon in Skytte.

Electro is fancy weapon that shoots lightning at enemies within a particular radius. It has a limited range but can shoot at several enemies at once and always hits successfully. It uses the same algorithm to draw curved lines to simulate lightning as the ray weapon but with a higher curve factor.

Techniques Used Link

PROCEDURAL CURVED LINE LINK

To create the laser beam effect and electro weapon we’ve developed an algorithm to count and transform the linear distance between the player’s ship and the enemy. In other words, we measured the distance between two objects, found the middle point and moved it randomly alongside the section. We repeat this action for every new section created.

To draw these sections we use HTML5 <canvas> draw function lineTo(). To achieve the glowing color we used multiple lines drawn over one another with more opaque color and a higher stroke width.

Procedural curved line
Procedural curved line. (View large version)

To find and offset a point between two other points:

var offset, midpoint;

midpoint = point2.midpoint(A, B);

// Calculate an unit-length vector pointing from A to B.
offset = point2.direction(A, B);

// Rotate this vector 90 degrees clockwise.
offset = vector2.perpendicular(offset);

// We want our offset to work in two directions perpendicular to the segment AB: up and down.
if (random.sign() === -1) {
  // Rotate offset by 180 degrees.
  offset.x = -offset.x;
  offset.y = -offset.y;
}

// Move the midpoint by an offset.
var offsetLength = Math.random() * 10;  // Offset by 10 pixels for example.
midpoint.x += offset.x * offsetLength;
midpoint.y += offset.y * offsetLength;

Below are functions used in the above code:
point2.midpoint = function(a, b) {
  var x = (a.x+b.x) / 2;
  var y = (a.y+b.y) / 2;
  return point2(x, y);
};

vector2.perpendicular = function(v) {
  /*
   * Rotates a vector by 90 degrees clockwise.
   */
  return vector2(-v.y, v.x);
};

random.sign = function() {
  return Math.random() < 0.5 ? -1 : 1;
};

FINDING NEAREST NEIGHBOR LINK

To find the nearest enemy for a rocket and the electro weapon, we iterate over an array of active enemies and compare their positions with the position of a rocket, or the shooting point in the case of the electro weapon. When a rocket locks on its target, it flies toward it until it hits or flies off the screen. For the electro weapon, it waits for a target to be in range.

A basic implementation may look like this:

function nearest(position, entities) {
  /*
   * Given position and an array of entites, this function finds which entity is closest
   * to `position` and distance.
   */
  var distance, nearest = null, nearestDistance = Infinity;

  for (var i = 0; i < entities.length; i++) {
    // Allow list of entities to contain the compared entity and ignore it silently.
    if (position !== entities[i].position) {
      // Calculate distance between two points, usually centers of mass of each entity.
      distance = point2.distance(position, entities[i].position);

      if (distance < nearestDistance) {
        nearestDistance = distance;
        nearest = entities[i];
      }
    }
  }

  // Return the closest entity and distance to it, as it may come handy in some situations.
  return {'entity': nearest, 'distance': nearestDistance};
}

Conclusion Link

These topics cover only the basic ideas that support them. I hope after reading the article you now have a better idea of how to start developing such things. Check out the resources below and try doing something similar yourself.

RESOURCES LINK