#How do you load several objects in the game using json?

1 messages · Page 1 of 1 (latest)

mighty bison
#

hey again, it is this Sunguy again, so... i have this question, i was following sara spalding's save and loading json tutorial, and... when i want to load variables for several objects from the variables of other objects i saved from the save data script, do i have to put all of their respective variables under the ```var _loadEntity = array_pop(_loadData);
with (instance_create_layer (0,0,layer, asset_get_index(_loadEntity.obj)))
{
//your loaded object variables here
}

codeblock or do i have to do something else so that the game can load the states for all the other objects? This is the part that i am getting stuck at
https://www.youtube.com/watch?v=R84mR52QaMg

Like the other tutorial I did, only better. A universal approach for when you need to save or load data in GameMaker, using JSON, structs and arrays.

▶ Source code: https://www.patreon.com/posts/44109513
▶ Support my work: https://www.patreon.com/shaunjs
▶ This same tutorial for older versions of GameMaker: https://www.youtube.com/watch?v=QmxQb...

▶ Play video
mighty bison
deep idol
#

do i have to put all of their respective variables under the
Only the ones that you absolutely need

#

You do not need to save all of the variables if you don't need most of them

#

And especially if you can just recreate that data, either from using said variables or the instance already creates them

#

(Like an object that creates methods, you don't need to save those)

mighty bison
#

thats the part that i am not sure about

deep idol
#

It seems that you are pushing more than one object type

#

So it'll be at least more than 1 object

#

And more than 1 instance

#

...Did you try any of it

#

Or are you just asking before trying things?

mighty bison
mighty bison
# deep idol ...Did you try any of it

no i didn't, i am asking it before trying because saving and loading stuff is pretty sensitive compared to anything else, it could mess up stuff if the loading code does not take into account several object type

deep idol
#

It's not that sensitive

#

Besides, I think you're at that point in coding that you can make those fair judgement and guesses based on the existing code

#

Worse case scenario, the saving or loading is broken, you can fix it

mighty bison
deep idol
#

Take a guess

mighty bison
# deep idol Take a guess

okay, well, the loading script will get triggered whenever i will enter back the level room where i saved the stuff, but... if the loading script is not put to use when i enter a level (like if its trigger activation code is removed or commented out), then the game will load default GM room editor assets as how it was defined in room editor instead of loading the stuff from the load data script. Is that how it would work?

deep idol
#

I can't entirely comment on that aspect, but I would assume as such coming from your own words

#

I think it's better to just give it a whirl

#

We could play 20 questions

#

Or you could answer all 20 in about 2-5 minutes

#

By testing your game

mighty bison
deep idol
#

The "safe" save directory

#

And that differs between platform

#

(Unless you're on desktop and sandbox is disabled, then rules are likely out)

pale mangoBOT
#

This read-only variable points to the area of local storage that is reserved for your game on the target device. See Save Area Locations.

deep idol
#

Will at least give you the path to where it would save

#

In game

#

Otherwise you can just read the manual page here and look up the respective OS

mighty bison
#

but alright

deep idol
#

I know

#

I'm linking you the manual with the intent on reading 🙂

mighty bison
#

as i didnt do that yet, i probably should

deep idol
#

I think you should just test it anyway

#

Before you do that

#

There's a chance that your code maybe does that already

mighty bison
#

i know, but i want it to make sure the instance exists for it to save the object anyway just for safety measures

deep idol
#

Sun, listen to me

#

I think you should just try your code

#

Before you go running around and making changes or adding in "safety measures"

#

Cause like, are you certain that you need to add them?

mighty bison
#

i am very sure, things can be very random in life, and you have to prepare for things

deep idol
#

Well if you are 110% sure, don't let me stop you

mighty bison
#

i will report any results that came from testing and if i run into the problems that i had feared about

mighty bison
# deep idol Well if you are 110% sure, don't let me stop you

ok so this thing happened when i tested loading feature, it seem to be not being able to load any progress at all, and my suspicion goes as to why, because of the fact that pause menu disables the layers when it activates, and because that the save game progress option only works if it finds that instances exist.

#

i am gonna do and make so that the game progress gets saved only if i press a letter button while being in the game itself and not in the pause menu

deep idol
deep idol
#

A deactivated instance would indeed not be included with the with()

#

You’d have to reactivate instances briefly

#

And then deactivate them again for that to work otherwise

mighty bison
#

yeah, got it

mighty bison
#

i think maybe its because the length variable wasnt set in its parent object since its create and step event use its parents event

#

ok i was able to make it save the progress, but when i try to load, it crashes because one of the objects does not have a walksp variable

#

yep, thats exactly one of things i feared about

#

we need to make so that the load script loads individual variables for each separate object type in the game

#

and the load script i have loads all the variables i wrote from the saved object types i loaded and does not distinguish other object types

mighty bison
#

like if i name obj_ground_door_button object type as
obj_door : object_get_name(object_index),
instead of
obj : object_get_name(object_index),
and then in load script make ``` var _loadDoorEntity = array_pop(_loadData);
with (instance_create_layer (0,0,layer, asset_get_index(_loadDoorEntity.obj_door)))

to load THAT object type's variables, then would it load the individual variables for them, right?
deep idol
#

Would you prefer spaghetti-based solutions

#

Or a more cleaner solution

mighty bison
deep idol
#

Define import/export methods for each object you wish to save/load, with export returning a struct of variables (on save), import assigning values from said struct (on load)

#

Then instead of saving a bunch of variables

#

In that upper most Struct

#

You can have

#
with(object_of_choice) {
var _saveData = {
   obj: obj_name,
   data: export(),
}
 // push
};
#

You don’t need to know what each of the variables are, or redesign your code to constantly deal with varying different objects

#

You can just have the objects handle export/import instead

#

A lot of save tutorials go down this route for the same reason

#

It’s clean

mighty bison
deep idol
#

Are you aware of what methods are, at all?

#

If you don’t, think about them like a function but it belongs to an instance

#

Scope wise

mighty bison
# deep idol Are you aware of what methods are, at all?

the ones with import and exporting, no, but wait you mean that, i can make a function within a object that has the names of all the variables. like...

//basic variables
hsp = 0
vsp = 0;

function living_object_variables(){
  hsp = 0
  vsp = 0;
}

this?

#

or maybe... like this?

scr_living_object_variables:
function living_object_variables(){
  hsp = 0
  vsp = 0;
}

living_object create event:
  scr_living_object_variables() //in place of the variables that would have been normally defined?
deep idol
#

Close but yeah

#

Methods are normally as living_object_variables = function()

#

Just because it’s easier to tell it’s not a global function

#

(Also GameMaker isn’t particularly the happiest with it defined the usual way)

#

(I’d suggest writing that in your notes/scratch pad project btw)

#

A method is just a function that belongs to an instance

#

I’ll get you a quick example

#
// obj_alice create event
get_name = function() {
    return object_get_name(object_index);
}

// obj_bob create event
get_name = obj_alice.get_name;

show_message(get_name());
#

In this example

#

Alice owns "get_name"

#

So when you have Bob take it from "Alice" and call it

#

You get obj_alice

#

Because the instance of Alice owns it, not bob

#

By that itself, it’s useful

#

But also since an object can define its own methods

#

You can give every single instance a custom method that does exactly what you want

#

So you could use it to define variables

#

Or to import/export any data per object type

mighty bison
#

right, uhh, i am gonna try and use this method when i come back because i need to go and clean snow outside my house as my dad told me to do it as a task

deep idol
#

All good

mighty bison
#

as soon as i come back and try it out, i will report the results

deep idol
#

I’d suggest try adding this to a test project and testing it out first

#

iirc this video does just that method

mighty bison
#

but i gtg, i will brb

deep idol
#

You’re right, it didn’t

#

Note to self: Tab needs to write a tutorial

mighty bison
# deep idol Close but yeah

okay i am back, heres something i had learned, apparently putting all the create variables from the object to the script of the variables then deleting the variables from the create event and placing the script in place of the variables is not a good idea because some events like draw event would not know the variable since the variable it uses is within that script and not the object and the game will think of it as "undefined" (feather messages told me this when i was trying to do that)

#

so instead of placing a script with variables in create event of the object, i need to define it as

  //variables here
}

instead, right?

deep idol
#

In fact

#

I don’t even know why we’re changing that right now

#

We’re just meant to do save/load, aren’t we?

mighty bison
#

yes

deep idol
#

Yes, so I think we shouldn’t focus too hard on changing how we define our variables in create ^^;

#

Think we should focus on export/import for now

mighty bison
deep idol
#

So, remember how we were defining our struct for each object with variables like x/y/image_index, etc?

#

We just have export() create a struct

#

And return that

deep idol
#

data just holds onto all of our variables we want to save, as a separate struct

#

This is pretty the same case as if you were to make separate global functions for each object type

#

So just

#
export = function() {
     return {
          x: x,
          y: y,
          image_index: image_index,
      };
}
mighty bison
#

or wait no

deep idol
#

That’s the point

#

You make a method per object type

#

In their create event

#

This is so you aren’t cluttering up your save/load logic with a bunch if/else or big switch for different objects

#

You just create an instance from the object and handle it with their import method

#

It keeps your code cleaner that way

deep idol
mighty bison
# deep idol You make a method *per* object type

ahh wait i got it, so like...

export = function() {
     return {
          x: x,
          y: y,
          image_index: image_index,
      };

//then inside the save data script:

with(living object) {
var _saveData = {
   obj: obj_name,
   data: export(),
}
 // push
};

that yeah?

deep idol
#

Yes

mighty bison
#

woohoo!

deep idol
#

Well, ofc obj_name being the objects name

#

import() is not much more complicated

#
import = function(_data) {
    x = _data.x;
    y = _data.y;
    image_index = _data.image_index;
}
#

And then on load, as you’re looping the array, you can do for example

#
with(instance_create_layer(0,0,"Instances", asset_get_index(__save[i].name))) {
     import(_save[i].data);
}
#

Many more things you can do to make it a bit more nicer

#

But that’s the general gist

mighty bison
# deep idol ```gml with(instance_create_layer(0,0,"Instances", asset_get_index(__save[i].nam...

i think i am getting the full picture now, but uhh... i am thinking that it would work like this:

export = function() {
     return {
          x: x,
          y: y,
          image_index: image_index,
      };
}

get_name = function(){
  return object_get_name(object_index);
}

import = function(_data) {
    x = _data.x;
    y = _data.y;
    image_index = _data.image_index;
}

//then inside the save data script:

with(living object) {
var _saveObjectData = {
   obj: get_name(),
   data: export(),
}
 array_push(_SaveLevelData, _SaveObjectData);
};

var _string = json_stringify(_SaveLevelData); 
    var _buffer = buffer_create(string_byte_length(_string) +1, buffer_fixed, 1); 
    buffer_write(_buffer, buffer_string, _string); 
    buffer_save(_buffer, "savedgame.save"); 
    buffer_delete(_buffer); 

//then the load script:
var _buffer = buffer_load( "savedgame.save"); 
var _string = buffer_read(_buffer, buffer_string); 
buffer_delete(_buffer);
var _loadData = json_parse(_string); 

var _loadEntity = array_pop(_loadData); 
  with(instance_create_layer(0,0,"Instances", asset_get_index(_loadEntity[i].obj))) {
       import(_LoadEntity[i].data);
  }
deep idol
#

The load portion would need to account for the whole array, since right now it’s only popping off 1 entry

#

But otherwise yes

#

(Also export is missing a right curtly brace)

#

The other thing to consider as well, this assumes that the loading script is at some point dealing with the instances that do already exist within the room (otherwise you’re making additional instances on top of the existing ones)

mighty bison
mighty bison
deep idol
#

nods

mighty bison
# deep idol *nods*

this is a bit unrelated, but would there be even easier way to save game data sometime in gamemaker's future? like in new updates and such?

#

like something that wouldn't require deleting existing instances and being able to load data into those existing instances?

deep idol
#

There are solutions you can apply now, but admittedly they aren’t the best. Especially if you’re adjusting where instance positions are in the room editor a lot

#

But you can save the xstart/ystart variables at the root of the struct (not data), and instead of destroying every single instance and replacing it with a new one

#

You check if there’s an object type that matches the same xstart/ystart.

#

And then you can call their import function instead

#

The xstart/ystart is the least work

mighty bison
# deep idol The xstart/ystart is the least work

ahh alright, that seems to be very interesting, also, destroying instances is kinda a problem because some objects in my game have a event that does something whenever they're destroyed, like spawning a coin, or spawning a powerup

#

and if i destroy that means they will spawn them even though that theoretically they shouldn't when we're loading them

deep idol
#

Instance destroy has an argument that can avoid that

pale mangoBOT
#

You call this function whenever you wish to "destroy" an instance, normally triggering a Destroy Event and also a Clean Up Event. This will remove it from the room until the room is restarted (unless the room is persistent). Calling the function with no arguments will simply destroy the instance that is currently in scope and running the code, but you can provide an optional "id" argument and target a specific instance by using the instance id value, or you can target all instances of a particular object by using an object_index. For example:

Arguments
id: OPTIONAL The instance ID to destroy, or the object asset to destroy instances of (optional, default is the calling instance)
execute_event_flag: OPTIONAL Set to true or false to perform the Destroy event or not (optional, default is true)

deep idol
#

If you set the second argument to false, it skips the Destroy event

mighty bison
#

ahhh

#

thats awesome

#

glad that feature exists!

deep idol
mighty bison
#

is it "get_name"? like...
_loadEntity[get_name]
this? or something else needs to be wrotten in place of [i]?

mighty bison
#

ok maybe later, i will come back to this post sometime later again

deep idol
#

Why does it say 84 fields omitted?

#

What are you exporting

deep idol
mighty bison
deep idol
#

I made an assumption based on an array loop

#

I think you can figure that out

mighty bison
#

Dont worry about it okay? There are reasons why. I just cant really explain it in english to you. But just know that i know what i am doing.

deep idol
#

I don't think a ping reply is needed every time

#

Maybe I want an explanation before proceeding

#

Unless you prefer to not get help

mighty bison
# deep idol Maybe I want an explanation before proceeding

Sorry its sometimes a habit for me to ping. But listen, those variables i export they're needed for the player's states, although, i could remove some of these variables if they turn out to be not needed, i am just a type of guy that would have wanted to take into account everything necessary for the safety.

deep idol
#

Do you take account for all built in variables too?

#

Not trying to say what you're saving isn't wrong, but I think it's good to evaluate what you need, and what you can just recreate

#

If it's data that you're saving that the player will have when you create an instance of them, then you don't need it

#

If it's state specific variables that are like timers and such

#

Then I could say saving them is worthwhile

#

You can be that type of guy sure, but also saving everything is bad for not just serializing/deserializing nightmares, but also because it's a bunch of unnecessary data taking up space you don't need

mighty bison
#

And i could remove them

deep idol
#

I'm just saying haha

#

It's better to make sure that stuff you don't need to be saved, that can be recreated on import, is definitely doable

mighty bison
#

Right, but be rest assured i can check what i actually need or not. I can figure that out myself, i do remember a couple of things that dont change at all

deep idol
#

nods

mighty bison
# deep idol I made an assumption based on an array loop

hey tabby fax, i wanna show this but i got this error when i tried loading the assets into the game, it says it cant find the object with grabbed variable at the load script, i removed the part with [i] to see if it would work just fine without it and it seems like it cant?

#

and if i try using the [get_name] part after the _loadEntity, i get this error instead:

deep idol
#

Okay, just to double clarify

#

Do you understand completely where a method is stored?

deep idol
#

(Could be also that grabbed wasn't exported, but hard to tell)

deep idol
mighty bison
deep idol
#

Nope

#

Try again

mighty bison
deep idol
#

Correct

#

Does it exist outside of that object?

mighty bison
deep idol
#

Does it actually?

mighty bison
deep idol
#

If no instance of that object exists

#

Does it actually exist?

#

If you want a genuine answer

mighty bison
#

no

deep idol
#

Correct

#

get_name is a variable

mighty bison
#

its a function

deep idol
#

Nope

#

It's an instance variable, that holds onto a method

#

It. Does. Not. Exist. Globally.

#

Getting that out of the way

deep idol
#

_loadEntity[get_name] is not needed

#

None of that is

#

Just _loadEntity.data

#

My suspicion is that one of your export methods happen to not be returning a struct

#

So that's why it's throwing an error on import

mighty bison
#

i tested the stuff out it all works just how it should, although now we would need to make a saving hierarchy system for separate rooms so that the game doesnt load the game state that i saved from other rooms and only loads the state that i saved in the room i saved it in

#

and how can we do that?

mighty bison
#

so how do we make it save and load stuff for separate rooms then?

deep idol
#

I can give you some ideas on where to take it from there

#

How familiar are you with structs as a whole?

mighty bison
#

i am half familiar with it, i sorta know what they are, like... for certain functions, but dont know them in-depth

deep idol
#

nods that's all good

#

We know that a struct is basically a very light weight object by comparison, just a container for variables

#
person = {
  name: "Alice",
  age: 27
};

show_debug_message(person.name);
#

So within reason, they can only follow variable defining rules

#

...However, there is one exception to that rule

#

Structs come with a ton of functionality, some that allow you to get/set from a struct, bypassing conventional rules

#
person = {};
person[$ "name"] = "Alice";
person[$ "age"] = 27;

show_debug_message(person[$ "name"]);
#

Keep in mind, it's pretty much the same as doing

#
person = {};
person.name = "Alice";
person.age = 27;

show_debug_message(person.name);
#

Except it's utilising what is known as the struct accessor (which is in of itself a supplement of struct_get/struct_get)

#

Why I bring this up, is because unlike the dot operator, the struct accessor lets you define things that aren't normally apart of a variable

#

But also can take in any string

#

Which means

#
// Defining a global room save struct in some script
global.saveData = {
  rooms: {},
};

global.saveData[$ room_get_name(rm_test_game)] = {};
#

The same as doing

// Defining a global room save struct in some script
global.saveData = {
  rooms: {},
};

struct_set(global.saveData, room_get_name(rm_test_game), {});
#

And you can fetch it t oo

show_debug_message(global.saveData[$ room_get_name(rm_test_game)]);

or

show_debug_message(struct_get(global.saveData, room_get_name(rm_test_game)));
#

Going with that, this means that you can save your data per room, and assign that data to the current room, to global.saveData

#

Then save global.saveData as a json file

#

On load, you would convert it back into a struct, and then fetch the current room, via room_get_name(room), and the struct accessor

#

And then you can point to the current room you wish to load in

#

I suggest taking a read on struct accessors here if you want anymore information

#

Or using these functions when it comes to interacting with structs, if it makes it easier for you

pale mangoBOT
#

With this function you can set the value of a given variable in a struct. You supply the struct reference as well as the name of the variable to set the value of as a string (see example code below), and then finally the value to set (can be any valid data type). If the variable does not exist already in the struct it will be created and then assigned the value.

Arguments
struct: The struct reference to set
name: The name of the variable to set (as a string)
val: The value to set the variable to

#

This function gets the value from a given named variable within a struct.

Arguments
struct: The struct reference to use
name: The name of the variable to get (as a string)

deep idol
#

As well as this, just to check if some room exists on save/load

pale mangoBOT
#

This function checks whether a variable exists within the given struct or not. You supply the struct reference to use as well as the variable name to check for as a string (see example code below). The function will return true if a variable with the given name exists for the struct and false otherwise.

Arguments
struct: The struct reference to check
name: The name of the struct variable to check for (as a string)

mighty bison
# pale mango

ohhhh nice, i will try to read them when i can, i need to go and eat some breakfast and stuff, i will get back later!

mighty bison
#

and... if i am assigning the data to multiple rooms, do i have to go like...

array_push(global.SaveRoomData[$ room_get_name(ROOM NAME 2)], SavePlayerEntity);
array_push(global.SaveRoomData[$ room_get_name(ROOM NAME 3)], SavePlayerEntity);

?

uneven moss
#

{} is a struct

mighty bison
uneven moss
#

yes you do

#

is global.SaveRoomData[$ room_get_name(ROOM NAME 3)] supposed to be a struct or array

mighty bison
uneven moss
#

i know

uneven moss
#

the [$ room_get_name(..}] stuff is correct

#

your code is not, because you're inconsistent in whether global.SaveRoomData [$ room_get_name(..}] is a struct or array

mighty bison
uneven moss
#

then you can't use array_push

uneven moss
#

not global.SaveRoomData

#

global.SaveRoomData[$ room_get_name(...)]

#

the thing you're array_push-ing to

#

maybe, it is supposed to be an array, and array_push is correct

#

you tell me

mighty bison
deep idol
#

The value that the struct is holding is a struct

#

Not an array

#

That’s what your code has

#

If you want to treat it like an array, you gotta define it as an array

#

Not a struct

#

Again, my code is purely an example

#

Need to differ/write comments/use that scratch pad project whenever you are stuck or confused @mighty bison

#

Path of least pain

mighty bison
deep idol
#

You’re gonna have to make time

#

Not an excuse

uneven moss
#

done sooner
why the rush

#

this isn't a game jam you've been working on this for ages

mighty bison
# deep idol You’re gonna have to make time

Well unfortunately i have the life made in a way that i need to be almost always on the move as i would soon need to go to university in a different country as i want to move out from country i live in due to the worsening life conditions and have to do chores like cleaning snow outside because of my region being located in arctic/russian far east (yes, its real, i am not making this up in the slightest, i am telling the truth)

deep idol
#

Sun, going to be completely honest

#

I don’t care

#

That’s an excuse

#

That hurts your learning, and not something I or anyone has to deal with

uneven moss
#

is the 30 minutes of your time to go to a separate project and test stuff out gonna throw a monkey wrench in that?

deep idol
mighty bison
deep idol
#

For testing and learning

uneven moss
mighty bison
# uneven moss ruin your plans

Somewhat yes, i had many times where spokes were put in my tires of the progress and i just really dont like when it happens suddenly (with me having no way of knowing that it would happen) and i want get stuff done as soon as possible to do anything else

deep idol
#

Here’s the deal sun

#

If you don’t do this

#

You prove to any programming-related jobs that you’re not fit for it

#

Because the sad truth is, this is one of the many programming critical skills

#

Being able to isolate and narrow down problems, and learning scope

#

This isn’t just for YOUR SAKE

#

This is literally a fundamental skill that every programmer should have

#

If you act like this in any professional environment, you’d be lucky if you even get a weeks notice after being fired

#

Rushing an entire game project, that you’re not even making a dime on

#

Isn’t going to magically make it better

#

So yes, you do need to slow down

#

You do need to break things down

mighty bison
deep idol
#

And not jam everything you find into a project

deep idol
#

It’s on GitHub

#

You can delete it safely

#

And pull/look at GitHub online if you ever need to refer to it

#

As simple as that

mighty bison
# deep idol Put it on GitHub

Still cant believe i have to make entire separate projects just to test something, it just didn't felt like fun doing it. You know?

deep idol
#

We all gotta do it

#

Especially in a professional job

#

Especially when you are on said professional job and you’re learning something brand new

#

It helps break it down tremendously

uneven moss
#

so here's what happens if you jam all your learning into one project:

you never ever start out doing something the first time well. so you keep it, but then later you want to add to it and you have no idea what's going on or how because the code is bad.
so you're spending time figuring out what the hell beginner you was doing + trying to find ways to make the new thing you want to add to work with the old thing
and then rinse and repeat

this is technical debt. and you have ALOT of it if your first and only project is your final project

#

i was telling you how your state machine was spaghetti and fundamentally flawed

#

this is an example of that

#

you're making it take longer to develop your game, by trying to rush everything early on

mighty bison
uneven moss
#

there are many many ways of making a state machine

#

and your spaghetti state machine is just an example

deep idol
#

Also

#

If you think doing that is boring

#

Imagine working on a programming job and you’re dealing with boring tasks

#

We don’t get to always decide “maaan I don’t like this, it’s boring, I’m doing something else”

#

#

You’ll get fired for not doing your work

#

Jobs aren’t going to be super merciful and let you get away with things

#

That’s just reality

#

If you can’t handle working with breaking stuff you’re trying to learn in programming, into smaller projects or even tests

#

Then programming is the wrong choice for you

#

And you’re much better off finding another career

mighty bison
#

Hey I just wanted to say this earlier, but if i am not gonna respond now, then i am working outside as i just went to go and cleaning snow as i have to finish my task my dad told me.

#

I will read all of this later

uneven moss
#

you've been in the help channels for however long sun
and we've just kept telling you over and over and things haven't really changed, and you're still here struggling with stuff

like, we can accomodate slow learning or taking your time, but at some point there has to be something you can do to help yourself. if you're just doing the same thing over and over and over and you're not learning or you're not making progress, then it wouldn't make sense to not change, right?

#

i'm pretty sure the things we're saying right now aren't new

#

iono man
we want to help you, and we're saying this for your own good. but like, it gets frustrating if you just don't take our advice
after months and months of repeating ourselves

mighty bison
#

Hey i am back from cleaning snow outside, now for answers... ahem ahem...

mighty bison
# uneven moss you've been in the help channels for however long sun and we've just kept tellin...

Wellllll i somewhat did manage to do certain stuff on my own, i mean there was this one time i asked something in one of channels but then changed my mind because i figured it out on my own after tinkering with the thing i was trying to solve, and that project i had is a different smaller one different from one i usually develop and able to figure out the rest. I can try and figure out stuff on my own but i am just a bit afraid of making certain mistakes, its my intuition that tells me when it comes to certain parts i am having hard time figuring out. Now, i am not saying i have hard time with literally everything new, i can go silently figure stuff on my own if i was already familiar with something thats similar to what i did before. And i am gonna be honest, those years i spent on this project alone kinda were actually not full 5 real years (like working on the game every single day), these years were spent on anything else considering my time in studying in college and other tasks i had to do and my time for break.

deep idol
#

Mistakes are a natural process of learning, sun.

#

You can’t be afraid

#

If you are hand holded through every problem

#

And someone does the work for you on figuring things out

#

Do you actually learn anything?

#

Just going to answer for you. No, no you don’t.

#

And it’s clearly evident

#

This is also why you use a test project

#

A test project will let you make mistakes freely

#

Without breaking your project in half

#

It also gives you a point of reference when it comes to troubleshooting

#

Cause you know what does work

#

Also….

deep idol
#

Done school for nearly a good chunk of my life

#

And all during that time I’ve made several test projects

#

I didn’t get good at GameMaker by being on/off 1 singular project

#

Or 3

#

I have tons

#

Hundreds

#

Of test projects

#

You don’t gain 17+ years worth of knowledge by taking shortcuts

#

And keep in mind, I have a learning disability

#

It was hard

#

But nothing stops me from developing skills to get faster at learning

#

You gotta do the same

#

I say all of this

#

Because I have also worked on multiple games

#

Big and small

#

Behind NDA and not

mighty bison
# deep idol Of test projects

hey sorry if i am gonna interrupt but i actually found a test project from 2 years ago i had that was used for move and collide function

#

i was using that to test if it was good for collision with slopes

#

i can just go and make test menu and make several rooms to test if saving in multiple rooms work

deep idol
#

Yes

#

Exactly

#

Do that every time you’re learning something new

#

And develop your own skills, your own system in learning and maintaining these things

#

Cause only you can do that

mighty bison
#

i am gonna go and quickly export some code from my main project to the test one and modify stuff so that things could save respective stuff from this test project itself

mighty bison
# deep idol Cause only you can do that

also i am gonna say this but... i am VERY grateful for my past self to have this old dusty test project lying around in my computer so i could quickly use it to test certain functions

#

i wish i could meet my past self and handshake him just for this very simple project alone as ANY form of small project is enough for me to just rapidly clone it for other testing purposes, i can save it as many other separate projects as i want and all will have different purpose for what they were testing

mighty bison
# deep idol Yes

hey so i made several rooms, made export, get name, and import function for the player, gave the option to switch between rooms and saving the progress via pressing T button and made the corresponding save and load scripts that do same thing as one from my bigger project but having to only handle one object

#

i am testing the saving and loading function, i will report in in literally few seconds

mighty bison
# deep idol Yes

yeah so here's results of the testing, save and loading works exactly as how it does from my bigger project, but just like the bigger project, it doesnt take to account the saving and loading for separate rooms

mighty bison
mighty bison
mighty bison
#

we were on the part where you, tabby fax told me that if i want the global.saveroomdata to be an array to be pushed, i need to make it to be one, right?

deep idol
#

Sun I’ve given you all that you need

#

I think it’s best for now you take some time learning

mighty bison
#

oh right, uhh

deep idol
#

The manual is your best friend

mighty bison
#

i am gonna go and tinker around with how i could make this thing save stuff in different rooms

mighty bison
# deep idol I think it’s best for now you take some time learning

okay so i decided to see what would happen if i use global.SaveRoomData = {}; instead of ```global.SaveRoomData = {
rooms: {},
};

and then instead of using multiple get names for actual rooms ```global.SaveRoomData[$ room_get_name(Room1)] = {}``` use ```global.SaveRoomData[$ room_get_name(room)] = _SaveLevelData;```, i saved the game, and it came with a debug message saying:
```game saved!{"Room3":[{"obj":"oPlayer","data":{"canJump":10.0,"x":448.0,"y":480.39981079101562,"image_blend":16777215.0,"grv":0.20000000000000001,"hsp":0.0,"image_index":0.0,"vsp":0.20000000000000001,"hspWalk":4.0,"vspJump":-5.0}}]}

i then decided to switch to another room and the game froze, i couldn't switch to any other room and i couldnt even quit to the main menu due to the appropriate room missing

#

i left the load script to be the same by the way, i didnt change anything in here

#

but since its now able to grab the name of the room, it appears that i am getting closer to what i want, i am gonna try to see what would happen if i define global.SaveRoomData[$ room_get_name(Room1)] = {}; global.SaveRoomData[$ room_get_name(Room2)] = {}; global.SaveRoomData[$ room_get_name(Room3)] = {}; as global.SaveRoomData[$ room_get_name(Room1)] = _SaveLevelData; global.SaveRoomData[$ room_get_name(Room2)] = _SaveLevelData; global.SaveRoomData[$ room_get_name(Room3)] = _SaveLevelData;
and then in load specify what room i wish to load the progress back in

uneven moss
#

ok sun, comment:

there's no point in doing room_get_name(Room1)

#

you already know the name of Room1

#

it's "Room1"

mighty bison
#

so then we just keep using the one with room_get_name(room) to generally save names of the rooms, alright...

uneven moss
#

room_get_name(room) is a more useful operation yes

mighty bison
#

alright then i guess i am going straight for the room loading specification to avoid confusing the game and leading to game freezing

mighty bison
mighty bison
mighty bison
mighty bison
#

then how do i point what room i want to load the progress back into?

uneven moss
#

backwards

#

global.SaveRoomData = import(_loadEntity.data)

mighty bison
#

right

#

thanks!

#

this is the moment of truth now, now i need to play and see how the save and loading works now...

mighty bison
mighty bison
uneven moss
#

what is this code supposed to do

#

there's a difference between asking to get rid of an error
vs asking for getting code to work

#

there's no error, but does that code make sense?

mighty bison
uneven moss
#

more specifically

#

the entire function is to "load back in the progress from its respective room"

#

what are those 4 lines of code i showed you supposed to do

mighty bison
#

ah the codeblock?

#

okay welll....

uneven moss
mighty bison
#

uhh yeah

#

it doesnt make sense

uneven moss
#

which part doesn't make sense

mighty bison
uneven moss
#

why do you think it doesn't make sense

mighty bison
#

because i am not actually pointing to a room i want it to be in

uneven moss
#

and
you're accessing a global variable. just as a whole

#

that global variable just gets overriden with import(...) for each entity

#

do you need global.SaveRoomData=?

mighty bison
#

no

uneven moss
#

what does import(_loadEntity.data) do

#

what is _loadEntity.data

mighty bison
uneven moss
#

sun i want you to think about it for yourself
these are guiding questions

mighty bison
uneven moss
#

ok so my one big tip and last thing for today is

if you're working with data, you need to be absolutely crystal clear 1. how that data is structured, and 2. what that data is supposed to contain

#

like absolutely clear

#

so if i ask you what does global.SaveRoomData contain, you should be able to tell me exactly what it is, and what it contains

#

or what it should contain

#

no touchy code

#

because if you don't get your data straight, you will be very very lost

#

and you can't just like
throw stuff at a wall til it sticks

#

that's not how this works

#

you need to sit down and re-evaluate your code and think

mighty bison
#

and two, its also used to tell which room i am pointing it at

#

which... gasp, wait a minute...

#

i am already pointing it which room i am telling it to load stuff into???

mighty bison
uneven moss
#

i can tell you don't really have a grasp of how your data is structured

mighty bison
# uneven moss i can tell you don't really have a grasp of how your data is structured

yeah, i now see that it is wrong, alright well lets see this from the matryoshka within matryoshka perspective alright, from save script, what i first make? an array for saveleveldata, then i make a global struct named "SaveRoomData", and after i make instance looping code, i make SaveRoomData grab the name of the room and put it inside _SaveLevelData, i stringify it, put it into json, then in load script, i check if "savedgame.save" exists, i then convert the buffer from savedgame.save file which contains saveleveldata array, turns it into a struct, i check if struct global.SaveRoomData exist and if it's a struct, then i override global.SaveRoomData with room1 even though its supposed to contain data of the stuff i saved in the rooms, tell it to recreate the saved objects and import their variables

mighty bison
mighty bison
#

i mean... from what i know from manuals, the global.SaveRoomData i made is a struct, which is a container for variables...

#

and it contains the variables that were previously mentioned, say, i mentioned a variable called health inside the "obj_person" object, then i define it in a struct like

{
  health : health
} 
#

and that creates an instance scope struct in the variable person_status_struct

mighty bison
#

and they can be added afterwards with a dot operator or (an accessor)

#

which can be... person_status_struct[$ "wellbeing"] = health

#

so then wait... i think that when i made ```global.SaveRoomData[$ room_get_name(room)] = _SaveLevelData;

i literally told it to ```
global.SaveRoomData = {
  (get name of the room) : _SaveLevelData
}

and that same _SaveLevelData contains:

  obj: Obj_Player
  //the objects variables()
}
#

so i am telling this SaveRoomDatastruct to get the name of the room, access the level data, and that contains arrays of the objects saved in the room... huh...

mighty bison
mighty bison
#

ohhhhh man... this is confusing...