From Event to Action: Accelerate Your Decision Making with Real-Time Automation
ITCamp 2011 - Catalin Zima - Common pitfalls in Windows Phone 7 game development
1. Common Pitfalls in
Windows Phone 7
Game Development
Catalin Zima-Zegreanu
Evozon Systems
email: catalin.zima@evozon.com
blog: http://catalinzima.com
twitter: CatalinZima
Microsoft XNA MVP
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
2. IT Camp 2011
• Thanks for coming!
• ITCamp is made possible by our sponsors:
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
3. Session agenda
• Introduction
• Performance
• Certification
• Devices
• Isolated Storage
• Miscellaneous
• Q&A
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
5. WP7 game development
• Windows Phone 7
– One of the three major players in the smartphone
world
– Standard chassis specifications
– 10 models from 4 manufacturers (more coming soon)
– New programming model
• XNA Game Studio 4.0
– One of the technologies available for WP7
development
– Recommended for Games
– Cross platform game development using C#
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
6. The questions
• What does this session contain?
– Common „gotchas‟
– Tips and advice for avoiding them
– NOT an introduction to XNA and WP7
(but don‟t go! This is still useful!)
• Who is the target audience?
– Game developers using XNA
– Game developers targeting WP7
• Why should you care?
– Learn from our mistakes
– Repairing is harder than preventing
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
7. Where we see all sort of things that can slow down an XNA game
PERFORMANCE
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
8. Loading Times
• Users like games that load fast
• Also, the watchdog watches you
– If the game does not show something to the
user in 10 seconds, it is closed
• Proper techniques can reduce loading
times significantly
• Example: Chickens Can Dream
– From 14 seconds to ~4 seconds
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
9. Techniques: Compression
• Use DXT compression for images
– Requires power-of-two size
– Unlike PNG or JPEG, the texture is actually
compressed in the GPU memory
– 1/8 compression for opaque images
– ¼ compression for images with transparency
• Precompile XML using the Content
Pipeline -> much smaller sizes
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
10. Techniques: Spritesheets
• Pack multiple sprites in a single texture
– http://create.msdn.com/en-US/education/catalog/sample/sprite_sheet
– http://spritesheetpacker.codeplex.com/
• Use sourceRectangle parameter of
SpriteBatch.Draw to draw individual sprites
• Benefits:
– Faster Loading (one big file instead of multiple small
ones)
– Avoids DXT power-of-two restrictions
– Bonus: faster drawing (fewer texture switches)
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
12. Loading Times
DEMO
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
13. Techniques: Blame someone else
• Phones without the NoDo update have
significantly slower loading times
– Tell everyone to apply the update
• Some HTC phones have loading times
much slower than all other phones
– Suffer the wrath of HTC owners, or just go
back to the two previous techniques
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
14. Garbage Collection
• .Net CF uses a non-generational GC
– At each collection, the whole heap is „swept‟
– Much slower that a generational GC
• If you generate garbage each frame =>
hiccups
• Mango Update– good news
– .Net CF receives generational GC
– This still doesn‟t solve the problem, just hides it
– Garbage is the #1 enemy for your performance
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
15. Garbage Collection
• If you think you have garbage issues, profile and
see who‟s allocating
– Use a Windows build of the project and the .Net CLR
Profiler
– Mango adds more profiling tools for the WP7 build
• Common sources
– String manipulations
– Linq extension methods
– Boxing
– foreach – don‟t use it for arrays
• Use Object Pools
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
16. Strings
• Strings are immutable
• String manipulation => Garbage creation
– .ToString()
– String.Format()
• Use StringBuilder
– Mutable
– SpriteBatch.DrawString has an overload that
accepts StringBuilder
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
17. LINQ Extension methods
• They all create garbage.
– use of delegates
– use of IEnumerable
• Intellisense makes these easy to use by accident.
• Removing “using System.Linq” will prevent accidents
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
18. Boxing
• Value types used as reference type
– structs that implement interfaces
– Dictionaries that use Enums as keys
• IEqualityComparer<T>.Default uses object
• See http://bit.ly/nick_enums for solution
– Methods working wit the object class
• Use Generics as often as possible
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
19. Using Object Pools
• Use a class to manage a list of instances for
reference types
– When you need new instance, instead of using
new, request an instance from the pool
– When done with an instance, release it back to the
pool
• Objects are pre-allocated
• Management of objects has to be done
manually (back to the dark ages?)
• Heap complexity is increased
– Occasional GCs are slower
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
20. Other Performance Tips
• Guide.IsTrial – Slow: cache and reuse
• Manual Inline sensitive code - Nasty, but efficient
• Use public fields instead of Properties
– Please hold the tomatoes back!
• Use „out‟ and „ref‟ methods when dealing with large
value types (Matrix, Vector2, Vector3)
• Use jagged arrays instead of 2D arrays
• GPU Fillrate - use a smaller resolution to investigate
• GPU batching –use spritebatch to batch more Draw
calls together
• Profile, profile, profile!
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
21. Where we try to pass certification in the first try
CERTIFICATION
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
22. Common certification fails
• Publisher name and version number
• The Back Button
• Background music
• Memory Limits
• Phone capabilities
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
23. Publisher name and version
number
• Rule 5.6 - Technical Support Information
– An application must include the application name,
version information, and technical support contact
information that are easily discoverable.
• Before November 1st 2011, this was only
„recommended‟
• One of the most common cert. failures
• Starting with June 3, this will return to
„recommendation‟ status.
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
24. The Back Button
• Rule 5.2.4
• Common failures: back button exits the
application
• Why? Default XNA template:
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
25. User Music
• To summarize rule 6.5:
– Don‟t mess with the user‟s background music
– Don‟t crash when user is playing music
• Simple solution:
– Use MediaPlayer.GameHasControl
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
26. Memory Limits
• Phones have a minimum of 256MB
• Your game has a maximum of 90MB
• The game simply exits without having the
chance to do anything.
• Use DeviceExtendedProperties to query
memory while debugging and keep usage
low
• Don‟t use it too often, as it generates garbage
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
27. Phone Capabilities
• Not a Fail reason, but still good to know
• During certification, your manifest file gets regenerated
– May result in detecting capabilities you don‟t actually use
– Ex: Having a Reference to System.Net => Game uses data
connection
• Users may chose not to install the game based on the
shown capabilities
• You just lost a customer
• Solution: Use the Windows Phone Capability Detection
Tool before submitting your game
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
28. Where we see that not all devices are created equal
DEVICES
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
29. Device Discrepancies
• Samsung Phones with AMOLED screens
– Color banding in gradients is more visible
• HTC Devices
– Experience with HD7 and 7 Pro, all reported
– SoundEffectInstance.Volume doesn‟t work
– If application is interrupted without
tombstoning (eg. phone call), the
Accelerometer class doesn‟t work anymore,
and a new instance needs to be created.
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
30. Remember the QWERTY
• Common scenario
– In your Windows build, you bind something to
keyboard keys (like invincibility, etc)
– You only have non-QWERTY devices to test
– You ship with the „forgotten‟ code in
– Some users discover the „cheat‟
• We shipped with such code in and it made us
doubt the users‟ highscores
• Tip: Use compile #if directives for your „cheats‟
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
31. Where we see what bad things can happen in isolation
ISOLATED STORAGE
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
32. Program Flow
• Game is launched or reactivated
• Load content to show on the screen
– To make sure the watchdog doesn‟t get us
• Load saved data from IsolatedStorage
• … game is played …
• On Deactivated is called
• Save user data to IsolatedStorage
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
33. Program Flow
• Game is launched or reactivated
• Load content to show on the screen
• User hits the Back button before loading is
done
• Load saved data from IsolatedStorage
• … game is played …
• On Deactivated is called
• Save user data (null) to IsolatedStorage
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
34. Accidentally deleting data
• Data is overwritten => User settings and data are
now gone
• Progress is erased
• User is angry -> bad review
• What to do ?
– Check for null before overwriting
– Save data directly to disk whenever it changes, not on
Deactivated event
– Keep a backup of the save file
– Use different files for different data
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
35. Game Updates - Scenario
• Use a class, let‟s call it… UserData to store
all the user settings and progress
• On save, serialize class to disk using XML
• On load, deserialize from XML
• On first run, if no data exists, create default
UserTemplate instance and save it to disk
• All works ok, QA approves, data is saved!
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
36. Game Updates - Scenario
• Add new functionality to the game
• New data added to the UserData class
• Added code to the code that properly
creates the default instance
• QA tests the new game version, all is well
• Everyone happy, game update is released
• The Nightmare begins!!!
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
37. What went wrong?
• Updating user has an older version of the
save file in his IsolatedStorage
• Deserialization failes because the class is
changed
• QA can‟t test this scenario
• Possible changes
– Add new value-type fields to UserData
– Add new reference type field to UserData
– Change the type of a member of UserData
– Remove any member of the UserData
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
38. True story, bro!
• Our first update to Chickens Can Dream faced this
problem
• We simply added a List<Boolean>
• 15.000 users who updated the game now had the
game crashing on startup
• Fixed the bug, updated, problem solved!
• However:
– Average ratings dropped by almost a full star
– We needed a full month to get back to the ratings before
the update
– Lots of reviews in the Marketplace saying that the game
doesn‟t work after the update
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
39. How to avoid?
• Be careful
– Pray someone doesn‟t miss something
– Check for nulls all over the place
– Use post-its to remind yourself!
• Use versions for your save files
– Tied to your game‟s version
– Code that reads an older version and converts
to a new version
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
40. Where we talk about stuff that didn‟t fit anywhere else
MISCELLANEOUS
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
41. User Input
• Unsupported Characters
– You ask for a name from the player
– Player uses non-ASCII characters
– When trying to draw the name => CRASH
• Global Highscores? That‟s just bad luck!
– Crisis averted in CCD by sanitizing text server-side
• Why it happens?
– Fonts are used as images in XNA
– The default SpriteFont only supports ASCII
• Fix: uncomment the DefaultCharacter tag
<!-- If you uncomment this line, the default character will be substituted
if you draw or measure text that contains characters which were not included
in the font. -->
<DefaultCharacter>*</DefaultCharacter>
• (or use Mango and Silverlight/XNA integration)
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
42. Tombstoning and resources
• There is a tendency to dispose and unload
resources when OnDeactivated is called
• DON‟T!
• Currently, for very short periods of time the
game might not be evicted from memory =>
ObjectDisposedException
• After MANGO, it may never be evicted
• TODO: just save your state, don‟t try to clear or
dispose anything
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
43. Challenge Accepted!
Q&A
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro
44. Don’t forget!
Get your free Azure pass! We want your feedback!
• 30+15 days, no CC req‟d • Win a WP7 smartphone
– http://bit.ly/ITCAMP11 – Fill in your feedback forms
– Promo code: ITCAMP11 – Raffle: end of the day
Premium conference on Microsoft’s Dev and ITPro technologies @itcampro / #itcampro