Save and loading tileset

Godot Version

4.3

Question

remember playing paper minecraft on scratch? i want to save the tiledata by parsing it into a string. then i want to give that string to the player so they can text friends the levels they made and let them load their friends levels with the text. how would i do this?

You would take one character for each block type you have. Then you would have to decide on a order in which you register your blocks. If you have a world border on the left and the right side it would be an easier algorithm since you dont have to worry about unloaded chunks.
This would be my approach to converting your map to a string (assuming you are using a 2d array of type block).

Your world’s script:

extends Node

const world_dimensions := Vector2i(32, 64)
var world: Array[Array]


func load_world(world_data : String) -> void:
	if world_dimensions.x * world_dimensions.y != world_data.length():
		printerr("world data invalid! Failed to load world")
		return
	
	var new_world = []
	var current_block: int = 0
	
	for x in world_dimensions.x:
		var blocks : Array[Block]
		for y in world_dimensions.y:
			blocks.append(Block.new(Block.get_decoded_type(world_data[current_block])))
			current_block += 1
		new_world.append(blocks)
		
		world = new_world

func export_map_data() -> String:
	var world_data : String = ""
	
	for x in world.size():
		for y in world[0].size():
			if world[x][y] == null:
				printerr("block({0}, {1}) not set to an instance of a block! Failed to export world data".format([x, y]))
				return "invalid world"
			world_data += (world[x][y] as Block).get_encoded_type()
	
	return world_data

Your Block class:

class_name Block

func _init(type : String):
	if not types.has(type):
		printerr("invalid block type")
		self.type = types.keys()[0]
	self.type = type

# block name, block character code, tilemap source id
const types : Dictionary = {
	"dirt" : ["a", 0],
	"stone" : ["b", 1],
	"cobble_stone" : ["c", 2],
}
var type : String

func get_encoded_type() -> String:
	return types[type][0]

static func get_decoded_type(encoded_type : String):
	for type_data in types.values():
		if type_data[0] == encoded_type:
			return types.find_key(type_data)
	printerr("encoded type '{0}' is not valid! Failed to return decoded type".format(encoded_type))
	return "invalid type"

func get_tile_source_id() -> int:
	return types[type][1]

You can change a tile accordingly to your your world array like this (world’s script):

var tilemap_layer : TileMapLayer

func set_tilemap_block(coordinates : Vector2i, block : Block):
	tilemap_layer.set_cell(coordinates, block.get_tile_source_id(), Vector2.ZERO)

Or update your whole tilmap:

var tilemap_layer : TileMapLayer

const map_dimensions := Vector2(32, 64)
var map : Array[Array]

func update_tilemap(coordinates : Vector2i, block : Block):
	tilemap_layer.clear()
	
	for x : int in map_dimensions.x:
		for y : int in map_dimensions.y:
			tilemap_layer.set_cell(Vector2i(x, y), map[x][y].get_tile_source_id(), Vector2.ZERO)