My evolving experience with UE4

I’ve decided to put up this thread as a kind of blog of my experiences dealing with UE4 4.7.6, to document what it’s like from a users perspective. I know Epic gets lots of feedback on individual issues, but I’m hoping that a more cohesive account helps them identify issues.

Good work Epic on getting things this far! I’m sure it’s a hell of a job, and I don’t envy you at all. Unfortunately from my experience with UE4 to date it’s been incredibly frustrating. I have a reasonably strong programming background, and have used UDK and also UE4 before, not to mention Unity and other platforms, so I have some idea of how things work. I know that some of the issues I’m experiencing are due to unfamiliarity with the way things work, but I feel that there are a lot of other issues that aren’t due to that.

If anyone wants to comment or throw their own issues into this thread, feel free.

So, the project I’m working on is a multiplayer game set in space. At this stage I have the basics of multiplayer in, and the player pawn replicates between the server and clients fairly well. Understanding how the client/server model worked wasn’t too bad. For the most part things worked as described in the documentation so congrats to whoever worked on that.

One thing that would have made my life easier would be the ability to just call a function in the actor like BroadCastIntToAllReplicated(uint32 value) - that would send the int to all instances of the object, even when called from a client. As it is I created my own set of functions (well, 3 actually because you can’t do it in less between the method, implementation and validate). I use it to broadcast state changes and use an Enum with things like DISPLAY_FORCEFIELD_OFF, etc.

The documentation in general I find difficult to work with, because it’s very heavily blueprint biased. As a programmer this isn’t much use to me. IMHO it would be better to split up the documentation into two separate areas, one for C++ and the other for blueprints. I’m also not a huge fan of having things so fragmented between the main documentation / answer hub / wiki / forum. I’d personally prefer to just have a well-maintained set of core documentation for each release and the forum. I would have expected the Wiki to feature more heavily, but I must admit when I search for things it rarely comes up in the list.

Another issue i’ve found with the documentation is because of the fairly rapid release cycle, and fairly major changes in core ways of doing things between releases, anything you find is often outdated. So if I find some documentation, I have no confidence in it. What this means is that if I find something, try it, and it doesn’t work, it’s hard to know where to start looking to fix it. If I had faith in the documentation, I would know it’s far more likely to be my own code that is the issue, and invest heavily debugging there. For most software that approach works well. Occasionally you’ll come across a bug in the documentation or the code, but thats less that 1% of the time. Now I find I can spend a day debugging my own code, only to find out that something in the engine code had changed and the code I was using was no longer the correct way of doing things. So I have to try and go down both pathways at once, which instantly halves my efficiency. Actually, its more than two paths, because I’ll often find that restarting the editor, or rebooting the computer fix issues. So I don’t know if the error is my code, outdated documentation, mismatch between my code and whats running in the editor, or just some odd memory problem that gets fixed by rebooting.

So now I have an issue where the playerpawn on the server doesn’t move if i test it with PIE. This happens about 50% of the time, otherwise it works fine. Doesn’t happen in the standalone game. So now I guess I’ll just have to do all my testing that way, but it means less debugging info and a longer round trip time.

I have asteroids that interact with a force field on the player ship - basically it just looks for overlapping actors and applies a force to them. What seems to be happening is that the field actor is receiving overlap events - I draw a white sphere on screen to visualise this. Yet even though it’s getting overlap events GetOverlappingActors() is returning an empty list. Also the overlap events only seem to be occurring on the server, not on the clients.

And periodically they all go to sleep and stop receiving events at all. This seems like strange default behaviour.

Update: If I just keep nudging the asteroid, to keep everything awake (I’ll try and fix that later), then it seems that I do indeed get the ReceiveActorBeginOverlap being called on both client on server. But on the client, GetOverlappingActors() always returns an empty list. Now I have a choice. I can either try and figure out whats happening the in underlying Epic code, which might be quick, or could take days. Or I can just write my own implementation that does what I would expect GetOverlappingActors() to do. That might take 30 mins, but would be a reliable solution without any hidden behaviour.

Why not use replicated variables? Then all you need to do is tell the server when the client wants to change that variable with a server UFUNCTION. If you handle state changes on the server side then you just set the variable and it gets replicated to all. I’m guessing you have some input key setup on the client to turn off the forcefield, in that case you would need 3 functions: Input function, ServerXXXValidate and ServerXXXImplementation along with the replicated variable. If you looked to see how Epic handles this in the generated code and on the backside then you’ll understand why it is done this way.

Documentation is always a problem no matter which software you use. Let’s face it, software guys don’t like to write documentation and then it has to go through tech edit and quality control, etc. In the game development world, we just don’t have time for that and what documentation is there has been good for us so far because we have the engine source code. I know what you mean about the bugs in the code. I’ve discovered at least 13 and all have been confirmed and I’ve only been using UE4 since last August. The best thing a person can do is grab the github source, find the bug, fix it, and submit a pull request so that it will get fixed. If I don’t have the time to fix it then I just give Epic as much information as possible and sometimes even give them simplified sample projects so that they can fix the problem. Sometimes in doing the simplified project I discover that the issue was actually my fault due to not understanding the engine. Perhaps you may want to do the same with your issue below.

What is the collision like on your Pawn? Can you create a simplified project where you can demonstrate this issue? Then 7-zip it all up but exclude the Binaries, Intermediate, and Saved folders and do not include any of the visual studio files, they can be generated from the uproject file.

Hi ! Thanks for you help here and in other threads.

Why not use replicated variables? Then all you need to do is tell the server when the client wants to change that variable with a server UFUNCTION. If you handle state changes on the server side then you just set the variable and it gets replicated to all. I’m guessing you have some input key setup on the client to turn off the forcefield, in that case you would need 3 functions: Input function, ServerXXXValidate and ServerXXXImplementation along with the replicated variable. If you looked to see how Epic handles this in the generated code and on the backside then you’ll understand why it is done this way.
[/QUOTE]

You guessed correctly, the local player sets a variable via inputs that I need to propagate to all other instances. I have currently done what you suggest, with the 3 functions. It just seems like a lot of work for something that must be a common issue. I’m guessing everyone ends up writing the same functions, which seems like a waste. I’m not sure exactly why it has to be this way, but if it does I’ll believe you :slight_smile:

Documentation is always a problem no matter which software you use. Let’s face it, software guys don’t like to write documentation and then it has to go through tech edit and quality control, etc. In the game development world, we just don’t have time for that and what documentation is there has been good for us so far because we have the engine source code. I know what you mean about the bugs in the code. I’ve discovered at least 13 and all have been confirmed and I’ve only been using UE4 since last August. The best thing a person can do is grab the github source, find the bug, fix it, and submit a pull request so that it will get fixed. If I don’t have the time to fix it then I just give Epic as much information as possible and sometimes even give them simplified sample projects so that they can fix the problem. Sometimes in doing the simplified project I discover that the issue was actually my fault due to not understanding the engine. Perhaps you may want to do the same with your issue below.
[/QUOTE]

Fair enough that people don’t like doing documentation, and there can be a lag. If this was a FOSS project then I’d understand, but this is a commercial product, and not without competition. I’m guessing that their marketing strategy is to make it free so that there are lots of people with experience with their engine, which will make it more popular for game devs to use. However, in order to retain people, you really need to make it as smooth a learning curve as possible, otherwise it will work against you. Apart from that side of things, I imagine it would be much more cost effective to create up to date documentation rather than have people answering AnswerHub and forum posts about the same topics. I think most people will try and solve problems on their own if there is documentation.

What is the collision like on your Pawn? Can you create a simplified project where you can demonstrate this issue? Then 7-zip it all up but exclude the Binaries, Intermediate, and Saved folders and do not include any of the visual studio files, they can be generated from the uproject file.
[/QUOTE]

Thanks for letting me know what I need to include - that will simplify things. Unfortunately I don’t have time to do that atm - but if I get completely stuck I will.

It seems that ReceiveActorBeginOverlap is followed immediately by ReceiveActorEndOverlap - so when my Tick gets called there are 0 overlapping actors, even though both of the overlapping actors are stationary. What I want is a list of actors overlapping my actor, and I don’t understand why a function called GetOverlappingActors() doesn’t do that for me.

Everything except for Physics pretty much happens within a Tick. Even on the dedicated server, if you set a variable to true and then later to false in the same Tick the clients will never be updated about those because the state before and after all of the Ticks were exactly the same. Regarding your overlapping actors issue, I have had similar cases. It would be best for you to handle your own list of overlapping actors. In the BeginOverlap add those to a


TArray<AActor*> OverlappingActors;

that you store in the class. In your Tick function iterate over that list like this:



...Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);
    for (AActor* Actor : OverlappingActors)
    {
        //Do something with Actor
    }
    OverlappingActors.Empty();
}


I would then forget about the EndOverlap unless you wanted to do something specific in that case. You must have some small overlapping objects and some fast moving objects/projectiles triggering them. Basically, they are firing both the Begin and End in the same Tick and by the time you get around to calling it in your Tick it is no longer overlapping. Actually UE4’s projectiles do some sub-stepping (meaning sub-Tick calculations).

Success!


MiningActiveComponent->GetBodyInstance()->OverlapMulti

Does the trick, and also doesn’t suffer from the problem of the components going to sleep or not responding until hit. I’m still deeply hurt and offended by the behaviour of GetOverlappingActors() and our relationship will never be the same. ReceiveActorBeginOverlap and ReceiveActorEndOverlap are also on thin ice.

Thats a good idea . I tried something similar but I was removing actors from the list when EndOverlap was called. Clearing it each tick and keeping a list of any overlapping actors in the interval is a good solution. Not sure it would help me with things falling asleep though.

A few more issues I’ve encountered:

If I create a custom collision profile in the .ini via the editor interface it fails to show up in the list of presets where you can edit them. It’s in the file ok, and even after restarting it fails to show up. It does show up in the list of presets attached to objects though, I just can’t view or edit it again except via the .ini file.

For this next one I’m happy to concede there may be a good reason for it, but I just can’t see it. As I mentioned I have a network game, and need to send messages between various instances of objects. My understanding is that a SimulatedProxy can’t call server functions, so if something happens to the Proxy that I want to tell the other worlds about, I have to create a function in my PlayerController class or something similar, then get that class to send a message to the server, which can then multicast. I think I read somewhere that is what Epic does as well. It would make my code a lot more self contained and modular if I could keep all of the functions in the same class. Not a deal breaker, just inconvenient and a bit of a gotcha when you first start out.

I’m not sure about the ini file, but look at the Shooter Game sample project. They use custom presets as far as I can remember. You can see how they set them up.

Regarding the simulated proxy issue, only the Owner can call server functions and only the server can tell all of the clients about something that has occurred. What are you exactly trying to do? I have yet to see or think of a use case where the owner or the server cannot handle it and why another client would have to handle it. Can you explain your use-case a bit more?

Thanks , the issue is not so much setting them up, it’s just seems to be a bug in the editor that I can’t edit them once created.

I have asteroids in the level that are a part of the level and are replicated. If one of the client versions gets hit by something I want to notify the other asteroids of this. However because they are proxies I can’t do it directly.

Why wouldn’t you just have the server handle all of this and just notify the clients? Like I said before, I don’t know of any use case that would require you to do it a different way.

Well lets say that in one world, a local player grabs the asteroid, while on the server, because of slightly different positions the asteroid flies past the player. I could just leave it to the server to be the authority, but I think the game experience suffers. I think it’s much better to give a sense of responsiveness to local player actions, so I would like the local version to be the authority in that particular case. I have tried leaving it to the server - for instance creating a pickup object. The player collides with the pickup on the server, which then spawns an object on the server and on the clients. You run into the same issue of collisions feeling slightly “off”, and if you have a high ping of > 100ms then it feels distinctly wrong somehow. As a player I feel distinctly cheated if I do something that should trigger an action and it doesn’t happen because the server version is different to the world I’m seeing.

I can accept that my particular use may be unusual, and I don’t think this is a bug or missing feature as such, but I don’t think that some sort of reverse replication (client -> server-> all clients) would be such a bad option to have. I guess if Epic say that’s what they do as well, then clearly there must be other scenarios this would be useful.

It may create a lot of traffic (unless you decrease net priority and other things) but aren’t the locations and rotations of the asteroids replicated? I’m not sure what the point of the asteroids would be, but to me it sounds like it may be important to gameplay, hence something only the server should be the authority on. If you are having problems with smoothing out the movements you’ll have to read up on client-side prediction and/or smoothing. Specifically for AActors look at any of these to override in your Asteroid class. You can then interpolate to the new positions.


	/** update location and rotation on client */
	virtual void PostNetReceiveLocationAndRotation() override;

	/** update velocity on client */
	virtual void PostNetReceiveVelocity(const FVector& NewVelocity) override;

	/** update physics state on client */
	virtual void PostNetReceivePhysicState() override;

You still see where I don’t see where you should be doing that from the client?

Hi ,

Thanks for posting those functions. Despite reading the networking documentation I hadn’t come across those before. Could be I missed it, but again things like that would be great to have in some formal documentation. I can see how they would be very useful for server->client replication. I guess our misunderstanding is that I have a genuine use for client->server replication where a particular client can become the authority temporarily. As for the traffic I have limited the update frequency to avoid issues.

I guess that brings me to something else I’ve noticed: I tend to try and avoid using the UE4 functions where possible, especially for things I can code myself and have complete control over. Take that Overlap example above - I wasted a lot of time on the underlying GetOverlappingActors function which I ultimately abandoned. Same with the physics. Most of that time was lost because the underlying UE4 functions didn’t work as advertised. Those experiences are incredibly frustrating and very costly time-wise, and I find myself doing everything I can to avoid them.

This is just about my experience though, and I’m hoping it will provide Epic with some idea of what it’s like to work with UE4 from the outside. If anyone wants to chime in and agree/ disagree with anything I’ve said, or share their own experiences feel free.

Oh yeah, I just remembered another reason I’m not using the inbuilt replication code - it doesn’t replicate physics (although I know has a demo of getting it to work somewhere)

Sorry, what do you mean by this?

Hi . I was under the impression that physics didn’t replicate well - as in it was a fairly clunky, or things were often in very different spots on the server vs client. However, I just went back and had a look - especially at this post:

And I must have read it incorrectly. Looks like it does work. I’ll have to give it a go and see how it feels. Ooops.