So, this used to work in Magma, but is failing in Jint:
JavaScript:
if(args[0] == "barricade"){
for (var allObj in World.Entities){
if(allObj.Name == "Barricade_Fence_Deployable"){
Util.DestroyObject(allObj.Object.gameObject);
}
}
}
It fails silently, and I read @
mikec post about that, tried a try/catch, Util.Log, but nothing shows up. It just fails, whereas it used to work in Magma.
Not sure what's going on.
This is one of my favorite bug reports now.

This bug report led me down the rabbit hole into the depths of the .Net Common Language Runtime (CLR). When I looked at the code for World.Entities, I knew what the solution was going to be, but I didn't understand why the bug was in World.Entities and not in Jint2.2. Now I understand why, and it was an important lesson learned.
It also give me an opportunity to talk about important differences between old Jint in Magma and new Jint2 in JintPlugin.
Thank you!
The problem in simple terms is that World.Entities is typed to return an IEnumerable which is a kind of list of Entity objects. The return value is:
C#:
return structures.Concat(deployables);
structures is a IEnumerable of structure components and deployables is a IEnumerable of deployable objects. Concat does just what it sounds like, it returns a new list with all the objects in deployables added to the end of structures.
Except that it doesn't. It actually returns an object of this type:
C#:
System.Linq.Enumerable+<CreateConcatIterator>c__Iterator1`1[Fougerite.Entity]



CreateConcatIterator is a private method in System.Linq.Enumerable which is called by the Concat method to join the two lists. c__Iterator1 is the compiler-generated name for the first of two foreach loops within CreateConcatIterator. It has no properties, no methods. It's an internal compiler-created object.
Q: Why does Jint2 return a compiler-generated object to a Javascript plugin?
A: Because the code in World Entities told it to:
return structures.Concat(deployables);
Q: Does old Jint return the compiler-generated object to a Javascript plugin?
A: Yes, it sure does. World.Entities returns the same object to all callers, any language.
Q: Then why does it work in Magma and C# but not in Jint2 Javascript plugins?
A: That's an excellent question. Glad you asked.
The object - two foreach loops in CreateConcatInterator - isn't executed to produce the combined list until it is used in a foreach loop . Javascript does not have a C#-style foreach loop. But in old Jint, a Javascript
for(var p in object) loop was transformed into a C# foreach loop "under the hood." Old Jint tried to allow Javascript to treat C# objects as Javascript objects.
Jint2 has a new Engine and takes a different approach. The only C# objects that appear as Javascript objects, with enumerable properties and methods (including the case of the member names) are those that are directly equivalent, or most closely equivalent when there isn't an exact match to a Javascript object. The only list-like object (class) in C# that has a direct equivalent in Javascript is Array. So a C# array in Javascript has .length property, not .Length, and a method .forEach, not .ForEach. And a C# string is a JS string with JS string methods, int is int, float is float (C# single-precision), and so on. And a Javascript
for(var p in object) loops
the (enumerable) properties of a Javascript object as documented. In the case of an array, the members are the indexes. If World.Entities was an array you would do this:
JavaScript:
for (var i in World.Entites) {
if(World.Entities[i].Name == "Barricade_Fence_Deployable"){
Util.DestroyObject(World.Entities[i].Object.gameObject);
}
}
But it doesn't act on other C# classes like List or Dictionary. Those objects don't have enumerable properties, not for Javascript. A loop over an object with no enumerable properties will run zero times. It's not an error. No exception is thrown.
HERE IS AN IMPORTANT POINT
But even if C# list-type objects - List, Dictionary, etc. - had Javascript-enumerable properties in Jint2, the for loop you wrote wouldn't work as you expected. It would return the members of the List or Dictionary class, not the elements of the collection wrapped up inside the class. And you couldn't refer to them "bare" as you did with your var allObj. You refer to
World.Entities[allObj] inside a Javascript for loop. allObj is just a string, the name of the property. The style of Javascript loop you wrote only works in old Jint.
So, old Jint has taught you bad Javascript. It's a good thing to be rid of it. And, a lot of ordinary Javascript won't run in old Jint. Things like jQuery. Jint2 can run jQuery.
The collection of elements are but one member of the class List or Dictionary, or any other C# Collection class. To get the elements the "Javascript way" you would need the name of the member that held the collection, and access it something like
Listname[membername][x] where x is the index in the array that underlies a C# Collection. But this is private to the class, and you can't access it directly.
Q: Things are looking pretty dismal for Jint2. I'd rather just write Rust plugins like I did before. "For" loops are easy in Magma. I care about making cool plugins, and not so much about correct Javascript. Jint2 seems more broken than correct, anyway. Are you going to fix it?
A: You can keep writing for Magma. It will work as-is indefinitely, and we'll still fix bugs that affect it. You can start writing plugins for Jint2 that share data with Magma plugins using DataStore. That way you don't have to start all over. You can migrate to Jint2 gradually.
Q: So, what about World.Entities? Is that Magma-only? Does Jint2 have a replacement?
A: In Fougerite MC5 I "finished the job" and converted the output of the Concat method to a List<Entity>. That's what it was in the original Magma 1.1.5. Magma plugins will work exactly the same, with a foreach loop behind the scenes returning each element of the collection.
Q: So I can do a for loop on it in my Jint2 plugin?
A: No. As I said, a List has no properties enumerable in Javascript and...
Q: Got it. GOT IT. SHUT UP I GOT IT.
A: OK. But now (in MC5) that World.Entities returns a List object, instead of a code fragment that produces a List, Jint2 plugins can use the properties and methods of the List class to manipulate the List. The code fragment object had no properties Jint2 plugins can use.
Q: Um. So... and then?
A: And this:
JavaScript:
function getbarricades(x) {
return x.Name == "Barricade_Fence_Deployable";
}
function destroy(x) {
Util.DestroyObject(x.Object.gameObject);
}
var barricades = World.Entities.FindAll(getbarricades);
Plugin.Log("BarricadesNoMore", "Destroying " + barricades.Count + " barricades.");
barricades.ForEach(destroy);
Q: That kinda sucks.
A: Noob. But that's OK. Have it your way.
JavaScript:
var entity = World.Entities.ToArray();
for(var i in entity) {
if(entity[i].Name == "Barricade_Fence_Deployable"){
Util.DestroyObject(entity[i].Object.gameObject);
}
}
Q: Ummmm.
A: JintPlugin offers some new methods for getting lists of game objects, and the lists are returned as arrays. You won't really want or need to use World.Entities soon.