Advertising SDK

From GameSpy SDK

Overview

As consumer product companies continue to aggressively pursue opportunities to market and promote their products to the 18-34 year old males, a demographic that has abandoned television and other traditional advertising outlets in favor of playing computer and video games, game publishers are well-positioned to take advantage of this opportunity through product placement and advertising integration into games.

The Marketing SDK provides the tools and services necessary to make this possible by allowing the game publisher to dynamically serve product placements and advertisements into games, modify and change them as desired, and track and measure the usage and performance of those advertisements.

The traditional scenario of hard-coding the advertising assets into a game forced the publisher to have signed agreements in place, artwork created and integrated into the game, and all the requisite approvals in place before the game reaches beta. Using the Marketing SDK, publishers can provision product placements and advertisements when they and their partners are ready for them.

(back to top)

Project Setup

Files to include

The Marketing SDK leverages the gHTTP and gSOAP libraries to provide a mature and robust network transport layer. In addition, the GameSpy common code is used to provide standardized data typing across supported platforms. These libraries must be included in the project.
Common Code
The source files found in the root SDK directory must be included in the project. The common code contains platform specific type definitions and shared utility functions.
gHTTP
The GameSpy HTTP SDK is used when downloading files to disk or when streaming data into memory. All files within the /ghttp folder should be included. (Samples and subdirectories should be omitted.)
gSOAP
This commercial SOAP library is used when querying for the active ad units and when reporting usage statistics. More information about gSOAP may be found on the gSOAP website at http://www.cs.fsu.edu/~engelen/soap.html
The gSOAP files may be found in the “/gsoap” directory.
Marketing SDK Files
All of the files within the “/Ad” directory must be included in the project. Files within the “/Ad/AdSoap” directory must also be included.
(back to top)

Integrating the SDK

Compile-time options

A variety of settings are defined at the top of Ad.h to control memory and bandwidth usage. These optional settings are fully detailed in the reference section of this document.

PS2 developers must define WITH_LEAN and WITH_LEANER. This reduces the size of the gSOAP library and removes code that may not be compatible with all network stacks.

(back to top)

Initialize the SDK

The Marketing SDK must be initialized before it may be used. It is recommend that the SDK be initialized in the following manner:

	AdInterfacePtr anInterface  = NULL;
	AdResult       aResult      = AdResult_NO_ERROR;
	AdInitParams   anInitParams;

	memset(&anInitParams, 0, sizeof(AdInitParams));
	anInitParams.mGameId = GAME_ID;

	aResult = adInitialize(&anInitParams, &anInterface);
	if (aResult != AdResult_NO_ERROR)
		printf("adInitialize failed (%d)\r\n", aResult);

The AdInitParams structure contains runtime settings that may be used to control SDK behavior.

typedef struct
{
  gsi_i32     mGameId;
  const char* mQueryHostOverrideURL;   // Override this for testing

  // For offline usage stats
  gsi_bool    mOfflineOnly;            // (e.g. single player)
  const char* mOfflineFilePath;        // relative to working directory

  // For ad download caching
  const char* mCachePath;              // cache directory

} AdInitParams;
(back to top)

Register each ad position

At the beginning of the game (or at the start of each level) the SDK must be told which ad positions are in use. In addition to the position name, information about a default advertisement must be supplied. The default advertisement will be used if network conditions prevent an ad download or if an ad file is corrupted.

AdResult AD_CALL adRegisterPosition(const AdInterfacePtr theInterface, 
						const char* thePositionName,
						AdUnitID    theDefaultAdId,        
						const char* theDefaultAdResource,
						const char* theDefaultAdExtraData);

Although a default ad is generally unbranded, the SDK will continue to collect usage statistics that will be visible through the publisher’s portal. Therefore, it is important that the default ad have a valid AdUnitID.

(back to top)

Query the active ad for each position

The logic for selecting advertisments and matching user information for targetted delivery is contained within the AdServer. The SDK must simply pass up the user information along with a list of ad positions and the ad server will return a list of advertisments to fill those positions.

Currently, the SDK supports targetting based on birthdate only. The user’s profileid is used to count unique downloads.

AdResult AD_CALL adQueryForActiveUnits(
                        AdInterfacePtr theInterface,
				gsi_u32  theProfileId,
				gsi_u32  theBirthDate,
				AdQueryForActiveUnitsCallback theCallback,
				gsi_time theTimeoutMs);

This is an asynchronous query, so a callback and timeout parameter are provided.

(back to top)

Download new creatives

The SDK can begin downloading new creatives as soon as the query for active ads has completed.

AdResult AD_CALL adDownloadNewCreatives(
       AdInterfacePtr theInterface,
	gsi_i32        theThrottle,
       AdDownloadNewCreativesProgressCallback  theProgressCallback,
       AdDownloadNewCreativesCompletedCallback theCompletedCallback,
       gsi_time       theTimeoutMs);

Win32 and Mac developers may take advantage of ad caching when using ad rotations. Caching is performed automatically by the SDK. When the adDownloadNewCreatives function is called, the SDK will check if the required ad exists within the local cache. If the file is found, the cached file will be used in place of a new download. CRC checks are performed to ensure ad integrity.

When developing on the PS2, the SDK will not store files to the memory card. Instead, the developer must process data received in theProgressCallback and copy it to the desired memory location.

When setting up advertisements in the publisher portal there are some cases where you may want to provide a URL for content, but do not want the SDK to auto-download it. I recommend prefixing the URL with a token to identify the type of content. The presence of this token will invalidate the URL causing the SDK to ignore it.

For example, if the movie url is “http://localhost/movie.swf” you might use “stream:http://localhost/movie.swf”. The game client can then detect the presence of the “stream” token and begin streaming the movie. Note that a crc value is not required when using this method since no download is being performed by the SDK.

(back to top)

Notify the SDK when ads are used

An ad download is usually binary data and may contain multiple game resources. The SDK has no knowledge of the internal file contents, so it’s left up to the developer to inform the SDK when an ad is on screen or is being interacted with.

There are two pre-defined categories for ad usage. The interpretation of the category names is somewhat arbitrary, but here are some helpful guidelines for when each category should be used.

UC_VIEWS
Usually defined as “time on screen”. Viewing a billboard, floating blimp or other passive impressions would fall into this category. e.g. The branded item exists for asthetic purposesly only, is not used in gameplay.
UC_INTERACTIONS
Drinking a branded soda or constructing a branded storefront would fall into this category. Please note that viewing a branded soda would fall into the UC_VIEWS category. Developers are free to use whichever category they prefer, but since this affects usage reporting we recommend that a clear separation is chosen.
AdResult AD_CALL adBeginTrackUsageTime(AdInterfacePtr theInterface, 
   const char*    thePositionName,
          AdUsageCategory theCat);  
AdResult AD_CALL adEndTrackUsageTime  (AdInterfacePtr theInterface, 
						   const char*    thePositionName,
						   AdUsageCategory theCat);
AdResult AD_CALL adIncrementUsageCount(AdInterfacePtr theInterface, 
						   const char*    thePositionName,
						   AdUsageCategory theCat);

As an example, imagine that you have a branded blimp that will fly through the users field of view. When the blimp appears on screen you should call adBeginTrackUsageTime. When the blimp explodes (or peacefully floats off-screen) you should call adEndTrackUsageTime.

You must call adEndTrackUsageTime once for each call to adBeginTrackUsageTime. This allows for simple tracking when multiple blimps are on screen. If you call adBeginTrackUsageTime five times, but call adEndTrackUsageTime only four times, the ad will still be considered “in use”.

Calling adBeginTrackUsageTime multiple times will not inflate the viewing time. If three blimps on are screen for five seconds, you are credited for five seconds of viewing time. (not 15)

(back to top)

Report usage statistics

We recommend that the adSendUnitUsageData function be called at least once every five minutes throughout the game session, and once again when the game session ends. This is a flexible guideline and may vary depending on game type.

(back to top)

Ad Metrics

Developers who are familiar with web based metrics may recall the terms “impression” and “click-through”. These are somewhat restricted usage metrics which are fit to current web server technology.

GameSpy client side ad reporting is much more robust and will increase the value of your ad inventory.

Views (UC_VIEWS)
This is usually interpreted as when an ad is on-screen.
Web developers may notice a similarity with ad “impressions”, however impression count is a limited report metric. GameSpy supports time based measurements which are unavailable in a web environment.
For example, when playing a flash movie in-game, the GameSpy Marketing SDK is able to report not only the number of times the movie was streamed, but also how many seconds the movie was viewed. This is not as simple as multiplying the number of downloads by the length of the movie. When given the option, your games gamers may close the advertisement before it has finished playing, or they may watch an interesting movie 3 or 4 times!
Interactions (UC_INTERACTIONS)
The interactions category is left for general developer use. Actions such as picking up a health pack or firing a gun are suitable for interactions.
(back to top)

Reference

Compile Time Options

These are defined at the top of ad.h.

GSI_AD_STATIC_MEM
When defined, this will cause the SDK to prefer static memory over dynamic memory. Array sizes must be defined at compile time and array growth will not be permitted.
GSI_AD_DEFAULT_FILE_NAME (“_gsiad.dat”)
File name used to store offline stats.
GSI_AD_MAX_TRANSFER_COUNT (1)
Specifies the number of simultaneous downloads the SDK will perform. The default is set to single downloads. Increasing this may result in faster download speeds, but will require additional memory for the ghttp sdk.
GSI_AD_MAX_FILENAME_LENGTH (255)
Buffer size for filenames. Reduce this only if you are extremely strapped for memory.
GSI_AD_POSITION_COUNT (5)
Maximum number of positions in any one level/map. This is the number of positions the SDK will keep in memory.
GSI_AD_MAX_POSITION_NAME_LENGTH (32)
Position names are string identifiers for ad positions.
GSI_AD_UNIT_ARRAY_INITIAL_CAPACITY (10)
Starting capacity for the unit array. You will usually need 2 x number of positions.
GSI_AD_UNIT_ARRAY_MAX_CAPACITY (15)
The maximum size that the unit array will grow to.
GSI_AD_UNIT_ARRAY_GROWBY (0)
Array growth size. The array will grow as needed until the max capacity is reached. The default of zero prevents memory growth and is required when using GSI_AD_STATIC_MEM.
GSI_AD_MAX_EXTRA_DATA_LENGTH (64)
Maximum buffer size of developer data. This data is associated with the ad using the publisher portal. Increase this if you require additional data.
GSI_AD_MAX_URL_LENGTH (255)
Maximum size of download URLs specified using the ad portal. Increase this if you require support for longer URLs.
(back to top)

Multithreading

The gSOAP library is a blocking TCP socket library, this requires that we run it in a dedicated thread.

The GameSpy common code will automatically create and destroy threads for gSOAP as needed. One thread is required for each outstanding gSOAP call. The stack size required by this thread will vary by platform. 8k is usually large enough as long as WITH_LEAN and WITH_LEANER are defined.

Because the gSOAP library is only used when retrieving a list of ads or when reporting usage statistics, the library will not affect performance during gameplay.

(back to top)

FAQ

While using the SNSystems stack for the PS2 I receive network errors from the update query. What might be happening?

PS2 developers using SNSystems must specify the number of threads that have network access when they call sockAPIinit. This number must include an extra thread for the gsoap library.

How often should usage data be reported?

We recommend that adSendUnitUsageData be called at startup, shutdown and periodically throughout the game (~5 minutes.) If the player’s network connection drops, usage data may be saved to an offline file. Sending usage data at program startup ensures that the offline data will be reported.

How can I create advertisements and set locations for my title?

Administrative functions may be found on the Ad Portal web site. For access to this site, please contact devsupport@gamespy.com. Once you have been granted access, please check the “Guide” section of the web site for helpful tips and directions.

Why do the cache files have a “bin” extension?

Advertisement creatives may contain any type of binary data, including zip files and self extracting executables. We save creatives as “bin” files to protect users against harmful file types, and use a check sum to verify the cache file integrity once it has been fully downloaded.

I can’t use the cache files because my title requires the file extension. What do you recommend?

We recommend renaming or copying the cache file into a new folder. If the cache file is remove the SDK may download it again at a future time. To prevent this, the default ad for the position may be updated with the new file name.

How can I see/test an advertisement in game before making it active?

Since advertisements are position based, we recommend using special position names for test builds of the game. In the future we may consider supporting ads that would be delivered only to “test” clients. Please contact devsupport@gamespy.com if you are interested in this or other feature requests.

(back to top)

gSOAP License Notice

Part of the software embedded in this product is gSOAP software.

Portions created by gSOAP are Copyright (C) 2001-2004 Robert A. van Engelen, Genivia inc. All Rights Reserved.

THE SOFTWARE IN THIS PRODUCT WAS IN PART PROVIDED BY GENIVIA INC AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

(back to top)