Results 1 to 3 of 3
  1. #1
    MSgt. Shooter Person
    Join Date
    Jun 2008
    Posts
    74

    Default UT3 Custom Mod and Seamless Server Travel

    For some time now we do have some trouble with custom mods and switching between them in online games on dedicated servers. In online games using a dedicated UT3 server some unexpected behaviour can often be observed after switching from a legacy game type (DM, CTF, ...) to a custom game type (for example GaltanorsInvasion, BTFA,...):

    1. Missing custom game type HUD
    2. Number of bots is twice as high as before and can not be modified
    3. UT3 (linux) server crashes after some time of playing
    4. Voting menu is missing
    5. No movement or hit fire to begin the game possible

    Those things seem only to happen in the first map after such a seamless server travel. In the second map within the same custom game type it seems fine again (if the server does not crash before).

    I tried to pinpoint the cause of this behaviour and I think to have found it for the first three points (still trying to pinpoint the others :-). Also found some workarounds which could be successfully tested with GaltanorsInvasion and BTFA ... but it would need some coding.

    Test-Setup:

    • Dedicated UT3 linux server (version 3808)
    • Windows Clients (version 2.1)
    • UnrealScript Source (version 1.5)
    • BTFA (Version 10)
    • GaltanorsInvasion (Version 0.22)


    1. Missing Custom Game Type HUD

    Problem:

    When switching the first time to a custom game type usually the game type specific HUD is missing. The only way to get the custom HUD displayed seems to be disconnecting from the server and reconnecting again.

    Cause:

    This seem to be a simple timing problem. When the UT3 server has switched to the new game type the reliable function is called on all clients:

    SetHUD() --> ClientSetHUD()

    But it seems that the client (at least our windows clients) needs some more time for switching to the new game type. When the server tries to set the new HUD on the clients the switching procedure to the new game type has not yet taken place on the clients and the new HUD can not be set.

    Workaround:

    The custom HUD of the new game type can be hardcoded in the derived 'PlayerController' class. In this way the custom HUD is set by the client by its own (independent of the server).

    Code:
    class <CustomMod>_PayerController extends UTPlayerController;
    
    ...
    
    simulated event PostBeginPlay()
    {
    ...
    
        ClientSetHUD(Class'<CustomMod>.<CustomHUDClass>', none);
    }

    2. Number of bots twice as high as before

    Problem:

    When switching the first time to a custom game type the number of bots is usually twice as high as in the previous mod. Furthermore, the admin command 'killbots' does allow to kill all bots but they are instantly re-spawned. At last, the UT3 server crashes when playing the first map for some time.

    Cause:

    This issue is a little bit more complex... first of all, when switching to the custom game type the server transfers all bots from the previous game type to the new one. In doing so, the bot controller classes from the previous game type must be replaced by the customs game type controller class. During this process the number of transfered bots should be specified ... but it is not and this is causing the first problem.

    Lets have a look at the source code:

    Code:
    0006: class UTGame extends GameInfo
    0007:	config(Game)
    0008:	abstract
    0009:	native;
    ...
    3822: event HandleSeamlessTravelPlayer(out Controller C)
    3823: {
    ...
    3835:	else if (B != None && B.Class != BotClass)
    3826:	{
    3837:		// re-create bot
    3838:		BotName = B.PlayerReplicationInfo.PlayerName;
    3839:		BotTeamIndex = B.GetTeamNum();
    3840:		B.Destroy();
    3841:		C = AddBot(BotName, (BotTeamIndex != 255), BotTeamIndex);
    3842:	}
    ...
    3866: }
    The else-block beginning from line 3835 is executed when the new game types bot class is different from the old one. The bot name and team number is stored, the old bot is destroyed and the same bot is spawned with the new bot class.

    Looks good? Yeah ... but is not because the member variable 'NumBots' is not initialized. During server travel when setting up the new game type 'NumBots' is zero. What happens then:

    Step-by-step(whatmighthappenandisnogood):

    • NumBots == 0
    • B.Destroy()->UTGame::Logout(B)::Numbots--
    • NumBots == -1
    • C = AddBot()::NumBots++
    • NumBots == 0

    So, we have a new bot but the number of bots is set to zero ... not good.

    But there is also another side effect ... a second problem. The UTGame::Logout() method has a code block which adds automatically a new bot if the number of bots is less than the specified desired minimum:

    Code:
    0006: class UTGame extends GameInfo
    0007:	config(Game)
    0008:	abstract
    0009:	native;
    ...
    1756: function Logout(controller Exiting)
    1757: {
    ...
    1800:	else if ( NeedPlayers() )
    1801:	{
    1802:		AddBot();
    1803:	}
    ...
    1814: }
    I have no clue why this is done in Logout() as it is usually done within the state 'MatchInProgress'. This block causes the number of bots to be doubled.

    Step-by-Step(whatreallyhappensandisevenworse):

    • NumBots == 0
    • B.Destroy()->UTGame::Logout(B)::NumBots--
    • NumBots == -1
    • UTGame::Logout(B)->Addbot()::NumBots++
    • NumBots == 0
    • C = AddBot()::NumBots++
    • NumBots == 1

    So, we have two bots spawned but the number of bots 'NumBots' is set to 1. This means for _each_ travelling bot there will be another one in the new game type.

    I think (but not sure) that this wrong value for number of bots 'NumBots' might also cause the server crashes (point three from above) after some time of playing the first map ... need some more testing.

    Workaround:

    The only workaround I can think of is to re-write the method UTGame::HandleSeamlessTravelPlayer() in your base game type class. The above mentioned block should be exchanged by something like the following:

    Code:
    else if (B != None && B.Class != BotClass)
    {
        // re-create bot
        BotName = B.PlayerReplicationInfo.PlayerName;
        BotTeamIndex = B.GetTeamNum();
    
        NumBots++;                      // because Destroy()->Logout() will decrement it
        NumBots += DesiredPlayerCount;  // prevent Destroy()->Logout() from auto adding new bots
        B.Destroy();                    // remove bot of class of previous game type
        NumBots -= DesiredPlayerCount;  // reset prevention of auto adding new bots
        if ( NeedPlayers() )            // check if DesiredPlayerCount of new game types is less than of old one
            C = AddBot(BotName, (BotTeamIndex != 255), BotTeamIndex);  // add bot from class of new game type
    }
    Didnot find the causes for points 4 and 5 ... yet
    Last edited by donaldo; 06-11-2012 at 05:00 AM.

  2. #2
    MSgt. Shooter Person
    Join Date
    Sep 2009
    Location
    Arlington, TX
    Posts
    373

    Default

    What is the benefit of using seamless travel? I have forgotten because we have had it disabled for so long due to problems with custom maps, the problems you mention, and the demoguy bug, if memory serves. Anyway, nice findings.
    "I have no clue why this is done in Logout()..."
    -The function is called to add a bot when a player leaves, which can happen in other states than MatchInProgress. (for example, this way the bot can show on the roster before a match has begun, for those who use Players Must Be Ready to settle teams.)

  3. #3
    MSgt. Shooter Person
    Join Date
    Jun 2008
    Posts
    74

    Default

    Quote Originally Posted by NickG View Post
    What is the benefit of using seamless travel? I have forgotten because we have had it disabled for so long due to problems with custom maps, the problems you mention, and the demoguy bug, if memory serves. Anyway, nice findings.
    Dont know any mod which seems to really need the seamless travel of actors from one map/gametype to the other ... So cannot say for sure. All I know is that using seamless travel had enabled voting menu from the second played map on... Tested non-seamless travel yesterday again and it seems not to be needed (anymore?) for voting menu to appear ... . Guess we will switch to non-seamless travel from now on :-)

    Also realized the demoguy bug yesterday For the first time ... Always thought it was supposed to be this way

    "I have no clue why this is done in Logout()..."
    -The function is called to add a bot when a player leaves, which can happen in other states than MatchInProgress. (for example, this way the bot can show on the roster before a match has begun, for those who use Players Must Be Ready to settle teams.)
    I see ... Makes some sense now, thanks ... Nevertheless, would have never expected from a method called Logout() to add/login new bot players ... Wouldnt it be better to be handled in other states like 'PendingMatch' or so...?
    Last edited by donaldo; 07-15-2012 at 05:56 PM.


 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Copyright ©2009-2011 Epic Games, Inc. All Rights Reserved.
Digital Point modules: Sphinx-based search vBulletin skin by CompletevB.com.