A Closer Look at Profile Management
Soon after making the decision to get started on Galactic Wars [3] 2.0, I ran into the problem of managing users and their profiles in a way that was not going to limit what I could do with the game. This article gives you a closer look at how I am handling users in the game.
I have decided to model my system after Halo 3, making a few assumptions along the way:
- Abstract Game from Player Specifics
By removing the use of any specific PlayerIndex in the code, I can build a game that supports any player on the system so long as they are signed in.
- Force Sign-In
I am only going to worry about players that are signed in to GamerServices (online or not). When a user signs off, the system makes sure it is not the last player. If it was the last player, it raises event with which I use to go back to the start screen.
- One NetworkSession to Rule Them All
By utilizing the built-in Network Session code, I will force all gameplay to go through a standardized lobby which will work for any type of gameplay whether it be campaign, local multiplayer, coop, deathmatch or whatever I decide to add to the game. This is very similar to Halo 3’s system and is done to ease the development of the UI code.
Let’s take a look at the code. I first declare the class which includes a list of profiles, an event and two event handlers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using Microsoft.Xna.Framework.GamerServices; namespace FocusedGames.GalacticWars.Data { class ProfileManager { private List<Profile> activeProfiles = new List<Profile>(); public event EventHandler LostAllGamers; public ProfileManager() { SignedInGamer.SignedIn += OnGamerSignedIn; SignedInGamer.SignedOut += OnGamerSignedOut; } |
Next we need to handle when a gamer signs out. If the profile exists in our system, we need to remove them and make sure we still have gamers left.
1 2 3 4 5 6 7 8 9 10 11 | protected virtual void OnGamerSignedOut(object sender, SignedOutEventArgs e) { Profile usedProfile = GetProfile(e.Gamer); if (usedProfile != null) { activeProfiles.Remove(usedProfile); CheckForGamer(); } } |
Similarly, when a gamer signs in we need to make sure that it isn’t already in the system for some reason. If it isn’t, we create / load it and add it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | protected virtual void OnGamerSignedIn(object sender, SignedInEventArgs e) { Profile newProfile = GetProfile(e.Gamer); // If the profile isn't in our system, we need // to load it! if (newProfile == null) { newProfile = Profile.FromGamer(e.Gamer); if(newProfile != null) activeProfiles.Add(newProfile); } } |
Finally, the two helper methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public Profile GetProfile(SignedInGamer gamer) { for (int i = 0; i < activeProfiles.Count; i++) if (activeProfiles[i].Gamer == gamer) return activeProfiles[i]; return null; } public void CheckForGamer() { // If no profiles are here, we need to // grab one! if (activeProfiles.Count == 0) { // Delegate the responsibility. Listener can move to a specific screen. if (LostAllGamers != null) LostAllGamers.Invoke(this, EventArgs.Empty); } } public Profile[] ActiveProfiles { get { return activeProfiles.ToArray(); } } } |
On the next page we will cover exactly what the Profile class is and what it does!
Pages: 1 2
Tags: FGF, Galactic Wars, Profile Management, Thrust, XNA
October 24th, 2008 at 12:25 pm
Could you talk some more about the “One NetworkSession to Rule Them All” aspect? I was thinking of doing something similar myself, and it’s always helpful to read about how someone else is going at it.
October 30th, 2008 at 10:48 am
I will go into it in great detail but in general the idea is that no matter what option they select from the main menu they will end up in a network session based game. The Xna Framework has a session type for local games as well so I force single player games to go through the session setup just like a LAN or Live game would. The benefit to doing this is that I only need to write one version of the lobby code that works independent of session type.
Hope this helps!