[Godot 3] Base 'Nill' while parsing .json file

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Yeldham
:warning: Old Version Published before Godot 3 was released.

I’m trying to parse a .json file, but I keep getting the following error:
Invalid get index ‘scene’ (on base: ‘Nil’).

I don’t know what exactly I’m doing wrong, it must be related to the while loop, because outside of it, the code works…

func loadProject():
    var file = File.new();

    if !(file.file_exists("user://project.json")):
	    return;

    file.open("user://project.json", File.READ);

    var currentObject;
    var newObject;

    while (!file.eof_reached()):
	    currentObject = parse_json(file.get_line());
	    newObject = load(currentObject["scene"]).instance();
	
	    add_child(newObject);

    file.close();

Well the problem would be inside parse_json(), so no idea. I would assume you’re not creating or loading a PackedScene and storing its reference in a dictionary key called “scene”.

avencherus | 2017-07-30 19:24

This is how the .json looks, by the way:

{"scene":"res://scenes/world/wall.tscn", "start":"(-663.12677, -61.055111)", "end":"(-284.924042, -227.260773)", "textureStart":0}
{"scene":"res://scenes/world/wall.tscn", "start":"(-284.924042, -227.260773)", "end":"(55.967224, -208.605072)", "textureStart":0.065561}
{"scene":"res://scenes/world/wall.tscn", "start":"(55.967224, -208.605072)", "end":"(300.187805, -25.439613)", "textureStart":0.772567}
{"scene":"res://scenes/world/wall.tscn", "start":"(300.187805, -25.439613)", "end":"(351.0672, 125.502289)", "textureStart":0.298946}
{"scene":"res://scenes/world/wall.tscn", "start":"(351.0672, 125.502289)", "end":"(237.436707, 242.524628)", "textureStart":0.095378}

And like I said, outside the while loop, it works.

Yeldham | 2017-07-30 19:30

What does your parse_json() function do?

Any built in parsing will not restore or build your objects and certain Godot data types. You have to recreate them during your parsing. So for example, your scene path, isn’t going to return a PackedScene, you will have to use load(path). For your vectors you will need to parse those values into a new Vector2(x, y).

avencherus | 2017-07-30 19:37

“parse_json()” is a build-in function of Godot.

And the code that I posted uses “load()”.

Yeldham | 2017-07-30 19:42

Oh I see, I thought you wrote your own, I’ve only seen parse_json() as a method on dictionaries. Let me go double check that.

avencherus | 2017-07-30 19:44

It’s a global method in Godot 3 now.

Yeldham | 2017-07-30 19:46

Oh interesting, yeah I’m working out of version 2.

If you print(currentObject["scene"]) what do you see?

Then take that output and test it in a preload() or load() in a test script somewhere, see what’s going on with the path itself.

avencherus | 2017-07-30 19:50

The scene’s path: res://scenes/world/wall.tscn five times, the same amount of times they appear in file, so that’s correct.

The path itself is completely fine, like I said, it only causes trouble when in a while loop. Repeating the error that I already stated: Invalid get index ‘scene’ (on base: ‘Nil’)

Yeldham | 2017-07-30 19:56

:bust_in_silhouette: Reply From: Yeldham

Found the problem, “file.eof_reached()” seems to trigger a line too late, making it return a null. A simple null check solves it, but I don’t think this is intended behaviour…