Import/export globals scripts not working properly

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

Post Reply
User avatar
Hedera
Slime Knight
Posts: 175
Joined: Tue May 17, 2011 11:38 am
Location: a dying forest (all forests are dying)

Import/export globals scripts not working properly

Post by Hedera »

In my game, I've got a setup where a set of tags are used to control whether certain things are displayed, and where the player can set those tags on and off in an options menu. These preferences are supposed to be remembered by the game when quitting and starting up again, as well as when loading a save file.

This is done by having scripts import and export global variables to a dummy save file; an export script runs whenever the tag is changed, and an import script runs at the title screen and whenever a save file's loaded. The tags are translated into global variables upon export, and vice-versa upon import.

(In this example, there's only one tag and one corresponding global variable. The export globals command is meant to work with multiple variables, but works fine with just one. I'm pretty sure that's not where the error's coming in.)

Code: Select all

    global variable (5, dummy gv)


plotscript, importing globals, begin


    dummy gv := import globals (1000, 5)

    switch (dummy gv)
    do    (
        case (0) set tag (5, 0)
        case (1) set tag (5, 1)
        case (else) show text box (18)    # error message
        )

    end


plotscript, exporting globals, begin
    
    
    wait (1)
    dummy gv := check tag (5)
    export globals (1000, 5, 5)

    end
The problem is, the settings are changed within an options menu; if it's changed and the game's either quit out of or a save is loaded, the changes are lost. However, if it's changed and the menu's closed, then it successfully carries over upon quitting/loading.

Is there a way to make it so that it carries over even if the player doesn't exit the menu?
User avatar
Bird
Slime Knight
Posts: 227
Joined: Thu Jan 26, 2012 2:19 pm
Location: Germany

Post by Bird »

Why should it be expected, that the settings are saved, when the player does not click on "Save Settings" and exits the settings menu? Depends on how big and complicated your settings are. Someone who "misconfigured" it will be glad to see an "abort" button instead of having it automatically saved.

Now if you want to save every change of the tags immediately (without having to close the menu), you could run a while loop after opening the settings menu. In theory, that would check the current tags as long as the menu is open. I didn't test this code, but it should run when being wrapped in a plotscript:

Code: Select all

while (menu is open (menu number) == true) do (
run script by ID (@exporting globals)
wait (1)
)
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Hello! Wow, I see you haven't posted here for 9 years!

When is "exporting globals" run? When the main menu exits? If the settings menu is a submenu of the main menu (from which the player can quit) then you need to get your script to run earlier somehow. You could do what Bird suggested (but just write "exporting globals" instead of "run script by ID (@exporting globals)") but that only works if the settings menu has the "Allow gameplay & scripts" bit on.
The most direct solution is to make "exporting globals" the on-close script for the settings menu, but that only works if the "Allow gameplay & scripts" bit on in the main menu (or whichever menu the settings menu exits to). And don't forget to turn on the "Suspend player even if gameplay allowed" bit.


Incidentally, I want to work on feature requests made for the Heart of the OHR 2018 contest very soon. One of them is to add commands like import/export globals, but for tags. I'll definitely add that now that I know someone else also wants it.
Last edited by TMC on Sat Apr 18, 2020 3:09 pm, edited 1 time in total.
User avatar
Hedera
Slime Knight
Posts: 175
Joined: Tue May 17, 2011 11:38 am
Location: a dying forest (all forests are dying)

Post by Hedera »

Yeah, I decided to actually sit down and make a game now that I (and most everyone else, ell oh ell) have a surplus of free time.

The options menu is, indeed, a submenu of the main menu; I probably should've been clearer on that, sorry. The script's supposed to run immediately when the player toggles the tag on/off, but it doesn't take unless all menus are closed.

"Allow gameplay & scripts" makes it so that NPCs are still active while the menu's up, right? What happens if said NPCs trigger battles on contact?
User avatar
Hedera
Slime Knight
Posts: 175
Joined: Tue May 17, 2011 11:38 am
Location: a dying forest (all forests are dying)

Post by Hedera »

Update: I've followed your advice and activated the "Allow gameplay & scripts" and "Suspend player [...]" bitsets for the main menu, and it works as intended! Thanks!

It also means the player can be thrown into a fight while the menu's up, which... I guess the next step is to have a script running in the background that checks for whether the main menu's active, and if so, suspending NPCs?
Last edited by Hedera on Sun Apr 19, 2020 4:05 am, edited 1 time in total.
User avatar
Hedera
Slime Knight
Posts: 175
Joined: Tue May 17, 2011 11:38 am
Location: a dying forest (all forests are dying)

Post by Hedera »

So, the following script's supposed to detect whether the main menu's open:

Code: Select all

plotscript, menu suspend npcs, begin


     if (menu is open (find menu id (main menu)) == true)
     then (
          suspend npcs
          )

     end
I set this as an on-keypress script in a map, but instead of detecting whether the menu's open, it opens the menu. How do I fix this?
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Running scripts in menus is unfortunately something the OHR makes difficult. I so want to overhaul it.

"main menu" isn't a constant, it opens the main menu. The main menu always has ID 0. You should just write "if (find menu ID(0))". If menu 0 isn't open, that returns zero (false), otherwise it's nonzero (true).

One alternative is the following:

-Make the settings menu disallow gameplay & scripts
-Turn on the "Close menu when activated" bit for the 'Settings' option in the main menu, so that it closes the main menu and replaces it with the settings menu
-Make the settings menu run a script when it's closed (because the main menu was already closed, when the settings menu closes there are no menus and scripts can run):

Code: Select all

plotscript, close settings, begin
  export globals  # Get rid of the wait(1) you have in this script
  main menu
end
-Turn on "Remember selection when reopening" bit in the main menu


By the wait, I would just write "set tag (5, dummy gv)" instead of that switch block you have. If you really want to check for invalid values, you could put that check inside a script or subscript:

Code: Select all

script, checked settag, tag, value, begin
    switch (value) do (
        case (true, false) set tag (tag, value)
        case (else) show text box (18)    # error message
    )
end
Last edited by TMC on Sun Apr 19, 2020 10:25 am, edited 4 times in total.
User avatar
Hedera
Slime Knight
Posts: 175
Joined: Tue May 17, 2011 11:38 am
Location: a dying forest (all forests are dying)

Post by Hedera »

I went with the following on-keypress script, instead:

Code: Select all

plotscript, when main menu opens, begin

     while &#40;find menu id &#40;0&#41; <> true&#41;
     do     &#40;
            wait for key &#40;menukey&#41;
            suspend npcs
            &#41;

     end
which, when combined with a script that plays upon closing the menu that resumes NPCs, and another that makes enemy NPCs wait for the menu to close before triggering a fight, solves everything. It's a kludge, but it works, and that's what's important.

Thanks again for showing me where the errors were cropping up.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

"while (find menu id (0) <> true) " isn't right (it will almost always be true), you should write "while (find menu id (0) <> false)" instead (which is exactly equivalent to "while (find menu id (0))").

But I'm not sure why you wrote that script like that, what the while loop is for, and what the "wait for key (menukey)" is for. You definitely need to get rid of or fix the while loop, or that script will (usually) never exit.
Maybe you instead want

Code: Select all

plotscript, on keypress, begin
     if &#40;keypress &#40;menu key&#41; && find menu id &#40;0&#41; == false&#41; then &#40;
          # The menu is about to be opened
          suspend npcs
     &#41;
end
User avatar
Hedera
Slime Knight
Posts: 175
Joined: Tue May 17, 2011 11:38 am
Location: a dying forest (all forests are dying)

Post by Hedera »

You're right, that didn't need to be a loop.

I've taken your suggestion and added a "&& (current text box == -1)" to the conditions, so NPCs won't come to a halt if the player hits the menu key while there's a textbox onscreen.
Post Reply