Page 1 of 2

Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 08:33
by gajop
For some reason Spring prevents us from specifying unit and feature ID on creation.
This most often happens if an object already had that ID, was recently destroyed, but the ID slot wasn't freed (yet).
I assume this was done to ensure users aren't sending commands for wrong units (due to latency).

This essentially makes setting IDs on object creation very unreliable, as there is no way for content devs to know *when* those IDs are freed.
The solution is usually to use a different ID system and map that to Spring IDs. This is ugly and introduced additional code bloat, but is what SpringBoard does now.

I would like a better engine solution to this. Any suggestions?

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 12:20
by FLOZi
In testing I found 3 frames were the required waiting period between death and the ID being freed, https://github.com/SpringMCLegacy/Sprin ... ld.lua#L78

You can check if the ID is valid by polling...?

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 12:40
by hokomoko
I don't think engine IDs are good for tracking a specific unit, that's not their purpose.
It shouldn't be too difficult to make a special unitrulesparam to keep track of units.

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 17:19
by sprunk
What *is* their purpose, then? What's the point of allowing to give a specific ID to `CreateUnit` if it won't even work in the most obvious use case?

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 17:20
by gajop
Thanks FLOZi, I think I might play with that as my workaround.

@hokomoko: What's the point of allowing content devs to set the object ID if those cannot be set reliably?

EDIT: sprunk beat me to it.

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 17:29
by smoth
why not merely grab the id and store it in a lookup table on creation?

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 17:34
by sprunk
Because you can't modify a unit ID after it has been created so everything that uses these IDs would have to do the extra step of translating the ID.

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 17:37
by gajop
I have been doing that for years smoth, but it complicates the rest of the code.
Everything needs to use the custom ID but still translate to spring ID when using Spring functions.

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 17:46
by smoth
just might be a necessary hurdle. Seems like the standard way of handling things even in dbs where you have unique ids. Id is never based on assigment as inevitably you will have an id conflict(at least that is what I was taught)

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 18:15
by hokomoko
gajop wrote:@hokomoko: What's the point of allowing content devs to set the object ID if those cannot be set reliably?
A short possible history lesson:
  1. CreateUnit was implemented in lua
  2. Some game dev asked the engine devs if they could set the unit ID of the unit being created.
  3. Engine dev replied: "No, it may still be in use and it's not reliable at all"
  4. The game dev said: "Well, so only do it if it's possible"
  5. Engine dev, demoralised and depressed said: "I have no idea how this helps you but I will code it in because my soul is empty"
  6. A few uneventful years pass
  7. gajop asks how to reliably set feature and unit IDs.
This may or may not reflect actual events, but it's a good story which matters more.

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 18:19
by sprunk
sad

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 18:40
by FLOZi
My view is that they can be set reliably so long as you don't try and destroy and create in the same frame (for obvious enough reasons).

I may be (one of) the game devs in #2 & #4, fwiw.

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 18:59
by sprunk
The delay makes any solution very inelegant though. Blinking out of existence (even for 3 frames) can have minor gameplay consequences but, more importantly, is just very unpolished visually and looks like a bug.

What if Spring.DestroyUnit had an extra boolean parameter that just hard-removed the unit and performed the extra cleanup that recycles the ID on the spot?

Re: Reliably setting feature and unit IDs on creation

Posted: 21 Aug 2017, 19:20
by hokomoko
What if you don't use engine ID for things that it isn't meant to do?

Re: Reliably setting feature and unit IDs on creation

Posted: 22 Aug 2017, 03:50
by Google_Frog
hokomoko wrote:
gajop wrote:@hokomoko: What's the point of allowing content devs to set the object ID if those cannot be set reliably?
A short possible history lesson:
  1. CreateUnit was implemented in lua
  2. Some game dev asked the engine devs if they could set the unit ID of the unit being created.
  3. Engine dev replied: "No, it may still be in use and it's not reliable at all"
  4. The game dev said: "Well, so only do it if it's possible"
  5. Engine dev, demoralised and depressed said: "I have no idea how this helps you but I will code it in because my soul is empty"
  6. A few uneventful years pass
  7. gajop asks how to reliably set feature and unit IDs.
This may or may not reflect actual events, but it's a good story which matters more.
For some more detail, I found that the save/load gadget in ZK used the unitID and featureID parameter. When I took over polishing the gadget I discovered that these parameters are unreliable so removed them in favor of a mapping table.

Re: Reliably setting feature and unit IDs on creation

Posted: 22 Aug 2017, 10:34
by Silentwings
Iirc hokomokos history lesson is basically what happened.

I can't see any solution to this except lua keeping a 'mapping table' for when it demands both unique and choose-able IDs. Asking that IDs are both choose-able and permanent with 100% reliability is not compatible with asking that they are also unique; the engine has to have the option to say "sorry, the ID you want is already in use". I guess that having a mapping table inside the engine (which is the logically elegant solution) is not possible because of cache misses.

Maybe from a practical point of view it would help to have e.g. Spring.IsUnitIDFree(unitID), to check if a unitID is currently free for use with Spring.CreateUnit(...), but this would add more empty souls into the history lesson.

Re: Reliably setting feature and unit IDs on creation

Posted: 22 Aug 2017, 10:47
by gajop
I think if there is not going to be callout which can be invoked beforehand, that would force-clear the IDs, it should simple be impossible to specify object IDs on creation, as it's not reliable or useful in any real way.

We're better off just making our own mapping tables.

Re: Reliably setting feature and unit IDs on creation

Posted: 22 Aug 2017, 13:07
by sprunk
Asking that IDs are both choose-able and permanent with 100% reliability is not compatible with asking that they are also unique; the engine has to have the option to say "sorry, the ID you want is already in use"
This wouldn't be a problem if you could recycle the ID immediately, without having to wait X=3 frames (destroying the previous unit in the process, but usually that's desired anyway).

However since hoko says this isn't meant to be, I agree with gajop that under the current state of things this is a trap that is probably better off removed.

Re: Reliably setting feature and unit IDs on creation

Posted: 22 Aug 2017, 13:23
by Kloot
Anyone who suggests a callout to force-recycle ID's does not sufficiently understand engine internals. /thread

The ability to assign ID's via Spring.Create{Unit,Feature} primarily exists to aid save/load gadgetry. It wasn't intended to be any more "reliable" than that (despite what some people might have started to believe) and also isn't going anywhere.

For the case of a newly upgraded unit evicting an old (which then gets destroyed) allowing in-situ creation is a far better idea, but empty souls etc.

Re: Reliably setting feature and unit IDs on creation

Posted: 22 Aug 2017, 13:53
by gajop
The ability to assign ID's via Spring.Create{Unit,Feature} primarily exists to aid save/load gadgetry.
Then it fails (is not reliable) at its primary purpose because that doesn't work when you first need to remove the existing units.