Cargo ships cannot spawn on servers with a limited world size

StarWarsFTW shared this bug 8 days ago
Reported

Good day! I recently helped in fixing a bug in the Torch API for servers that prevented cargo ships from spawning, but some servers still weren't getting spawns. As it turns out, this is related to a world size limit check in the base game - no longer Torch-related - so I'm putting it here.

Whenever a cargo ship spawn event is fired by the game, the Sandbox.Game.World.MyNeutralShipSpawner.Spawn(object senderEvent, MySpawnGroupDefinition spawnGroup) method gets called by the linked event handler. This method takes a randomly selected cargo ship and is supposed to figure out the spawn location, among others. This fails on worlds with a limited size.

The decompiler won't show me your internal variable naming, but the following is the flawed part of this rather long method:

bool flag = MySession.IsWorldLimited();
if (flag)
{
    num1 = Math.Min(num1, (double)MySession.WorldSafeHalfExtent() - (double)spawnGroup.SpawnRadius);
    if (num1 < 0.0)
    {
        MySandboxGame.Log.WriteLine("Not enough space in the world to spawn such a huge spawn group!");
        return;
    }
}
else
{
    using (MyUtils.ReuseCollection<MyPlayer>(ref MyNeutralShipSpawner.m_playersBuffer))
    {
        MySession.Static.Players.GetOnlineHumanPlayers(MyNeutralShipSpawner.m_playersBuffer);
        int randomInt = MyUtils.GetRandomInt(0, MyNeutralShipSpawner.m_playersBuffer.Count);
        int num2 = 0;
        foreach (MyPlayer myPlayer in MyNeutralShipSpawner.m_playersBuffer)
        {
            if (num2 == randomInt)
            {
                if (myPlayer.Character != null)
                {
                    start = myPlayer.GetPosition();
                    MyLog.Default.WriteLine(string.Format("SpawnCargoShip event picks player '{0}' out of {1} online.", (object)myPlayer.Identity?.DisplayName, (object)MyNeutralShipSpawner.m_playersBuffer.Count));
                    break;
                }
                break;
            }
            ++num2;
        }
    }
}
double num3 = 2000.0;
Vector3D vector3D1;
BoundingBoxD spawnBox;
if (flag)
{
    spawnBox = new BoundingBoxD(start - num1, start + num1);
}
else
{
    MyNeutralShipSpawner.GetSafeBoundingBoxForPlayers(start, num1, out spawnBox);
    double num4 = num3;
    vector3D1 = spawnBox.HalfExtents;
    double num5 = vector3D1.Max() - 2000.0;
    num3 = num4 + num5;
}
Vector3D? nullable1 = new Vector3D?();
for (int index = 0; index < 10; ++index)
{
    nullable1 = Sandbox.Game.Entities.MyEntities.TestPlaceInSpace(new Vector3D?(MyUtils.GetRandomBorderPosition(ref spawnBox)).Value, spawnGroup.SpawnRadius);
    if (nullable1.HasValue)
        break;
}
if (!nullable1.HasValue)
{
    MyNeutralShipSpawner.RetryEventWithMaxTry(senderEvent as MyGlobalEventBase);
}
else
{
    // Continuation for when a position was successfully selected
}
As you can see in this rather long snippet, the boolean variable "flag" is raised whenever the world size is limited.

At the end, there is a loop of 10 iterations broken whenever a suitable spawn position is found on the surface of "spawnBox" - a BoundingBoxD around a selected player. I'm not sure why there is a condition related to "flag" here, but in both cases, the "spawnBox" is ultimately created based on the "start" position.

The "start" position is initialized to a zero vector (corresponding to 0,0,0 coordinates, the middle of the EarthLike planet on the Star System world, which most of our servers use) and never changed due to what looks like an unintended else clause for the conditional related to "flag" right at the start, which is presumably intended to limit the bounding box size.

The world size being limited therefore causes the Spawn method to never pick a player to spawn around, never pick a position to center the spawnBox around and therefore try to pick a spawn location based on a spawnBox in the middle of the Earth.

I presume this is done under the assumption that world size limits are used to create arena-like servers no more than a few kilometers in diameter, where this logic would result in spawns on a box centered around the arena's middle and independent of players, but servers also use this to limit the Star System map to thousands of kilometers to prevent players from running off into the middle of nowhere - in which case, this completely breaks cargo ships for them.

Replies (2)

photo
2

This was encounter on my server. It is a real issue, no cargo ships will spawn if the world limit size is modified

photo
1

Hi Starwars,

We have successfully reproduced the issue on our side and registered it in our internal system.

Thank you for the bug report.


Best regards,

Keen Software House – QA Department

Leave a Comment
 
Attach a file
You can't vote. Please authorize!