Colobot Forum - International Colobot Community

Full Version: [SOLVED] Critical errors with a program in lvl controller after loading saved game
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have serious problem with a program written for level controller. This particular trouble appears in the level 4-4 "Explosives" of my usermod. I don't know, maybe I should've tried to create a separated level dedicated to troubleshooting purposes instead? Anyway, when I start the game, save the game and then load the save, either one of two things happen:
1) Level controller stops working by throwing "illegal object" error, and that's all.
2) Level controller does not stops working. But when I kill all three spiders in the first camp northward from the space ship, thus triggering respawn, the game just crashes.

I encounter this problem by using level controller, but about two things I am certain:
1) This is not related to level controllers per se, because if I use ordinary bots instead results are just as bad.
2) It doesn't matter if you load your program to object (a level controller or a bot) in scene.txt or manually after starting the game.

Mayhaps there is some glitchy-glutchy function that I shouldn't use yet or use differently than I do and somebody might know more about it, otherwise it can be fixed only in the game engine and in that case I just try to get more attention to this problem...

EDIT: I opened an issue in my github on this topic so that it can be referenced if anything.
I was thinking about this yesterday...
Saving the game saves only some game parameters that are needed to load it.
So that means, your controller uses something that is not saved
OR
the controller is started before everything gets to load properly. (Which is unlikely because you said you started the program manually and it still happened.)

That's just a theory.
I wonder if it's possible to somehow dump the level's memory to analyse it later... I have never played with custom levels before, so I have no idea what happens in there.
Thanks for reply. I also suspect that it might have to do something with static objects. In other levels their level controllers work mostly fine even after loading savegame. And the most notable difference? They do not use a single static object, while this particular one does uses static objects. I couldn't think of proper way to remove static objects from this level controller to see if this hypothesis is true, though, because static data is the very essential part of it. Hmm...
Singleton? If you use singleton or singleton-like construct, it won't be static but could work a bit like static.
Does it not needs to contain static elements, though?
...
Whatever it is, it can't be done that way. There is interaction with objects going on in which objects call a function. I've thought of some really dirty workaround... But nope, it's useless.
Singleton in normal programming has private constructor, field with element of itself, and a static getter "getInstance()" which returns that only instance.
You'll have a single object with the parameters (as a object, not a static class with values, it theoretically should get saved) and a static method (aka function) to always return that one element.

Though, I have no effing idea how statics work in CBOT... Where is the thing you think the problem is located? ^^'
I already tried to do it before, just didn't manage to do it properly. This time I did: 1) I made all the variables in the class Camps static, it is all in the very beginning; 2) I also used a variable for search() at 240 (before) / 236 (after).
Before:
https://github.com/rbcat/returbot/blob/9...ontrol.txt
After:
https://github.com/rbcat/returbot/blob/1...ontrol.txt

With the second change, I do not catch "illegal object" error anymore. Apparently, something must be wrong with search() instruction, because this is not the first case when it throws "illegal object" error in a running program after you load a savegame, while radar() instruction never caused such error. I'm still not 100% sure, but if it's indeed a thing, then it should be reported as an issue to github of Colobot. If it wasn't already, of course.

With the first change, conditions in which the game crashes became different. I load a savegame, clear just one camp, triggering respawn for that one camp, and the game doesn't crashes anymore, it works all the way fine. But then, when I clear another one camp and trigger respawn for it, the game crashes. Now you need to trigger respawn for two camps instead of just one to cause the game to crash... NOW I'm confused, because what the heck, that just doesn't makes a sense for me. Note: as it appears, it doesn't matters which camps I choose to clear.



Quote:Where is the thing you think the problem is located? ^^'
You mean the program? If so, history versions are above in this post and original one is here:
https://github.com/rbcat/returbot/blob/m...ontrol.txt
The problem in it is most likely with Camps class which contains all the static data.

There are three functions that access Camps class: Spawn, Rdata_set and LvlCntlr_main. The problem here is either in LvlCntlr_main or Rdata_set or both, because both are being called all the time while Spawn() is only called when a new spider should spawned. The game crashes immediately right as I load a savegame with respawn already running. Rdata_set is being called by the spiders themselves and they have a little delay in their programs. On the other hand, LvlCntlr_main is the main program of the controller which runs all the time and never stops looking through static data of Camps class, but what is important, it does it even before respawn is triggered. That's all complicated.

Your suggestion might or might not work. Accessing private static objects via that function might indeed work bona fide where accessing public static objects directly causes the game to crash. Now I've got only to try and find out myself.

UPD: I also realized that it might be that there are too many instances of Camps being created over the time. Just now I added destruction of it at the end of Rdata_set, but it didn't help, of course. Though, it should be destroyed automatically.
Quote: I also realized that it might be that there are too many instances of Camps being created over the time.
Tongue
That's what singleton would fix. Though, do you even operate on the values in Camps? If not, there shouldn't be a problem with having multiple instances... unless you have problems with memory then.

I wanted to convert Camps to singleton, but I have problems with making a static method for getInstance(). Oo' CBOT environment in the game says "Type declaration missing" if I add "static" and that's strange because I didn't remove anything. And idk how I can access static method from the outside anyway. (ClassName.method() doesn't work.) 
...I think I still prefer normal languages.
UPDATE: there's something I didn't noticed in the first place. @melex750 already fixed this issue using setters and getters. More info is here.



Quote:That's what singleton would fix.
Even if it's not being destroyed by garbage collector by itself after returning from the function, shouldn't "instance = null;" be enough to throw it into bin then?

Quote:Though, do you even operate on the values in Camps?
I sure do. And it seems as though changing them is what causes the game to crash, because LvlCntlr_main reads them all the time from the very beginning of the game, and does it without crashes. That is, unless regular creation of new instance of Camps in Rdata_set or something else is to be blamed.

Quote:I wanted to convert Camps to singleton, but I have problems with making a static method for getInstance(). Oo' CBOT environment in the game says "Type declaration missing" if I add "static" and that's strange because I didn't remove anything.
It seems that in CBOT there is no way to make method of class static. What is the purpose of it anyway, again?

Quote:And idk how I can access static method from the outside anyway. (ClassName.method() doesn't work.)
In CBOT you can't access anything in the class itself. You have to create instance of class and access everything in it. Like that:
Code:
Classname instance();
instance.method();

Quote:...I think I still prefer normal languages.
We all do, hazel, we all do. But CBOT is what we got here.
By operating on values, I meant exactly changing them. It's what could cause crashes, yes.
Maybe adding synchronization somewhere would fix this? Though, I'm not sure about static-ness of Camps itself (I mean, Camps.Camps) - it's not declared as static, so if there are multiple instances, 'Camps' array is not shared anyway(?).

As for static methods, the documentation (SatCom) of 'static' states that I can make static methods. :c But it seems I can't. And I would need to access them without the instance anyway, so, well, it's stupid.

I wanted to make something like this - Wikipedia on singletons.
Single instance, no way of creating other instances (private constructor), static getter to get that single instance... Because you first thought it's about static things.
Quote:By operating on values, I meant exactly changing them.
I got that, yes.

Quote:Maybe adding synchronization somewhere would fix this? Though, I'm not sure about static-ness of Camps itself (I mean, Camps.Camps) - it's not declared as static, so if there are multiple instances, 'Camps' array is not shared anyway(?).
I don't remember what result I got exactly when I tried to declare camps as static, because it was a time ago, but I remember that it didn't work.

Well, that's how things are working here. I'm honestly glad that TT implemented some basic OOP in CBOT at all.