• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

how do I loop though a directory and make objects out of json and lua files?

S

Shadowblitz16

Guest
hello I recently bought @YellowAfterlife 's apollo lua extesion

but I was wondering how to loop though the base directory and all its sub directories and populate the game with objects with json and lua files?

basically the way I want it to work is that I have a base folder which contains all the default code for the game.
and then I have a worlds folder where the users can override or add objects and scripts.

worlds would be for the overworld and levels

the format would go something like this...
Code:
\worlds folder
-\actual world folders with unique name
--\world file and level files
--|level folders with same name as level files
---\overridden base 
----\...

can someone give me a step by step process on how to do this?
I also might need help with those individual steps
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
You'll need to loop over directories recursively.
I at one point wrote an example of copying folders recursively that uses this same idea. Can even do without making an array of files - not sure why that's in there.
 
S

Shadowblitz16

Guest
@YellowAfterlife this doesn't really answer the whole question.
is this the recursive code?
Code:
/// file_copy_dir(source, target, attributes)
// Copies contents from source directory to target directory.
// Add fa_directory to attributes for recursive copying.
var fname, i, file, files, from, to;
// create directory if it doesn't exist yet:
if (!directory_exists(argument1)) directory_create(argument1)
// push matching files into array:
// (has to be done separately due to possible recursion)
files = 0
for (fname = file_find_first(argument0 + "/*.*", argument2); fname != ""; fname = file_find_next()) {
   // don't include current/parent directory "matches":
   if (fname == ".") continue
   if (fname == "..") continue
   // push file into array
   file[files] = fname
   files += 1
}
file_find_close()
how would I populate the objects into my game?
 
Last edited by a moderator:
S

Shadowblitz16

Guest
@YellowAfterlife something like this?
Code:
/// @description Lua Create
// You can write your code in this editor

state = lua_state_create();
lua_add_function(state, "print", ref_print);
lua_add_function(state, "new",   ref_new);

load_files("Objects", 0);
Code:
/// @desc load_files(source,  attributes)
/// @arg source
/// @arg attributes

var source     = argument[0];
var attributes = argument[1];


// Create directory if it doesn't exist yet:
if (!directory_exists(source)) directory_create(source)

// Get first file
var first    = file_find_first(source+"\*", attributes)

//Create universal file holders
global.names    = ds_map_create();
global.objects  = ds_map_create();
global.frames   = ds_map_create();
global.scripts  = ds_map_create();

while(first != "")
{
    var fullname = source + "\\" + first;
 
    if (first == "." || first == "..") load_files(fullname, attributes);
    else                          
    {

        //First is <null> here
        var data     = load_json(fullname);
        var name     = data[? "name"];
 
        switch(filename_ext(first))
        {
            case ".object":
                global.names[? name]    = fullname;
                global.objects[? first] = fullname;
                break;
          
            case ".lua   ":
                global.scripts[? first] = fullname;
                break;
          
            case ".frames":
                global.frames[? first]  = fullname;
                break;
        }
        file_find_next();
    }
}
Code:
/// @desc load_json(fname)
/// @arg fname

var fname = argument[0];
var data  = "";

var file = file_text_open_read(fname);

while(!file_text_eof(file))
{
    data += file_text_read_string(file);
    file_text_readln(file);
}
file_text_close(file);
return json_decode(data);
 
Last edited by a moderator:

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Upon further evaluation,

load_files:
Code:
/// @desc load_files(source)
/// @arg source

var source     = argument0;

//Create universal file holders
global.names    = ds_map_create();
global.objects  = ds_map_create(); 
global.frames   = ds_map_create(); 
global.scripts  = ds_map_create(); 

if (directory_exists(source)) {
    // Loop over contents
    load_files_rec(source);
} else {
    // Create directory if it doesn't exist yet
    directory_create(source)
}
load_files_rec:
Code:
var source = argument0;
//
var files = ds_list_create();
var fname = file_find_first(source + "/*.*", fa_directory);
while (fname != "") {
    show_debug_message("found " + fname);
    switch (fname) {
        case ".": break;
        case "..": break;
        default: ds_list_add(files, fname);
    }
    fname = file_find_next();
}
file_find_close();
//
var n = ds_list_size(files);
show_debug_message("Found " + string(n) + " files in " + source);
for (var i = 0; i < n; i++) {
    var fname = files[|i];
    var fullname = source + @"\" + fname;
    if (directory_exists(fullname)) {
        load_files_rec(fullname);
    } else {
        show_debug_message("Loading "+fullname)
        switch(filename_ext(fullname))
        {
            case ".object": 
                var data     = load_json(fullname);
                if (data != -1) {
                    var name     = data[? "name"];
                    global.names[? name]    = fullname;
                    global.objects[? fname] = fullname; 
                } else show_debug_message("JSON is invalid");
                break;
               
            case ".lua": 
                global.scripts[? fname] = fullname; 
                break;
               
            case ".frames": 
                global.frames[? fname]  = fullname; 
                break;
        }
    }
}
ds_list_destroy(files);
 
S

Shadowblitz16

Guest
@YellowAfterlife thankyou but I have another question
we I do this in my lua controller object
Code:
/// @description Lua Create
// You can write your code in this editor

//Create universal file holders
global.names    = ds_map_create();
global.objects  = ds_map_create(); 
global.frames   = ds_map_create(); 
global.scripts  = ds_map_create(); 

state = lua_state_create();

//Init Library
lua_add_function(state, "print", ref_print);
lua_add_function(state, "new",   ref_new);

//Load files
load_files(working_directory+@"\Objects");

//Exit game if main script doesn't exist
if (!ds_map_exists(global.scripts, "main.lua")) game_end();
else
{
    //Run main file script
    lua_add_file(state, global.scripts[? "main.lua"]);
   
    //Call entrance hook
    lua_add_function(state, "onStart", ref_onStart);
    lua_call(state, "onStart");
}
and then I have this as my ref_new function
Code:
/// @desc ref_new()
/// @arg string

show_debug_message("Creating object: "+string(data));
if ( argument_count == 1)    return lua_show_error("print: takes 1 arguments, got " + string(argument_count))
if (!is_string(argument[0])) return lua_show_error("print: expected a string for argument 1, got " + lua_print_value(argument[0]));

var data = load_json(global.names[? argument[0]]);


var box  = instance_create_depth(0, 0, 0, Box);
    box.name    = data[? "name"];
    box.depth   = data[? "depth"];
    box.hp      = data[? "health"];
    box.defence = data[? "defence"];
    box.offence = data[? "offence"];
    box.agility = data[? "agility"];
    box.frames  = load_json(data[? "frames"]);
    box.scripts = data[? "scripts"];
   
   
return box;
and this as my main script..
Code:
function onStart()
    box = new("box")
    print("entering main script");
end
no box object gets created
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
@YellowAfterlife thankyou but I have another question
we I do this in my lua controller object
Code:
/// @description Lua Create
// You can write your code in this editor

//Create universal file holders
global.names    = ds_map_create();
global.objects  = ds_map_create();
global.frames   = ds_map_create();
global.scripts  = ds_map_create();

state = lua_state_create();

//Init Library
lua_add_function(state, "print", ref_print);
lua_add_function(state, "new",   ref_new);

//Load files
load_files(working_directory+@"\Objects");

//Exit game if main script doesn't exist
if (!ds_map_exists(global.scripts, "main.lua")) game_end();
else
{
    //Run main file script
    lua_add_file(state, global.scripts[? "main.lua"]);
  
    //Call entrance hook
    lua_add_function(state, "onStart", ref_onStart);
    lua_call(state, "onStart");
}
and then I have this as my ref_new function
Code:
/// @desc ref_new()
/// @arg string

show_debug_message("Creating object: "+string(data));
if ( argument_count == 1)    return lua_show_error("print: takes 1 arguments, got " + string(argument_count))
if (!is_string(argument[0])) return lua_show_error("print: expected a string for argument 1, got " + lua_print_value(argument[0]));

var data = load_json(global.names[? argument[0]]);


var box  = instance_create_depth(0, 0, 0, Box);
    box.name    = data[? "name"];
    box.depth   = data[? "depth"];
    box.hp      = data[? "health"];
    box.defence = data[? "defence"];
    box.offence = data[? "offence"];
    box.agility = data[? "agility"];
    box.frames  = load_json(data[? "frames"]);
    box.scripts = data[? "scripts"];
  
  
return box;
and this as my main script..
Code:
function onStart()
    box = new("box")
    print("entering main script");
end
no box object gets created
You should not have
Code:
lua_add_function(state, "onStart", ref_onStart);
if you want to call a "onStart" function defined on Lua side - lua_add_function stores a reference to a GML script in the given global Lua variable, so you are overriding your function with a GML script.
 
S

Shadowblitz16

Guest
ok cool I will try it

EDIT: so what about this error..
Loading C:\Users\Shadowblitz16\AppData\Local\GameMakerStudio2\GMS2TEMP\LuaTest2_39EE9AB8_VM\\Objects\main.lua
Lua error: ...rStudio2\GMS2TEMP\LuaTest2_39EE9AB8_VM\\Objects\main.lua:2: print: takes 1 arguments, got 1

I get it from this
Code:
/// @desc ref_print()
/// @arg string

if ( argument_count != 1)  return lua_show_error("print: takes 1 arguments, got " + string(argument_count));
if (!is_real(argument[0])) return lua_show_error("print: expected a number for argument 1, got " + lua_print_value(argument[0]));

show_message(argument[0]);
 
Last edited by a moderator:
Top