GSoC is finally coming to end, and what an exciting experience it has been! In this post I’ll be showing off the fruits of my labor.
User collections were added to Games last week, and that marks the last major milestone of my GSoC project of “Implementing game collections in GNOME Games”. I’m very glad that I was able to finish all the major milestones in time. Below I’ll give a quick summary of my journey.
About the Project
Before getting straight into it, I’d like to give a quick introduction for the uninitiated (You can also read my previous posts here). My project this summer is to introduce collections to Games. Games is a game launcher and an emulator for several platforms, and it lists all of your games in one place with help from tracker. It’s written in a beautiful language called Vala, which I liked the more I used it in this project. Games is available as flatpak and you can get it from flathub. You can view the repo on GNOME GitLab and it’s maintained by Alexander Mikhaylenko (a.k.a. @exalm and @alexm), who is also my mentor for this project.
As of starting my work on the project, Games had a main “Games” page, where all games are listed, and a “Platforms” page, where games were classified into the platforms they belong to. My work includes adding a new “Collections” page where users can access and manage their collections, and to work on the back-end to support game collections. Collections are basically “playlists” or “albums”, but for games, and hopefully they’ll improve the user experience.
The issues I worked on are:
Issues relevant to my GSoC project
- #70: Add a “Collections” view
- #71: Support “smart” collections
- #94: Allow users to hide games marked as finished
- #127: Keep a list of “favorite” games
- #304: Right click should open selection mode
- Also related: #302, #303
MR’s relevant to my GSoC project
- !400 (Merged): Introduce selection mode
- !407 (Merged): Add Favorite Collection
- !412 (Merged): Add Recently Played Collection
- !416 (Merged): Add support for user collections
- !420 (Merged): Add selection mode support in CollectionsPage
- !421 (WIP): Enable selection mode on Right Click / Long Press / Shift + F10
!422 (WIP): Introduce hidden collections
- Also related: !409 (Merged), !417 (Merged), !419 (Merged)
The First Milestone: Selection Mode
For something like collections the first milestone is to implement an efficient way to manage multiple collections and the games in it. The best way to do that is to implement a selection mode in Games. So that’s what we did. It consisted of adding an overlay checkbox to all
GameIconViews, and some work on
PlatformsPage to support header-bar changes, search and selection while in selection-mode. This work can be seen in !400. With selection mode complete, I could focus on introducing the collections itself. This is how selection mode in Games looks like:
The Second Milestone: Predefined Collections
After introducing selection mode, the next major milestone was to introduce a few simple built in collections that mey be useful to the users. And so a Favorites collection along with Recently Played collection was introduced.
Favorites collection (!407) adds the ability to mark games as favorite using the selection mode. Users can then view those games in the “Favorites” collection. The context aware star icon in selection mode offers a quick way to add or remove games from a collection view easily.
Recently Played collection (!412) helps you keep track of recently played games so that you could quickly jump to this collection and continue your recently played game. Games did not have any support for sorting the games in any other order than by their names. So I also implemented a sorting mechanism that also helped me sort the games in Recently Played by their last played time.
These predefined collections will be hidden when they don’t have any games in them. Working on thumbnails for collections were fun. It previews the first four games of the collection in the thumbnail. On the back-end side I also implemented a database migration system along with the general work of making the database support saving and retrieving collections. It was nice to brush up on SQL queries again.
The Last Milestone: User Collections
With predefined collections working nicely, it was time to introduce the ability for users to create their own collections. This also entails some work on renaming, removing, ways of adding user collections, manually adding games from anywhere to these collections, and removing games from the collection. These were also the key differences from predefined collections and user collections.
Renaming and removing collections can be done in the corresponding collection sub-pages (a page to view games in a collection) via the menu button that is visible for user collections in the header-bar. The menu will not be available for predefined collections as those can’t be removed or renamed. Collections can also be removed while in selection mode too. Since removing collections are destructive I also worked on an in-app undo notification which allows to revert the last “Remove Collection” action. Games can be removed from user collections by going in to selection mode while in collection sub-page.
Adding user collections and adding games can be done while in selection mode itself. Apart from that empty collections can also be created using the inline “Add Collection” widget in the “Collections” page. The above two actions and their dialog are coupled into a single “Collection Action Window”. The window consists of two pages: “Add to collection” and “Add a collection”.
On using the inline “Add collection” widget, a modal pops up with the “Add a collection” page. On using the “Add to collection” action on selected games in the selection mode, the modal pops up with “Add to collection” page, where users can see all their user collections to add the selected games to. It also provides a search, and a way to create a collection on the go, which when used slides open the previously said “Add a collection” page.
And with that most major milestones are done :) Now I’ll sit back, fix any related bugs, or improve existing features.
There’s one more predefined collection we could support: Hidden collection. This allows games to be marked as hidden so that’s it’s not visible to the user in main view. The hidden games can be brought back by navigating to the hidden collection and by simply “un-hiding” it. I have a WIP MR (!422) that adds support for this, but there are a few issues which is blocking it from being good to be merged. The current mechanism that replaces “placeholders” of cached games, or games already discovered by tracker in earlier instances of Games, with actual games that are currently being discovered again by tracker, is one which does not allow to modify the actual Game object instead of the placeholder ones in all the game models. This was done for performance and user experience gains because replacing the placeholder games in the game model with the actual/replaced ones can be very expensive and causes flashing in game thumbnails. We already use a not so good workaround for collections by replacing games with actual ones in the collection’s game model. All of this will eventually be solved after refactoring the game replacement mechanism with one which provides more flexibility. This work is beyond the scope of my GSoC project so this will have to be looked after GSoC.
Some More Fun with Games
During GSoC I also hacked on some other stuff related to Games. Some of them are:
- Make preferences use more libhandy widgets to make preferrences more adaptive and of course for more eye candy: !389.
- Even more eye candy work on game covers which you can also see from the previous screenshots: !403
- Generalize shader code in retro-gtk, which is a Libretro front-end framework that Games uses: !84
- Also some hacking on retro-gtk to support display rotation so that some emulators that give incorrectly rotated output can be corrected: !80
I talked about most of the above work in my previous blog posts.
What I Gained from GSoC with GNOME
My experience and the lessons I gained from working on Games with Alexander is truly immeasurable. It quite literally changed how I thought about work in my field and how open source would be like, especially since this is my first experience working on any project, let alone an open source project. Before GSoC, I just knew the basics of “theoretical” C/C++, Python, SQL for writing extremely tiny programs, and a very minimal git workflow of
git add .; git commit -m "fEx a tYpeO haHa"; git push" because I honestly feared any command next to
git other than those three.
I remember being very interested to contribute and to be part of an open source project, but having no experience in any project at all, I was taken aback when I saw the sheer size of the repos and almost cryptic “practical” code which made no sense to me even though I “knew” the language it’s written in. My first ever contribution was to simply use display-names of files for displaying file names in UI, which as simple as it is for me now, was an extremely giant step for me then. And I remember grinning with joy on seeing the “The changes were merged” and the green tick next to it. That’s when I knew I have a new hobby from then on :)
My mentor, Alexander is an exceptionally talented person and I’m very sure everyone who knows him, already knows this. He helped me with a lot of things about open source and programming in general from the low level workings of Vala, C, GTK, GObject to the best practices to write good code.
And now by the end of this GSoC, I can confidently say I’ve mastered git. I also have a much better understanding of how programming languages work, how to use libraries, how to refer to documentation efficiently, what consists of good or bad code, how to properly structure your work as atomic commits and most importantly how “practical” programming works, which I wouldn’t have know otherwise.
All these lessons are invaluable to me and I’m sure will be helpful to me through out my future projects and work.
My exciting journey for the last three months is coming to an end as I have reached the destination and I had a great time. I’d like to give a huge shout out and thanks to Alexander Mikhaylenko, who is kind, helpful and immensely talented, for all the help and for taking time to review my work and to help me improve :)
Thanks to the GNOME community for the wonderful and friendly experience, and for GUADEC which I’m very happy to have participated in. And wishing the best to all of you!
Also thanks to Google for providing a platform to have these wonderful experiences.
It’s truly a bittersweet moment, but GSoC ending doesn’t really matter as I’ll still be around :)