ldtk icon indicating copy to clipboard operation
ldtk copied to clipboard

Multilines fields serialize newlines differently after opening their editor

Open Trouv opened this issue 2 years ago • 1 comments
trafficstars

LDtk 1.4.1, arch linux

steps

  1. Create new LDtk project (henceforth named newlineBug.ldtk)
  2. make a minimal level
  3. add a multilines field to the level with a value containing newlines, such as
This is the first line.

This came after two newlines.
Just one newline there.
  1. Save, and copy the file to a backup
$ cp newlineBug.ldtk newlineBugAfterEdit.ldtk
  1. Close and reopen the project, and save again
  2. Observe the diff between the file and the backup
$ diff -u --color newlineBug.ldtk newlineBugAfterEdit.ldtk

expected

There should be no difference between the file and its backup

actual

The multilines value of the backup uses \\n for newlines in the json, while the multilines value of the just-saved file uses \n:

$ diff -u --color newlineBug.ldtk newlineBugAfterEdit.ldtk
--- newlineBug.ldtk	2023-11-06 19:55:31.578568297 -0700
+++ newlineBugAfterEdit.ldtk	2023-11-06 19:39:42.839915458 -0700
@@ -22,8 +22,8 @@
 	"defaultPivotX": 0,
 	"defaultPivotY": 0,
 	"defaultGridSize": 16,
-	"defaultEntityWidth": 16,
-	"defaultEntityHeight": 16,
+	"defaultEntityWidth": null,
+	"defaultEntityHeight": null,
 	"bgColor": "#40465B",
 	"defaultLevelBgColor": "#696A79",
 	"minifyJson": false,
@@ -154,7 +154,7 @@
 			"externalRelPath": null,
 			"fieldInstances": [{ "__identifier": "Multilines", "__type": "String", "__value": "This is a test\n\nhello this is a test.\nJust one newline there.", "__tile": null, "defUid": 1, "realEditorValues": [{
 				"id": "V_String",
-				"params": ["This is a test\n\nhello this is a test.\nJust one newline there."]
+				"params": ["This is a test\\n\\nhello this is a test.\\nJust one newline there."]
 			}] }],
 			"layerInstances": [
 				{

notes

Opening the multilines editor again and saving transforms newlines back into \\n, then you can repeat the process.

There's also a difference in a couple other values that have nothing to do with multilines but those might have just been my error? Not sure.

Trouv avatar Nov 07 '23 03:11 Trouv

I'm guessing this extra escaping / unescaping is the culprit:

https://github.com/deepnight/ldtk/blob/f645d2efc625cec4ab4080556bb19e7ac2a1f4f1/src/electron.renderer/data/inst/FieldInstance.hx#L216-L234

I don't think that logic should be necessary to correctly handle newlines.

The DOM API's <textarea> .value will return a string with newline characters in it. You can pass that string directly to any JSON serializer to encode correctly, as "\n". That JSON will also parse correctly using a JSON parser into a newline character. Likewise, if the user enters a \ followed by a n, that will be returned from the DOM, encoded, and decoded as JSON, as a two-character string containing a \ and a n, not a newline. Which is correct and what the user wanted.

The only logic you might want to keep is a normalizer to convert CRLF into LF. I don't remember if certain browsers/OSs put CRLF newlines into a <textarea> when you hit "Enter."

cspotcode avatar Mar 18 '25 02:03 cspotcode