No announcement yet.

clientside actors [partially solved]

  • Filter
  • Time
  • Show
Clear All
new posts

    clientside actors [partially solved]

    Thanks & Credits to: meowcat, Poker, porkmanii and the WIKI
    __________________________________________________ _____________________________________


    Some things that are important for code that should be executed clientside.
    This is for a mutator example, so it might not fit all situations.

    simulated functions example:
    // needs a function that is already simulated.
    // Tick() for example. Bad example, this will
    // _flood_ your log files.
    simulated function Tick(float deltatime)
            // we call our own simulated function:
    simulated function LogSomething()
    	// code in here gets executed on client AND server:
    	Log(" Something, NetMode: "$Level.NetMode,'SomeClass');
    default properties:
         RemoteRole=ROLE_SimulatedProxy    // at least. 
         bAddToServerPackages=true    // not needed if you add it manually.

    for quickly starting a netplay test setup on one computer you can create batchfiles:

    one batchfile for starting the server:
    @echo off
    :: starting a dedicated server
    ucc server dm-1on1-idoma?MinNetPlayers=0?Mutator=xGame.NoAdrenaline -log=UT2004server.log
    Note 1: to stop the server you can press control-C ( strg-C in other countries ). That is, if you called the
    batch file from a command-prompt-window (start->execute->cmd) and this window is the active window.
    Note 2: the "pause"-command is recommended, so in case you get errors, the window doesn't close right away.
    Note 3: you can easily create different ini-files, in order to use them here. Same goes for Log file names.
    Note 4: to those that make lots of batch files: "::" is a quicker way for marking out things than "rem", just so you know

    another batchfile for starting the client:
    @echo off
    :: connecting to your server
    ut2004 -ini="UT2004.ini" -userini="User.ini" -log=UT2004client.log -newwindow

    starting command shells:

    To quickly access the command prompt window and set it to the right path you can make
    a new desktop link and edit its properties. Change the following lines:

    Note that you could also create a shortcut here.
    __________________________________________________ _____________________________________

    Still got some problems to solve... See last post if you'd like to help me.

    adding those default properties into your mutator should work. Just make certain that your tick function is simulated. Here is a bit of code I use to add a special interaction to the local player in my mod
    simulated function tick(float dt){
        local PlayerController PC;
        local VisionInteraction myVision;
        PC = Level.GetLocalPlayerController();
        if ( PC != None){
            myVision = VisionInteraction( PC.Player.InteractionMaster.AddInteraction("yarm.VisionInteraction", PC.Player) );
            if ( myVision !=none) myVision.enable_Vision(bUseTherm, bUseNVG, bUseMotion);


      Originally posted by meowcat View Post
      adding those default properties into your mutator should work. Just make certain that your tick function is simulated.
      Just to clarify, remember that declaring "simulated" won't prevent the code inside Tick() from running on the server ... to do that you'll still need put your client-only code inside a (Level.NetMode != NM_DedicatedServer) check.

      Meowcat's code works because this check is performed within the call to Level.GetLocalPlayerController(), which returns None if the machine is a dedicated server, in which case the rest of his Tick() code isn't executed.

      There are other ways of getting client-only actors to work that don't involve empty Tick() calls, depending on what exactly you're trying to do.


        Thanks for the answers.

        Well basically I just need to spawn an actor on each client, with the localPlayer as its owner.

        When spawned, this actor sets its location to that of its owner.

        Plus it does spawn further actors... which themselves also should be client-side only.

        edit: i.e. what roles should these actors have? They don't need anything replicated... RemoteRole=Role_None for all?


          Originally posted by fftunes View Post
          edit: i.e. what roles should these actors have? They don't need anything replicated... RemoteRole=Role_None for all?

          As for running dedicated server and client on the same machine, I've never had any problems. How did you start the server, and try to connect? A simple example (which should work, off the top of my head) is:
          ucc server DM-Antalus
          (Though this won't work as is in a batch file - it'll wait for the server to shut down before opening the client!)

          Also, if you need to open two game windows (i.e. test a listen server and client), run the game with the -newwindow switch (and optionally -windowed). E.g.:
          ut2004 -newwindow -windowed
          (From a command prompt, or as the target of a shortcut.)


            cool, thanks a lot!

            Well, when thinking about it... i just tried once in a hurry, and as i have these things in a custom gametype, i probably didn't adjust the gametype filter tab...

            EDIT: i'm glad i can correct myself: there is no gametype tab in the lan server browser...
            Still got to try it via command prompt... will post back.

            still, thanks again for your help.


              ...eventually i found out how to set up ded&client on one machine... (thanks a lot porkmanii for your tips)

              However I can't spawn my actors on the client... i imagined this would be easy try & error about roles... but .

              I'd like to use two ways (i.e. for different actors with different purposes):

              One needs to spawn with every playerpawn, so i'll use a modifyplayer;
              While the other needs to be spawned once per client, so i'm about to abuse tick.
              So it looks something like this (quickly rewrote it from top of my head, just to show what i'm about):

              class myMut extends Mutator;
              var anotherDummy thatDummy;
              simulated function ModifyPlayer(Pawn Other)
              simulated function Tick(float deltaTime)
                  if( thatDummy != none ) return;
                  thatDummy = spawn(class'anotherDummy');
                  if( thatDummy == none ) Log("Spawning failed",'myMut');
              class testDummy extends Actor;
              simulated function PostBeginPlay()
                  Log(" WOOT I LIVE "$string(Level.NetMode),'TestDummy');
              the classes i want to spawn are fully working, everything works flawless in instant action. i just started using testdummies, which do nothing else but log, to find out how i can make this work in netplay... so in order to exclude any possible issues, i made everything as simple as possible for now... but:

              SO FAR i only got them to spawn on the dedicated server itself - which is the contrary of what i want.
              I don't remember the exact roles i have set at the moment...
              What are the correct Roles/RemoteRoles for the mut/dummies, and/or are there other ways to solve this?

              Note: i wouldn't want to extend them to inventory... one of them would probably work, but not the other...

              Thanks a lot for any help.

              EDIT: wee, i guess i'm stupid... don't hurry, i've got another hint for now...


                The Mutator should be RemoteRole=ROLE_SimulatedProxy, so that simulated functions may execute. It should also have bAlwaysRelevant=True, otherwise it may not always exist on each client. (I think because it's invisible and not owned by any player, it would never be relevant if bAlwaysRelevant==False.)

                Please note: marking a function as "simulated" does not automatically make it execute on the client. It may allow it to be executed on Simulated Proxies, but the function still needs to be replicated (using a replication statement.) In the case of Tick (and other native-caused events, such as PostBeginPlay), the client triggers it client-side, so there is no need for replication.

                Replication statements can only be written for functions/variables declared in the current class (not parent classes), so you cannot make ModifyPlayer replicated.

                Additionally, function calls can only be replicated between the server and the client which owns the actor, not any other clients.

                Looking at your code, I'd say anotherDummy doesn't work because the Mutator is never relevant to clients (doesn't exist), and testDummy doesn't work because ModifyPlayer is only executed on the server. If you want to spawn them client-side, they should have RemoteRole=ROLE_None. (RemoteRole only applies to the client when the actor is spawned on the server.)

                UnrealWiki: Simulated Function may be of some help.


                  Thanks for your patience, porkmanii...

                  I think i read the wiki all over... i'm really really lost.
                  So i made another quick test.
                  According to the wiki, this should work:

                  class mutSimTest extends mutator;
                  simulated function Tick(float deltatime)
                  simulated function logsome()
                  	//according to the wiki, code in here should get
                  	//executed on client AND server:
                  	Log(" #### HOORRAAYY #### ",'mutSimTest');
                  	Description="this is just a test"
                  However this doesn't log anything to the client's log file (please don't tell me i need a special command to log to a client).
                  As for the testdummies, i think i tried every Role on them... nothing worked.
                  The mutators always had bAlwaysRelevant==true, and RemoteRole==ROLE_SimulatedProxy... (<- tried others as well, just to make sure)

                  I'm really really lost here.


                    What about ServerPackages? It should either be in the ServerPackages list, or have bAddToServerPackages=True (in the mutator.) If it has neither, the client won't load it, so the server won't be able to replicate the mutator or any other actors in the package.


                      dang! _now_ i feel stupid...

                      btw thanks a lot for clearing my modifyplayer issue... which leads me to the next question: what would be the most common (netplay-)way to catch each player, like a modifyplayer would?

                      PS: this thread is not yet about the real issue i have with one of my actors... I really just cut it out from my gametype to release it as a single mutator... to get you guys to help me... sorry about all the inconvenience. Your help is highly appreciated.

                      EDIT: I try to describe the new issues i've got... thanks to everyone who's patient enough for reading this...

                      Now that i've got my actors to spawn clientside, i learned that they "don't know" about pickups in the map.
                      My first guess was that the client doesn't know about pickups and everything was done & decided by the server...
                      But on second thought: The client can "see" the pickup, so i'm not so sure anymore about the pickups "not being"
                      on the client at all... (???) next guess is that they are handled in Level or LevelInfo. I'll post back about this.

                      However, so far i only tried replicating the related function.
                      The myFunction contains code that needs access to the pickups.
                          reliable if( bNetOwner && Role<ROLE_Authority )
                      It compiled fine but it did not what i wished for... still on it. See ya