ldtk
ldtk copied to clipboard
Multilines fields serialize newlines differently after opening their editor
LDtk 1.4.1, arch linux
steps
- Create new LDtk project (henceforth named
newlineBug.ldtk) - make a minimal level
- 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.
- Save, and copy the file to a backup
$ cp newlineBug.ldtk newlineBugAfterEdit.ldtk
- Close and reopen the project, and save again
- 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.
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."