midspace / Space-Engineers-Admin-script-mod

Modding script for Space Engineers with dozens of Admin commands for creating game scenarios or supporting servers.
43 stars 13 forks source link

Sim speed issues with cube placer #138

Open midspace opened 8 years ago

midspace commented 8 years ago

I found this one in single player.

I've got a copy of a complex world, when running it averages about 0.70 Sim speed. Without the Admin mod installed, when I go to place a block the sim speed can slip to 0.67. With Admin mod installed and I got to place a block, the Sim speed tanks to ~0.22.

Spcemarine commented 8 years ago

SP or MP?

midspace commented 8 years ago

I've just had look at this on dedicated server and couldn't reproduce the large sim speed drop. There is a slight drop, but not as horrible and game wrecking as above. So it was only occurring in 'private', which is technically multiplayer.

I may have had Fraps running at the time, but it crashed for some reason.

Spcemarine commented 8 years ago

Ok, now it becomes a little weird. I think it was caused by the FindLookAtEntity there:


        public override void UpdateBeforeSimulation()
        {
            if (_multiplayerActive && MyAPIGateway.CubeBuilder != null &&
                MyAPIGateway.CubeBuilder.BlockCreationIsActivated && MyAPIGateway.Session.Player != null &&
                MyAPIGateway.Session.Player.Controller.ControlledEntity != null)
            {
                var cubeGrid = Support.FindLookAtEntity(MyAPIGateway.Session.Player.Controller.ControlledEntity, true, false, false, false, false, false) as IMyCubeGrid;

and I think we should just add that PAs must be enabled before executing that code. Could you try that? I think on the DS it works better because not all entities are loaded.

midspace commented 8 years ago

This only plugs performance when PA is off. We need a cut down version of FindLookAtEntity, as it does a loop through all entities in game (or at least in the client session) which can be quite a few. It would make more sense to get a list of entities in a small sphere radius, and then do a ray trace for which ones are in front and are of a cubegrid.

Spcemarine commented 8 years ago

I agree that this is not very efficient and I'll work something out when I've got enough time. :D

Spcemarine commented 8 years ago
float range = MyAPIGateway.Session.SessionSettings.GameMode == MyGameModeEnum.Creative ? 105 : 15;
Matrix worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true);
Vector3D startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
Vector3D endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);

var line = new LineD(startPosition, endPosition);

//TODO init var entities

IMyCubeGrid nearestGrid = null;
foreach (IMyEntity entity in entities)
{
    var grid = entity as IMyCubeGrid;

    if (grid == null)
        continue;

    double distance;
    IMySlimBlock block;
    if (!grid.GetLineIntersectionExactAll(ref line, out distance, out block).HasValue)
        continue;

    line = new LineD(startPosition, worldMatrix.Forward * ((float)distance + 0.5f)); // shorten the line
    nearestGrid = grid;
}

return nearestGrid;

This is what I've got so far. At the moment I wonder if MyAPIGateway.Entities.GetEntitiesInSphere(...) iterates through all entities. If it does, it might slow down the process more than directly iterating through all entities as the check if the entity is inside the sphere might be slower than calling grid.GetLineIntersectionExactAll(ref line, out distance, out block). Do you by chance know something about the matter? Further, do you still have the complex world mentioned above? I'd like to see if the code improves the performance and how much it does.

midspace commented 8 years ago

My memory is hazy, but I think GetEntitiesInSphere only went down to grids, not cubes. Probably need to recheck it.

This is a copy of an active server with a lot of entities. Note, it is still set as public. you will have to change it to private (or offline). https://dl.dropboxusercontent.com/u/26211652/Ramblers%20Frontier%20Wars%202015-12-17.zip

Spcemarine commented 8 years ago

I don't really think anymore that it is caused by the Find...(...) method itself as I'm only getting the error at one particular ship and not on every ship. Also it does not make a difference which method I choose, even with the CubeBuilder.FindClosestGrid() method it breaks down to about 0.22. On other grids it'll only drop by about 0.08...

Spcemarine commented 8 years ago

Honestly, I'm at my wits end with this perf issue. It's just so weird! Regardless which method I use the sim speed constantly drops to 0.22 when I'm looking at the ship "Origin". With other ships it's fine and I can't find out anything special about the "Origin". Do you have any idea why the drop differs from ship to ship?

Regardless I think it might make sense to restrict the calculation to a smaller area as it will get more stable even with huge worlds.

Spcemarine commented 8 years ago

Ok, if I remove the wheels from the ship everything is normal, so the wheels are causing the problem. To reproduce it: Just place like 100 wheels on a grid and look at it with building and PAs enabled. I'll try to somehow work around this. I guess it has to do with raycasts on wheels...

midspace commented 8 years ago

Wheels technically don't have owners. Because none of the blocks on that grid have Terminals.

I logged a recent bug with Keen, which I think they fixed, where your own turrets would shoot through the wheels (trying to shoot an enemy) even though the grid it was connected to was owned by you.

Tracing ownership of a grid can be tricky. I'd look at that as the performance issue.

Spcemarine commented 8 years ago

Most likely it's not connected to the ownership. I guess that wheels have a rather complex model so it takes longer to perform the raycast. So instead of using the model we could use the wheel's boundingbox but I have no idea how to get it in an efficient way...