# Deeplinks in Text Express

## Analysis:

> Literature study, Available product analysis, Requirements prioritization, Literature study, Interview, Domain modeling, Task analysis

### Current situation

Text Express doesn't have a system which the players or developers to use to advertise the game and invite their friends in the game. Tjien- the designer of the game, believes that such a feature is necessary and could be achieved by adding deep links functionality to the game. The following assignment was given to me with the view that if it is implemented, it will increase the organic growth of the game:

### Graduation assignment

There were 3 requirements for this deep linking system, which the game designer of Text Express gave me:

![Initial requirements for deeplinking system](/files/-M_ywtld2RoHSxAkCTV8)

After a discussion with the designer, I have summed up the requirements:&#x20;

* [x] Develop a friend referral system using the deep links.
* [x] Develop a navigational link, which when opened, the player is sent to a specific section within the game- Shop, Certain level, etc.
* [x] Develop a rewarding link, which when opened, the player is granted an in-game currency reward.

### Clarifications

#### *How will those links work?*

After internet research, it was found out that those deep links will be generated from a 3rd party service, which will have to support Unity integration.

#### *What 3rd party services are other games from Gamehouse using for such a system?*

I wanted to collect information from other game studios in Gamehouse about what service are they using for handling deep links in their game and why. Only 2 studios were using deeplinks and I contacted them: One studio was contacted via chat and the other via video call.

![One of the studios asked about what deep links service are they using](/files/-M_w-VjrBJRw8XqG1aq-)

In the end, from the information gathered, it was found out that both studios were using One Link from AppsFlyer for handling deep links.

#### *What service to use for deep linking?*

Although all studios I have asked were using OneLink from AppsFlyer, I wanted to see why and what other alternative there are ([GetSocial](https://blog.getsocial.im/deeplink-battle-branch-firebase-getsocial/), [Unity deep links](https://docs.unity3d.com/Manual/enabling-deep-linking.html), [AppsFlyer- OneLink](https://support.appsflyer.com/hc/en-us/articles/115005248543-OneLink-overview)) and make a comparison:

![Pros and Cons of the researched deep linking services](/files/-M_yj6kseA16fuaTS9kT)

After information gathering, assessing and a discussion with my technical manager, I chose to use [AppsFlyer-OneLink](https://support.appsflyer.com/hc/en-us/articles/115005248543-OneLink-overview), for handling deep linking in Text Express, because Text Express is also already using AppsFlyer and it would be **cheaper, easier** and **faster** to implement it.

#### *How to implement OneLink?*

In order to implement OneLink fast and successfully, I have researched what has to be done and have created a plan to follow:

* [x] Implement the needed Deep link functionality for the Unity SDK- [**guide**](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/master/docs/Guides.md#deeplinking)&#x20;
* [x] Create a simple link template to navigate the users who don't have the game to the app store- [**guide**](https://support.appsflyer.com/hc/en-us/articles/207032246)
* [x] Start the game from a link, if the players have the game installed on their device- [**guide**](https://support.appsflyer.com/hc/en-us/articles/208874366)
* [x] Read the custom data you had set in the link template and program the game to read and react on it- [**guide**](https://support.appsflyer.com/hc/en-us/articles/207033836)
* [x] Know when a user installs the game for the first time- [**guide**](https://support.appsflyer.com/hc/en-us/articles/207032096)

![Plan on setting up deep links](/files/-ManQeYb5TXbpaLg5zME)

#### ***How will the navigation via deep link system work?***

When the latter steps are implemented successfully, the navigation to a specific section in the game will come after reading the custom JSON data and handling that data to send the user to the specific section in the game:

![](/files/-Mbp5PTCyi_O5dchTLjA)

#### ***How will the friend invite system work?***

After discussion with the game designer- Tjien, I managed to extract the requirements and the flow which is wanted from the **friend invite system** and created a user flow diagram which served as a plan for what I have to do:

![User flow and plan on how the friend invite system will work](/files/-MbpPAhZhRWieDfXMRGW)

## Design:

> Brainstorming, Literature study, SWOT analysis

### Navigation System

No particular design was needed for the navigation system, as it was pretty straight forward system to implement, if you have the OneLink system up and runnning.

### Friend Invite System

#### Deeplink template design

From the plan I have created in the [Analysis phase](/social-and-community-features-in-text-express/features/deeplinking.md#how-will-the-friend-invite-system-work) it was determined the following: When a friend installs and opens the game via "**friend invite" deep link**, a reward to the player who sends the invite link is sent.<img src="/files/-MbpPOH4jtyaz8vwW_n7" alt="" data-size="original">&#x20;

This means that in the **"friend invite" deep link** there should be included data about the person who is distributing this deep link (in the latter image, the data should be for **Player "A"**). Always having a different data of the person who is sharing the deep link, means that the deep link, has to be dynamically constructed in the game, every time a friend invite is being shared\~\~.\~\~

To do that, I researched and found out how a deep link is storing and carrying data. This is done via the text in the link:

![Disection of a deep link, showing how data is stored in the link ](/files/-Mbq6Oh8kGza6PuS23_h)

After understanding how a deep link stores its data, I can now dynamically modify deep link templates from the game, just by specifyinga key and a value at the end of the deep link.&#x20;

#### Rewarding functionality

**First plan:**

During the analysis phase it was determined that after the user was invited to the game by a friend, at the start of the game, both friends will be presented with a reward.

&#x20;<img src="/files/-MbpBBKxi-PhSBL7fOhw" alt="" data-size="original"> \
Currently, in Text Express there is the "**Title news**" system: Whenever there is a global event in a country (Christmas, Easter, Halloween, etc), the game shows a pre-configured "**Title news**" screen and gives a reward to *all* players, who start the game during that day of the event:

![Title news example](/files/-MaYsV2_EnjjswgScJ-y)

The "**Title News**" reward is given at **the start of the game**. As the reward for the **friend referral** has to be given at the start of the game as well, at first I wanted to extend the "**Title news**" functionality, by allowing it to work for one player only, rather than just have it always working for all players.

![How "Title News" are working now](/files/-Mahpeh4-hUiC9wDPBXj)

![How I plan to extend the "Title News" functionality, so I use it for the friend referral system](/files/-MahmaeybuWZ-3XiCcyP)

**First plan design:**

When I started looking into how I can extend the "**Title news"** system, I started noticing that there are only 2 things, the "**Title news**" and the "**Friend Referral**" systems have in common, however a lot of differences.&#x20;

![Why it is not worth extending the "Title news" system](/files/-MahEtFyTb6bp6EOW_hP)

As there are more different than common functionalities, I decided to create a brand new feature, called "**Personal notifications**", which will serve in the "**Friend referral**" feature, but later on can be used for other features as well.

**New feature "Personal Notifications" design:**

Each feature which modifies the player data in Playfab, has to work in sync with the backend of the game. This is done so that the game is more secure from hackers ([Development requirements](/social-and-community-features-in-text-express/project-approach.md#development-requirements)). As this is a new feature and it will read and modify the Player data in Playfab, it had to be designed together with the backend developer:

{% content-ref url="/pages/-Mc7wIGiin7qxSX\_Z-6p" %}
[Personal Notifications Feature in Text Express](/social-and-community-features-in-text-express/research/untitled.md)
{% endcontent-ref %}

## Realization

> Code review, Unit testing, Guideline conformity analysis, Design pattern research, Available product analysis, Static Code analysis

### Navigation Deep links

By following [the steps,](/social-and-community-features-in-text-express/features/deeplinking.md#how-to-implement-onelink) which I've set up during the Analysis phase, I've set up a OneLink deep link template by adding **custom data for navigation to a specific section**:

![Setting custom data for navigation to the "shop"](/files/-MaxactNcWgAYW-0yvUr)

After the deep link was set I had to set up the SDK in the client. This was done with the view to follow the **Single responsibility principle (SRP)** for the DeeplinkManager class, so that there is only one place in the code, which will handle deep links:

![Instantiating the Deep link SDK in a specified class for all 3rd party services in TX](/files/-Max56DlIt5NjXpAJtXk)

After the SDK is initialized successfully it will check if the game was opened via a deep link or not. If the game is being opened via a Text Express deep link, which I have pre-configured in the OneLink console, then **onAppOpenAttribution** (Deep links Image 1) will be called and it will handle the incoming data.&#x20;

![Deep links Image 1](/files/-Max7Z5fTReQQ_S4AaF0)

I handle the incoming data as a JSON file. As you see in the image above, if I have a key "navigationPage", then I have to check the value and act on it

![Deep links Image 2](/files/-Max50fG3rx0sQj15PWo)

### Personal Notifications and "Friend Invite" System

#### Dynamically generating deep links in-game

I have managed to dynamically generate deep links from the game, which can carry the data of the person, who wants to invite their friends. An example link was:

![](/files/-Mbq87_A5E5fEXEjn9E0)

#### Personal Notifications feature

Implementing the "Personal Notifications" feature, which handles the rewarding functionality for the friend referrals was smooth, as I followed the solid design document, prepared in the [Design Phase](/social-and-community-features-in-text-express/features/deeplinking.md#rewarding-functionality). During the implementations, no major setbacks were encountered.

#### Rewarding function for "Personal Notifications"

After having the personal notifications data and architecture integrated, I had to create a function to calculate the reward which has to be granted for the notification:

![Explanation on what the rewarding function should do.](/files/-MbuFMDTUYCkFDBzX5kb)

For this function I created 2 different solutions. One short one, using only [LINQ ](https://www.tutorialsteacher.com/linq/what-is-linq)and a longer one using several "If" and "foreach" statements.&#x20;

```
                         SHORT (LINQ) soluiton


public void GrantRewardForNotification(string type)
    {
        var notif = config.notifications.FirstOrDefault(x => x.Type == type);
        var rewards = new ResourcesPackage(); // zero rewards if it is null at the end
        currentReadNotificationCount = Math.Min(GetReadNotificationsOfType(type),  
        rewardsPerAmountOfNotifications.Max(x => x.NotificationsAmount));
        var notificationRewardsConfig = RewardsPerAmountOfNotifications
            .LastOrDefault(x => amount >= x.NotificationsAmount);
        return null == notificationRewardsConfig ? 
        GiveRewards(rewards) : GiveRewards(notificationRewardsConfig.Rewards);
    }
```

```
                        LONG (FOR/FOREACH) solution


public void GiveRewardsForNotification(string type)
{
    foreach (var item in config.notifications)
    {       
        if (item.type == type)
        {    
            if (item.rewardsPerAmountOfNotifications.Count == 0) // zero rewards will be given
            {
                GrantRewards(null)
                return;
            }
            int currentReadNotificationCount = GetReadNotificationsOfType(type) + 1;
            for (int i = 0; i < item.rewardsPerAmountOfNotifications.Count; i++)
            {
                if (currentReadNotificationCount >= item.rewardsPerAmountOfNotifications[i].notificationsAmount) 
                {
                    if (i + 1 < item.rewardsPerAmountOfNotifications.Count) 
                    {
                        if(currentReadNotificationCount < item.rewardsPerAmountOfNotifications[i + 1].notificationsAmount)
                        {
                            GrantRewards(item.rewardsPerAmountOfNotifications[i].rewards);
                            break;
                        }
                        else 
                        {
                            GrantReards(item.rewardsPerAmountOfNotifications[i].rewards);
                            break;  
                        } 
                    }
                }
            }
        }
    }
}
```

Both functions did the same thing and I wondered, which one should be the one I choose, as both had pros and cons:

![LINQ vs. Explicit "for"s and "foreach"s](/files/-MbuYa1tSd1Wk8ndfMXL)

As it would take a lot of time to isolate the code and make a test for myself on how much overhead does LINQ adds compared to the "for" and "foreach" solution, I made research on the internet to find out ([**benchmarks**](https://medium.com/swlh/is-using-linq-in-c-bad-for-performance-318a1e71a732#_=_)**,** [**forums**](https://stackoverflow.com/questions/1185209/do-linq-queries-have-a-lot-of-overhead#:~:text=LINQ%20does%20not%20come%20for,until%20you%20actually%20need%20it.)).\
\
As conclusion, when using LINQ only a small **%** of the performance is influenced (around 10%), compared to using "for"s and "foreach"s. With all modern and high-end devices, nowadays, this percent will probably not make any difference to how the game feels. However, in the end, I chose the longer version, as it will be understandable for all programmers, no matter their skills and knowledge, and eventually modifying and introducing changes to this rewarding functionality will be easier.

**Unit Testing (almost)**

After the function was implemented, I wanted to test it. As it is very hard to implement unit testing on a big Unity project, which has never had unit tests, I had to find another way to test if the rewards are properly calculated:

![One example of the several manual unit tests I have runned to check if the function is calculating correct.](/files/-MbvUccwG4_xocyaCoEs)

Although, my manual tests worked and proved useful by finding issues in the code (which later on were tackled), I believe that it would have been way easier if Text Express had and was built around a framework which would allow proper unit tests.

### Sharing Menu

After the system was working I only had to find a way that a player can send an "invite friend" link to friends. My experience with apps and games, which have such an inviting system, is that when you want to share an invite link, a native Android or IOS sharing menu comes up and you use it to select a sharing service (WhatsApp, Email, Messenger, etc) and to send it to whoever you want. \
\
I played and researched the "Gamehouse" games, to see if they have such a system. In the end, "Bed And Breakfast" has an invite system, which had a sharing menu, so I talked with one of its developers to see how they are handling this functionality.

![Asking Bed and Breakfast developer on how the sharing menu works in their game](/files/-MaykpbyZrQ6DSAlb4gQ)

After research, it was determined that the plugin is free of charge and can be used without any contract.

The implementation of the "[native sharing menu](https://assetstore.unity.com/packages/tools/integration/native-share-for-android-ios-112731)" was described well and easy to follow. After testing and checking if it works, I've sent a "showoff" invite deep link to my colleagues to show them that it works:&#x20;

![Showcasing that the sharing menu works well and receiving appreciation](/files/-M_phctz4pkTvqYHzjpg)

## Evaluation

> Root cause analysis, Brainstorming

#### Navigation links

What Text Express currently has in and working is deep links that can open different sections of the game such as the Shop Page, the Events page, or the Customization Page. With such links, the developers of TX can easily prompt the players to those sections and show them immediately what new stuff they have to offer. Such functionality definitely improves the communication between the community and the game/creators(Blue Giraffe).

![Clicking navigation deep link, opens the store of the game at start ](/files/-McEBK3sOeKYwO4pp5EA)

#### Friend Referral system

With deep links we now allow our players to invite their friends and reward them for doing so. By adding such functionality, we allowed the Text Express players to do "word-of-mouth" advertising, which will exponentially increase the organic growth of the game and save up money for User Acquisition.

![Clicking a link send you to the Google Play store when you don't have the game](/files/-McEI725jQ_EQasun8IT)

![After clicking on a friend refer and installing the game for the first time a welcome reward is introduced](/files/-McEGiRk5MVdv9NzbcAG)

### For the future:

I am not even sure if it is possible at this step in the development of Text Express or if it is worth the time, but it would be very good that the whole Text Express project takes a step back and tries to implement [Zenjeck](https://github.com/modesttree/Zenject). This tool allows to use Dependency Injection in a Unity project and then easily implement Unit tests. Unit tests will allow faster testing and therefore, faster build/updates/features deliveries.

{% content-ref url="/pages/-M\_aMy261XnrAGu68xtP" %}
[Push Notifications in Text Express](/social-and-community-features-in-text-express/features/remote-push-notifications-in-text-express.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lyudmil.gitbook.io/social-and-community-features-in-text-express/features/deeplinking.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
