Xbox LIVE Indie Games
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 5 (108 posts) 1 2 3 4 5 Next >

Global scoreboard component, by Spyn Doctor

Last post 2/11/2013 6:42 PM by to be determined. 107 replies.
  • 9/12/2010 5:06 PM

    Global scoreboard component, by Spyn Doctor

    Hi,

    since recently quite a few people here on the forum have had problems integrating global scoreboards into their games, I decided to make my own implementation public, which I used in Your Doodles Are Bugged! and Kuchibi.

    Download and more details in my Dev Log:

    http://spyn-doctor.blogspot.com/2010/12/global-scoreboard-component-for-xna-40.html
    [EDIT: Changed URL to point to new XNA 4.0 version of the component.]

    Maybe this makes life easier for some of you. If you end up using it and like it, I would appreciate some feedback here in the thread. Of course you can also post if you have questions or problems with it.

    EDIT: Oh, and if you find any bugs, then I would also be interested to hear about them!

    EDIT2: One thing I forgot to mention: My component separates the network part (the actual synching of the data via Xbox LIVE) from the storage part (maintaining the scores in a list, storing that list on a device, etc.). So you can essentially use the network part to synchronize any kind of data that you have (as long as that data implements a certain interface, and does this in the correct way).
    Of course most likely you will want to use it for global scoreboards, so I have included a sample implementation of the storage part for scoreboards. The sample implementation can be configured to support a single scoreboard or several boards (for example one for each difficulty, or one for each level). Depending on your game, and depending on what kind of data you want to have in the scoreboard, you may have to make adjustments to this storage/scoreboard part.
    However, most likely you will be able to use the network part as-is, without any changes. And I guess it is the network part that people had the most problems with...

    Doc
  • 9/16/2010 9:04 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Update: I have updated my scoreboard component a bit. Some minor bug fixes, plus I added optional friends-list filtering to the sample implementation for a global scoreboard. And the readme.txt now contains an additional "how-to" about how to write an UI to display the scores from this sample scoreboard. Follow the link in the post above to get it.

    Doc
  • 9/16/2010 10:16 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Nice one Doc.  Does it play nice with all the rules discussed in the other thread (filtering locals, etc)?
  • 9/17/2010 2:56 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Answer
    Reply Quote
    The issues covered by these rules are actually a level above my implementation. There were essentially two rules that emerged from that discussion: Don't start the score sharing using a Gold gamertag that is not actively playing, and only put gamertags of Silver/Gold players into the scoreboard. It would be the responsibility of the caller to make sure to adhere to these rules.

    Doc

     

     

  • 9/17/2010 4:33 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Awesome, I'll may give this a try soon.

  • 9/17/2010 7:38 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Spyn Doctor:
    The issues covered by these rules are actually a level above my implementation. There were essentially two rules that emerged from that discussion: Don't start the score sharing using a Gold gamertag that is not actively playing, and only put gamertags of Silver/Gold players into the scoreboard. It would be the responsibility of every caller to make sure to adhere to these rules.

    Doc

    Seems like a candidate for some common handling to me but you've already donated your code / time so thanks again :-)
  • 9/24/2010 11:31 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Answer
    Reply Quote
    I just got a question via email about what kind of setup I used to test the score sharing (two Xboxes, or two PCs, or whatever), and I thought that my answer might be of interest to others too, so I'm posting it here too:

    I did most of my testing with an Xbox and a PC, using SystemLink networking. If you check the comments in the class OnlineDataSyncManager, it describes a conditional compilation symbol called SYSTEM_LINK_SESSION. If you define this in your project properties, then the class will be compiled to use a local network SystemLink session, which you can use to test between Xbox and PC. I tested this as follows:
    I opened two instances of Visual Studio (VS C# Express in my case, but I guess that works with the full version too) and loaded my project in both instances at the same time. I took care to only change/edit my source files in one of the instances (the other instance then detects these changes and asks if you want to reload the changed files, which you usually do). From one VS instance I ran a copy of the game in debug mode on the PC, and from the other VS instance I ran a copy in remote debug mode on the Xbox. My score exchange code logs debug messages to the output console, so I also had the output windows of both instances open, arranged so that I could see both at the same time (two monitors help here :-). Both in the Xbox game and the Windows game you need to have an Xbox LIVE profile signed in, or otherwise you can't start the OnlineDataSyncManager. On the Xbox, you of course must have your CC-membership logged in anyway, to start the game in the first place, so no problem there. In the Windows game, unless you have a second account with a CC-membership, you need to log in with a local account. If you don't have one yet, see below on how to create one. Once the two instances of the game are running, and in both instances a profile is signed in and was used to start the OnlineDataSyncManager, you should see the debug output in the two output consoles showing you how the two game instances connect to each other and share their scores. The debug output will also show you if the score sharing was actually initialized and started correctly or not. You can now generate some scores in one of the game instances and should see them show up in the other instance.

    You can of course also test with two Xboxes, but then you also need two CC-membership accounts to run your game on both Xboxes at the same time. If you have two Xboxes and two CC-memberships, you can either test with SystemLink, or via "real" Xbox LIVE, with a PlayerMatch session. For system link, the CC-membership profiles can be Silver profiles, if you want to test PlayerMatch/XboxLIVE, they must be Gold profiles.
    But if you don't have two Xboxes and CC-accounts, it should be enough to just get the score share working between one Xbox and the PC, with SystemLink, as described above. Once that works, you just remove the SYSTEM_LINK_SESSION symbol from your project settings and recompile the game to use PlayerMatch/XboxLIVE, for a version to submit to Playtest (and later Review).

    To create a local account on Windows: Start your game on Windows. When the game is running, press the Guide button on the controller. Then select "New Profile" (or "New Account" - I'm not sure about the English labels). Next you'll see a window with the title "Games for Windows LIVE" and a lot of text. Do not click the "Continue" button, but instead use the scrollbar to scroll to the bottom of the text. There should be a link at the end of the text to create a new local profile.

    Doc
  • 9/28/2010 7:29 AM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    To be honest, on the Xbox Live Network, the ability of network layer is not so strong. While you exchange data between each client, you had better not transfer too much data for sync. The network bandwidth is very expensive for Xbox indie game. If using in the wrong way, the bandwidth would increase incredibly, which is depending on not only the sync counts and data structure for each player data, but also the transfer method, such as in one packet or in mutliple packets.

    And I think it had better use SendDataOptions.None option for SendData. Once you use reliable, it may affect other game network function. Certainly, if you just only use the global-scoreboard, then nothing to care about this.
  • 9/28/2010 6:31 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Gameloft community games:
    And I think it had better use SendDataOptions.None option for SendData. Once you use reliable, it may affect other game network function. Certainly, if you just only use the global-scoreboard, then nothing to care about this.
    The component uses ReliableInOrder, which is of course the most inefficient but also the most reliable method. This is necessary to make sure that both peers are always in the exact same state during the transfer and know exactly what to expect next from the other peer. Otherwise the risk for data being misunderstood by one peer would simply be too big (for example a score for one level being misinterpreted as belonging to another level, because the data that signaled the level change was lost on the way).

    However, this doesn't really matter because the component works in the background anyway, with the lowest possible thread priority and also does frequent Thread.Sleep() in order to not hog the CPU too much (and you can tweak the length of the sleep).

    Also, this will not have any negative effect on other game network functionality, as other networking is not possible anyway while the component is running. The component creates, ends, joins and leaves network sessions independently, while it looks for other instances of the game to share with. And of course there can always be only one network session, so while the component does this, it is not possible to have another network session for online play.
    So if you want to use this (or any similar) component with a game that offers online play, then you have to stop the component before starting an online match, and only start it again after the online match is finished.
    While score sharing during an online match would theoretically be possible, you would have to add this to your actual online match code yourself, i.e. in addition to the normal online match data packets, you would have to mix in the score sharing data packages. You couldn't use my component for this, but would have to program that yourself. It wouldn't make much sense though, since you would only be able to share data with the game instance(s) that the player is currently in a match with. Personally, I wouldn't bother implementing that. It would be error prone, mixing the score sharing packets with the online match packets, and would most likely degrade performance for the online match. I would only implement score sharing during local play or while at the menus, and that's what my component is meant for.

    Doc
  • 10/2/2010 12:32 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Hi,
      I integrated the code and I have a couple of questions. (I haven't tested the networking yet but I have it saving/loading/adding entries/displaying pages locally etc).

    1. Regarding this line from the readme, "*** IMPORTANT *** BEFORE you can use the current TopScoreListContainer, you need to implement one pending TODO, in the endSynchronization() method:". I went for the direct call to my save routine when this happens. However my save isn't threaded and so stalls for a short time, which is fine because I only save at the start of menu screens or on the 'level complete' screen. However if the sync manager can call this at anytime it's going to cause major stalls? Do I really need it? Since I save at the ends of levels can I wait until then?

    2. In OnlineDataSyncManager.cs it mentions in the comments increasing SLEEP_DURATION to reduce stuttering. I require a solid 60Hz because of the physics in my game, so is there a way I can only have the scoreboard syncing during menus? I would try mSyncManager.stop when you enter a level and then mSyncManager.start when you go back to the menus? Or is this going to mess up the networking too much?

    Thanks,
    Raoghard.
  • 10/2/2010 2:23 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Answer
    Reply Quote
    Raoghard:
    1. Regarding this line from the readme, "*** IMPORTANT *** BEFORE you can use the current TopScoreListContainer, you need to implement one pending TODO, in the endSynchronization() method:". I went for the direct call to my save routine when this happens. However my save isn't threaded and so stalls for a short time, which is fine because I only save at the start of menu screens or on the 'level complete' screen. However if the sync manager can call this at anytime it's going to cause major stalls? Do I really need it? Since I save at the ends of levels can I wait until then?
    I really can't say if it can cause major stalls, that really depends on how much is ongoing in your game at the moment (processing wise). If your game is doing something that requires a lot of processor, then having the synching thread doing a save in parallel to the main thread running the game may introduce a stutter in the main thread (but then again, it may not). If whatever is going on in the main thread does currently not take much CPU, then having a parallel thread doing a save will most likely not be noticable - it really depends on what the game is currently doing when the synching thread completes a score transfer and wants to save the result (see also next answer).
    The main caveat is not the possible stalling, but the possibility to have two threads calling the save method at the same time, if the synching thread should call it just at the same moment where the player finishes a level and the main thread calls it too. If you have the saving method protected with a "lock (...) { }" or similar, then that shouldn't be a problem. The lock itself shouldn't introduce any stalling while you play either, because during play, the main thread will not call the save method, so the synching thread can enter the lock without problems (and without further stalls). And if both threads happen to call the save method at the same time, then one of them will have to wait until the other releases the lock, so this thread may take a bit longer to complete, but it will just look as if the saving took a bit longer (if it is noticable at all).
    But to answer you question: No, you do not actually need it. If you do nothing at the TODO-location, then the result will simply be, that once a score transfer is complete, the result will not be saved immediately, but only once your game decides to save the data again (at the end of a level or wherever). So at worst, what would happen in such a case is that a score transfer completes, the results are not immediately saved, and then the user exits without ever triggering another save. For example if he exits in the middle of a level via the guide button, thus not passing the "save" code at the end of the level. In such a situation, the results of the last score transfer would then have been lost, which however not a serious problem. So if you can live with that, you can simply do nothing instead of the TODO.
    Alternatively, you could for example introduce a "volatile bool" flag somewhere. At the location of the TODO you set the flag to "true" and the saving procedure resets it to "false". The synching thread would then not do an actual save operation, but would only signal the "need to save" by setting this flag to "true". You could then add checks for this flag in other suitable locations of your code to trigger a saving even when normally you wouldn't save. But that depends on your game if you have such locations where you can react to this signal and save the game. For example, if your game has levels that require reloading when the player enters a new area in the current level, so you are showing a "loading, please wait" message anyway (or whatever). Then you could simply throw in an additional call to the save method at this point, if the signaling flag is "true". That way, the result of the score synch would not only be saved at the end of the level, but also during the level, whenever the next area is being loaded. Or similar - it really depends on the game.

    Raoghard:
    In OnlineDataSyncManager.cs it mentions in the comments increasing SLEEP_DURATION to reduce stuttering. I require a solid 60Hz because of the physics in my game, so is there a way I can only have the scoreboard syncing during menus? I would try mSyncManager.stop when you enter a level and then mSyncManager.start when you go back to the menus? Or is this going to mess up the networking too much?
    Yes, that is totally possible. But I really would recommend this only if you have a rather small score list (not many entries), because there won't be much time to do data transfers during the time the player is at a menu. And each stop/start will start a new transfer beginning at the start of the list, so if the transfer of the whole list takes a longer time, the player may often leave the menu (and stop the transfer) before the full list is transferred - so while transfers are initiated whenever the player enters the menu, each time it is only the beginning of the list that makes it over to the peer until the transfer is again interrupted. And also the whole peer-to-peer thing relies on the possibility of being able to communicate with as many peers a possible, one after the other. If the score exchange is always stopped again after a short time, then even with a short list you might only be able to contact one or two peers, but not many.
    So while you can certainly do this, I would recommend to at first leave the transfer running all the time and do some playtesting and see if there actually are any frame drops introduced by it. If there are, you can then start optimizing (either tweak SLEEP_DURATION or stop the transfer during actual game play). But you may not even notice any problems even with the score exchange in the background. It really depends on how much your game already utilizes the CPU, and it's more or less impossible to say up front if there even will be a problem. You will just have to test it to find out.

    Doc
  • 10/2/2010 4:07 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Thanks, excellent answer :) Ok, first I'm going to try not saving in endSynchronization and I'll leave the syncManager running all the time. So it should get a chance to transfer but if it doesn't call save then there should be no save stall. I have cpu time free but it's the sum of cpu & render that worries me. I'm currently using for 10 score lists with 1000 entries each as you did, perhaps 100 entries each would be better.
  • 10/2/2010 5:14 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Hi,
       I've had it running now in system link between my 360 and my PC. The server sent scores and all seemed well. However when a higher score was entered on PC with an 'addEntry' it didn't seem to reach the 360 until I deleted the save game on 360 and restarted everything. How long can I expect to wait to see scores update (when testing)? (I was refreshing with fillPageFromFullList(0, pageIndex, page);)
     Should I be tweaking WAIT_TIME_FOR_RECENT_HOST during testing to make it happen quicker?

  • 10/3/2010 11:55 AM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Raoghard:
    However when a higher score was entered on PC with an 'addEntry' it didn't seem to reach the 360 until I deleted the save game on 360 and restarted everything. How long can I expect to wait to see scores update (when testing)? (I was refreshing with fillPageFromFullList(0, pageIndex, page);)
     Should I be tweaking WAIT_TIME_FOR_RECENT_HOST during testing to make it happen quicker?
    This is strange, because that's not how it should work (and I've never observed such a behavior myself). And no, you should normally not have to tweak WAIT_TIME_FOR_RECENT_HOST during testing.

    It should work as follows:

    After two peers have exchanged their scores, each of them remembers the other peer as an "excluded" peer. There will be no further score exchanges with such an "excluded" peer until the WAIT_TIME_FOR_RECENT_HOST has elapsed (30min by default) or one of the two peers has a new score entry in one of his score lists, whichever comes first.
    So if you have a new score entry on the PC, this should immediately trigger a new transfer.

    You can see this in the code of TopScoreListContainer.addEntry, where a call to OnlineDataSyncManager.notifyAboutNewLocalEntry is made. However, there are two pre-conditions that are in the if-clause of that method:

    • The new score must actually have been added to the list (i.e. it must have been "better" than the previous score entry for the same gamertag).
    • You must have passed your instance of the OnlineDataSyncManager as the third argument when calling "addEntry". If you pass "null", the entry will still be added, but no new transfer will be triggered.

    BTW, if you run the game in debug mode and with the output window open (as I explained in one of the previous posts), then you should see the debug log output, which should allow you to see if your new score was added, and if that correctly triggered a new score transfer.

    Doc

  • 10/3/2010 4:35 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Hi,
       I think it is working actually. I found that I was re-loading the save game in the menu and I think this was overwriting the scoreboards which made it look like they hadn't updated. My game flow isn't quite finished :)

    Thanks for helping again.
  • 11/1/2010 6:27 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    With the default settings this component just plain works. I took his default score object, added a string to it to track the time for the play run - all in all the whole thing took maybe 8 hours to get fully up and verified running. It should be noted that you'll want to store 2 versions of your score table - 1 that stores an entry each time a new score posts on the local machine, and one that shows only online scores. All in all though compared to my last scoreboard implementation it was very simple. The fact it was also built to share really any data object, not just a hard coded score table.

    I'd recommend it to anyone thinking of doing high scores. Just know that I will test your game for blocked locals with my 'f*ckurscores' local account. =)

    Kudos!

    Also - I know radiangames is also using this as his base for adding scoreboards to his games.
  • 11/1/2010 7:44 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Answer
    Reply Quote
    Xalterax asked me on Twitter about the garbage created by my code, and I thought that responding here is easier than in 140 chars bites on Twitter ;-).

    My code consists of two parts: The actual networking part, and the sample implementation of the score board. The first part is what you really need for the score exchange, the second part you can easily replace with a similar implementation of your own, if you need to, as long as you implement the interface correctly (see the readme.txt).

    So we have to look at those two parts separately when analyzing garbage:

    I actually do not know if the networking part creates garbage, because I do not know how the XNA framework implements the network packets. One possible implementation would be, that for each new incoming packet, new storage is allocated. And once you have handled the packet, that storage becomes garbage. Or maybe the framework re-uses earlier packets to avoid garbage. I really don't know which is the case. If the former is the case, then it is essentially impossible to have any networking without garbage. In that case, my component would also create garbage during network communications, and there would be nothing I, or you, could do about it. If the latter is the case, then the networking part of my code should already not create garbage (or at least only very little garbage, and you should be able to change it to avoid even that little garbage).

    Now, the second part of my code, the sample scoreboard implementation: This definitely produces garbage! It allocates new score board entries and discards previous entries without caring about garbage. If your game is garbage conscious, then you can likely not use this sample implementation as is. You will have to change it to instead re-use score board entries (with a pool or something). That depends on your game.

    Doc
  • 11/1/2010 8:01 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Answer
    Reply Quote
    I have a fairly comprehensive garbage heap tracking system in my game - here's what I can tell you. 

    Right now:

    If I start the game with a local profile, there are 2 score list objects running in the BG - local players only get added to the small one and can only see the small (local one). 
    If I press the guide the button at any point and sign in with a gold profile (on the active controller) the primary screen update detects this and immediately enables the networking part of the component.
    If I open the guide again and go back to a local profile during game play the networking component shuts off.

    When the networking part is off, no garbage is added to the heap. 
    When the networking part is on, garbage is added to the heap at a modest rate - resulting in 1 collection every 60 seconds or so.

    The garbage seems to be somewhere in the networking code -or- could also be a result of the networking code interacting with the non-garbage conscious score list object. I'm really not sure which. All I could tell via CLR Profiler is that the garbage is from string allocation - thats about it.

    I may tackle it in a final effort to get garbage back down to 0 if I reach a point with the Torque end where I'm generating very little garbage. If I can get away with it, the idea of the game having to run for an hour before hitting a collection sits quite well with me. =)
  • 11/1/2010 8:07 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Xalterax:
    The garbage seems to be somewhere in the networking code -or- could also be a result of the networking code interacting with the non-garbage conscious score list object.
    The latter is definitely the case. When new packets are received, they are converted into new score board entries, and these entries are always created/discarded without regards to garbage. To avoid this, you would have to change the score board implementation to use entry pooling or something similar. The former may also be the case (as I wrote, I'm not sure if/how the XNA networking produces garbage), but if you see string allocations, then I don't think the allocations come from the network packet, but rather later, when the byte data in the packet is converted into the score board entries, i.e. the latter case again.

    Doc
  • 11/1/2010 8:17 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Regardless, your component is still the fastest, cleanest, and most reliable score sharing code I've seen to date. I'm pretty sure the code I used for Chaos Node generated garbage as well, but that was back when I was so new as a dev that I didn't really know or care that garbage was even a problem.

    Thanks for sharing - and again, anyone thinking about doing peer to peer high scores, level sharing, or any sort of object sharing - this is the best option I've seen so far.
  • 11/4/2010 8:28 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    A couple quick questions:

    I'm basically using the system as-is with the sample implementation (though with ints changed to longs since scores could break 2 billion in theory).  I was wondering if I could adjust the following variables when the player is paused/dead/in-a-menu so that score sharing would be speedier.  These are the two variables in OnlineDataSyncManager:

    WAIT_TIME_FOR_RECENT_HOST
    SLEEP_DURATION

    Can I dynamically adjust these during the game, or do they need to be the same for all players? 

    Also, even though I'll probably figure this out before the answer is posted: I'm saving the data at the same time I'm saving all the non-scoreboard data for the game.  Is there any reason this might cause trouble?  The two data sets don't really interact (local scoreboards are saved using my own custom system).

    Thanks!

    Luke
  • 11/4/2010 10:56 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Answer
    Reply Quote
    For your scenario, adjusting WAIT_TIME_FOR_RECENT_HOST would not help to make the score exchange faster. This value defines, how long a time must have passed between two data exchanges between the same hosts. The default is 30 minutes. Or in other words: Once two hosts have exchanged their scores, they will not exchange their scores again for the next 1/2 hour, so that they instead have a chance to exchange with other hosts. That's because the Xbox LIVE match-making doesn't guarantee that the next "match" you find is the same host as before, even if other hosts would be available. Therefore this wait time, so that even if you are paired with the same host again, you immediately break off communication again and look for other available hosts.
    Well, with one important exception: If during the 30min wait time either of the two hosts gets a new entry into his score list, then a pairing of these two hosts is accepted again, even before the 30min time runs out.
    So the complete rule is: After two hosts have exchanged their score, they will not exchange scores again for the next 30min (or whatever value is in WAIT_TIME_FOR_RECENT_HOST), or until either of them gets a new score entry, whichever comes earlier.

    The SLEEP_DURATION however is something that you can indeed adjust dynamically, if you want. The default is 12 milliseconds, and it is used for a number of Thread.Sleep(SLEEP_DURATION) calls that are included at strategic locations in the network code, so that the worker thread does not hog the CPU too much. But if you are in an area of the game that you know does not need much CPU, you can lower this value dynamically, to give the worker thread more CPU time (and the other way round, in an area of the game that is very CPU intensive, you could dynamically set this to a larger value to slow down the worker thread even more than normally). Although I wouldn't expect too big a speed improvement even when setting this to 0, because the main limiting factor is still the network bandwith itself, because there's throttleing code in there that makes sure to only send more data after the network buffer is empty (before I added this, I ran into network buffer overflow situations, when the worker thread wrote data more quickly then it could be sent over the network).

    About your last question: By "saving at the same time", do you mean you have two threads saving data to two files, at the same time, or do you mean you save first the normal data, then the scoreboard data, all into the same stream/file? Well, actually the answer is probably the same in both cases: I don't see how that should be a problem. :-)

    Doc
  • 11/14/2010 10:44 AM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    I have updated my scoreboard component with two fixes (still the same download link as given in my first post):

    Xalterax has found out that the actual networking part of my scoreboard component generated some garbage. This was caused by a call to DateTime.Now in the main loop of the worker thread. Apparently, this call causes garbage (which is a bit surpising, I must say). I have now changed my code to avoid this call. Instead, I'm using a Stopwatch.

    I've also tweaked the code that disables the chat function (which is enabled by default), to make sure that chat is switched off between the two partners that exchange the scores.

    Doc
  • 11/14/2010 10:58 AM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    Spyn Doctor:
    I have updated my scoreboard component with two fixes (still the same download link as given in my first post):

    Xalterax has found out that the actual networking part of my scoreboard component generated some garbage. This was caused by a call to DateTime.Now in the main loop of the worker thread. Apparently, this call causes garbage (which is a bit surpising, I must say). I have now changed my code to avoid this call. Instead, I'm using a Stopwatch.

    I've also tweaked the code that disables the chat function (which is enabled by default), to make sure that chat is switched off between the two partners that exchange the scores.

    Doc


    AWESOME! Thanks Doc.  Great timing - I plan to use this soon in MiG Madness!  :)
  • 12/5/2010 2:54 PM In reply to

    Re: Global scoreboard component, by Spyn Doctor

    I have updated my component again, with again some additional code to disable the voice chat. Even with the change I mentioned in my previous post, Xalterax still reported some "ghost voices" in his game Break Limit. I hope that with this latest change, the voice chat disabling now finally works reliably. Chat is now disabled at several different locations: On the client side, as soon as the server session is joined. On the server side, as soon as a client has joined the session. And, just to be sure, I've also kept the disabling I had before, right before sending the first data record to the other peer. So on each peer's side, there are now two locations where voice chat is disabled: After the session join, and right before sending the first record. Hopefully this will now finally exorcize the ghost voices! (This change is in the file OnlineDataSyncManager.cs, change date 2010-12-05.)

    Doc
Page 1 of 5 (108 posts) 1 2 3 4 5 Next > Previous Discussion Next Discussion