The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

+1 vote

So, i just finalized the structure of my game, and i managed to use Resource as save file: each node with data to be saved owns a custom made resources, which contains all the export var needed, that are saved locally (server side) with ResourceSaver
It works flawlessy and it is super fast both to save and load, even with thousands of resources in game.

The game is supposed to be multiplayer, and i need the ability to share those custom made resources between server and client using NetworkedMultiplayerENet.
However, if i send a rpc call with a resource as argoument, the client will receive the simple resource object ID, not the actual resource content.

I found this scary post:
https://godotengine.org/qa/15457/what-the-best-way-share-resources-between-server-and-client

Is there a way to achieve this?
Please tell me i dont have to start all over

Godot version 3.2.3
in Engine by (1,514 points)
edited by

1 Answer

+1 vote
Best answer

Ok let's ignore those scary people.

Firstly you'll want to use inst2dict() on your server side then encrypt that data and send it to the client where you use dict2inst() and add_child() to reconstruct or duplicate the tree structure.

Words of caution

When using the above method there are some values that you will have to replace....i.e if your instance is a node derivative then the nodepath and node name need extra attention

If your resource is a binary file like an image simply convert it to a PoolByteArray then repeat the above.

by (6,942 points)
selected by

that's it, one day spent searching online and found nothing, and there was a single function that did what i needed.
Thank you!!

I think it should work, but i tried right now by simply replacing rpc("function", resource) with rpc("function", inst2dic(resource)) and it did not work, i suppose because my single save file resource is actually nested (the "main save file" contains a dictionary of resources for each object of the game).

Before start working on a way to break down each resource to a dictionary, is there a built in function to inst2dic nested resources?

Is there a built in function to inst2dic nested resources?

Hmm that's quite tricky, not to my knowledge and also ints2dict may only save the resource itself and all it's members excluding additional (nested) instances.

I think it should work, but i tried right now by simply replacing and it did not work

quite odd. Is any data even being sent?

Sorry i was too generic in my comment: it works, the data is sent and the resource correctly reconstructed on client side, but as soon as the client start opening one of the nested resources, it stops because this second layer has not been transformed in a dictionary (again, only the object id is passed).
So i basically shifted the problem to the second layer of nested resources.

I was hoping there was a way to serialize a resource completely in a dictionary, because Godot is already able to do it with ResourceSaver in a file, but I suppose i will have to change the save structure and send the client each resource individually with inst2dict

Or another option you can go with is saving then sending the file itself

If that's possible it would solve everything!
I can't find much information on the topic, how i am suppose to send it? Will inst2dict still work? Or can I send the file directly as argument?

Solved! i passed the file as an argument using get_buffer()
Basically, on server:

func save_on_server():
  ResourceSaver.save(resource_used_as_savefile, path)
  var file=File.new()
  file.open(path, File.READ)
  rpc(load_on_client(file.get_buffer(file.get_len()))
  file.close()

on client:

func load_on_client(buffer):
 var file=File.new()
 file.open(path_to_temp, File.WRITE)
 file.store_buffer(buffer)
 file.close()
 resource_used_as_savefile=load(path_to_temp)

Note: pathtotemp points to a file that doesnt have to necessarely exist.
Note2: the file has the .res extensions, it works with .tres as well (using get_as_text() and store_string() instead of buffer, but it seems slower to me)

Thanks Wakatta for your suggestions!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.