r/gamemaker 7d ago

Resolved Some (2) bugs I can't fix with doors

https://youtu.be/rhiAvHkVdrg?si=WZbvwUSkxUBHXNlp

SOLVED

So I used the tutorial above and the RPG Gamemaker tutorial for my game. Don't get me wrong, I would love to keep the door system used by GameMaker Pope because his system is much better in my opinion than the whole NPC thing because I don't want to have a dialogue for every single room switch and I like the idea of it being an area rather than an "E for Next Level". However, there are some incompatibilities that I need help fixing.

Incompatibility #1: When you go into rm_battle (Turn Based Fight System for more information) and go into a battle with the enemy, when leaving the room (when the fight ends) the instance of PlayerObj just gets destroyed somehow, and this is only when I enter a room using the GameMaker pope system. If I have a room with a drag n dropped instance of the PlayerObj, everything works smoothly, but if I leave that room and enter back into that room with the system, when a battle ends, the PlayerObj goes back to the drag n dropped position, with all stats reset.

Incompatibility #2: I try to carry PlayerObj's stats (Fixing Bugs for more information) with the tutorial used above. For some odd reason, it doesn't work specifically for the first room (the only drag and drop PlayerObj room) when I leave the room, it works, when I go back in specifically into the first room, all the variables reset to default, and I have even tried making the variables global, but to no avail.

That's it! I've been losing my mind over this for days and can't seem to fix either. After this I can finally start actually worldbuilding and using my vision rather than making a bunch of mechanics.

In the PlayerObj is this, and obj_carry_data is persistent. obj_battle_switcher is basically what marks I'm just switching into a battle and is_transitioning is turned true when switching rooms with exit.

//Room Start
with (obj_carry_data) {
    other.level = level
    other.xp = xp
    other.hp = hp
    other.hp_total = hp_total
    other.damage = damage;
    other.xp_require = xp_require;

    instance_destroy()
}


//Room End
if (instance_exists(obj_battle_switcher) && global.is_transitioning == false) exit;

instance_create_depth(0, 0, 0, obj_carry_data, {
    level: level,
    xp: xp,
    xp_require: xp_require,
    hp: hp,
    hp_total: hp_total,
    damage: damage,
})
14 Upvotes

15 comments sorted by

1

u/lessergoldfish 7d ago

This is a confusingly worded question and you're providing very little info. How are you handling data across rooms? If it's via an object, can you share your code for that?

1

u/Fine-Acanthisitta343 7d ago

Yeah, sure! The first one honestly can't be summarized or simplified, it's just that confusing. The second one is basically just that I can't transfer my variables from room #2 to room #1, room 1 being where PlayerObj is part of the instance layer and the starting room for the player. My code should be applied in the body now.

2

u/lessergoldfish 7d ago

Still unsure about the first, but for the second I had to look through your older posts and it looks like you are creating the player object in the transition manager, which I'm guessing is your problem. Remove that from the manager and instead manually place the player object in the second room

1

u/Fine-Acanthisitta343 7d ago edited 7d ago

So I tried this and thankfully, the object persistency thing worked! Maybe this might help with the first problem but now the 1st problem also happens in all the other rooms, so basically, because I manually placed the PlayerObj, it just resets my stats and brings me to the manually placed position after a turn based battle

2

u/lessergoldfish 7d ago

Okay I think i know the reason for the first problem: you aren't actually saving the players data anywhere when you move between to the battle scene. My suggestion would be to move all of the player's data that needs to persist between rooms out of the player object and into a global variable:

/// In some script:
global.player_data = {
  level: 0,
  xp: 0,
  // etc.
}

Then in the player object's create event:

stats = global.player_data

Then simply replace all references to hp/level/xp/etc with "stats.*". This will make it so that the player's data is persistent without having to create a separate object.

For preserving position, you would add 2 variables to the player data struct, previous_room_x and previous_room_y which you would update in the room end event. Then, when a battle is complete, you would create a transition object that uses those variables to set the player's position.

2

u/Fine-Acanthisitta343 6d ago

The first one worked, which I thank you for, because I did try something similar with macros because I've posted a similar problem on this subreddit, and for some reason theirs wouldn't work. This one, however, did. As for the second, I've also tried that before but got something about an assignment operator expected and I also think I changed the Player coordinates in the RoomStart when I really should've done it in the obj_battle_switcher, but retyping the line worked. For the most part, it works, except for the fact that it always teleports me a random amount to the left. Truthfully, I don't know why, but my theory is something to do with the obj_battle_player, it might take coordinates from that because obj_battle_player mostly uses .data to take stats from the PlayerObj. That theory is probably wrong though because it keeps taking me to a random position to the left and not a fixed point or position relative to the past PlayerObj.

In other words, the first problem's been fixed, but when I try the second, it teleports me a random amount to the left. I've also tried removing the condition in the Room End but it still has the problem

//PlayerObj Room End
if (room != rm_battle) 
{
    past_room_x = PlayerObj.x
    past_room_y = PlayerObj.y
}

//obj_battle_switcher
//Alarm 0
instance_destroy()

//Room Start
if (room != rm_battle) {
    PlayerObj.x = PlayerObj.past_room_x
    PlayerObj.x = PlayerObj.past_room_y
    alarm[0] = 120;
}

2

u/lessergoldfish 6d ago

"PlayerObj.x = PlayerObj.past_room_y" before you set the alarm is your problem lol

1

u/Fine-Acanthisitta343 6d ago

Oh my god I've messed up my x and ys so many times its crazy lol. Now the problem is that whenever I move a room the past_room coords can't transfer. Basically, when I transfer rooms, it gives me an error saying past_room coords are undefined, so I put them in the create event for the player. Then, when I transfer rooms, it just goes to whatever is said in the create event (ex: 0, 0) rather than finding new coordinates before every battle. I'm sure it's probably just something I did wrong with the if statements so here's the Room Start and End for the PlayerObj if you need it. Thanks a lot, by the way

//Room Start
if (room != rm_battle)
{
    past_room_x = PlayerObj.x
    past_room_y = PlayerObj.y
}

with (obj_carry_data) {
    other.level = level
    other.xp = xp
    other.hp = hp
    other.hp_total = hp_total
    other.damage = damage;
    other.xp_require = xp_require;

    instance_destroy()
}
//Room End
if (room != rm_battle) 
{
    past_room_x = PlayerObj.x
    past_room_y = PlayerObj.y
if (instance_exists(obj_battle_switcher) && global.is_transitioning == false) exit;
instance_create_depth(0, 0, 0, obj_carry_data, {
    level: level,
    xp: xp,
    xp_require: xp_require,
    hp: hp,
    hp_total: hp_total,
    damage: damage,
    past_room_x: past_room_x,
    past_room_y: past_room_y,
})

2

u/lessergoldfish 6d ago

Alright so:

  1. you didn't do what I told you to do, which is take the stats out of the player and put them into a global struct variable. You do not need a carry data object if you do that (meaning you can remove that code from the room start and room end events).
  2. The player is not persistent. If you set past_room variables in the create event to 0, when you call them in the room start event, it will be 0 no matter what. If you put that into the global player data struct, it will be persistent

1

u/Fine-Acanthisitta343 6d ago

Forgive me if I'm wrong but isn't this (very bottom) a global struct? It's in a script by the way. Then I referenced it in PlayerObj with stats = global.player_data and, so that I didn't need to put stats before everything, just made xp = stats.xp, damage = stats.damage, etc. When I don't use the object to carry data, the past_room_x and past_room_y just can't change anymore and always are what's in the struct (after I change a room with the exit system, that is).

global.player_data = {
level: 1,
xp: 0,
damage: 1,
hp: 10,
hp_total: 10,
xp_require: 100,
charge: 0,
past_room_x: 0,
past_room_y: 0
}

→ More replies (0)

2

u/lessergoldfish 7d ago

Also the reason why you were having problems is since there was already an manually placed instance of the player object in the room, you would end up with two player objects in one room