Pages: 1
  Print  
Author Topic: My platform generation code does not work in ENIGMA.  (Read 9453 times)
Offline (Unknown gender) crxtrdude
Posted on: December 06, 2015, 08:11:52 am
Member
Joined: Dec 2015
Posts: 22

View Profile WWW
Firstly, I don't know what to expect when pressing the debug mode for Enigma, I want to know what would come out in Windows. Apparently it's screwed up by the antivirus I have or something?

Secondly, I made some kind of way to make a map maker for my platform game. the map maker I made works, you could put blocks and player into the maker and then save it using file_text commands. When I incorporated the load code to my platformer, which reads the text file and then puts the instances again. I ran it on Game Maker, it works, but when I placed it on Enigma, it seemingly didn't run the function to put the objects into the level.

The thing works like this, you read the text file and put the values of the objects (along with their X and Y coords) into an array. The reason for this is so that I could go to another transitory room to resize the map room. When the map is resized, I go to the map room, read the array and make the instances.

If the debug mode apparently works, I might see something that will lead me to the solution.

I'll share the code probably later if someone would respond with the debug thing.
« Last Edit: December 07, 2015, 02:05:24 am by crxtrdude » Logged
Offline (Unknown gender) TheExDeus
Reply #1 Posted on: December 06, 2015, 10:15:15 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Debug mode enables many internal error checks that will trow an error box (basically call show_error()) if any of those checks fail. This involves things like using uninitialized variables, using resources with id's that don't exist, like draw_sprite(background_20, x, y) will trow an error because you try drawing a background with a sprite function. That is not guearanteed to trow an error though, just because how GM and ENIGMA handle resources (they are just numbers starting at 0), so if there is a sprite with ID == background_20 (which might represent number 20, for example) then it will draw that sprite instead of trowing an error. This is a limitation I am trying to fix, but it cannot be done without totally changing the parser.

Can you maybe post an example of your instance problem here? It's hard to know what the problem is. Maybe the file isn't loading or the array doesn't work right (which might be true as it involves the parser).
Logged
Offline (Unknown gender) crxtrdude
Reply #2 Posted on: December 06, 2015, 08:33:27 pm
Member
Joined: Dec 2015
Posts: 22

View Profile WWW
Okay, here's the code for loading the file (saved from 'file_text' functions):

Code: [Select]
///scr_load_map(file);
if (!file_exists(argument0)) exit;

var filename,obj,xpos,ypos,objname;

filename=file_text_open_read(argument0);

//Check if valid QUEUEMAP.
if (file_text_read_string(filename) != "QUEUEMAP")
{
    show_message("NOT A VALID MAP FILE.");
    //Exit if invalid.
    file_text_close(filename);
    game_end();
}
else
{
    file_text_readln(filename);
    global.temp_width = file_text_read_real(filename);
    file_text_readln(filename);
    global.temp_height = file_text_read_real(filename);
    file_text_readln(filename);
    var m;
    for (m = 0; !file_text_eof(filename); m += 1)
    {
        //Proceed if is a valid QUEUEMAP.
        obj=file_text_read_string(filename);
       
        if (obj != "PLAYER")
        {
            switch (obj)
            {
                case "SOLID":
                objname = obj_solid;
                break;
                case "FLOOR":
                objname = obj_floor;
                break;
                case "LEDGE":
                objname = obj_ledge;
                break;
                case "LADDER":
                objname = obj_ladder;
                break;
                default:
                objectname = noone;
                break;
            }
           
            file_text_readln(filename);
            global.map_contents_x[m] = file_text_read_real(filename);
            file_text_readln(filename);
            global.map_contents_y[m] = file_text_read_real(filename);
            file_text_readln(filename);
            global.map_contents[m] = objname;
        }
        else
        {
            global.is_player_placed = true;
            file_text_readln(filename);
            global.map_contents_x[m] = file_text_read_real(filename);
            file_text_readln(filename);
            global.map_contents_y[m] = file_text_read_real(filename);
            file_text_readln(filename);
            global.map_contents[m] = obj_player;
        }
    }
    global.map_contents_count = m;
    file_text_close(filename);
   
    room_goto(rm_transition);
}

Then here's the code that parses it:

Code: [Select]
local float m;
mcc = global.map_contents_count;
for (m = 0; m < mcc; m += 1)
{
    instance_create(global.map_contents_x[m], global.map_contents_y[m], global.map_contents[m]);
}

Here's the GMK file, compatible with Game Maker 8, works on Game Maker 8. Basically have the same code (except with some parts). Haven't really cleaned it up before throwing it here actually. Oh yeah, it's a working game too.
https://www.dropbox.com/s/jed375a5k5k2i1c/queue.gmk?dl=0
Here's the editor, made in LateralGM. Has the same load code, but of course not that cleaned. The save function is also here.
https://www.dropbox.com/s/2aqxl4rb82x3zbe/queueed.egm?dl=0

ALSO since I didn't share the setup that I have. Yes, I dowloaded the Portable exe from the Wiki. Enigma is updated to the latest one using the update script in the git-bash included. I'll test it without the update and see what's up.
« Last Edit: December 06, 2015, 08:50:51 pm by crxtrdude » Logged
Offline (Unknown gender) crxtrdude
Reply #3 Posted on: December 06, 2015, 09:08:25 pm
Member
Joined: Dec 2015
Posts: 22

View Profile WWW
Tested on the fresh download of the portable from the wiki, it doesn't work. Ran the GMK on LateralGM and it crashed and returns:

Code: [Select]
Game returned -1073741819

Oh yeah, it might throw an error or not since the map01 didn't exist:
https://www.dropbox.com/s/jyqpcc4hgkne3uh/map01.qlv?dl=0

The level is designed in the level editor that I made. You could edit the thing too on the editor. And I didn't put the controls:
S - Save
L - Load
O - Options.

Available options is only the resolution setting.
« Last Edit: December 07, 2015, 02:06:22 am by crxtrdude » Logged
Offline (Unknown gender) TheExDeus
Reply #4 Posted on: December 07, 2015, 05:08:03 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
It's is actually weird that it works in GM8. The reason it is not working is because "Game Start" event is executed AFTER create event (just like in GM, see here http://docs.yoyogames.com/source/dadiospice/000_using%20gamemaker/events/other%20event.html and here: http://docs.yoyogames.com/source/dadiospice/000_using%20gamemaker/events/index.html . Even the GM8 manual: http://gamemaker.info/en/manual#game%20start%20event).

So what happens in your code:
1) The file is loaded in create event and the global variables are initialized. Most importantly mapcontentscount is set to the number of objects loaded.
2) Game start event is called and all the global variables are reset. You cannot really reset the whole arrays so except the first one ([0] you null) the rest still hold the data, but mapcontentscount is set to 0.
3) Your room transition thing happens and you are back at room 1 and the parser is called. The room parser sees mapcontentscount == 0 and the for loop doesn't execute.

Try putting 'show_message("Running game start!");' in Game Start event and 'show_message("Running create!");' in Create event to see in which order they run.

After I removed everything from Game Start event it worked fine.


I also find it weird that Game Start runs AFTER Create event, Creation code and even Room start, but sadly that is how GM does it. We had a discussion about this a while back and sadly we chose compatibility. But it seems it's not possible to be compatible with GM if even they don't do what they say they do.

On the other hand it could be an ENIGMA bug, but right now it seems we are just more consistent.
« Last Edit: December 07, 2015, 05:11:45 am by TheExDeus » Logged
Offline (Unknown gender) crxtrdude
Reply #5 Posted on: December 07, 2015, 05:15:32 am
Member
Joined: Dec 2015
Posts: 22

View Profile WWW
I put what you said, it goes create -> game start -> create. So I need to separately initalize my variables into a different place than worldspawn?

I read the event sequence. I really don't get why GM would use game start after create though, but yeah, because of compatibility sake, that's there.

So I deleted the game start code, it did work. Now the question is if this is the case, I don't need to initalize variables already now that they're already initalized through the scr_load_map? I'm used to programming where you initalize your variables at the beginning of the program before you use them or something, I think this led me to use Game Start.
« Last Edit: December 07, 2015, 05:24:07 am by crxtrdude » Logged
Offline (Unknown gender) TheExDeus
Reply #6 Posted on: December 07, 2015, 07:52:38 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
If you assign to them, then it is initialization. So in scr_load_map you only assign to the global variables and that is why it is okay. If you used them like "global.mapcontentscount += 1;" then it would be bad. But it wouldn't crash, because by default any uninitialized variable is zero. For example, in worldspawn create event you have "if (global.initialized)", but global.initialized is actually not set. So when you use it defaults to 0, which makes the if check fail and call scr_load_map() instead. After that global.initialized is set to true and it works the second time.

Normally if you use uninitialized variable you would get an error if ran in Debug mode. It seems it doesn't apply to global variables, not sure if a bug or not (probably a parser bug and should be a ticket in Git).

If you want a solid way to set initial variables (like all the globals), the I suggest making a new room (room_init) and an instance (obj_init) which inits everything in the create event and the goes to the next room. That is how I usually do it. It is also useful if you need to load external resources as you can make a loading screen there later.

ENIGMA has an internal event named "PreCreation event", which is the earliest event called on game start (or more precisely room start). Sadly we don't allow user to add code to it, but that is an LGM limitation. We use it internally to allow LGM to add transformations (rotation, scale, blending etc.) to instance sprites inside the room editor. If we allowed users to append code to it, then it would also be a good place to do initialization.

Another possibility is dropping GM compatibility even more. Clearly even GM isn't GM compatible.
« Last Edit: December 07, 2015, 08:03:22 am by TheExDeus » Logged
Offline (Unknown gender) crxtrdude
Reply #7 Posted on: December 07, 2015, 08:01:35 am
Member
Joined: Dec 2015
Posts: 22

View Profile WWW
Okay, I'll take note of that, thanks! Who should add that ticket BTW?

I'm optimizing it for now and make it better and adding the game stuffs like items and enemies. I'm also going to be making the level editor better as well so that I'm just generating maps instead of placing them in the room itself.

BTW, how do you find the platformer so far? Just curious as you tested it. I'm going to put up those links and clean them up, and I might share a tutorial on working platformers on Enigma once I'm done so.
« Last Edit: December 07, 2015, 08:04:30 am by crxtrdude » Logged
Pages: 1
  Print