League of Legends Assistant Part 2 - Frontend
Posted on : October 16, 2021 Reading Time: 10 mins
In this post, I will explain a bit about how I developed the frontend of the League of Legends assistant app, there is a previous post, where I comment on the backend architecture.
App needs
In the frontend part, a desktop app is required that on one hand shows the statistics of all characters obtained from the backend, and on the other hand, it can connect to the game launcher, so that based on the feedback received from it plus the statistics, it can provide a series of advice.
Technologies used
As it’s my preferred framework, I used ReactJS for the interface, and I also used Electron to make the app a desktop application.
It was my first approach to Electron, and it turns out that it doesn’t get along very well with ReactJS (at least using create-react-app), so the project setup was relatively more complex than expected. But eventually everything worked as it should and I even managed to enable really useful features like automatic updates.
ReactJS + Electron setup
For practicality’s sake, I always use create-react-app when starting a React project. Because of the complexity of state management, in this case, I also used Redux.
Electron in this case is not only going to serve to make the application executable, but it’s also going to be in charge of connecting to the game launcher.
The setup with Electron in this case is applied inside the public folder, where when Electron is executed it starts loading the index.html generated by ReactJS. At the same time, it provides its functions at the window level to communicate with the React side.
Once this is done, a series of events have to be generated to be triggered from React, which allow all actions that can only be executed from Electron to be carried out.
In this case, ipcRenderer will serve as a bridge between React and Electron, in practice it will work as asynchronous functions that are called or listened from React.
Communication with the launcher
The League of Legends launcher uses certain web technologies, and enables a series of endpoints and sockets that can be used to receive real-time feedback.
To communicate with it, it is necessary to check a temporary file that is generated in the game installation folder and stores a set of key/value for making these requests. In this case, to avoid reinventing the wheel, I decided to use a small library that takes care of listening to changes in that file and facilitating the connection.
On the other hand, once there is an ongoing match, an endpoint is enabled that allows you to bring information about the ongoing match, minute of the match, timers of objectives, current builds of each player, etc.
Developing the functionalities
The first step for the application to work is to bring the statistics from our backend and be able to visualize them, there is not much to expand on here. The basic functionalities are to show a list with basic statistics and multiple filters. When focusing on a champion, you can see other details related to it, like the recommended builds.
Once that’s ready, we move on to state management with Redux.
There are multiple possible states for the launcher:
- Inactive
- Creating lobby / Looking for match
- In champion selection
- Playing
Depending on the current state, in the Ingame tab of the app one thing or another should be shown. In Electron, I developed a series of listeners that send messages to React, so that when these messages are received, React will update the application state in Redux, these constant state updates allow the application to keep pace (and strangely, sometimes surpass) with the game launcher.
In lobby / Looking for match
In this state, you should show all the people who are in your lobby, and you should also be able to check statistics of the others as well.
In certain matches, it is customary to request the line by chat, where the first one to ask for it “keeps it”, so I also added a feature that allows you to instantly send the desired line when entering the champion selection, this in my experience gets you the line you want in 9 out of 10 matches.
On the other hand, another useful feature is to automatically accept the match. Depending on certain conditions, it can take several minutes to find a match, so if you get distracted and don’t manage to hit the accept button, several minutes can be lost.
In champion selection
In this state, the current state of the champion selection should be shown, as well as advice on which characters to ban or choose to tip the balance in your favor.
On the other hand, you should be able to automatically obtain information from allied players to know what lines or characters they play, thus facilitating cooperation and having a certain advantage that you don’t have when entering blind. You can also see a match history of each allied player, which gives a wider panorama.
This player information is brought from the launcher itself, so it is not necessary to use requests through the Riot API that is mainly used in the backend.
A key feature in these cases is to load the recommended equipment for the current champion, the app allows you to load it automatically when selecting a champion, or manually.
The runes are loaded using a socket to the launcher, while the builds are loaded by adding a JSON file to the game files, so that when you are in a match and enter the store, it shows you a list of objects recommended by the app.
In match
In this screen, data from the ongoing match is displayed, all the statistics from the previous state are available but this time also for rival players.
On the other hand, it also shows the distribution of gold among the teams, the current items, the minute of the match, players currently alive or dead, and how much time is left for the spawn of the different objectives within the game.
Final comments
With this, the basic description of the frontend functionalities is covered, without having gone into much detail.
The development of this part was much longer than the backend, even when the architecture is simpler.
The CSS is almost entirely handmade which took a good part of the time dedicated to it.
As for the interaction with the launcher, I leave here a website where I was able to get some information about the endpoints that are available to interact with it, out of all of them, really very few work, so the website must be outdated. Through trial and error, I found those I needed and are still working.
Basically, every action within the launcher can be triggered from one of these endpoints, so the possibilities are very wide. With this, I conclude for the moment the explanation about the League of Legends assistant app.