1. Problem
You want to distribute an
application that provides a trial version. Also, you want your
application to remind users to buy the full version.
2. Solution
You have to use the Guide class from the GamerServices
namespace, which provides properties and methods enabling you to check
whether your application is running in trial version mode. Moreover, the
Guide class provides methods to
simulate both trial mode and buy request when your application is
running in either debug mode or in the emulator.
3. How It Works
Microsoft again helps
developers: Marketplace implements a feature enabling users to choose
between a trial version and a full version of your application. As a
developer, you don't have to provide two versions of your software, but
simply check your code to see whether the application is running in
trial mode. In fact, when the user chooses to install the trial version
of your application, Marketplace adds a trial license file to the
directory where the application is installed. If the user decides to buy
the application after having tried it, Marketplace replaces the trial
license with a full license.
Depending on the framework
chosen to write your application, either XNA or Silverlight, there are
different ways to check whether the application is running in trial
mode. The XNA framework provides the Guide class contained in the GamerServices namespace (see Figure 1 for Guide class diagram). The Silverlight framework provides the LicenseInformation sealed class with the IsTrial method.
Your job as a developer in
implementing trial mode in the application is to add test conditions in
your code, excluding extra application functionalities available only
after the user buys the full version of the application. For example,
you can show extra menus during the load of the form when the IsTrial method returns false, or you can show an image in your game indicating that the next level is locked if the IsTrialMode property of the Guide class returns true.
As stated before,
Marketplace informs the application if it has been bought or if it is in
trial mode. So when you test your application in the emulator or from
your device, and the application is not being installed by Marketplace,
both the IsTrial method and the IsTrialMode property return false.
Therefore, it is not so easy to test the application functionalities in
trial mode. By the way, there are a lot of solutions that you can
implement to resolve this behavior and decide when to run the
application in trial mode or full mode. It has been suggested that you
could create your own version of the LicenseInformation
class, use the var keyword to define the object instanciated from it,
and specify via an internal member field whether the application is a
trial or not. After testing the code, you could simply remove the class
from the project and change a few other code rows. But we don't like
this solution, because the XNA framework provides the SimulateTrialMode property from the Guide class, which enables you to specify when the application is in trial mode (by setting the property to true) or not (by setting the property to false).
The Guide class can be
used with Silverlight applications too. This is an example of using
mixed code between the XNA and Silverlight frameworks. As stated in a
previous recipe, the only mixed code that is prohibited is that related
to graphics context. We prefer to use the Guide
class in Silverlight because it is already provided by the XNA
framework, and even if you have to reference the XNA assembly in your
project, using Guide doesn't add any extra space in the XAP application's distribution file.
Finally, it is a good practice to ask users whether they want to buy the
full application before exiting from it. If they agree to buy the full
application, you have to show the related Marketplace page. This can be
accomplished by using either the Marketplace APIs such as the MarketplaceDetailTask and MarketplaceReviewTaskShowMarketplace method from the Guide class. classes or the
We have created two
examples to show different trial approaches in Silverlight and XNA
Windows Phone applications. Both examples use the Guide class from the Microsoft.Xna.Framework.GamerServices
namespace, but they differ in their event handlers. These two
applications print a message on the screen telling users that the
application is running in trial mode.
In the XNA world,
everything is a sprite, so the same is true for text. To print text on
the screen, you have to use a sprite font. You can add a font in the
Content project (in the example, this is called XNATrialApplicationContent) from Visual Studio 2010 by selecting Project => Add New Item. From the dialog box that appears, you then have to select the Sprite Font item and give it a name (see Figure 2).
The .spritefont
file added to the project is an XML file containing the font's
characteristics such as font family, dimension, and style. You can edit
this file to change the font's characteristics. Moreover, the Asset Name
property is important because it represents the name of the font that
you have to refer to in your code (press F4 to see the font's
properties).
SilverlightTrialApplication
uses a new text block added to the main content panel, and its text is
used to show the message. To add a new text block, you can either drag
it from the toolbox or type the XAML code in the editor (see Figure 3).
3.1. The Code
In the XNA game application, we use the Draw
event handler to show a message indicating that the application is in
trial mode. We add a class Boolean field to store the value from the IsTrialMode property of the Guide class. This is suggested by Microsoft because reading the IsTrialMode
property for each instance consumes more time, and in a game, saving
time is very important! This operation is accomplished in the Initialize method, where another interesting feature is present. The #DEBUG compiler directive is used to set the SimulateTrialMode
property. In that way, when the application is compiled with debug
settings, you can simulate the trial mode and test your code.
The Draw method uses the IsTrial property to check that the application is in trial mode and uses the DrawString method in the affirmative case. The DrawString
method is necessary for printing information on the screen. This method
accepts the sprite font object, the message to show, the X,Y position
indicating where to print the message, and the font color to use. The
sprite font object is loaded in the LoadContent method.
Finally, in the OnExiting event handler, we add the code to ask users to buy the application. The Guide class provides the ShowMarketplace method to accomplish that. Internally, the method already checks for the IsTrialMode property, so it is not necessary to add this check too.
namespace XNATrialApplication
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont font;
bool isTrial = false;
. . .
/// <summary>
/// Allows the game to perform any initialization it needs to
/// before starting to run.
/// This is where it can query for any required services and load any non-graphic-
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
#if DEBUG
Guide.SimulateTrialMode = true;
#endif
isTrial = Guide.IsTrialMode;
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
font = this.Content.Load<SpriteFont>("Font");
}
. . .
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
if (isTrial)
{
spriteBatch.Begin();
spriteBatch.DrawString(font, "The Application is in Trial Mode",
new Vector2(10, 10), Color.Black);
spriteBatch.End();
}
base.Draw(gameTime);
}
protected override void OnExiting(object sender, EventArgs args)
{
Guide.ShowMarketplace(PlayerIndex.One);
base.OnExiting(sender, args);
}
}
}
Writing text in the SilverlightTrialApplication application is easier than XNA application. The lbMessage TextBlock control provides the Text property, where you can specify the string message to print. In the MainPage.xaml code, you can specify the Loaded event, and in the related code-behind method, you can check whether the application is in trial mode.
<phone:PhoneApplicationPage
x:Class="SilverlightTrialApplication.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True" Loaded="PhoneApplicationPage_Loaded">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Height="69" HorizontalAlignment="Left" Margin="6,6,0,0"
Name="lbMessage" Text="" VerticalAlignment="Top" Width="450" />
</Grid>
</Grid>
</phone:PhoneApplicationPage>
namespace SilverlightTrialApplication
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
#if DEBUG
Guide.SimulateTrialMode = true;
#endif
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
if (Guide.IsTrialMode)
{
lbMessage.Text = "The Application is in Trial Mode!";
}
}
}
}
Finally, in the App.xaml.cs code, the Application_Closing()
event handler is defined and is called by the Windows Phone operating
system before closing the application. It is the best place to insert
the call to the ShowMarketplace method.
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
Guide.ShowMarketplace(PlayerIndex.One);
}
4. Usage
When both applications run,
they check for trial mode and then print the appropriate message on the
screen. When both applications close, they show a message asking users
to buy the application. In Figure 4,
you can see both examples' output. On the left is the XNA application,
in the middle is the common screenshot asking to buy the application,
and finally on the right is the Silverlight application.