├── Just the scripts ├── array_2d_sort.gml ├── ds_grid_to_array.gml ├── ds_list_add_list.gml ├── ds_list_add_map.gml ├── ds_list_create_from_keys.gml ├── ds_list_create_from_map.gml ├── ds_list_delete_value.gml ├── ds_list_pop_bot.gml ├── ds_list_pop_top.gml ├── ds_list_swap_values.gml ├── ds_map_add_multiple.gml ├── ds_map_find_key.gml ├── ds_map_flip.gml ├── ds_map_write_multiple.gml ├── json_load.gml ├── json_save.gml ├── json_secure_load.gml ├── json_secure_save.gml └── memory_clean.gml ├── Lazyeye's Data Scripts.yyz └── README.md /Just the scripts/array_2d_sort.gml: -------------------------------------------------------------------------------- 1 | /// @function array_sort(_array, _row); 2 | /// @desc Sorts the 2d array in an ascending order inside the given row. 3 | /// @param {array} _array 4 | /// @param {real} _row 5 | 6 | var a = argument0; 7 | var r = argument1; 8 | 9 | // Full progression 10 | for (var i = 0; i < array_height_2d(a); i++;) 11 | { 12 | // Individual sort 13 | for (var j = i; j > 0; j--;) 14 | { 15 | // Check for mis-order 16 | if (a[@ j, r] < a[@ j - 1, r]) 17 | { 18 | // Shift whole row 19 | for (var k = 0; k < array_length_2d(a, j); k++;) 20 | { 21 | var _held_data = a[@ j, k]; 22 | a[@ j, k] = a[@ j - 1, k]; 23 | a[@ j - 1, k] = _held_data; 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Just the scripts/ds_grid_to_array.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_grid_to_array(_grid, _destroy_grid) 2 | /// @desc Returns an array translated from a grid, with the option to destroy the grid afterwords. 3 | /// @arg {real} _grid 4 | /// @arg {bool} _destroy_grid 5 | 6 | // Translate grid into array 7 | var _array; 8 | for (var i = 0; i < ds_grid_width(argument0); i++;) 9 | { 10 | for (var j = 0; j < ds_grid_height(argument0); j++;) 11 | { 12 | _array[i, j] = argument0[# i, j]; 13 | } 14 | } 15 | 16 | // Destory grid 17 | if (argument1) 18 | { 19 | ds_grid_destroy(argument0); 20 | } 21 | 22 | return _array; -------------------------------------------------------------------------------- /Just the scripts/ds_list_add_list.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_add_list(_list, _list) 2 | /// @desc Adds a list to a list (for the purpose of JSON encoding) 3 | /// @arg {real} _target_list 4 | /// @arg {real} _source_list 5 | 6 | ds_list_add(argument0, argument1); 7 | var _index = ds_list_find_index(argument0, argument1); 8 | ds_list_mark_as_list(argument0, _index); -------------------------------------------------------------------------------- /Just the scripts/ds_list_add_map.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_add_map(_list, _map) 2 | /// @desc Adds a map to a list (for the purpose of JSON encoding) 3 | /// @arg {real} _list 4 | /// @arg {real} _map 5 | 6 | ds_list_add(argument0, argument1); 7 | var _index = ds_list_find_index(argument0, argument1); 8 | ds_list_mark_as_map(argument0, _index); -------------------------------------------------------------------------------- /Just the scripts/ds_list_create_from_keys.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_create_from_keys(_map) 2 | /// @desc Creates a list out of the given map's keys 3 | /// @arg {real} _map 4 | 5 | // Indices 6 | var _list = ds_list_create(); 7 | var _map = argument0; 8 | 9 | // DS testing (hardly a guarentee due to lack of true data types, but a basic check) 10 | if (not ds_exists(_map, ds_type_map)) 11 | { 12 | show_error("Error in ds_list_add_map_values: " + string(_map) + " does not point to a valid map.", false); 13 | exit; 14 | } 15 | 16 | // Loop through map 17 | var _key = ds_map_find_first(_map); 18 | while (not is_undefined(_key)) 19 | { 20 | ds_list_add(_list, _key); 21 | _key = ds_map_find_next(_map, _key); 22 | } 23 | 24 | // Return the new list 25 | return _list; -------------------------------------------------------------------------------- /Just the scripts/ds_list_create_from_map.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_create_from_map(_map) 2 | /// @desc Creates a list out of the given map's values 3 | /// @arg {real} _map 4 | 5 | // Indexes 6 | var _list_index = ds_list_create(); 7 | var _map_index = argument0; 8 | 9 | // DS testing (hardly a guarentee due to lack of true data types, but a basic check) 10 | if (not ds_exists(_map_index, ds_type_map)) 11 | { 12 | show_error("Error in ds_list_add_map_values: " + string(_map_index) + " does not point to a valid map.", false); 13 | exit; 14 | } 15 | 16 | // Loop through map 17 | var _key = ds_map_find_first(_map_index); 18 | while (not is_undefined(_key)) 19 | { 20 | var _value = _map_index[? _key]; 21 | 22 | // DS testing 23 | if (ds_exists(_value, ds_type_list)) 24 | { 25 | ds_list_add(_list_index, _value); 26 | } 27 | else if (ds_exists(_value, ds_type_map)) 28 | { 29 | ds_list_add(_list_index, _value); 30 | } 31 | else 32 | { 33 | ds_list_add(_list_index, _value); 34 | } 35 | _key = ds_map_find_next(_map_index, _key); 36 | } 37 | 38 | // Return the new list 39 | return _list_index; -------------------------------------------------------------------------------- /Just the scripts/ds_list_delete_value.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_delete_value(_list, _value) 2 | /// @desc Finds and deletes the given value from a list 3 | /// @arg {real} _list 4 | /// @arg {*} _value 5 | 6 | var _index = ds_list_find_index(argument0, argument1); 7 | ds_list_delete(argument0, _index); -------------------------------------------------------------------------------- /Just the scripts/ds_list_pop_bot.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_pop_bot(_list) 2 | /// @desc Returns and removes the top value (0 index) from a list 3 | /// Yes, pop_back would be more proper, but pop_bot also sounds hilarious 4 | /// @arg {real} _list 5 | 6 | var _val = argument0[| ds_list_size(argument0) - 1]; 7 | ds_list_delete(argument0, ds_list_size(argument0) - 1); 8 | return _val -------------------------------------------------------------------------------- /Just the scripts/ds_list_pop_top.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_pop_top(_list) 2 | /// @desc Returns and removes the top value (0 index) from a list 3 | /// Yes, pop_front would be more proper, but pop_top sounds hilarious 4 | /// @arg {real} _list 5 | 6 | var _val = argument0[| 0]; 7 | ds_list_delete(argument0, 0); 8 | return _val -------------------------------------------------------------------------------- /Just the scripts/ds_list_swap_values.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_list_swap_values(_list, _index_one, _index_two) 2 | /// @desc Takes the given two indices and swaps their values in a list 3 | /// @arg {real} _list 4 | /// @arg {real} _index_one 5 | /// @arg {real} _index_two 6 | 7 | var _list = argument0; 8 | var _index_one = argument1; 9 | var _index_two = argument2; 10 | var _val_one = _list[| _index_one]; 11 | var _val_two = _list[| _index_two]; 12 | _list[| _index_one] = _val_two; 13 | _list[| _index_two] = _val_one; -------------------------------------------------------------------------------- /Just the scripts/ds_map_add_multiple.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_map_add_multiple(_id, _key, _value, ...) 2 | /// @desc Adds multiple keys and values to the given map 3 | /// @arg {string} _key 4 | /// @arg {*} _value 5 | /// @arg ... 6 | 7 | var _map = argument[0]; 8 | for (var i = 1; i < argument_count; ++i;) 9 | { 10 | var _key = argument[i]; 11 | var _value = argument[++i]; 12 | ds_map_add(_map, _key, _value); 13 | } -------------------------------------------------------------------------------- /Just the scripts/ds_map_find_key.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_map_find_key(_map, _value) 2 | /// @desc Returns the first key that holds the given value in a map 3 | /// @arg {real} _map 4 | /// @arg {*} _value 5 | 6 | var _key = ds_map_find_first(argument0); 7 | while (not is_undefined(_key)) 8 | { 9 | if (argument0[? _key] == argument1) 10 | { 11 | return _key 12 | } 13 | _key = ds_map_find_next(argument0, _key); 14 | } -------------------------------------------------------------------------------- /Just the scripts/ds_map_flip.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_map_flip(_map) 2 | /// @desc Returns a map with the keys and values swapped from the given map 3 | /// @arg {real} _map 4 | 5 | var _new_map = ds_map_create(); 6 | var _key = ds_map_find_first(argument0); 7 | while (not is_undefined(_key)) 8 | { 9 | ds_map_add(_new_map, argument0[? _key], _key); 10 | _key = ds_map_find_next(argument0, _key); 11 | } 12 | 13 | return _new_map -------------------------------------------------------------------------------- /Just the scripts/ds_map_write_multiple.gml: -------------------------------------------------------------------------------- 1 | /// @function ds_map_write_multiple(_id, _key, _value, ...) 2 | /// @desc Updates multiple values in the given map 3 | /// @arg {real} _map_index 4 | /// @arg {string} _key 5 | /// @arg {*} _value 6 | /// @arg ... 7 | 8 | var _map = argument[0]; 9 | for (var i = 1; i < argument_count; i++;) 10 | { 11 | var _key = argument[i]; 12 | var _value = argument[++i]; 13 | if (not ds_map_exists(_map, _key)) show_error("Error in ds_map_write_multiple: key not found!", false); 14 | _map[? _key] = _value; 15 | } -------------------------------------------------------------------------------- /Just the scripts/json_load.gml: -------------------------------------------------------------------------------- 1 | /// @function json_load(_filename) 2 | /// @desc Loads the JSON file and returns its data in a map 3 | /// @arg {string} _filename 4 | 5 | var _map = ds_map_create(); 6 | var _buff = buffer_load(argument0); 7 | _map = json_decode(buffer_read(_buff, buffer_text)); 8 | buffer_delete(_buff); 9 | return _map; -------------------------------------------------------------------------------- /Just the scripts/json_save.gml: -------------------------------------------------------------------------------- 1 | /// @function json_save() 2 | /// @desc Saves the given map to a file in JSON format with the given filename. 3 | /// @param {real} _map 4 | /// @param {string} _filename 5 | 6 | var _str = json_encode(argument0); 7 | var _str = json_minify(_str); 8 | var _str = json_beautify(_str); 9 | var _buff = buffer_create(string_byte_length(_str), buffer_fixed, 1); 10 | buffer_write(_buff, buffer_text, _str); 11 | buffer_save(_buff, argument1); 12 | buffer_delete(_buff); -------------------------------------------------------------------------------- /Just the scripts/json_secure_load.gml: -------------------------------------------------------------------------------- 1 | /// @function json_secure_load(_file, _crypt_key) 2 | /// @desc Loads the encrypted JSON file and returns its data in a map 3 | /// NOTE! This function will only work with the script 'json_secure_save' by lazyeye! 4 | /// @arg {string} _file 5 | /// @arg {real} _crypt_key 6 | 7 | // Set seed 8 | var _seed = random_get_seed(); 9 | random_set_seed(argument1); 10 | 11 | // Decoding 12 | var _map = ds_map_create(); 13 | var _buff = buffer_load(argument0); 14 | buffer_seek(_buff, buffer_seek_start, 0); 15 | var _new_buff = buffer_create(buffer_get_size(_buff) + 3, buffer_fixed, 1); 16 | repeat (buffer_get_size(_buff) / 4) 17 | { 18 | var _bytes = buffer_read(_buff, buffer_u32); 19 | var _bytes = _bytes ^ irandom(0xffffffff); 20 | buffer_write(_new_buff, buffer_u32, _bytes); 21 | } 22 | 23 | // Cleanup / return map 24 | buffer_seek(_new_buff, buffer_seek_start, 0); 25 | var _map = json_decode(buffer_read(_new_buff, buffer_text)); 26 | buffer_delete(_buff); 27 | buffer_delete(_new_buff); 28 | random_set_seed(_seed); 29 | return _map; -------------------------------------------------------------------------------- /Just the scripts/json_secure_save.gml: -------------------------------------------------------------------------------- 1 | /// json_secure_save(_map, _filename, _crypt_key) 2 | /// @description Saves the given ds_map to a file in an encoded JSON format 3 | /// with the given filename and encryption key. 4 | /// @arg {real} _map 5 | /// @arg {string} _filename 6 | /// @arg {real} _crypt_key 7 | 8 | // Recrod / set seed 9 | var _seed = random_get_seed(); 10 | random_set_seed(argument2); 11 | 12 | // Encode data 13 | var _str = json_encode(argument0); 14 | var _buff = buffer_create(string_byte_length(_str), buffer_fixed, 1); 15 | 16 | // Create buffers 17 | buffer_write(_buff, buffer_text, _str); 18 | buffer_seek(_buff, buffer_seek_start, 0); 19 | buffer_resize(_buff, buffer_get_size(_buff) + 3); 20 | var _new_buff = buffer_create(buffer_get_size(_buff), buffer_fixed, 1); 21 | 22 | // Encode buffer 23 | repeat (buffer_get_size(_buff) / 4) 24 | { 25 | var _bytes = buffer_read(_buff, buffer_u32); 26 | var _bytes = _bytes ^ irandom(0xffffffff); 27 | buffer_write(_new_buff, buffer_u32, _bytes); 28 | } 29 | 30 | // Save and cleanup 31 | buffer_save(_new_buff, argument1); 32 | buffer_delete(_buff); 33 | buffer_delete(_new_buff); 34 | random_set_seed(_seed); -------------------------------------------------------------------------------- /Just the scripts/memory_clean.gml: -------------------------------------------------------------------------------- 1 | /// memory_clean() 2 | /// @function Attempts to destroy all persistent instances, data structures, buffers, and surfaces. 3 | /// Prints a summary to the console. 4 | /// NOTE: This script isn't a guarantee! The script will stop scanning after 5 | /// it has read 100 indices with no data found for each type. 6 | /// While this should be sufficient, it is possible that gaps in data may exist. 7 | /// Do note that if you do intend to use this as your primary source of cleaning, you should avoid 8 | /// manually remove your data structures in other cleanup events. 9 | 10 | // Counts 11 | var _list_count = 0; 12 | var _map_count = 0; 13 | var _grid_count = 0; 14 | var _priority_count = 0; 15 | var _queue_count = 0; 16 | var _stack_count = 0; 17 | var _buffer_count = 0; 18 | var _surface_count = 0; 19 | var _instance_count = 0; 20 | 21 | // Break variable 22 | var _break = 0; 23 | 24 | // Time 25 | var _start = current_time; 26 | 27 | // Instance Destruction 28 | with (all) 29 | { 30 | if (persistent == true and id != other.id) 31 | { 32 | instance_destroy(); 33 | _instance_count++; 34 | } 35 | } 36 | 37 | // Data Destruction 38 | for (var i = 0; i < 100000; i++;) 39 | { 40 | // List destroy 41 | if (ds_exists(i, ds_type_list)) 42 | { 43 | ds_list_destroy(i); 44 | _list_count++; 45 | _break = 0; 46 | } 47 | 48 | // Map destroy 49 | if (ds_exists(i, ds_type_map)) 50 | { 51 | ds_map_destroy(i); 52 | _map_count++; 53 | _break = 0; 54 | } 55 | 56 | // Grid destroy 57 | if (ds_exists(i, ds_type_grid)) 58 | { 59 | ds_grid_destroy(i); 60 | _grid_count++; 61 | _break = 0; 62 | } 63 | 64 | // Priority queue destroy 65 | if (ds_exists(i, ds_type_priority)) 66 | { 67 | ds_priority_destroy(i); 68 | _priority_count++; 69 | _break = 0; 70 | } 71 | 72 | // Queue destroy 73 | if (ds_exists(i, ds_type_queue)) 74 | { 75 | ds_queue_destroy(i); 76 | _queue_count++; 77 | _break = 0; 78 | } 79 | 80 | // Stack destroy 81 | if (ds_exists(i, ds_type_stack)) 82 | { 83 | ds_stack_destroy(i); 84 | _stack_count++; 85 | _break = 0; 86 | } 87 | 88 | // Buffer destroy 89 | if (buffer_exists(i)) 90 | { 91 | buffer_delete(i); 92 | _buffer_count++; 93 | _break = 0; 94 | } 95 | 96 | // Surface destroy 97 | if (surface_exists(i)) 98 | { 99 | surface_free(i); 100 | _surface_count++; 101 | _break = 0; 102 | } 103 | 104 | _break++; 105 | 106 | // If we have passed through 100 iterations with no data found 107 | if (_break >= 100) 108 | { 109 | show_debug_message("\nMemory cleared. Summary: " + "\n" 110 | + "Lists: " + string(_list_count) + "\n" 111 | + "Maps: " + string(_map_count) + "\n" 112 | + "Grids: " + string(_grid_count) + "\n" 113 | + "Priority Queues: " + string(_priority_count) + "\n" 114 | + "Queues: " + string(_queue_count) + "\n" 115 | + "Stacks: " + string(_stack_count) + "\n" 116 | + "Buffers: " + string(_buffer_count) + "\n" 117 | + "Surfaces: " + string(_surface_count) + "\n" 118 | + "Persistent Instances: " + string(_instance_count) + "\n" 119 | + "Iterations: " + string(i) + "\n" 120 | + "Total Time: " + string(current_time - _start) + "\n"); 121 | return; 122 | } 123 | } 124 | 125 | // In case we somehow don't break? 126 | show_debug_message("\nMemory cleared. Summary:" + "\n" 127 | + "Lists: " + string(_list_count) + "\n" 128 | + "Maps: " + string(_map_count) + "\n" 129 | + "Grids: " + string(_grid_count) + "\n" 130 | + "Priority Queues: " + string(_priority_count) + "\n" 131 | + "Queues: " + string(_queue_count) + "\n" 132 | + "Stacks: " + string(_stack_count) + "\n" 133 | + "Buffers: " + string(_buffer_count) + "\n" 134 | + "Surface: " + string(_surface_count) + "\n" 135 | + "Persistent Instances: " + string(_instance_count) + "\n" 136 | + "Iterations: " + string(i) + "\n" 137 | + "Total Time: " + string(current_time - _start) + "\n"); 138 | return; -------------------------------------------------------------------------------- /Lazyeye's Data Scripts.yyz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameMakerDiscord/Lazy-Data-Scripts/e61f28570266ea8e2f04b68233c255971fe470f8/Lazyeye's Data Scripts.yyz -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lazy Data Scripts 2 | 3 | Do you love data as much as I do? If so, you may be a bit frustrated at how working in GMS isn't quite as elegant as other languages. Fear not! This collection of scripts adds many "missing" or otherwise useful functions to be used inside of GMS2. This is a library that I have constructed for the past few months whenever I had need for a new script. I will more than likely be adding more as I come up with more ideas. 4 | 5 | If you have ideas for other functions, let me know and I'll look into making them! 6 | 7 | ## Current Functions 8 | 9 | ### `ds_list_add_list(_list, _list)` 10 | 11 | Adds a list to a list (for the purpose of JSON encoding) 12 | 13 | ### `ds_list_add_map(_list, _map)` 14 | 15 | Adds a map to a list (for the purpose of JSON encoding) 16 | 17 | ### `ds_list_create_from_map(_map)` 18 | 19 | Creates a list out of the given map's values 20 | 21 | ### `ds_list_create_from_keys(_map)` 22 | 23 | Creates a list out of the given map's keys 24 | 25 | ### `ds_list_swap_values(_list, _index_one, _index_two)` 26 | 27 | Takes the given two indices and swaps their values in a list 28 | 29 | ### `ds_list_delete_value(_list, _value)` 30 | 31 | Finds and deletes the given value from a list 32 | 33 | ### `ds_list_pop_bot(_list)` 34 | 35 | Adds a map to a list (for the purpose of JSON encoding) 36 | 37 | ### `ds_list_pop_top(_list)` 38 | 39 | Returns and removes the top value (0 index) from a list 40 | 41 | ### `ds_map_add_multiple(_id, _key, _value, ...)` 42 | 43 | Adds multiple keys and values to the given map 44 | 45 | ### `ds_map_write_multiple(_id, _key, _value, ...)` 46 | 47 | Updates multiple values in the given map 48 | 49 | ### `ds_map_find_key(_map, _value)` 50 | 51 | Returns the first key that holds the given value in a map 52 | 53 | ### `ds_map_flip(_map)` 54 | 55 | Returns a map with the keys and values swapped from the given map 56 | 57 | ### `array_sort(_array, _row)` 58 | 59 | Sorts the 2d array in an ascending order inside the given row 60 | 61 | ### `ds_grid_to_array(_grid, _destroy_grid)` 62 | 63 | Returns an array translated from a grid, with the option to destroy the grid afterwords. 64 | 65 | ### `json_save()` 66 | 67 | Saves the given map to a file in JSON format with the given filename. 68 | 69 | ### `json_load(_filename)` 70 | 71 | Loads the JSON file and returns its data in a map 72 | 73 | ### `json_secure_save(_map, _filename, _crypt_key)` 74 | 75 | Saves the given ds_map to a file in an encoded JSON format 76 | 77 | ### `json_secure_load(_file, _crypt_key)` 78 | 79 | Loads the encrypted JSON file and returns its data in a map 80 | 81 | ### `memory_clean()` 82 | 83 | Attempts to destroy all persistent instances, data structures, buffers, and surfaces. 84 | --------------------------------------------------------------------------------