Presentation ITCamp 2014 - Intellectual Property in Software
ITCamp 2011 - Catalin Zima - Common pitfalls in Windows Phone 7 game development
-
Upload
itcamp -
Category
Technology
-
view
1.105 -
download
4
description
Transcript of ITCamp 2011 - Catalin Zima - Common pitfalls in Windows Phone 7 game development
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
Common Pitfalls in Windows Phone 7
Game Development
Catalin Zima-Zegreanu Evozon Systems
email: [email protected] blog: http://catalinzima.com
twitter: CatalinZima Microsoft XNA MVP
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
IT Camp 2011
• Thanks for coming!
• ITCamp is made possible by our sponsors:
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
Session agenda
• Introduction
• Performance
• Certification
• Devices
• Isolated Storage
• Miscellaneous
• Q&A
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
INTRODUCTION
What? Who? Why?
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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#
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
PERFORMANCE
Where we see all sort of things that can slow down an XNA game
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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)
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
Spritesheet example
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
DEMO
Loading Times
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
Strings
• Strings are immutable
• String manipulation => Garbage creation – .ToString()
– String.Format()
• Use StringBuilder – Mutable
– SpriteBatch.DrawString has an overload that accepts StringBuilder
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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!
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
CERTIFICATION
Where we try to pass certification in the first try
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
Common certification fails
• Publisher name and version number
• The Back Button
• Background music
• Memory Limits
• Phone capabilities
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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.
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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); }
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
DEVICES
Where we see that not all devices are created equal
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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.
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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‟
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
ISOLATED STORAGE
Where we see what bad things can happen in isolation
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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!
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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!!!
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
MISCELLANEOUS
Where we talk about stuff that didn‟t fit anywhere else
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
• (or use Mango and Silverlight/XNA integration)
<!-- 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>
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
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
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
Q&A
Challenge Accepted!
@itcampro / #itcampro Premium conference on Microsoft’s Dev and ITPro technologies
Don’t forget!
Get your free Azure pass!
• 30+15 days, no CC req‟d
– http://bit.ly/ITCAMP11
– Promo code: ITCAMP11
We want your feedback!
• Win a WP7 smartphone
– Fill in your feedback forms
– Raffle: end of the day