The Game Discovery Center - Theme Tutorial

This post should help theme developers create a custom theme for the Game Discovery Center. I assume you already have some knowledge about how Big Box themes work.

Written By Brian Faeran

Last updated 26 days ago

What is the Game Discovery Center

From a themers perspective, the Game Discovery Center is a list embedded in another list. You have a list of games inside of a list of lists. It consists of just one xaml file where all code is located within. The file is called DiscoveryPageView.xaml

How to start coding this view in your Custom Theme

Assuming that you've run Big Box at least once with version 13.10 or higher, you can simply find the following file and copy it into your own custom theme's Views folder:

LaunchBox\Themes\Default\Views\DiscoveryPageView.xaml

To start editing the view, open your custom theme's project file, or open the DiscoveryPageView.xaml directly.

The View File

This section will break down the major parts of this file, so you can get an idea of what things are.

​The Parent List (The List of Lists)

This will show up in the code as: <flow:DiscoveryPageList ...>

Place this code where you want all the lists to appear on the screen. Here's a list of some properties you should know about:

VisibleRows (int)
This controls how many rows should be visible at any given time. The lower the number the better performance, but go too low and you could get rows appearing from out of nowhere. You'll need to find a balance based on what your view looks like.

SelectedItemPosition
This controls where the selected row will appear in the space you provide. This can force the selected list to always appear in one spot on the screen.
The values are: Bottom, Center, None, Top

SelectedItemOffset (int)
This will offset the list on the y-axis, starting at the top of the space provided, to give you more granular control over where the selected list appears.

The following sections are used inside of the DiscoveryPageList:

flow:DiscoverypageList.Style (optional)

A basic Style section. In the default theme, it's used to change the SelectedItemOffset and SelectedItemPosition values for specific lists.

flow:DiscoveryPageList.ItemTemplate

This will contain what each list will look like.

A DataTemplate will hold the layout of what each list will look like.

Inside of a DataTemplate, you can add a FlowControl list or a ListView list (or both). These lists will contain the list of games (You can see examples of both inside of the default DiscoveryPageView.xml file). A FlowControl is a regular wheel type of list and is heavily documented inside of the Documentation.pdf file. A ListView is a type of list that is used in Text List Views, as well as the thumbnail lists on some platform views that display favorited and recently played games.

flow:DiscoveryPageList.ContentLists

This will contain the type of lists you want to see in your view. They will display in the order that you list them. The default theme contains a number of them that you can use. There are two distinct types of lists you can use:

Hardcoded Lists
We've hardcoded a number of lists that can be used inside your view

Lists a random group of favorited games

<win:BindingProxy x:Key="Favorites" Data="{Binding FavoritesList}" />

Lists a random group of highly rated games of user ratings with a fallback to community star ratings

<win:BindingProxy x:Key="HighlyRated" Data="{Binding HighlyRatedList}" />

Lists recently played games in the order of most recently played

<win:BindingProxy x:Key="RecentlyPlayed" Data="{Binding RecentlyPlayedList}" />

Lists a random group of MAME Arcade games that are supported by the MAME High Score Leaderboard feature

<win:BindingProxy x:Key="MameHighScoresList" Data="{Binding MameHighScoresList}" />

Lists a user's platforms in alphanumeric order

 <win:BindingProxy x:Key="Platforms" Data="{Binding PlatformsList}" />

Auto-Populated Lists
Lists based on our auto-populate playlist ruleset A list of all hardcoded binding options:

An example of a hardcoded list of recently played games:

Under the UserControl.Resources section of the view, add the following line to declare your list:

<win:BindingProxy x:Key="RecentlyPlayed" Data="{Binding RecentlyPlayedList}" />

Then under the ContentLists section, place your list:

<controls:SingleItemCollection Item="{Binding Source={StaticResource RecentlyPlayed}, Path=Data}" />
An example of a Auto-Populate list that shows recently added games: <controls:SingleItemCollection>
   <controls:SingleItemCollection.Item>
      <flow:GameContentList Title="Recently Added" Sort="DateAdded" MaximumItems="25" MinimumItems="5">
         <flow:GameContentList.Criteria>
            <flow:GameContentListCriteria Field="DateAdded" Comparison="RecentDays" Value="360" />
         </flow:GameContentList.Criteria>
      </flow:GameContentList>
   </controls:SingleItemCollection.Item>
</controls:SingleItemCollection>

flow:GameContentList

This list type will populate games based on the choices you make within. Here are notable properties and what they do:

Title
Gives your list a title which you could use in triggers and also use to display on the view somewhere

Sort
Will sort the list based on possible values:

DateAdded, DateModified, Developer, Favorite, GameCompleted, Genre, Installed, LastPlayed, LaunchBoxId, MameHighScore, MaxPlayers, Platform, PlayCount, PlayMode, PlayTime, Portable, Publisher, Rating, Region, ReleaseDate, ReleaseDateYear, ReleaseType, Series, Source, StarRating, Status, Title, Version, Random

SortAscending (bool)
Tells which direction the games will be sorted.
Default value is True

MaximumItems
The maximum amount of items that will be generated in this list

MinimumItems
The minimum amount of items that the list requires before it will be displayed

flow:GameContentList.Criteria

In this section, you can list all possible rules you want your list to adhere to. The rulesets are equal to what we have available under the auto-populate section when creating a playlist. It's highly recommended to build out an auto-populate playlist first so you can check if the games that get added to it meet what you want to accomplish. Then you can use that playlist to determine the values that need to be entered into the list.

The following are the 3 available fields and their potential values (Remember that not all Field values work with all Comparison values)

Field

AnyAchievement
AlternateName 
Amazon 
ApplicationRomPath 
Broken 
Complete 
ControllerSupport 
DateAdded 
DateModified 
Developer 
Ea 
EpicGames 
Favorite 
Genre 
Gog 
GogAchievements 
Hide 
Installed 
LaunchBoxId 
LastPlayed 
HighScoreSupport 
MaxPlayers 
Notes 
Platform 
PlayCount 
PlayMode 
Portable 
Publisher 
Rating 
Region 
ReleaseDate 
ReleaseType 
RetroAchievements 
Series 
Source 
SortTitle 
Steam 
SteamAchievements 
StarRating 
Status 
Storefront 
Title 
Uplay 
UseDosBox 
UseScummVm 
Version 
Xbox

Comparison

EqualTo 
NotEqualTo 
IsEmpty 
IsNotEmpty 
OnOrBefore 
OnOrAfter 
RecentDays 
GreaterThan 
LessThan 
Contains 
IsTrue 
IsFalse 
HasAllValues 
HasAtLeastOneOf 
HasNoneOfTheValues 
IsBetweenDates 
IsBetweenNumeric 
MainGameIs 
MainGameIsNot 
AnyAppIs 
NoAppIs 
Supports 
DoesntSupport 
PartiallySupports 
FullySupports 
Requires 
DoesntRequire 
DoesntContain 
IsSimilarTo 
IsNotSimilarTo 
IsAmazon 
IsEpicGames 
IsGog 
IsOrigin 
IsSteam 
IsUplay 
IsXbox 
AchievementsSupported 
AchievementsNotSupported 
AchievementsNotStarted 
AchievementsInProgress 
AchievementsCompletedv

Value
This is the value that you would input into the auto-populate playlist value field

Dynamic Lists

The system is designed to display an unlimited amount of dynamic lists which will start appearing after your lists in the XAML end. To the user this will be seamless, as a theme developer this is something you should be aware of when building your view. There's a lot of different types of lists that this can consist of, and each time the view loads, it will generate a completely random set of dynamic lists.

Here's a breakdown of some types of lists that may appear in this section:

  • Best - displays a random group of games that is above a specific user or community star rating

  • Explore - displays a random group of games

  • Worst - displays a random group of games that is below a specific user or community star rating

The above may also be combined with other pieces of metadata, for example:

  • Best of [year]

  • Explore [platform]

  • Worst of [genre]

  • Best [genre] games of [year]

F.A.Q.

I want some game lists to look different than other lists, how do I do this?

Within your UserControl.Resources section, you can create a number of different DataTemplates. You can use one DataTemplate as your default, while the others can be triggered for a specific type of list (ListType), or a specific list altogether (Title).

Let's say you create a "Default" template, a "Tall" template, and a "Sqaure" template.

  • ie: <DataTemplate x:Key=Default" ...>

  • ie: <DataTemplate x:Key=Tall" ...>

  • ie: <DataTemplate x:Key="Square" ...>

Under your flow:DiscoveryPageList.ItemTemplate section, you can use triggers to determine which lists or list types use which DataTemplates.

ie: Use the Tall template when displaying the MameHighScores listtype, and the Square template when displaying the list titled "Recently Added":

<ContentPresenter Content="{Binding}">     
   <ContentPresenter.Style>         
      <Style TargetType="ContentPresenter">             
         <Setter Property="ContentTemplate" Value="{StaticResource Default}"/>                    <Style.Triggers>                 
            <DataTrigger Binding="{Binding ListType}" Value="MameHighScores">
               <Setter Property="ContentTemplate" Value="{StaticResource Tall}" />
            </DataTrigger>
               <DataTrigger Binding="{Binding Title}" Value="Recently Added">
                  <Setter Property="ContentTemplate" Value="{StaticResource Square}" />
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </ContentPresenter.Style>
</ContentPresenter>

How do I display an image or text outside of a template?

There are two distinctive ways to bind to the selected item:

  • SelectedListItem - changes instantly to the selected item (can cause performance issues) ie: Display publisher of selected game (points to the name of your DiscoveryPageList) <TextBlock Text="{Binding ElementName=DiscoveryList, Path=SelectedListItem.Publisher}" />

  • ActiveItem - changes to the selected item 500ms after navigation has stopped (more performant) ie: Display publisher of selected game <TextBlock Text="{Binding ActiveItem.Publisher}" />

It is recommended to use FlowImage to display your images.

Here are examples of it in use:

Display clear logo using ActiveItem:

<flow:FlowImage DataContext="{Binding ActiveItem}" ImageType="Clear Logos" />

Display clear logo using SelectedListItem:

<flow:FlowImage DataContext="{Binding ElementName=DiscoveryList, Path=SelectedListItem}" ImageType="Clear Logos" />

How do I display a video outside of a template?

It is recommended to use FlowVideo.

Here is an example of it in use:

Display video using ActiveItem:

<flow:FlowVideo DataContext="{Binding ActiveItem}" LoadDelay="3000" PlayVideo="True" PlayAudio="True" />

How do I change the title of a hardcoded or dynamic list?

You can change the name of a title by using a DataTrigger. You'll find examples of this in the default theme.

Keep in mind that hardcoded and dynamic titles can not be translated into other languages. This DataTrigger will only work in the language you choose to make this DataTrigger for.

Here's an example of the code needed to change the Title of a specific list. This code will work if the TextBlock is outside of any lists:

<TextBlock>
   <TextBlock.Style>
      <Style TargetType="TextBlock">
         <Setter Property="Text" Value="{Binding ElementName=DiscoveryList, Path=SelectedList.Title}"/>
         <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=DiscoveryList, Path=SelectedList.Title}" Value="Best of Sega Genesis">
               <Setter Property="Text" Value="Sega Genesis Does What Nintendon't" />
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>

This code is saying if the title is equal to "Best of Sega Genesis", change it instead to "Sega Genesis Does What Nintendon't".