Author Topic: ERROR debug  (Read 52922 times)

0 Members and 2 Guests are viewing this topic.

Offline robbo007

ERROR debug
« on: June 18, 2025, 06:46:10 AM »
Hi guys,
I'm trying to troubleshoot this error. Not an object $ffff. I've resolved the heap space issue by DisposeLoad the region_path script that seemed to be lingering in memory but after adding a few more embellishments to the room 7 which calls room 503 I get the error on init. Commenting out the "timer init" in Rm007 resolves the error so it looks like there is something in the TIMERMANGER_SCRIPT that is tipping the error.

Rm007 does use the timer script but I'm disposing that before loading Rm503.

Rm007 calls timer script via Rm306 using a local variable called timer.
Code: [Select]
(= timer (ScriptID 306 0))
    (timer init:)

I Disposeload both Region path and Rm306 before loading Rm503 where I have the error:
Code: [Select]
(DisposeLoad TIMERMANAGER_SCRIPT) ; Dispose TIMERMANAGER_SCRIPT before initialising the room
(DisposeLoad TIMER_SCRIPT)
(gRoom newRoom: 503)

Rm306 TIMERMANER SCRIPT:
Code: [Select]
;;; Sierra Script 1.0 - (do not remove this comment)
;;
;; Timer Manager Script - Handles shared timer across rooms
(script# 306)
(include sci.sh)
(use Main)
(use Timer)
(use Obj)
(use Controls)
(public
    timerManager 0  ; This makes it available to other scripts
)

(local
    gDhcTimer
    gTimeLimit = 50  ; 10 minutes (600 seconds)
)

(instance timerManager of Obj
    (properties)
   
    (method (init)
        ; Initialize the global timer if it doesn't exist
        (if (not (IsObject gDhcTimer))
            (= gDhcTimer (Timer new:))
            (gDhcTimer setReal: self gTimeLimit)
        )
    )
   
    (method (cue)  ; Called when timer expires
        (Print "Time's up! Ms. Cheatem is back!")
        (gRoom newRoom: 100) ; Failure room
        ; Clean up timer
        (if (IsObject gDhcTimer)
            (gDhcTimer dispose:)
            (= gDhcTimer 0)
        )
    )
   
    (method (showTimeLeft &tmp secondsLeft)
        (= secondsLeft
            (if (IsObject gDhcTimer)
                (gDhcTimer seconds?)
            else
                -1
            )
        )
        (if (== secondsLeft -1)
            (Print "No active timer.")
        else
            (FormatPrint "Time left: %d:%02d" ;printf equivelent
                (/ secondsLeft 60)
                (mod secondsLeft 60)
            )
        )
    )
   
    (method (dispose)
        ; Clean up when no longer needed
        (if (IsObject gDhcTimer)
            (gDhcTimer dispose:)
            (= gDhcTimer 0)
        )
        (super dispose:)
    )
)

Any ideas what could be crashing it? So I cant look deeper into it.
Thanks,
« Last Edit: June 18, 2025, 07:06:50 AM by robbo007 »



Offline doomlazer

Re: ERROR debug
« Reply #1 on: June 18, 2025, 10:55:31 AM »
Looking at disposeload, the documentation says it takes a resourceType followed by resource numbers. I don't see a resource type in the code you posted. Maybe switch to disposeScript or see how they dispose of timers in the Sierra releases.
« Last Edit: June 18, 2025, 11:04:36 AM by doomlazer »

Offline robbo007

Re: ERROR debug
« Reply #2 on: June 18, 2025, 11:16:24 AM »
Thanks for that Doomlazer,
I think it was a combination of both that and also not disposing of other resources that the script used. This seemed to work fine. I've made sure when existing the rooms its completely disposes it.

Code: [Select]
(method (newRoom newRoomNum)
        ; Save room state if needed
        ; (= [gRoomStates 7] 0) ; Uncomment and define state if needed
        ; If going to room 503 or 006, dispose timer script
        (if (or (== newRoomNum 503) (== newRoomNum 006))
            ; Save timer state
            (= [gTimerState 0] gTimerActive)
            (if (IsObject (ScriptID 306 0)) ; timerManager
                (if (IsObject (ScriptID 306 1)) ; gDhcTimer (local, selector 1)
                    (= [gTimerState 1] ((ScriptID 306 1) seconds?))
                else
                    (= [gTimerState 1] 0)
                )
                ((ScriptID 306 0) dispose:) ; Dispose timerManager
            )
            ; Dispose script #306
            (DisposeLoad 0 306)
        )
        ; Clean up room resources
        (gCast eachElementDo: #dispose)
        (gFeatures eachElementDo: #dispose)
        (gAddToPics eachElementDo: #dispose)
        ; Transition to new room
        (super newRoom: newRoomNum)
    )
)

Offline lskovlun

Re: ERROR debug
« Reply #3 on: June 18, 2025, 09:53:09 PM »
I can see another potential problem. You're defining timeManager as an instance and not as a class. An instance an only override existing methods and properties, not define new ones - so it should be a class. I'm not sure why Companion accepts it, but it could cause hangs or odd crashes. Also, from what you showed us first, there isn't an export #1 in script 306. So (ScriptID 306 1) is likely to be a fatal error.
« Last Edit: June 18, 2025, 10:05:54 PM by lskovlun »

Offline doomlazer

Re: ERROR debug
« Reply #4 on: June 19, 2025, 10:32:36 AM »
What's the difference between disposeLoad and load anyway? Seems redundant

Offline Kawa

Re: ERROR debug
« Reply #5 on: June 19, 2025, 10:54:32 AM »
Let's get one thing straight: DisposeLoad is actually called LoadMany. Brian named it such because it does two things.

Example uses provided by Pablo Ghenis himself:
Code: [Select]
(LoadMany VIEW 110 111 201) ;to load a series of views
(LoadMany SCRIPT 110 111 201) ;to load a series of scripts
(LoadMany FALSE 110 111 201) ;to use DisposeScript

And that's the key, really: so long as what/rsType is not false, it Loads each of the listed resources. If it is false, it calls DisposeScript[/i] on each listed item, implied to be a script resource.

So the difference is, Load loads a single resource and LoadMany loads many. This also makes for smaller and more readable code -- (Load VIEW 110) (Load VIEW 111) (Load VIEW 201) would compile to a much bigger block of PMachine bytes than (LoadMany VIEW 110 111 201).

Offline doomlazer

Re: ERROR debug
« Reply #6 on: June 19, 2025, 11:00:12 AM »
OK, I thought it might be LoadMany; which is certainly a better name, IMO. Thank you for clarifying and always good to remember that the SCICompanion documentation might not map 1:1 in all situations.

I don't work with the SC template games much, so the idiosyncrasies throw me off a bit. I think EO's templates correct some of the issues.

I like that you have to specify a resource type; a convenience function with limited convenience if you need multiple types. IDK, maybe just support &rst in Load?
« Last Edit: June 19, 2025, 11:17:14 AM by doomlazer »

Offline Kawa

Re: ERROR debug
« Reply #7 on: June 19, 2025, 11:22:46 AM »
IDK, maybe just support &rst in Load?
Load is a kernel function. The only way you're gonna see that support more than one resource type/num pair is if you add it to the interpreter itself.

Even then you'd need a way to specify which arguments are resource types and which are resource numbers -- VIEW or rsView or whatever is just the number 128, so if you do (Load VIEW 110 120 130 SOUND 150) how will it know you mean to load three views (110 120 130) and one sound (150), instead of five views (110 120 130 132 150) and no sounds? And that is why LoadMany takes only one type per call.

Worst thing is, I absolutely could make Load the kernel function work exactly like LoadMany the script procedure. Skips the whole "find and load the LoadMany script, run the function, including iteration, and then dispose of it like it says to" hassle.

Offline lskovlun

Re: ERROR debug
« Reply #8 on: June 19, 2025, 12:20:16 PM »
Load is a kernel function. The only way you're gonna see that support more than one resource type/num pair is if you add it to the interpreter itself.
Some SCI interpreters actually have this. Including the one you've improved.
EDIT: Well, one type and several resource numbers.
« Last Edit: June 19, 2025, 12:38:02 PM by lskovlun »

Offline Kawa

Re: ERROR debug
« Reply #9 on: June 19, 2025, 12:38:09 PM »
hold on

*checks source code*

Oh yeah, so it does! No disposing though, that part of LoadMany isn't there.

Offline lskovlun

Re: ERROR debug
« Reply #10 on: June 19, 2025, 10:31:00 PM »
On the whole, the Load/UnLoad/DisposeScript trinity was misunderstood. I've seen them misused many times. For one example, we have this in QfG1 (cemetery):
Code: [Select]
                (DisposeScript riseUpLeft)
                (DisposeScript riseUpRight)
                (DisposeScript riseDownLeft)
                (DisposeScript peekABoo)
All four lines refer to instances of Script, not script numbers. "There are two things we at Sierra call scripts" explained the guy in that interview. Yes, and it clearly causes misunderstandings sometimes.

Offline Kawa

Re: ERROR debug
« Reply #11 on: June 20, 2025, 03:34:14 AM »
At this point I'm thinking, what if
Code: [Select]
(class Cutscene of Object
  (properties
    name "Script"
    ;; rest of the Script class stuff
There, now you can't mistake a Script-as-in-cutscene for a script-as-in-module, and people looking at the result can't tell you did it.

Offline lskovlun

Re: ERROR debug
« Reply #12 on: June 20, 2025, 04:23:35 AM »
Another common mistake I see is doing (Load rsSCRIPT n). This will force some of the disk I/O to take place during room init as intended, but it won't load the corresponding heap resource (in SCI1.1 and higher) and won't instantiate (as it's called in ScummVM) the desired script, or any dependent scripts. That will have to be done later.

Offline doomlazer

Re: ERROR debug
« Reply #13 on: June 21, 2025, 12:47:07 PM »
Is there a correct way to load it?

Offline lskovlun

Re: ERROR debug
« Reply #14 on: June 21, 2025, 02:29:14 PM »
(ScriptID n). Or just name a class in the script.


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

Page created in 0.06 seconds with 22 queries.