Essentials icon indicating copy to clipboard operation
Essentials copied to clipboard

Voxels Cleanup Asteroids with Storage deletion does not regenerate asteroid

Open LordTylus opened this issue 4 years ago • 0 comments

Hello there,

it appears the !voxels cleanup asteroids true removes the asteroid from the storage correctly, however even after a server restart the asteroid is never regenerated again.

Verified in Essentials v1.7.1.46-107-g70fdb93 (SE version 194) (Torch v1.3.1.109)

This is due to the sbc file containing:

<ExistingObjectsSeeds>

Basically it says "I already generated the Asteroid so no need to generate again". So as long as this information is in memory the asteroid wont be regenerated. I was told by Inflex that this is mostly due to performance.

Clients generate asteroids that have never been touched by anyone themselves and dont bother the server for that. There is an RPC call that basically tells the client "these asteroids were touched before and I tell you about changes. the rest is up to you".

The interesting class for that is MyProceduralAsteroidCellGenerator. Which in its GenerateObjects method does skip all Asteroids which are already generated.

There are a few possible fixes Inflex told me about:

  1. Remove the Seed from the existingObjectsSeeds Set. However a Voxel does not have a clue which seed it was generated with. So you would either need to figure out how to calculate that or Save a mapping of that when a new Asteroid is generated.

  2. Patch the GenerateObjects Method and pass an Empty HashSet into it. The Method is self repairing. Which checks if there already is a vx file and if there is it adds it to the list and does not add anyting new.

In any scenario you need to communicate with the client however. because if the Asteroid will be removed the client needs to rid it from its own ExistingObjectsSeeds set as well. Since closing the voxelMap only tells the client its gone. But as long as the client does not have this entry removed from its own set it wont attempt to respawn it, because the server wont send updates for untouched asteroids.

Having this data inconsistent has two possible problems:

  1. Asteroid is invisible for client and a player could crash into it.
  2. Asteroid looks like it was never touched although it was. So its submerging grids and messing with collision on the clients.

So I assume just patching the method to pass an empty set will not yield the desired results.

The original seed must be come from somewhere so if that code piece is found its probably possible to reverse engineer the seed and inform the client about it. I guess it uses the world seed and the position to figure out how the asteroid should look. But thats just me taking a guess.

Thats all info that I have :-)

LordTylus avatar Mar 29 '20 21:03 LordTylus