Save levels inside of a png

Godot Version

4.2.stable

Question

How would i save levels (resources) inside of a png file? I want the player to be able to create a level using my level editor, and godot would take a screenshot of an image and save it as a png. Then, it would save the actual level data inside of the png. Is there any way to do this?

you can create a bitmask for your level, what shade of grey for example. That’s 256 values. if you have some entities like trigger, exit etc. you have to combine them via rgb… you can do it by using channel R for tiles, channell G for entities etc… and then you have to make your own parser which will read these byte values and decompose them into a tilemap… from there you have to make your own api

and then this is how it should look like, this is my bitmask that recognized tiles for the map and compiled the whole tilemap
obrázok


and this is what the binary data in the image looks like again, this is specifically the encoded tile graphics. one pixel represents 4 bytes (RGBA) over which the whole 1bit tiles are then rendered
obrázok

i think i may have explained the problem wrong. The png image and saving would be seperate. The image would just be a screenshot of the game, but inside the file would be the actual saved resource.

All I know is that, in principle, that’s what they do sometimes. But I’d like to know the details myself. I suppose that .png is at the very beginning of the file and is read by the system and viewers as a picture, and the data is further away. It is necessary to tell the game that it would consider .png as a resource containing data. Is it possible to implement this in Godot — probably so, but I can’t say how simple it is.

aha like this…
I think it has been solved here on the forums somewhere, a viewport snapshot was made

I have looked into this extensively for the purposes of my own project. Unfortunately, Godot does not have support for accessing the metadata fields (tEXt) in PNG documents in its API. This means that, unless you want to roll your own solution for accessing metadata fields in PNGs, you will need to use another solution. One such solution is steganography, or embedding hidden messages in plain sight. On StackExchange, there is an extensive discussion on how to achieve this.

The solution Spore uses is by embedding a small amount of information into the lower bits of the image file in each bit (R, G, B, A). This does cause visible noise on a Spore save card, which is perceptible to the naked eye, but tightly packs all of the information needed for the save in the image itself, without needing additional space for data in most cases.

If this is not ideal or appropriate for your scenario, you can submit a feature proposal describing your use case.

If you need more detail about implementation, please feel free to reach out.

Regards,

2 Likes

@SuperMatCat24 but he writes that this was not his point, I also understood it that way. He’s obviously asking how to create a screenshot of the map and save it to a png in the filesystem. at least now I understand it that way.

and what you are writing, which I also mentioned here (my misunderstanding of the topic), can be implemented now in godot. if you can read a pixel, which you can do now, the data in the image is not a problem for this purpose. it’s up to your structure how you read and write it. I have one application that is done this way via godot and it works great.

but I don’t want to digress from the topic of the topic :wink:

Thank you!

If the question is regarding screenshots, it appears it has been answered before.

You can render a Viewport/SubViewport to a ViewportTexture, and then save the contents of the ViewportTexture as follows using Texture2D.get_image():

var viewport_texture = $"path/to/your/viewport/texture"

func save_screenshot() -> Error:
    return viewport_texture.get_image().save_png("path/to/your/output.png")

Please note I have not personally tested the above code, but it should be roughly correct. In the case of any doubt, please refer to the linked documentation.

If you need to perform some operation, say the steganographic technique discussed before, you can use Image.save_png_to_buffer() instead, and then operate directly on the created buffer.

Regards,

@powderedespresso you learn all your life, I didn’t know that this technique is called steganographics. thanks for the enlightenment :wink: I’ve actually been using it for a long time and I didn’t even know it was called that.

@SuperMatCat24 I apologize for partially misunderstanding the question. :godot:

1 Like

Its chill bro dw! Might test out your method some time for a different game

1 Like

Can you reverse the idea?
Save the resource with a png screenshot as its contents?

Hello esteemed sancho2,

This is possible, although it depends on the nature of the containing document. For textual data, for example, every bit has just as much importance as every other bit, thus encoding a hidden message in the lowest bits would not be possible; however depending on the type of containing document, it may be possible to append metadata to the document, although it would be outside of the scope of this thread for implementation.

Generally speaking, the nature of the containing document is more important than the nature of the contained document. So long as arbitrary data can be encoded in the enclosing document with minimal noise, steganographic technoques can be applied.

Sometimes, the medium can be the message, such as in the ‘Free Speech Flag’.

I recommend researching into your desired format and its limitations, as well as capacity for arbitrary metadata. Keep in mind, many file hosts, especially image hosts, may perform arbitrary operations on your data for the sake of compression, including stripping metadata, so transmission is not always guaranteed depending on your desired solution. Deeper discussion of storing arbitrary image data in a non-image container may constitute its own thread.

Regards,

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.