Announcement

Collapse
No announcement yet.

TCP Link between game server and AI server

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #16
    Originally posted by KrisWood
    I think it's quite obvious that I realize this, but what do I DO about it? I need it to send a message once or twice every second for the duration of the game...
    Heheh.

    I don't really know what I'm talking about here, but Tick() is probably your friend. Tick() is called regularly by the engine for all actors and is given a delta time, so you can figure out how long it's been since you last got tuck.

    As wormbo says, avoid inifinite loops ...

    See also SetTimer http://wiki.beyondunreal.com/wiki/Actor/Methods

    This of course means you need an actor to get ticked, I don't think GameType is an actor. Just extend (=subclass) actor and spawn one of your custom actor at (prebeginplay? postbeginplay?)

    Comment


      #17
      your gameinfo will get ticked =)
      be careful what how much you put into tick though, as it will be executed every game update, and can really hit performance. But since there will be only 1 instance of your gameinfo in the game you should be alright =).

      Comment


        #18
        Tick is once every frame refresh, I'd rather not go that route as it needs to be on a less lag dependent timer. The rest of this sounds promising I'll look into it. Thanks for all the replies

        Comment


          #19
          Ok here's what I've got now:

          Wanderlust_Game.uc
          Code:
          class Wanderlust_Game extends Gameinfo
          	config(Wanderlust);
          
          //user-editable vars
          var() 	config	bool			bLogDebug;
          var string WLhelloWorldString;
          
          event InitGame( string Options, out string Error )
          {
          	super.InitGame(Options, Error);
          
          //    bForceRespawn=true;
              WLhelloWorldString = "This is a test of the Wanderlust Hello World system.";
              WanderlustSendMessage (WLhelloWorldString);
          
              if(bLogDebug)
              {
              }
          }
          
          
          function WanderlustSendMessage (string SendThisString)
          {
              super.PostBeginPlay();
          
              Log(SendThisString);    // Write our log message
              TextToSpeech(SendThisString, 5 );
          }
          
          ...etc...
          Marzer also wrote me the following as an example timer, but I'm not sure how to call it from within my gametype...

          WanderlustServerTimer.uc
          Code:
          class WanderlustServerTimer extends Actor;
          
          var float timerInterval;
          var Wanderlust_Game m_game; //adjust names accordingly - pointer to the game info, fill it from the game info when you spawn this actor
          
          function PreBeginPlay()
          {
          	super.PreBeginPlay();
          	SetTimer(timerInterval,true);
          }
          
          function Timer()
          {
          	if (m_game == None)
          		return;
          	//message code, I would have it call a ServerTimer() function on your gameinfo using the pointer
          }
          
          defaultproperties
          {
          	timerInterval=0.5
          }

          Comment


            #20
            Originally posted by KrisWood
            Marzer also wrote me the following as an example timer, but I'm not sure how to call it from within my gametype...
            It should be getting invoked by the engine because of the SetTimer() call. Put a log() in there and see.

            /edit BONG I see what you mean. Should be able to spawn() it into your level.

            Comment


              #21
              I talked with another of my friends, Knight (creator of the TD mod) and he gave me enough advice to come up with the following...

              Code:
              class Wanderlust_Game extends Gameinfo
              	config(Wanderlust);
              
              var() 	config	bool			bLogDebug;
              
              var string WLInitString;
              var string WLStatusString;
              var string WLShutdownString;
              
              event InitGame( string Options, out string Error )
              {
              	super.InitGame(Options, Error);
              
                  WLInitString = "Initializing the Wanderlust Game";
                  WanderlustSendMessage (WLInitString);
              
                  if(bLogDebug)
                  {
                  }
              }
              
              event PreBeginPlay()
              {
                  WLStatusString = "PreBeginPlay";
                  WanderlustSendMessage (WLStatusString);
              }
              
              simulated function PostBeginPlay()
              {
              	super.PostBeginPlay();
                  WLStatusString = "PostBeginPlay";
                  WanderlustSendMessage (WLStatusString);
              
              	GotoState('WLGameInProgress');
              }
              
              function WanderlustSendMessage (string SendThisString)
              {
                  Log(SendThisString);    // Write our log message
                  TextToSpeech(SendThisString, 5 );
              }
              
              state WLGameInProgress
              {
              	simulated function BeginState()
              	{
              		SetTimer((0.5), false);
              	}
              
              	simulated event Timer()
              	{
                      WLStatusString = "Status update";
                      WanderlustSendMessage (WLStatusString);
              		SetTimer((0.5), false);
              	}
              
              	simulated function EndState()
              	{
              		SetTimer(0.0, false);
              	}
              }
              
              function EndGame( PlayerReplicationInfo Winner, string Reason )
              {
              	super.EndGame( Winner, Reason );
              }
              
              defaultproperties
              {
              	MaxLives=1
              
                  GameName="Wanderlust"
              	Description="Do you have the Will to Wander?"
              	Acronym="WL"
              
                  DeathMessageClass=class'XGame.xDeathMessage'
                  ScreenShotName="UT2004Thumbnails.DMShots"
                  DecoTextName="XGame.Deathmatch"
              
              }
              As you can see he recommended that I put the timer in a state within my gametype. Here's what the log gives me...

              Code:
              Log: Browse: DM-1on1-Albatross?Name=Player?Class=Engine.Pawn?Character=Jakob?team=255?game=Wanderlust.Wanderlust_Game
              ScriptLog: No loading hint configured for  Wanderlust_Game
              Log: Collecting garbage
              Log: Purging garbage
              Log: (Karma): Level Karma Terminated.
              Log: Garbage: objects: 39702->35729; refs: 540838
              Log: Game class is 'Wanderlust_Game'
              Log: Bringing Level DM-1on1-Albatross.myLevel up for play (0) appSeconds: 36.994000...
              Log: (Karma): Autodetecting CPU for SSE
              Log: (Karma): Using SSE Optimizations
              ScriptLog: GameInfo::InitGame : bEnableStatLogging False
              ScriptLog: Initializing the Wanderlust Game
              ScriptLog: PreBeginPlay
              ScriptLog: PostBeginPlay
              Log: Spawning new actor for Viewport WindowsViewport
              Warning: PlayerReplicationInfo DM-1on1-Albatross.PlayerReplicationInfo (Function Engine.PlayerReplicationInfo.PostBeginPlay:0048) Accessed None 'GameReplicationInfo'
              ScriptLog: New Player Player id=2ae48f93318bca881b441ae441b4c490
              Log: Precaching: DM-1on1-Albatross.LevelInfo0
              Log: Static mesh batches: 2899008 vertex bytes, 402048 index bytes
              Log: Allocating 16384 byte dynamic index buffer.
              Log: Allocating 72576 byte dynamic index buffer.
              Log: Finished precaching geometry in 1.520 seconds
              Log: Finished precaching textures in 1.045 seconds
              Log: appRequestExit(0)
              Exit: Preparing to exit.
              It's not getting into my state at all :-/ it gets to PostBeginPlay function though... Once again out of ideas...

              Comment


                #22
                Right, looking at the source http://wiki.beyondunreal.com/wiki/UnrealScript_Source

                (If you didn't already get the source, it's well worth it for problems like this)

                GameInfo contains

                Code:
                /* Initialize the game.
                 The GameInfo's InitGame() function is called before any other scripts (including
                 PreBeginPlay() ), and is used by the GameInfo to initialize parameters and spawn
                 its helper classes.
                 Warning: this is called before actors' PreBeginPlay.
                */
                event InitGame( string Options, out string Error )
                {
                    local string InOpt, LeftOpt;
                    local int pos;
                    local class<AccessControl> ACClass;
                    local class<GameRules> GRClass;
                	local bool bIsTutorial;
                
                    InOpt = ParseOption( Options, "SaveGame");
                    if (InOpt != "" && CurrentGameProfile == none)
                    {
                        CurrentGameProfile = LoadDataObject(class'GameProfile', "GameProfile", InOpt);
                
                ...
                    SetGameSpeed(1.0);
                ...
                }
                
                ...
                
                //
                // Set gameplay speed.
                //
                function SetGameSpeed( Float T )
                {
                    local float OldSpeed;
                
                	if ( !AllowGameSpeedChange() )
                	{
                		Level.TimeDilation = 1.1;
                		GameSpeed = 1.0;
                		Default.GameSpeed = GameSpeed;
                	}
                	else
                	{
                		OldSpeed = GameSpeed;
                		GameSpeed = FMax(T, 0.1);
                		Level.TimeDilation = 1.1 * GameSpeed;
                		if ( GameSpeed != OldSpeed )
                		{
                			Default.GameSpeed = GameSpeed;
                			class'GameInfo'.static.StaticSaveConfig();
                		}
                	}
                    SetTimer(Level.TimeDilation, true);
                }
                ...
                function Timer()
                {
                	local NavigationPoint N;
                	local int i;
                
                    // If we are a server, broadcast a welcome message.
                    if( bWelcomePending )
                    {
                		bWelcomePending = false;
                		if ( Level.NetMode != NM_Standalone )
                		{
                			for ( i=0; i<GameReplicationInfo.PRIArray.Length; i++ )
                				if ( (GameReplicationInfo.PRIArray[i] != None)
                					&& !GameReplicationInfo.PRIArray[i].bWelcomed )
                				{
                					GameReplicationInfo.PRIArray[i].bWelcomed = true;
                					if ( !GameReplicationInfo.PRIArray[i].bOnlySpectator )
                						BroadcastLocalizedMessage(GameMessageClass, 1, GameReplicationInfo.PRIArray[i]);
                					else
                						BroadcastLocalizedMessage(GameMessageClass, 16, GameReplicationInfo.PRIArray[i]);
                				}
                		}
                	}
                
                    BroadcastHandler.UpdateSentText();
                    for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint )
                		N.FearCost *= FearCostFallOff;
                }
                ...
                There's a bunch of stuff I didn't even bother reading, but you have an event Timer() - event just means a function called by the engine's native code - A SetGameSpeed function that sets the timer rate, and This is called from event InitGame - so I'm assuming InitGame is also hard-wired into the engine. This runs before actors are created, so forget your texttospeech in your debug and just stick with the logfile. (It wasn't till looking tonight at your earlier code that I spotted you were calling super.postbeginplay from within your logging function - very naughty!)

                Comment


                  #23
                  Originally posted by sweavo
                  Right, looking at the source http://wiki.beyondunreal.com/wiki/UnrealScript_Source

                  (If you didn't already get the source, it's well worth it for problems like this)

                  There's a bunch of stuff I didn't even bother reading, but you have an event Timer() - event just means a function called by the engine's native code - A SetGameSpeed function that sets the timer rate, and This is called from event InitGame - so I'm assuming InitGame is also hard-wired into the engine. This runs before actors are created, so forget your texttospeech in your debug and just stick with the logfile. (It wasn't till looking tonight at your earlier code that I spotted you were calling super.postbeginplay from within your logging function - very naughty!)
                  The texttospeech is only there so I can hear it in real time when it happens in-game. I find it handy so I don't have to read the screen hehe. I read the log afterward. The super.postbeginplay has been removed from the logigng function but there's no change in the behavior. I'm stuck as a spectator and my state never begins so my timer never begins.

                  Comment


                    #24
                    Originally posted by KrisWood
                    The texttospeech is only there so I can hear it in real time when it happens in-game. I find it handy so I don't have to read the screen hehe. I read the log afterward. The super.postbeginplay has been removed from the logigng function but there's no change in the behavior. I'm stuck as a spectator and my state never begins so my timer never begins.
                    That's fine if the TTS doesn't need the game to have started, I don't know whether it does or not.

                    do you have the sources?

                    Why not start with deathmatch, get it running, then comment out code until you get it down as minimal as you want it?

                    Comment


                      #25
                      Yeah I have the sources, I exported them all via ucc. I guess I could download them too *shrugs* i'll try starting with deathmatch and see what happens.

                      Edit: Oh hey wait, accessed nones are bad right?

                      Warning: PlayerReplicationInfo DM-1on1-Albatross.PlayerReplicationInfo (Function Engine.PlayerReplicationInfo.PostBeginPlay:0048) Accessed None 'GameReplicationInfo'
                      Edit: Well, I didn't fix the access none, instead i made a lot more of them by basing my gametype off deathmatch instead of gameinfo. Still no change in displayed behavior. Then I commented out the GotoState line:

                      Code:
                      //	GotoState('WLGameInProgress');
                      Suddenly my map list is back, my gametype is now showing up in the instant action menu, and I don't have to open maps via command line anymore. I can now also start the match and run around. No timer though yet.

                      Comment


                        #26
                        try putting

                        SetTimer((0.5), true);

                        ( NOTE: true not false! )

                        after where you commented your GotoState

                        Comment


                          #27
                          Ok round two with MarZer:

                          He told me how to call a class from within another class:

                          Wanderlust_Game.uc
                          Code:
                          ...
                          
                          var WanderlustServerTimer m_Timer;
                          
                          event InitGame( string Options, out string Error )
                          {
                          	super.InitGame(Options, Error);
                          
                              WLInitString = "Initializing the Wanderlust Game";
                              WanderlustSendMessage (WLInitString);
                          
                              m_Timer = spawn(class'WanderlustServerTimer');
                              m_Timer.m_game = self;
                          
                              if(bLogDebug)
                              {
                              }
                          
                          ...
                          }
                          and WanderlustServerTimer.uc
                          Code:
                          class WanderlustServerTimer extends Actor;
                          
                          var float timerInterval;
                          var Wanderlust_Game m_game; //adjust names accordingly - pointer to the game info, fill it from the game info when you spawn this actor
                          
                          function PreBeginPlay()
                          {
                          	super.PreBeginPlay();
                          	SetTimer(timerInterval,true);
                          }
                          
                          function Timer()
                          {
                          	if (m_game == None)
                          		return;
                              Log("Time");    // Write our log message
                              TextToSpeech("Time", 5 );
                          	//message code, I would have it call a ServerTimer() function on your gameinfo using the pointer
                          }
                          
                          defaultproperties
                          {
                          	timerInterval=0.5
                              bStatic=true
                              bNoDelete=false
                              bHidden=true
                          }
                          He recommended spawning it as an actor instead of including it as a state in my game info because:

                          MarZer: you can do both, but when your game info gets more complicated messing with states will get very annoying and confusing
                          So we puzzled it out and now it repeats the word "time" infinitely once every half second while I run around in whatever level. Progress! \o/ So now the question is, I either need to be able to pass arguments to the timer so it can send the messages, or I need to be able to have the timer return an elapsed time, and upon those time updates have the Wanderlust_Game class send messages to the irc.

                          Comment


                            #28
                            just a tip u cant spawn a
                            bStatic=true object

                            Comment


                              #29
                              Wow, good call B!G-A. I was wondering why it stopped working all of a sudden lol. I've now got it sending the time updates to my main game info class. I think I'm ready to give it somewhere to send the info at last!

                              Comment


                                #30
                                Don't see why you need a separate timer - should work right there in the GameType

                                Comment

                                Working...
                                X