Community
SCI Programming => SCI Community How To's & Tutorials => Topic started by: gumby on December 31, 2012, 08:11:36 PM
-
I just utilized the dying.sc script for the first time and I immediately noticed that there is a significant delay between calling the the script and the death 'screen' popping up.
This is by design, but I didn't like the fact that the delay length was hard-coded into script. Making a few modifications, I exposed the delay property for the script:
(instance public DyingScript of Script
(properties
seconds 3 // Exposed this property (just by adding it here),
) // which is inherited from the Script class & set the default to 3
(method (changeState newState)
(var mbResult, message)
= state newState
(if(== state 0)
ProgramControl()
(send gTheMusic:fade())
(send gRoom:setScript(0))
Load(rsSOUND 2)
//= seconds 3 // Commented out this line, which set the delay to 3 seconds
)(else
(if(== state 1)
...
So now, when I call the dying script, I can specify seconds like so:
(send dyingScript:
caller(802)
seconds(1) // You can set this to however long you wish, based on your animation length
register("You are dead.")
)
If you need more granularity than seconds, it would be simple to expose the 'cycles' property instead of the 'seconds' property in the Script class, then change the dying script to use cycles instead of seconds.
-
I take it that the interpreter or compiler can't deal with milliseconds? It may not matter much in this case, but I would be a little leery of using cycles to time much of anything. It is the source all of the timer bugs in the Sierra SCI games, including the "Can't initialize your audio hardware" SoundBlaster error. I can't think of an SCI0 game with a serious timer bug, so SCI0 may not be as prone as SCI1, but someone may play your game with DOSBox set at core=dynamic and cycles=max and expose any potential speed bugs.
-
Yeah, I think that avoiding the use of cycles is a good idea - just wanted it in there for completeness :)
-
Does it fail to compile if you set the seconds as a division? i.e. seconds(1/2) for a half sec?
-
For some reason, you cannot specify any value smaller than 1 (this includes zero for 'no delay'). Fractions above that seem to work, but it's tough to tell if it's working correctly or simply truncating or rounding the value to the nearest whole second.
-
I suspect that it only accepts whole integers, even if it performs the division. I wonder if this is a limitation of the interpreter, the compiler or both.
-
This is a limitation of the Script class, but it may be possible to change it to support finer granularity. Here's the related code (Obj.sc, Script class):
(method (doit)
(var theTime)
(if(script)
(send script:doit())
)
(if(cycles)
(if( not --cycles )
(self:cue())
)
)(else
(if(seconds)
= theTime GetTime(gtTIME_OF_DAY)
(if(<> theTime lastSeconds)
= lastSeconds theTime
(if( not --seconds )
(self:cue())
)
)
)
)
)
-
I wonder what else there is in the scripts that only allows whole seconds. If the aim is to make the template game as ideal as possible, I would say that nothing in the template should have course enough timing granularity to tempt a developer to use cycles.
-
From what I've found there are 4 or 5 scripts that would need to be changed. When I get some time, I'll look into if it's possible to get better granularity than seconds and modify the scripts.
-
Sounds like 'ticks' are what we want, though I'm not sure whether a tick is synonymous with a cycle. The Wait kernel function is defined as this (from the SCI Studio help file):
Wait
number Wait(number ticks)
This waits (halts the game) for the specified number of ticks. Since the interpreter is on 60Hz beats, a Wait(60) is equivilant to one second. It returns the time passed between the end of the last Wait() call, and the current one.
Additional info on ticks in the Timer class documentation:
void setReal(heapPtr theClient, number milliSec[, number sec, number min])
Assigns the timers client and time. This is basicly the same as set(), but can be more precise. milliSec is between 0 and 59 for the amount of interpreter "ticks".
-
That makes it seem as if it is cycles of the "PMachine", not the host's or real PC's CPU cycles. There should be no issues if it it is fixed at 60Hz. However, if it halts the game during the wait, does this mean that everything else during the wait be paused, too?
-
Yes, that is my understanding of what the Wait function does, it does block other game processes. I'm not necessarily suggesting that we utilize this particular function, but rather just as a reference to functions that use ticks rather than seconds (looking for a clear definition of what ticks are).
Sure sounds like it should be possible to rework all the scripts that use whole seconds to use ticks instead.
-
I can't imagine a need for anything finer than one tick.
-
Again, Gumby, could you add an article on the Wiki for this?
-
Done :)
-
Thanks.