Author Topic: [LB2CD] approachVerbs causes inset to display graphical issues  (Read 327 times)

0 Members and 1 Guest are viewing this topic.

Offline avo323

[LB2CD] approachVerbs causes inset to display graphical issues
« on: November 05, 2025, 02:58:34 PM »
Hi! I'm having troubles with a strange phenomenon after coding some bugfixes for LB2CD's safe in Carrington's office (#560, #561). The CD version of LB2 ditched the auto-closing of the safe/picture that was present in the floppy version, but that decision brought multiple side effects they overlooked (apart from the infamous "unable to open picture" bug).

Since they let the picture stay open, the player can try to use verbs from afar on it, on the safe or on the safe's door. None of these props are initialized with approachVerbs (in the floppy version that makes sense because the painting would close before you could interact from afar to begin with), what leads to ego being able to trigger them as if Laura had a remote control. Considering this, I modified them so they're initialized with approachverbs, a pretty basic and straightforward alteration.

In #560, safePic:doVerb:
Code: [Select]
;((ScriptID 561 0) init:) ; safePicture
((ScriptID 561 0) init: approachVerbs: 4 1 8)

In #561, safePicture:init:
Code: [Select]
;(safe init: stopUpd:)
(safe init: stopUpd: approachVerbs: 4 1 8)
;(safeDoor init: stopUpd)
(safeDoor init: stopUpd: approachVerbs: 4 1 8)

Everything works well, except for one bizarre issue. When you use the DO verb on safeDoor, it has to set an inset of the dial (inDial). If you do it from afar, ego now correctly approaches the safe (yay!), but the moment the inset appears I get this:



And when the inset is disposed, remainders of it stay on screen. The funny thing is that this doesn't happen if I use the DO verb on safeDoor when ego is next to it and doesn't need to approach it (using the exact same code, just ego being close).

That inset is set by safeDoor:doVerb in #561:
https://github.com/sluicebox/sci-scripts/blob/12c1ab894c4bd5fbf4157eb18a9e86653ec15d1b/ra-cd-dos-1.1/src/safePicture.sc#L78-L130

And this would be the inDial inset, also in #561 (it initializes a ton of features):
https://github.com/sluicebox/sci-scripts/blob/12c1ab894c4bd5fbf4157eb18a9e86653ec15d1b/ra-cd-dos-1.1/src/safePicture.sc#L132-L182

I found out that by creating a simple instance of Script to wrap the "(gCurRoom setInset: inDial)" with a 1 cycle wait in the initial state, and attaching it to safeDoor:doVerb using "(gCurRoom setScript: sInDial)" instead directly setting the dial using "(gCurRoom setInset: inDial)" makes it properly display. Without the 1 cycle wait it'll still glitch.
Code: [Select]
(instance sInDial of Script
(properties)

(method (changeState newState)
(switch (= state newState)
(0 (= cycles 1))
(1
(gCurRoom setInset: inDial)
(= cycles 1)
)
(2 (self dispose:))
)
)
)

Does anyone know why this would happen? I'm suspecting the game requires a small delay to set it properly if ego approaches it, but I don't see any logic behind this. I'd prefer to avoid coding any new instance, including additional classes or add new methods if possible (as I'm not a fan of making heap patches if they're not strictly needed), but safeDoor is a prop and afaik these have no means to delay execution or execute things sequentially. Any suggestions are welcome. Thank you!
« Last Edit: November 05, 2025, 03:03:51 PM by avo323 »



Offline lskovlun

Re: [LB2CD] approachVerbs causes inset to display graphical issues
« Reply #1 on: November 09, 2025, 08:18:16 PM »
safeDoor is stopUpdated. You need to kick off a forceUpd or something, I think. Or accept that safeDoor can't be stopUpdated anymore and remove the stopUpd:
« Last Edit: November 09, 2025, 08:31:50 PM by lskovlun »

Offline avo323

Re: [LB2CD] approachVerbs causes inset to display graphical issues
« Reply #2 on: November 11, 2025, 12:02:07 PM »
Thank you for your suggestion and taking the time to look into it, and sorry for the late reply. I tried out getting rid of one of safeDoor's "stopUpd:". I tried removing only the one in safePicture:init,  only the one in inDial:init, and even both of them, but the glitch still occurs no matter what I do.

But you made me realize stopUpd is relevant, since if I remove "(safeDoor stopUpd:)", "(safePicture stopUpd:)" and "(gEgo stopUpd:)" from inDial:init things look better: the dial inset is then fully drawn but the numbers 6 and 7 start blinking, which is also undesirable for multiple reasons, but at least I'm seeing a different behavior that could help to find the culprit. Anyway, the thing is that I had to remove the three of them for the dial inset to appear fully drawn with blinking numbers. If I keep any of them, even if it's just one, the inset will look "cropped" like in the screenshot I shared above.

I still find this illogical... I don't understand why I'm getting the glitchy inset only when LB2CD's built-in approach code makes ego move near the safe before safeDoor:doVerb is called, everything looks fine if ego is already next to the safe (x:76 y:95 coords) and doesn't need to move there. Or why setting the inset using an instace of Script with a 1 cycle delay makes the problem fully vanish.

Offline lskovlun

Re: [LB2CD] approachVerbs causes inset to display graphical issues
« Reply #3 on: Yesterday at 08:26:02 AM »
I looked into it some more, and it turns out (which I had forgotten) that Insets replace the cast list temporarily. This is why your script works, because it gives the original cast list (which contains the safe door) a chance to update.

You could try replacing
Code: [Select]
(gCurRoom setInset: inDial)with
Code: [Select]
(Animate gCast 0)
(gCurRoom setInset: inDial)
(maybe change the 0 to 1 here if that doesn't work)

Offline avo323

Re: [LB2CD] approachVerbs causes inset to display graphical issues
« Reply #4 on: Yesterday at 06:08:32 PM »
Thanks again for your time and the helpful suggestions, it's appreciated. You're totally right about Insets and it's very likely that's related. "(Animate gCast 0)" or "(Animate gCast 1)" kept throwing me errors but I've seen that all around LB2CD, what's used to update the cast is "(Animate (gCast elements?) 1)" or "(Animate (gCast elements?) 0)", so I gave them a go. Unfortunately the inset keeps behaving in the same glitchy way. It's as if the game only found opportunity to update the cast once the inset is already being shown, no matter what I try within safeDoor:doVerb, but it can be just my impression.

I've been investigating a bit how Features work in the game, more specifically how they handle events, to try to understand better what's going on. I've seen that Feature:handleEvent is where is checked if ego needs to approach the Feature/Prop/View, and uses Polypath to move it if that's the case. Here:
https://github.com/sluicebox/sci-scripts/blob/12c1ab894c4bd5fbf4157eb18a9e86653ec15d1b/ra-cd-dos-1.1/src/Feature.sc#L121-L148
If ego doesn't need to approach or face the object, "(CueObj changeState: 3)" is called, CueObj in turn runs the client's doVerb method during state 3 (the client here would be safeDoor). If ego needs to approach the object, CueObj is instead called from the start after ego has been moved with Polypath.

So, CueObj's states 1 and 2 only get executed when the object has approachVerbs and ego needs to approach it (the exact situation where this inset's glitch happens). State 1 changes ego's heading so it faces the object, but state 2 has a 3 cycles wait to give ego time to face the object:
https://github.com/sluicebox/sci-scripts/blob/12c1ab894c4bd5fbf4157eb18a9e86653ec15d1b/ra-cd-dos-1.1/src/Feature.sc#L30
I've done a quick and dirty modification in state 2 to see what happens if I skip that wait:
Code: [Select]
[...]
(2
(self changeState 3)
;(= cycles 3)
)
[...]
After doing this, the inset glitch no longer happens after ego approaches the object. Leaving a change like that in CueObj is of course a horrible idea, this was just to investigate the matter at hand. At least now the glitch isn't so "mysterious" anymore, that 3 cycles wait makes a big difference in this case, though I don't exactly understand why it would. Maybe some of you here knows.

I'll keep investigating, but if I'm unable to do further progress I think I'll end up reusing one of the Script instances already existing in #561 to call inDial from there whenever I need it. It wouldn't be the most elegant solution ever but that would be safe, would avoid the glitch and it wouldn't require a heap patch. Please let me know if you happen to look more into it and figure out another way to tackle this.


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

Page created in 0.029 seconds with 16 queries.