Skip to content

[VSCRIPT] Class defined in the script' scope is not accessible in another class in the same scpoe #173

Closed
@VZhelev

Description

@VZhelev

Description

I found a strange behavior of the execution context in a script.
The following example works fine when it is executed directly in squirrel 3.1, but it fails when it is executed in the game with the following message AN ERROR HAS OCCURRED [the index 'Point' does not exist]

Steps to reproduce

Steps to reproduce the strange behavior:

  1. Have a .nut script that has the following code:
class Point {
	x = null;
	y = null;

	constructor(_x, _y) {
		x = _x;
		y = _y;
	}
}

class Rectangle {
	topLeftPoint = null;
	bottomRightPoint =  null;

	constructor() {
		topLeftPoint = Point(0, 0);
		bottomRightPoint = Point(100, 100);
	}
}

rectangle <- Rectangle();
  1. Craete a map that references our script by logic_script entity and run the map.
  2. See the following error in the console AN ERROR HAS OCCURRED [the index 'Point' does not exist]

Expected behavior

The expected behavior is to run the map and the Rectangle class is successfully instantiated.

Additional context, that may help for better understanding the problem

After hours of reading, debugging and testing I reproduce the same error in pure squirrel (v3.1), and it looks like the core of the problem should be in the execution context.

  1. Reproduced in Squirrel v3.1 - Nested execution context
CustomScope <- {}
class CustomScope.Point {}
class CustomScope.Circle {
	position = null;
	constructor() {
		// Here the Point does not exists either in current environment (this) and root table(::).
		// It exists ony in the CustomScope table
		position = Point(0, 0);
	}
}
function CustomScope::Run() {
	// Here the Point and Circle exists, because the current environment(this) is the CustomScope.
	local point = Point(); 
	local circle = Circle();
}
CustomScope.Run();
  1. Reproduced in Squirrel v3.1 - Execute a file in nested execution context
## execution code
CustomScope <- {}
function CustomScope::Run() {
	dofile("file-to-include.nut"); // load, compile and execute a code in the CustomScpoe execution context
}
CustomScope.Run();
## file-to-include.nut
class Point {}
class Circle {
	position = null;
	constructor() {
		// Here the Point does not exists either in current environment (this) and root table(::).
		// It exists ony in the CustomScope table
		position = Point(0, 0);
	}
}
// Here the Point and Circle exists, because the current environment(this) is the CustomScope.
local point = Point(); 
local circle = Circle();
  1. Tested in Mapbase VScript - Workaround for the issue
// define the script's scope in the root table, in order to access it in any execution context
::MyScriptScope <- this;

class Point {
	x = null;
	y = null;

	constructor(_x, _y) {
		x = _x;
		y = _y;
	}
}

class Rectangle {
	topLeftPoint = null;
	bottomRightPoint =  null;

	constructor() {
                // access the Point class by accessing the MyScriptScope, which is defined in the root table
		topLeftPoint = ::MyScriptScope.Point(0, 0);
		bottomRightPoint = ::MyScriptScope.Point(100, 100);
	}
}

rectangle <- Rectangle();
printl(rectangle);

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't workingVScriptMapbase - Involves VScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions