 |
Castle Paradox
|
View previous topic :: View next topic |
Author |
Message |
chronoboy Into the past with a splash

Joined: 04 Jun 2010 Posts: 162 Location: Canada
|
Posted: Sun Nov 21, 2010 9:30 pm Post subject: Using built-in scripts with @script-name |
|
|
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 |
|
 |
TMC On the Verge of Insanity
Joined: 05 Apr 2003 Posts: 3240 Location: Matakana
|
Posted: Sun Nov 21, 2010 9:57 pm Post subject: |
|
|
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 |
|
 |
chronoboy Into the past with a splash

Joined: 04 Jun 2010 Posts: 162 Location: Canada
|
Posted: Sun Nov 21, 2010 10:15 pm Post subject: |
|
|
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  |
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 |
|
 |
TMC On the Verge of Insanity
Joined: 05 Apr 2003 Posts: 3240 Location: Matakana
|
Posted: Sun Nov 21, 2010 10:56 pm Post subject: |
|
|
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 |
|
 |
chronoboy Into the past with a splash

Joined: 04 Jun 2010 Posts: 162 Location: Canada
|
Posted: Sun Nov 21, 2010 11:28 pm Post subject: |
|
|
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 |
|
 |
TMC On the Verge of Insanity
Joined: 05 Apr 2003 Posts: 3240 Location: Matakana
|
Posted: Mon Nov 22, 2010 1:07 am Post subject: |
|
|
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 |
|
 |
|
|
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
|