I’ve built a level editor that can export packed scenes so I can more easily build levels for my game - and so far everything seems to work properly. My editor generates a level mesh, a skybox, static objects, and spawners - which all save properly.
However, I’m also saving a 256x256 grid alongside my level (making a hex grid strategy game)
I’m giving each cell 16 bits of data - or 2 bytes - leading to me having a 256x256x2 PackedByteArray (131072 elements)
When saving my level into a PackedScene, the PackedByteArray doesn’t get saved with it - and it seems to be the only thing not getting saved.
Is there some behavior in Godot preventing it from saving large pieces of data? Or why would this happen / how could I circumvent it?
EDIT:
Forcing the PackedByteArray to be a much smaller size (I tried 5 elements) didn’t fix the issue.
So I guess it’s just that PackedByteArrays don’t save into PackedScenes?
EDIT 2:
Converting the PackedByteArray into a non-packed array of integers seems to save properly - but that feels like an unnecessary conversion for saving and loading a level
extends Node
@export_storage var data:PackedByteArray
extends Node
func _ready() -> void:
var n = preload("res://my_node.gd").new()
for x in 256:
for y in 256:
n.data.append(randi() % 256)
n.data.append(randi() % 256)
prints("Written", n.data.size())
var ps = PackedScene.new()
ps.pack(n)
ResourceSaver.save(ps, "user://scene.tscn")
var scn = ResourceLoader.load("user://scene.tscn").instantiate()
prints("Loaded", scn.data.size())
Ah - good to know about @export_storage, I had just been using @export
Here’s what I use for saving my scene:
func _on_export_pressed() -> void:
MapGen.PrepareForExport()
var toSave = PackedScene.new()
if toSave.pack(PreviewGrid) == OK:
var path = ExportPath + FileName + "/"
DirAccess.make_dir_recursive_absolute(path)
ResourceSaver.save(toSave, path + FileName + ".tscn")
And notably, here’s the implementation of PrepareForExport():
func PrepareForExport():
for i in GridPreview.multimesh.instance_count:
var data: Color = Color(CoreTypes.CELL_COLOR.EMPTY,0.0,0.0,0.0)
GridPreview.multimesh.set_instance_custom_data(i, data)
GridPreview.Lightmap = load("res://Scenes/Grid/Skybox/level_lightmap.tscn").instantiate()
GridPreview.add_child(GridPreview.Lightmap)
GridPreview.Lightmap.owner = GridPreview
This wasn’t saving GridPreview.Grid - so I updated it to this (which works but is ugly):
func PrepareForExport():
for i in GridPreview.multimesh.instance_count:
var data: Color = Color(CoreTypes.CELL_COLOR.EMPTY,0.0,0.0,0.0)
GridPreview.multimesh.set_instance_custom_data(i, data)
GridPreview.Lightmap = load("res://Scenes/Grid/Skybox/level_lightmap.tscn").instantiate()
GridPreview.add_child(GridPreview.Lightmap)
GridPreview.Lightmap.owner = GridPreview
GridPreview.SaveGrid.clear()
var intArray = GridPreview.Grid.to_int64_array()
for i in intArray:
GridPreview.SaveGrid.push_back(i)
And the variables in question are currently setup like so:
var Grid: PackedByteArray = []
@export_storage var SaveGrid: Array[int] = []
I’ve tried adding @export or @export_storage to Grid, but no matter what I do it won’t save but SaveGrid will