-
-
Notifications
You must be signed in to change notification settings - Fork 608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Allow sending spawnData when spawning entities using the MultiplayerService #1400
Conversation
Thanks for this. The public API seems fine. However, implementation-wise, SpawnData can carry non-serializable data, so I'm just a bit cautious it may break compatibility with existing projects and/or cause confusion regarding the contractual obligation of SpawnData. Is there a way we can achieve the same without making SpawnData serializable? Perhaps some internal or public data structure (which is serializable) that can carry the spawn data, Another aspect we need to try and figure out is what to do when SpawnData does carry non-serializable data. Using |
I agree with your concerns about changing SpawnData serializable, I think it should be up the the users to make sure all the data is serializable if they choose to create a subclass of Does this sound okay? I can make the changes and then we can see if its enough |
Where do you want the NetworkSpawnData class to live? Under entity like with SpawnData or together with the MultiplayerService under the multiplayer package? |
Probably alongside MultiplayerService, we can change later as needed. Above all sounds good. |
Not sure if helpful, but perhaps you can make use of |
I wonder if |
I'd go with a constructor for now |
I tried to do something like this but my demo fails since SpawnData is not serializable. open class NetworkSpawnData(val spawnData: SpawnData) : Serializable {
}
-----------------
fun spawn(connection: Connection<Bundle>, entity: Entity, entityName: String, spawnData: SpawnData) {
if (!entity.hasComponent(NetworkComponent::class.java)) {
log.warning("Attempted to network-spawn entity $entityName, but it does not have NetworkComponent")
return
}
val networkComponent = entity.getComponent(NetworkComponent::class.java)
val event = EntitySpawnEvent(networkComponent.id, entityName, NetworkSpawnData(spawnData))
// TODO: if not available
val data = replicatedEntitiesMap[connection]!!
data.entities += entity
fire(connection, event)
}
----------------------
Demo
// This does not work.
SpawnDataspawnData = new SpawnData(x, y);
Entity entity = spawn("test", spawnData);
getMultiplayerService().spawn(connection, entity, "test", spawnData);
//This work because I send my custom spawn data class which implements Serializable
CardSpawnData cardSpawnData = new CardSpawnData(x, y, card.suit(), card.rank());
Entity entity = spawn("card", cardSpawnData);
getMultiplayerService().spawn(connection, entity, "card", cardSpawnData);
I could try to use a Bundle somehow, but I'm not too sure on how to use it. I could also set data inside SpawnData x,y,z,data manually on the NetworkSpawnData, but then I'm not sure to get custom variables/fields that exists on subclasses of SpawnData |
|
I was thinking something like this.
Not sure what we should do if Once we get NetworkSpawnData through the network to the other end, we need to reconstruct local Incidentally, I don't know/remember why |
5c6831d
to
a2316d8
Compare
I implemented something like you said, but I also included the position x,y,z because it didn't look like they were a part of I left the Does the new changes look like something you had in mind? |
Many thanks, yes that's exactly what I had in mind. I'll take a look and merge later today. I'll have a think about how to write a simple test for it, but in the meantime, can you confirm this implementation works for your use case? |
Yes, I had to do some adjustments since I extended |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thank you
An attempt at resolving my own question on the discussion page.
Tested with a local project where I first encountered the need for this.