Castle Paradox Forum Index Castle Paradox

 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Gamelist   Review List   Song List   All Journals   Site Stats   Search Gamelist   IRC Chat Room

Nagging Question About For/Do Alternatives

 
Post new topic   Reply to topic    Castle Paradox Forum Index -> HELP!
View previous topic :: View next topic  
Author Message
Pepsi Ranger
Reality TV Host




Joined: 05 Feb 2003
Posts: 493
Location: South Florida

PostPosted: Fri Apr 13, 2007 3:31 pm    Post subject: Nagging Question About For/Do Alternatives Reply with quote

Okay, this has boggled me for years, and now I think it's time I finally ask:

Is there a better way to create an infinite sequence of a looped action (terminated only by leaving the map, fighting, or triggering a script that purposely stops it) than putting a ridiculously high number in a for/do command?

For example, I am creating a script that uses multiple tile animations (six frames instead of three). This animation calls a random number (the tile number), writes the corresponding tile block, and then does it again two ticks later calling some other random frame and writing it in. However, I don't want the thing to run out on me should the player decide to hang out in the area for awhile.

Likewise, every once in awhile I'll get the brilliant idea to run an action while something else is taking advantage of a repeated loop. The best method I have so far is to create actions during the break moments, but that looks tacky and "scripted." So is there another (better) way to script a repeated action (like someone shaking his head for a minute straight) while something else is playing out (like someone else walking a defined path from a table to a door and leaving) without having to interrupt the for/do script, or guesstimating how long it'll take the character to finish his path before needing the wait for whoever command to interrupt the looped action?

Any practical insight on this matter would be greatly appreciated.
_________________
Progress Report:

The Adventures of Powerstick Man: Extended Edition

Currently Updating: General sweep of the game world and dialogue boxes. Adding extended maps.

Tightfloss Maiden

Currently Updating: Chapter 2
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Newbie_Power




Joined: 04 Sep 2006
Posts: 1762

PostPosted: Fri Apr 13, 2007 4:36 pm    Post subject: Reply with quote

Quote:
Is there a better way to create an infinite sequence of a looped action (terminated only by leaving the map, fighting, or triggering a script that purposely stops it) than putting a ridiculously high number in a for/do command?
Is this what you are looking for?

If you want to stop this infinite loop, all you have to do is make the condition you put into the while loop not true. Say I use while (x == 1), and a fight or script triggers the script to end, so now x = 2 so the loop can't continue.
_________________

TheGiz> Am I the only one who likes to imagine that Elijah Wood's character in Back to the Future 2, the kid at the Wild Gunman machine in the Cafe 80's, is some future descendant of the AVGN?
Back to top
View user's profile Send private message
msw188




Joined: 02 Jul 2003
Posts: 1041

PostPosted: Fri Apr 13, 2007 6:07 pm    Post subject: Reply with quote

The while loop is usually the easiest thing for infinite loops. I have plenty of scripts that start with:
Code:
while (current map == map:MyMap), then

This will usually handle anything that you want to be constantly going on on a map.

As for your second question, I've often wanted to have several different script actions going on, and I've come to the conclusion that it is practically impossible. The only advice I could give is that if your desired animation is simple enough, you could have it designed using custom rather than a plotscript, and then it could run at the same time as a different script-controlled event. I'll use your example to try and illustrate. Instead of using npcs to illustrate the guy shaking his head over and over, I use animating map tiles. Then instead of a script that needs to constantly wait to change the position of the head, I have a one line script that writes the maptile in question, eliminating the problem of conflicting waits. Animating maptiles aren't enough for everything, but they can accomplish a lot. Other things in custom that might be helpful are pacing NPCs, or NPCs set to turn a certain direction upon hitting a wall. Using these together with clever wallmaps (again, setable without using waits in a script) and/or clever use of the NPC's animation frames may help.

All in all though, this is still a problem area for me, and I'd be very interested if anyone else has discovered other methods for faking this kind of functionality.
_________________
My first completed OHR game, Tales of the New World:
http://castleparadox.com/gamelist-display.php?game=161

This website link is for my funk/rock band, Euphonic Brew:
www.euphonicbrew.com
Back to top
View user's profile Send private message Visit poster's website
Moogle1
Scourge of the Seas
Halloween 2006 Creativity Winner
Halloween 2006 Creativity Winner



Joined: 15 Jul 2004
Posts: 3377
Location: Seattle, WA

PostPosted: Fri Apr 13, 2007 8:40 pm    Post subject: Reply with quote

msw188 wrote:
The while loop is usually the easiest thing for infinite loops. I have plenty of scripts that start with:
Code:
while (current map == map:MyMap), then


This should say do instead of then.

As for the second question, I'm pretty sure what you're asking for is possible, but can you elaborate?
_________________
Back to top
View user's profile Send private message Visit poster's website AIM Address
TMC
On the Verge of Insanity




Joined: 05 Apr 2003
Posts: 3240
Location: Matakana

PostPosted: Sat Apr 14, 2007 4:23 am    Post subject: Reply with quote

I really want to add the ability to run multiple scripts at once, totally unaffected by each other, the OHR update after next. In the meantime, here are some fun ways to fake it!

Without the ability to jump out of and into scripts, what you need to do is write your scripts so that rather than being called in the normal way, and containing wait statements, all or all but one are called once every tick and exit without waiting.

In the example you gave one script, walking an npc down a particular route, would be a pain to rewrite without use of wait statements, but nodding an npc's head is pretty simple:

Code:
script, nod head, begin
  set npc frame (npc frame (somenpc), xor, 1)
end


Then you have a master script:

Code:
script, master loop, begin
  variable (i)
  for (i, 1, X) do (
    nod head
    script 2
    script 3
    #...
    wait
  )
end

Or, in the example you gave, a 'master' script which does things itself:
Code:
script, wait and nod head, ticks, begin
  variable (i)
  for (i, 1, ticks) do (
    nod head
    #other script can be added here
    wait
  )
end

script, multiplexed sequence, begin

  #set our scene (using wait is OK)
  #and set global variables like somenpc if necessary

  #from this point, run nodhead in the background!

  walk npc (...)
  wait and nod head (30)    #instead of wait(30)
  walk npc (...)
  wait and nod head (40)

  #etc

end

If you wanted to use a waitfornpc statement, you'd have to write a script like:
Code:
script, wait for npc and nod head, npc, begin
  while (npc is moving (npc)) do (
    nod head
    wait
  )
end

There's a whole lot of complicated things you could do here: if you want nod head to be called every 4th tick, you could hardcode that into either wait and nod head or nod head, or you could have nod head return 4, and have the wait script count as many ticks as returned before calling it again. You could have nod head return -1 when it's finished and never needs to be called again.

You probably do have to deal with the case of your scripts finishing at different times: nod head could count the number of times it has been called and stop doing anything after the nth time, or prehaps an extra wait and nod head (X) is required at the end... It depends on what needs to happen next, really.


If we wanted to get really complex, we could use timers or switch statements (Ubersetzung features), call script by id, and more.

Finally, I'll note the way the intro to Trailblazers is scripted:
Code:
variable (time)
# this sequence is 1000 ticks long
for (time, 0, 1000) do (
  if (time == 0) then (
    # walk some npc, show a textbox, etc
  )
  if (time == 2) then (
    # walk some other npc
  )
  if (time == 30) then (
    # something else
  )
  #etc

  wait
)

That's another way of doing this all in the same script, and probably necessary to run two complicated scripts in parallel, but suffers from difficult timing requirements.
_________________
"It is so great it is insanely great."
Back to top
View user's profile Send private message Send e-mail
Pepsi Ranger
Reality TV Host




Joined: 05 Feb 2003
Posts: 493
Location: South Florida

PostPosted: Sat Apr 14, 2007 1:22 pm    Post subject: Reply with quote

About the first question:

I realize now that the last time I tried using it without "key is pressed," I used it with the wrong conditional, and thus it didn't work, and thus was the reason I didn't think it worked for infinite action. But I tried it with a "checktag" last night and it did exactly what it was supposed to, so thanks for reminding me to try that again.

About the second question:

The Mad Cacti wrote:

Or, in the example you gave, a 'master' script which does things itself:

Code:
 
script, wait and nod head, ticks, begin
  variable (i)
  for (i, 1, ticks) do (
    nod head
    #other script can be added here
    wait
  )
end

script, multiplexed sequence, begin

  #set our scene (using wait is OK)
  #and set global variables like somenpc if necessary

  #from this point, run nodhead in the background!

  walk npc (...)
  wait and nod head (30)    #instead of wait(30)
  walk npc (...)
  wait and nod head (40)

  #etc

end
 




Okay, you'll have to forgive me, but I'm still not that good with script arguments. In the script

Code:

script, wait and nod head, ticks, begin
  variable (i)
  for (i, 1, ticks) do (
    nod head
    #other script can be added here
    wait
  )
end


can the word "ticks" just be written into the header, or is there another script defining it somewhere (in theory)?

And, regardless of where it's defined, is the use of "ticks" in the for/do command just another way of keeping the script running until a conditional is met, or does it define a specific variable?

And on this part

Code:

script, multiplexed sequence, begin

  #set our scene (using wait is OK)
  #and set global variables like somenpc if necessary

  #from this point, run nodhead in the background!

  walk npc (...)
  wait and nod head (30)    #instead of wait(30)
  walk npc (...)
  wait and nod head (40)

  #etc

end


are you telling me that a script can be told how many times to run, or is the (30) and (40) the number that defines the "ticks" argument?

The latter would make more sense, based on what I think I know about arguments, and would probably answer my first question (about "ticks"), but I just want to be sure since arguments are my weakness.

Timers I'm not so great with, either. I have rudimentary knowledge of ways to implement a timer, but I have no idea how to keep them running from one map to another (or in any instance where a script runs the risk of terminating prematurely). The best I have is the check real time features in plotscript, or to countdown ticks with a global variable, but again that requires every map to run the same script, and that grossly limits what can be run on top of it.

In other words, I can think of podunk ways to get a time limit like the one in Scary Game to work, but not to actually make it effective, or to let other scripts run on top of it while staying true to the real time limit.

Of course, your example from Trailblazers makes some sense of it in a local setting, so that might serve as a fine groundwork, and will probably come in handy some day.

For Moogle, I'll private message you with the specific example and the script that runs it, if you'd like. I'd like to make it more fluid than it runs already if possible.

Thanks.
_________________
Progress Report:

The Adventures of Powerstick Man: Extended Edition

Currently Updating: General sweep of the game world and dialogue boxes. Adding extended maps.

Tightfloss Maiden

Currently Updating: Chapter 2
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Moogle1
Scourge of the Seas
Halloween 2006 Creativity Winner
Halloween 2006 Creativity Winner



Joined: 15 Jul 2004
Posts: 3377
Location: Seattle, WA

PostPosted: Sat Apr 14, 2007 1:33 pm    Post subject: Reply with quote

Feel free. As for the timers issue, check out the timer script featured in the first issue of Hamsterspeak as well as the associated RPG file. It does exactly what you're asking for and I'll be glad to help you work it into your game.
_________________
Back to top
View user's profile Send private message Visit poster's website AIM Address
msw188




Joined: 02 Jul 2003
Posts: 1041

PostPosted: Sat Apr 14, 2007 9:58 pm    Post subject: Reply with quote

The Trailblazers example looks like it would be horrendous to have to plan out. Are there a set number of computer ticks that take place in each step? Is this how the number for an NPC's speed is calculated? Does this change from computer to computer? Even if all of this could be predetermined, such a script can only work if the player is suspended. If we want to have one master background script controlling several NPCs at once (smoothly) that is allowed to be interrupted by the player, even something so simple as the player getting in the way of an NPC trying to get out the door, I still feel like this is not possible under the current restrictions of Hamsterspeak, although I am certainly no expert.
_________________
My first completed OHR game, Tales of the New World:
http://castleparadox.com/gamelist-display.php?game=161

This website link is for my funk/rock band, Euphonic Brew:
www.euphonicbrew.com
Back to top
View user's profile Send private message Visit poster's website
Camdog




Joined: 08 Aug 2003
Posts: 606

PostPosted: Mon Apr 16, 2007 6:01 am    Post subject: Reply with quote

Don't know if Moogle already answered this in a PM, but if not or in case anyone else is wondering...

Pepsi Ranger wrote:
can the word "ticks" just be written into the header, or is there another script defining it somewhere (in theory)?

And, regardless of where it's defined, is the use of "ticks" in the for/do command just another way of keeping the script running until a conditional is met, or does it define a specific variable?


Since 'ticks' is defined as an argument in the script here:

Code:
script, wait and nod head, ticks, begin


It should be written as shown into the header, since that is in fact where it is defined (it is defined as whatever number is passed to this function whenver the function is called), which brings us to the next part of the question...

Pepsi Ranger wrote:
are you telling me that a script can be told how many times to run, or is the (30) and (40) the number that defines the "ticks" argument?

The latter would make more sense, based on what I think I know about arguments, and would probably answer my first question (about "ticks"), but I just want to be sure since arguments are my weakness.


Yeah, you're absolutely right about it being the latter. The script 'wait and nod head' takes one argument, called 'ticks'. In the first case, the line

Code:
wait and nod head (30)


Passes the number 30 as the argument, which means ticks will be defined as 30 for that function call only. Later, when the argument is 40, ticks will be 40 for that call. In other words, arguments behave exactly like variables (they are variables, in fact), they are simply defined by whatever number is passed to the function when it is called.

You can also pass multiple arguments to functions, as in this example:

Code:
script, showTextboxAndNumber, textBoxNumber, otherNumber, begin
  show text box(textBoxNumber)
  show value(otherNumber)
end

script, start game script, begin
  showTextboxAndNumber(1, 20)
  advance text box
  wait(50)
  showTextboxAndNumber(5, 35)
  advance text box
end


If you set your start game script to 'start game script', it would first show text box 1 and the number 20, wait 50 ticks, and then show text box 5 and the number 35. If you reversed the order of the numbers, it would show text box 20 and the number 1, wait 50 ticks, and then show text box 35 and the number 5. Also remember that you can pass variables as arguments, so 'showTextboxAndNumber(x, 35)' would work as well, assuming you had defined 'x' somewhere in your script.

Also, excuse my pedantry, but instead of checking a condition you know is true to create an infinite loop, you can simply write:

Code:
while (true) do(
  #do your infinite loop stuff
)
Back to top
View user's profile Send private message
Mr B




Joined: 20 Mar 2003
Posts: 382

PostPosted: Mon Apr 16, 2007 8:03 am    Post subject: Reply with quote

Okay...curses. This is my second attempt at a reply. CP logs me out when I'm writing and doesn't allow me to go back to recover my text.

Anyways. A couple of years ago I programmed a...thingy...that permitted me to run several scripts (almost) simultaneously.

It had a few parts:

1.) A timer. This was a simple variable that increments and returns to its lowest value after it reaches a certain point.

2.) A bubble-up data structure contained in an array. Each element had several sub elements; the first contained the ID number of a script to be called, the second contained the timer value at which it would be called, and the rest contained values to be passed to the script.

The above were all contained in a while loop that incremented the timer and ran the scripts when their time came.

The scripts themselves could do just about anything as long as they didn't contain any "wait()" statements. Instead of "wait()" statements they needed to create a new entry in the array with an execution time of one more than the current timer value.

It worked pretty well (after much suffering), but I was to exhausted to make the actual game. Programming with something like this ended up being really weird.

Um yeah. You're probably not looking for anything quite so complex as this -- the other advice might very well do you just fine.
Back to top
View user's profile Send private message
Mr B




Joined: 20 Mar 2003
Posts: 382

PostPosted: Tue Apr 17, 2007 7:50 am    Post subject: Reply with quote

"Simulated multithreading," that's the ticket.

Somewhat more expressive than "thingy."
Back to top
View user's profile Send private message
Pepsi Ranger
Reality TV Host




Joined: 05 Feb 2003
Posts: 493
Location: South Florida

PostPosted: Wed Apr 18, 2007 6:59 pm    Post subject: Reply with quote

Thanks for the replies, guys. Yeah, Moogle already PMed with his take on this. The bottom line, which I'm getting from most of you, is that I need to use a timer in instances like these, so that's what I'll try next time I reach a place where it's necessary.

And, no, I'm not afraid of timers. I already have one scene (in the same place as the requested example, believe it or not), where the hero has to serenade a shop owner with made-up song (to the tune of a real one), and that, of course, involved a lot of perfection in timing. It was a day-long pain, but it paid off, so I'm not afraid to do it again with a walking script, or anything else for that matter.

And now that I know that while/do and for/do scripts don't terminate upon leaving the map, as I originally thought, my ideas for timers are multiplying.

So thanks to everyone who mentioned that.
_________________
Progress Report:

The Adventures of Powerstick Man: Extended Edition

Currently Updating: General sweep of the game world and dialogue boxes. Adding extended maps.

Tightfloss Maiden

Currently Updating: Chapter 2
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Moogle1
Scourge of the Seas
Halloween 2006 Creativity Winner
Halloween 2006 Creativity Winner



Joined: 15 Jul 2004
Posts: 3377
Location: Seattle, WA

PostPosted: Wed Apr 18, 2007 7:48 pm    Post subject: Reply with quote

You may prefer something like this:

Code:
while (current map == map:Fooville) do (
 xyz
)

_________________
Back to top
View user's profile Send private message Visit poster's website AIM Address
Display posts from previous:   
Post new topic   Reply to topic    Castle Paradox Forum Index -> HELP! All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group