Announcement

Collapse
No announcement yet.

Inability to call RPCs on unowned objects encourages ugly god class pattern

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

    Inability to call RPCs on unowned objects encourages ugly god class pattern

    This is something I've noticed time and time again, so I'm interested in how other people are handling this for their projects.

    Our most recent example this this:
    - We have a procedural sky actor in the level
    - It has a dynamic day cycle that can be toggled
    - Every client with permissions is supposed to be able to toggle it

    So, the most obvious solution in my opinion would be:
    - Create a "ServerAny" RPC on the sky actor, that takes the calling player controller and a bool
    - Have the client call this
    - Verify whether the calling client had permission to do this
    - Update the sky state

    However a ServerAny RPC does not exist in the engine, and no client owns the sky, so we have to resort to this nonsense:
    - Add another RPC to the player controller
    - Have the client call this
    - Search for the sky on the server side and continue as above

    Anyone have comments on this?
    Last edited by Zeblote; 06-23-2018, 10:46 AM.

    #2
    I think the intended design is that any interaction the player has with the server ought to go through the controller or the pawn, which is fine on its own. But your situation is not invalid due to this as there is a similar problem with that setup, namely if the server wanted to change the time of day, that'd have to be an RPC or replicated variable on the game state, it couldn't be something on the sky actor, which is an issue.

    Comment


      #3
      Originally posted by DamirH View Post
      But your situation is not invalid due to this as there is a similar problem with that setup, namely if the server wanted to change the time of day, that'd have to be an RPC or replicated variable on the game state, it couldn't be something on the sky actor, which is an issue.
      Not necessarily, a replicated variable or multicast RPC works fine on unowned actors. My problem is that I can't send anything the other way without adding an unnecessary indirection through the player controller (which is really filling up with all sorts of garbage passthrough rpcs)

      Comment


        #4
        I guess it depends on what your definition of 'unnecessary indirection' is. As Damir says, in terms of how it works under the hood, this is a design decision. Presumably though your issue is more related to keeping code clean and separating concerns? If so, I think you could encapsulate the indirection using a component or subobject. Disclaimer - I don't know much about UE4 networking.

        Say you create a component (or just UObject) for dealing with time of day related server comms. Put any RPCs on it, and stick it onto your player controller so it should be RPC-capable. That should clean up your PC class a bit. Then if you want, you can implement the ideal solution you outlined, where a method exposed on the sky actor internally just finds the comms object on the PC you passed in, and calls the relevant RPC. You could encapsulate permissions as part of this too, by only adding the permitted comms objects to a given player's controller.

        More boilerplate than ideal, but I think it would make things a bit cleaner.

        Comment


          #5
          It has come up a few times when dealing with the simple client to server input where I feel using a gameplay ability or dedicated RPC function on the player controller would be a waste.

          In these cases, I have just resorted to creating input proxy actors who's sole job is to pass client input to the server.

          For example:


          For any serious actions, I do go back to the player controller or gameplay ability system.
          Rule#21: Be polite, be professional, but have a plan to kill everyone you meet.

          Comment

          Working...
          X