Author Topic: [SOLVED] SCI0 - Variables that aren't reset by Restore  (Read 8295 times)

0 Members and 1 Guest are viewing this topic.

Offline Doan Sephim

[SOLVED] SCI0 - Variables that aren't reset by Restore
« on: December 12, 2020, 12:39:56 PM »
Is it possible to tweak Restore in such a way that it doesn't reset certain variables?

Code: [Select]
(method (restore &tmp gameNum oldCursor hSound)
(= gameNum  -1)
(Load rsFONT gSaveRestoreFont)
(Load rsCURSOR gNormalCursor)
(Load rsCURSOR gLoadingCursor)
(= oldCursor (self setCursor: gNormalCursor))
(= hSound (Sound pause: 1))
(if (GetSaveDisk TRUE)
(if gPrintDlg (gPrintDlg dispose:))
(= gameNum (Restore doit: &rest))
(if (!= gameNum -1)
(self setCursor: gLoadingCursor)
(if (CheckSaveGame objectName gameNum gVersion)
(gCast eachElementDo: #dispose)
(gCast eachElementDo: #delete)
;(= saved 1)
;(FormatPrint {Saved %u} saved)
        (RestoreGame objectName gameNum gVersion)

This is in the "Game" script and I have set a test global variable there "(saved =1)" and I test a print to make sure it works before the "RestoreGame" is called. I do get confirmation that the variable is set to 1 before the restore, but after the restore it is predictably set back to its original value.

I looked everywhere in vain to find where "RestoreGame" is set up. It looks like a procedure to me, but I can't find it anywhere.
« Last Edit: December 13, 2020, 02:38:49 PM by Doan Sephim »


Artificial Intelligence Competition

Offline OmerMor

Re: SCI0 - Variables that aren't reset by Restore
« Reply #1 on: December 12, 2020, 02:50:09 PM »
Have you thought of looking in Codename: Iceman's scripts? IIRC, it has cheating prevention mechanism in the submarine that maintains its state even after restores.

Offline OmerMor

Re: SCI0 - Variables that aren't reset by Restore
« Reply #2 on: December 12, 2020, 02:52:13 PM »
From wikipedia:
Quote
At one point, the player must obtain a bottle from a crewman on the sub, but only if the player can beat him at a dice game. The crewman 'accuses' the player of cheating if the player repeatedly saves and restores in an effort to win at dice (he is allowed to do so only twice).

Offline Doan Sephim

Re: SCI0 - Variables that aren't reset by Restore
« Reply #3 on: December 12, 2020, 03:01:49 PM »
Have you thought of looking in Codename: Iceman's scripts? IIRC, it has cheating prevention mechanism in the submarine that maintains its state even after restores.
That's very interesting. I have not looked at it. I will try, but I'm not the most savvy programmer, so I may overlook the solution even if it's there!

Offline Kawa

Re: SCI0 - Variables that aren't reset by Restore
« Reply #4 on: December 12, 2020, 03:36:04 PM »
I have looked at it and that is not the solution.

The anti-scum measures in Iceman use the replay method of the minigame's room to detect that you restored a game and increases an ordinary local variable. This doesn't normally happen but Iceman's Game::replay has the line (gRegions eachElementDo: #replay) in it. The dice game's restore counter is saved and loaded as any, then incremented and checked. And that's how it can tell.
« Last Edit: December 12, 2020, 03:48:40 PM by Kawa »

Offline Doan Sephim

Re: SCI0 - Variables that aren't reset by Restore
« Reply #5 on: December 12, 2020, 03:42:22 PM »
I have looked at it and that is not the solution.

The anti-scum measures in Iceman use the replay method of the minigame's room to detect that you restored a game and increases an ordinary local variable. This doesn't normally happen but Iceman's Game::replay has the line (gRegions eachElementDo: #replay) in it. The dice game's restore counter is saved and loaded as any, then incremented and checked. And that's how it can tell.
Thanks for looking Kawa. You saved me time and trouble.

I've not had any further success finding anything about "RestoreGame." It looks like a procedure, but maybe it's something else? There doesn't seem to be anything like it in any of the Scripts the Game Script uses (or subheaders for that matter).

Offline Kawa

Re: SCI0 - Variables that aren't reset by Restore
« Reply #6 on: December 12, 2020, 03:49:53 PM »
Lemme just elaborate a bit on why your test variable gets reset and such: saved games are basically saved states, including all the variables. When you restore a game, the engine itself clears out everything, unpacks the heap from state to RAM, sets an internal flag, and resets itself to just before it calls your game's play method. Except it doesn't because the internal flag lets it know to call replay instead. This is all done by the engine itself, you can't influence that from inside the game.

I've not had any further success finding anything about "RestoreGame." It looks like a procedure, but maybe it's something else? There doesn't seem to be anything like it in any of the Scripts the Game Script uses (or subheaders for that matter).
Kernel procedure, part of the engine.

Edit: I just got an idea on how to make certain variables not reset. What you could try to do is have Game::restore write the specific globals you want to persist to a file. You do this right before the (RestoreGame objectName gameNum gVersion) call. Then in Game::replay, somewhere at the start, you check for that file's existance, read the values for those same globals back in, and delete the file. That way, if your persistent global was, say, 42 at the time you decide to restore, it'll save that 42 to the temp file, restore the game and reset the global to whatever that savegame says it was at the time (41?), and then immediately see the file and load 42 from it.
« Last Edit: December 12, 2020, 04:03:07 PM by Kawa »

Offline Doan Sephim

Re: SCI0 - Variables that aren't reset by Restore
« Reply #7 on: December 12, 2020, 04:08:32 PM »
Edit: I just got an idea on how to make certain variables not reset. What you could try to do is have Game::restore write the specific globals you want to persist to a file. You do this right before the (RestoreGame objectName gameNum gVersion) call. Then in Game::replay, somewhere at the start, you check for that file's existance, read the values for those same globals back in, and delete the file. That way, if your persistent global was, say, 42 at the time you decide to restore, it'll save that 42 to the temp file, restore the game and reset the global to whatever that savegame says it was at the time (41?), and then immediately see the file and load 42 from it.
Thanks. I appreciate you explaining the goings on when the game restores. You mentioned "writing the specific globals to a file." I wonder if that is similar to how QFG allowed you to import characters - by writing certain variables to files?

Do you know how one would accomplish the writing of a variable to a file? I would like to test this out, but don't know how to do that (or check it for that matter).

Offline Kawa

Re: SCI0 - Variables that aren't reset by Restore
« Reply #8 on: December 12, 2020, 04:34:59 PM »
Thanks. I appreciate you explaining the goings on when the game restores. You mentioned "writing the specific globals to a file." I wonder if that is similar to how QFG allowed you to import characters - by writing certain variables to files?
Basically yes.
Quote
Do you know how one would accomplish the writing of a variable to a file? I would like to test this out, but don't know how to do that (or check it for that matter).
The big issue here is that SCI0's file kernels don't let you read and write anything but strings. You could go balls-out like QfG, or you could just read and write strings.

I've had persistent settings in Catdate at one point but that's SCI11, which can do a little better 😉

But this is SCI0 so let's just take one from LSL3's book. To save:
Code: [Select]
(= fileHandle (FOpen "persist.tmp" fCREATE))
(if (!= fileHandle -1)
(Format @str "%6d %6d %6d" gPersistMe gPersistMeToo gGuessWhat)
(FPuts fileHandle @str)
)
(FClose fileHandle)
Add as many "%6d" as you have variables you want to persist. To load:
Code: [Select]
(= fileHandle (FOpen "persist.tmp" 1)) ;there's a historical typo in SCI.SH
(if (!= fileHandle -1)
(= gPersistMe (ReadNumber (FGets @str 8 fileHandle)))
(= gAlsoMePlz (ReadNumber (FGets @str 8 fileHandle)))
)
(FClose fileHandle)
...and then I realize there is apparently no "delete" in SCI0, so you're stuck with a leftover file. Hm.

Offline Doan Sephim

Re: SCI0 - Variables that aren't reset by Restore
« Reply #9 on: December 12, 2020, 04:42:38 PM »
...and then I realize there is apparently no "delete" in SCI0, so you're stuck with a leftover file. Hm.
I look forward to tinkering around with this. Thank you for doing the leg-work, because there is 0.01% chance I would arrive at this info on my own.

As to your comment about no "delete" mechanism in SCI0 - would that suggest that it would create a new file every time there was a restore? I guess this wouldn't be terrible if I just created a folder that stored them...but then again, how would it know which file to read from on the restore?

Offline Kawa

Re: SCI0 - Variables that aren't reset by Restore
« Reply #10 on: December 12, 2020, 04:48:43 PM »
As to your comment about no "delete" mechanism in SCI0 - would that suggest that it would create a new file every time there was a restore? I guess this wouldn't be terrible if I just created a folder that stored them...but then again, how would it know which file to read from on the restore?
No, no, you just re-use the exact same file every time you restore, "persist.tmp".

It's why SCI0 games have "Replace" in their save dialogs instead of "Delete" -- they can't actually delete LL3SG.007, only reuse it.

Offline Doan Sephim

Re: SCI0 - Variables that aren't reset by Restore
« Reply #11 on: December 12, 2020, 04:59:33 PM »
That's good to know. I'm glad I won't be making tons and tons of new files.

Having some trouble with the code though

Code: [Select]
  [Error]: Expected something to which we could get a pointer: str  Line: 215, col: 15
  [Error]: Expected something to which we could get a pointer: str  Line: 216, col: 25

These errors are in reference to:
Code: [Select]
(Format @str "%6d %6d %6d" gPersistMe gPersistMeToo gGuessWhat)
(FPuts fileHandle @str)

I simply added the variables to the main Script without definition. Am I missing an obvious step?

Offline Kawa

Re: SCI0 - Variables that aren't reset by Restore
« Reply #12 on: December 12, 2020, 05:06:19 PM »
str would be a temporary, method/procedure-local variable, so something like (method (save &tmp [strDescBuf 20] gameNum oldCursor hSound [str 10])

Offline Doan Sephim

Re: SCI0 - Variables that aren't reset by Restore
« Reply #13 on: December 12, 2020, 05:14:24 PM »
Right. I was missing something obvious.

Code: [Select]
(= fileHandle (FOpen "persist.tmp" 1)) ;there's a historical typo in SCI.SH
(if (!= fileHandle -1)
(= gPersistMe (ReadNumber (FGets @str 8 fileHandle)))
(= gAlsoMePlz (ReadNumber (FGets @str 8 fileHandle)))
)
(FClose fileHandle)

With this in the replay method, I also need to add str as a variable correct?

Also, what does the 8 stand for in the FGets?

Assuming I am saving 3 variables, how does it know which value to assign to each variable? Or does it just go in order?

EDIT: Good and bad news. I succesfully restored the game with a variable of a different value than saved. Bad new? It was the wrong value. I assigned it to 3 just before running the save to file code, but when I checked it after restoring, it said the value was 0. (I had the value set to 1 originally)
« Last Edit: December 12, 2020, 05:19:29 PM by Doan Sephim »
Artificial Intelligence Competition

Offline Kawa

Re: SCI0 - Variables that aren't reset by Restore
« Reply #14 on: December 12, 2020, 05:27:43 PM »
The 8 is the maximum length of the string to read -- up to eight characters or up to the end of the line or file. And yes, it does read them in the same order you write them.

This is about as far as I can help.


SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.038 seconds with 23 queries.