Spawn actor in networked game: noticeable delay when lag is high

I have an actor called Explosive and it uses physics simulation (I know, bad, but I always can change it to projectile movement).
When lag is 0 literally everything is fine: I can shoot Explosives, they work cool.
When lag is 200-300 ms then I can notice significant delay between LMB and actor spawn, what is pretty much expected in the way I’am doing it.
If for bullets (there is also bullets, but they are not an actors) I can prespawn “fake” bullet and I don’t even need to have any linkage with server ones, then I don’t know what to do with Explosive.
I need to spawn them instantly on client, send message to server that it also need to do that, resimulate them on server and bind server and client together… Sounds mad.
There is one solution I know, but I’am 100% sure that there is much more elegant solution that this one:
Spawn local actor on client and also send message on server, then when server’s Explosive appears on client machine delete local Explosive. This will take much of code to do that…
In short, how to spawn actor on server with instant feedback on client? or How to spawn replicated actor without significant delay in networked games?

I have the same problem, if you have a solution, can you comment here?

There is, but you will not like it.
There should be a gun, that looks after the projectiles it has created.
On client it should first send the shot data (basically info about how the projectile was fired) and spawn the projectile locally and save the pointer to it into some array. On client it does nothing except flying, obviously.
On server, on the other hand, when server receives client’s wish to fire the projectile it launches:

  1. Non-replicated actual projectile that deals damage and sends to everyone, except to the client that fired it, message to create cosmetic projectile, just like the one that client-initiator has created earlier locally;
  2. Replicated actual projectile which’s movement is replicated among clients, but is not replicated to the client-initiator.
    I would prefer the option number 1, since it does not make mess between actual projectile (which is invisible, actually) and just cosmetic one in a single actor class, and it’s easy to send RPC to everyone – the owning client will just not spawn it since it (the client) already has one.
    The second option is possible, but it makes code a little bit more difficult to understand, since the flow of a single actor divides between having it as a true one and as a fake one.
    I would recommend using image of an actor, it’s fake and approximate representation for everyone, that is so much easier to handle.
    Of course, while the projectile is in scene you can make movement corrections if needed by sending messages like “I want to make sure that you know it bounced off the wall here” to the gun actor and the gun, having all projectiles saved in some array, corrects the position of the projectile. And again, if you’re working with images it’s easy to do.
    P.S. Image is when you separate actual position of the object and it’s visible and hittable part. You lose precision, but increase ease of use.
    P.P.S. My English has evolved dramatically since then, daayym…

So what you meant is that the character must have a child actor in which you will call the function for the child to shoot the projectile, since, who will shoot in fact is the client who is the child actor and not you who is the character
or set the projectile to unreplicated for the client, which called and will only be visible to the other clients and to you, you will see the projectile as unreplicated, and if some event that needs to be seen for everyone in the projectile then it defines as replicated and calls the event for everyone, example: Create particle, before it self-destructs.

It would be like an instant lag for all the clients on the server, but it can work, I’ve never tried it before.

Well, it’s not necessary for it to be an actor, it can be component or even simple UObject, the fact is that none of the projectiles is replicated. Switching between replicated and unreplicated is not very good idea, at least because it’s rather uncomfortable way to do this.
The only replicated actor is the gun that shoots: it sends to server messages about shots and receives back messages about events that are happening to the certain projectiles (and makes needed corrections).
Making projectile as an actor might be a good idea, since if the gun gets destroyed the projectile will remain and will self-destruct after a period of time automatically.
You also can do tricky stuff with delay, but it is really tricky: you can slowly interpolate position between what non-shooter client sees (with net lag) and what it would look like on server (with no net lag). Basically you have projectile on server, that is source one, and projectile on receiving client, that is delayed one. Knowing the approximate amount of delay we can simulate the projectile in such way that, for example, in 1 second it will gain the time difference.
Like this: The projectile has been shot, it’s time is 0 on server. Receiving client will see it be launched with a delay, so when server simulated 0.2 seconds, client only got the message and spawned the projectile. But after 1 second projectile’s time becomes 1.2 secs and client’s one also becomes 1.2 secs, because in 1 second it simulated 1.2 seconds of flight time. Might or might not be visible, but reduces the effect of “being hit behind the cover”.
And net lag is the thing you can’t get rid of if it’s present. You have to sacrifice something.