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

Using built-in scripts with @script-name

 
Post new topic   Reply to topic    Castle Paradox Forum Index -> HELP!
View previous topic :: View next topic  
Author Message
chronoboy
Into the past with a splash




Joined: 04 Jun 2010
Posts: 162
Location: Canada

PostPosted: Sun Nov 21, 2010 9:30 pm    Post subject: Using built-in scripts with @script-name Reply with quote

Considering this menu generation script?

Code:

plotscript, debug shop, begin
  variable (mymenu,tmp,i)
  mymenu := create menu
  set menu bit (mymenu,menubit:allow gameplay,off)
  for (i,0,total items,1) do, begin
    tmp:=add menu item(mymenu)
    get item name (1,i)
    set menu item caption(tmp,1)
    set menu item type (tmp,menutype:script)
    set menu item subtype (tmp,@get item)
    set menu item bit (tmp,menu item bit:close menu when selected)
    set menu item extra (tmp,0,i)
  end
end


It fails to compile... Instead of using this more direct method, I am forced to write a "wrapper script" around get item.

I can only assume that @script-name will not work with any built-in scripts, when using things like run script by ID and such... *sigh* and wanted to make self-modifying code in OHR... well sort of, store everything in global variables and run the code from global variable 1. Consider this(while I got your attention):

Code:

ptr:=1
while (true) do, begin
  cmd:=read global(ptr)
  if (cmd==-1) then (break)
  run script by ID (cmd,read global(ptr+1),read global(ptr+2),read global(ptr+3))
end


Basically this would be your HSS file, and all your game scripting code would reside in your SAV file, preferably one of the unused save slots. During gameplay, your scripts could modify one another and really make things interesting.

If your wondering how to get your script into the SAV globals, before this script runs, use my nifty script to check if debug keys are enabled. If they are enabled, then run a special bootstrap script which would in turn write a huge amount of globals into the SAV file then quit or run the above script to test.

I am rather tempted on writing a tech demo which would utilize this type of thing, I would create some "wrapper scripts" around the "real functions" in order to glue everything together.

Example on how to write out the scripts to the SAV file to be read and EXEd using the script above:

Code:

global variable (ptr)
ptr:=1
script, save script by ID,scr,p1,p2,p3, begin
  write global (ptr,scr)
  write global (ptr+1,p1)
  write global (ptr+2,p2)
  write global (ptr+3,p3)
  ptr:=ptr+4
end


This is obviously very simple, as it only allows for 3 arguments, but 3 is plenty for most things in OHR. An better version would allow diversity and perhaps the inclusion of strings for arguments.

I'll see about releasing a tech demo "OHR VM" next month, I would sooner, but I have my Heart of OHR game to worry about. Imagine that though, a bytecode interpreter built on plotscript. It would be really fun to make a very simple BASIC interactive interpreter in plotscript running in OHR. Something along the lines of GW-BASIC... then finding a way to actually import old .BAS file from GW into plotscript to interpret, such as Eliza or colossal cave. There are definitely enough globals to hold an entire source file, but as each command is entered it will convert it to a bytecode. It would be as slow as glue if I were to use the ascii command in plotscript over a billion times to run something.

Interesting note: This would be a good experiment nonetheless to see how much the plotscript engine can really handle and how fast it can run like this.
_________________
Current project: Chronoboy Adventures

Website: http://www.chronoboy.com/
Back to top
View user's profile Send private message Visit poster's website
TMC
On the Verge of Insanity




Joined: 05 Apr 2003
Posts: 3240
Location: Matakana

PostPosted: Sun Nov 21, 2010 9:57 pm    Post subject: Reply with quote

Wow, I am amazed that you have come up with such a crazy use of scripting that not even I had thought of it.

I had an idea for extending @ to built-in functions, you can read more at Replace runscriptbyid with function call operator syntax? (warning: much of that page is just ideas jotted down; several of them will definitely be scrapped, and it doesn't list newer ones either)

Quote:
Interesting note: This would be a good experiment nonetheless to see how much the plotscript engine can really handle and how fast it can run like this.


The hamsterspeak interpreter is really slow compared to other scripting interpreters (actually I have not compared it, but this is clear), though it is vastly faster than it was 10 years ago. I would welcome benchmark code!

However, without decent arrays, strings, or pointers, I'd say writing a BASIC to bytecode compiler is pretty much insane. Guess you like insane challenges :)
_________________
"It is so great it is insanely great."
Back to top
View user's profile Send private message Send e-mail
chronoboy
Into the past with a splash




Joined: 04 Jun 2010
Posts: 162
Location: Canada

PostPosted: Sun Nov 21, 2010 10:15 pm    Post subject: Reply with quote

The Mad Cacti wrote:
However, without decent arrays, strings, or pointers, I'd say writing a BASIC to bytecode compiler is pretty much insane. Guess you like insane challenges Happy


Pointers will work under the interpreted code, to point to memory locations allocated via global variables. Since the bytecode per say is being stored in global variables, the array is essentially program memory. Below is a full working example, create a new RPG file, write a textbox with something fun, and enjoy! This can be extended obviously, by creating more scripts to be called from the VM, and it does allow self-modifying code, if you create a script which allows you to read and write globals. The PTR variable is global, as this way I can make flow control work by simply changing the variable to somewhere else in the code.

Code:

include, plotscr.hsd

global variable (1,ptr)

plotscript, init, begin
  import globals (1,2,import globals (1,1))
  if (read global(1)==0) then (bootstrap)
  ohrvm
  game over
end

script, tbox,p1,p2,p3, begin
  show textbox (p1)
  wait for textbox
end

script, save script by ID,scr,p1,p2,p3, begin
  write global (ptr,scr)
  write global (ptr+1,p1)
  write global (ptr+2,p2)
  write global (ptr+3,p3)
  ptr:=ptr+4
end

script, end code, begin
  write global (ptr,-1)
  save in slot (1)
end

script, bootstrap, begin
  ptr:=2
  save script by ID (@tbox,1,0,0)
  end code
end

script, ohrvm, begin
  variable (cmd)
  ptr:=2
  while (true) do, begin
    cmd:=read global(ptr)
    if (cmd==-1) then (break)
    run script by ID (cmd,read global(ptr+1),read global(ptr+2),read global(ptr+3))
    ptr:=ptr+4
  end
end


GREAT IDEA ON HOW THIS COULD BE USED IN AN RPG GAME: Say, you have an RPG game which technically breaks the "forth wall", in which your NPCs, characters, etc.. know the player exists. They could essentially edit their own code, all NPC/Character code could be stored in the players SAV file, allowing them access to edit it. It would be interesting to see if some cool AI could be made this way.

PROGRAMMING MINI-GAME IDEA: Another fun idea, is to put a mini interpreter in the game which will work with a mini-game, for example, hacking a computer for that file, or something else along those lines. Since it would be partly tied into plotscript, it would allow the player to feel as if he was really hacking. Input string would accept commands and interpret them then execute the relevant plotscript which would lead the player either closer or further from unlocking the secret.

I am sure there are other neat things which could be done with such a system... I'll leave it to the read to think of other insane ideas for this.

P.S. Has anybody really used the run script by id yet?
_________________
Current project: Chronoboy Adventures

Website: http://www.chronoboy.com/
Back to top
View user's profile Send private message Visit poster's website
TMC
On the Verge of Insanity




Joined: 05 Apr 2003
Posts: 3240
Location: Matakana

PostPosted: Sun Nov 21, 2010 10:56 pm    Post subject: Reply with quote

Code:
  import globals (1,2,import globals (1,1))
  if (read global(1)==0) then (bootstrap)

I think this is wrong: "import globals (1,1)" reads global 1 and returns it, it doesn't actually change global 1.

Anyway, sadly although it is much hyped, self modifying code is not really much/any help when programming AI, and you'll have enormous trouble finding a good use for it in an RPG. And you'd have to be programming in Lisp for it to be practical.

Yes, lots of people use runscriptbyid. Since HamsterSpeak is so limited, people use the most advanced features they can :)
_________________
"It is so great it is insanely great."
Back to top
View user's profile Send private message Send e-mail
chronoboy
Into the past with a splash




Joined: 04 Jun 2010
Posts: 162
Location: Canada

PostPosted: Sun Nov 21, 2010 11:28 pm    Post subject: Reply with quote

The Mad Cacti wrote:
I think this is wrong: "import globals (1,1)" reads global 1 and returns it, it doesn't actually change global 1.

I believe your right, I updated the code as follows(No longer requires textbox):

Code:

include, plotscr.hsd

global variable (1,ptr)
global variable (2,rt)
global variable (3,bootcode)

plotscript, init, begin
  import globals (1,1,3)
  if (ptr>>0) then (import globals (1,bootcode,ptr)) else (bootstrap)
  ohrvm
  game over
end

script, tbox,p1,p2,p3, begin
  show textbox (p1)
  wait for textbox
end

script, global vars,p1,p2,p3, begin
  if (p1==0) then (exit returning(read global(p2)))
  if (p1==1) then (write global(p2,p3))
end

script, memcopy,p1,p2,p3, begin
  variable (i,i2)
  i2:=0
  for (i,p1,p2,1) do (write global(i2+p3,read global(i)),i2:=i2+1)
end

script, memerase,p1,p2,p3, begin
  variable (i)
  for (i,p1,p2,1) do (write global(i,0))
end

script, memmove,p1,p2,p3, begin
  variable (i)
  memcopy (p1,p2,p3)
  memerase (p1,p2,p3)
end

script, print,p1,p2,p3, begin
  globals to string(p2,p1+1,read global(p1))
  show string at (p2,0,0)
end

script, goto,p1,p2,p3, begin
  ptr:=p1
end

script, save script by ID,scr,p1,p2,p3, begin
  write global (ptr,scr)
  write global (ptr+1,p1)
  write global (ptr+2,p2)
  write global (ptr+3,p3)
  ptr:=ptr+4
end

script, save string,strid,sptr, begin
  variable (strlen)
  strlen:=string length(strid)
  write global (sptr,strlen)
  string to globals (strid,sptr+1,strlen)
  return (sptr)
end

script, end code, begin
  write global (ptr,-1)
  save in slot (1)
end

script, bootstrap, begin
  bootcode:=100
  ptr:=bootcode
  $1="Hello OHRVM!"
  save script by ID (@print,save string (1,10),1,0)
  end code
end

script, ohrvm, begin
  variable (cmd)
  rt:=0
  ptr:=bootcode
  while (true) do, begin
    cmd:=read global(ptr)
    if (cmd==-1) then (break)
    rt:=run script by ID (cmd,read global(ptr+1),read global(ptr+2),read global(ptr+3))
    ptr:=ptr+4
  end
  wait for key(any key)
end


The two new globals I added are for return value from a script, and the entry global variable of the code, this way I can start the code at global 100, and have stuff before it used for other purposes.

I haven't tested out the memcopy, etc... use at your own risk I guess. Be sure to delete the SAV file before using this newer version of the code. The goto script will change the code pointer to anything you tell it. Thus, you can use the global vars script to do some manipulation in the code and then run it after. I'll post after I have an example of this.

Here is an interesting thing that may appease all OHR developers:

Code:

script, string to globals improved,p1,p2, begin
  write global (p1,string length(p2))
  string to globals(p2,p1+1,read global(p1))
end

script, globals to string improved,p1,p2, begin
  globals to string(p2,p1+1,read global(p1))
end


It works just like the normal built-in scripts, but automatically handles the length information for you. The parameters are also swapped... I have never needed to save strings in globals for my games yet, but as I was working briefly on the VM tech demo, I saw how ghastly complicated the current strings to globals storage worked. yuk. In most languages you would write a NULL at the end of the string to indicate the end of it, but hspeak is not like other languages, so this method works great too.
_________________
Current project: Chronoboy Adventures

Website: http://www.chronoboy.com/
Back to top
View user's profile Send private message Visit poster's website
TMC
On the Verge of Insanity




Joined: 05 Apr 2003
Posts: 3240
Location: Matakana

PostPosted: Mon Nov 22, 2010 1:07 am    Post subject: Reply with quote

Yeah, "strings to globals" is another command that will become obsolete (you'll be able to store a string in a single global variable), and which I will be very glad to see go. Storing strings as null terminated isn't the best approach because HS strings can contain null bytes. It was maybe a bad idea to not include the length.

I don't really know what you plan to do with this, but I'll have fun using this as a benchmark for the new script interpreter. For that purpose, how about adding branching/looping and maybe math operator instructions?
_________________
"It is so great it is insanely great."
Back to top
View user's profile Send private message Send e-mail
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