Question about eatsoap.hss

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

Post Reply
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Question about eatsoap.hss

Post by Inqualls901 »

So, I've been browsing and enjoying games here for about a year now. This is my first post though. I'm having a lot of fun looking through all the different plotscripts that come packaged with some of the games. I've been trying to learn about all the cool things you can do with advanced plotscripting and hamspeak. Commenting out many game scripts has been helping me a lot.

Anyway, I have been looking through the .hss file for don't eat soap and I'm stumped on the whole 'set exbit' and 'get exbit'. How can the slice extra data being set to n (either 0 or 1) be set so many times and return the correct true/false value depending on the 'get exbit' script call. I just don't see how the exbit constants matter as script arguments. If the meta extra is set to (0 or 1) previously then wouldn't a different 'get exbit' call still return the same extra data (0 or 1) since that value already exist in meta extra. I'm just not able to figure out what's going on here. Any incite would be greatly appreciated :)
User avatar
Bob the Hamster
Lord of the Slimes
Posts: 7660
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

Ah! Yes! One of my favorite slice extra data tricks :)

Using bitwise boolean operators, it is possible to cram 32 individual bits into one integer number
I am typing from my phone right now, but tomorrow I would be happy to write up an explanation
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

Wow, thanks for replying so quickly. I remember laughing to myself when I realized you stored script ID's in the players meta x and y values. Very innovative! The part that is messing me up is how you have an enemy or player being created with three or four 'set exbit' calls which place a value 'n' (0 or 1) into meta's extra data field. How can you set so many without erasing the previously set 'n' value.

I know that each call has a 'bit' argument with a different constant value but I can't see the significance in that when 'bit' is used in '2^bit'. No matter what the constant value of 'bit' is it always returns 1 when placed next to a comparison operator. I just want to know how 'get exbit' is able to return so many 'bit' specific booleans when it appears that meta extra can only be set for one 'bit'? On a side note, I'm very happy that you provided your scripts for 'dont eat soap' and 'bell of chaos'. These games are both nearly 4000 lines of code and are very educational for understanding what's under the hood as far as Ohrrpgce and hamspeak go. So, thank you and I hope you can help me understand this whole 'exbit' magic you've got going on here.
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

UPDATE: I think I got it. I was reading this part wrong:

if(value)
then(n := n, or, 2^bit)
else(n := n, and, (-1 xor 2^bit))

Let's say 'bit' = 4 and n = 0 and value =1
I thought the 'then()' read out as 'then (0, or, 1)' or if n = 1 'then (1, or, 1)' where both
return 1 but now I realize we would actually return 16, the true value of
2^bit and not the bit value '1'. Now 'get exbit' would make sense to return
specific 'bit' true or false boolean values.

Please let me know. If this isn't it then I really am out of ideas.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Hello!

The HS "or", "and" and "xor" operators are NOT logical comparison operators, that's what's confusing you. They are bitwise operators. The logical comparison operators in HS are written ||, && and ^^ ('or', 'and' and 'xor' respectively). In most programming languages, including C, C#, Java, Python and Ruby, the bitwise operators are written as |, & and ^ instead of 'or', 'and' and 'xor'. The reason HS uses these strange spellings is because James copied them from BASIC. ||. && and ^^ were only added to the language some years ago, so you will see that most OHR users continue to use 'and', 'or' and 'xor', even though this is discouraged because it can lead to bugs.

Bitwise operators operate individually on each bit of an integer. For example, 7 written in binary (as a 32 bit integer) is 00000000000000000000000000000111 (4 + 2 + 1) and 13 is 00000000000000000000000000001101 (8 + 4 + 1), so "7, and, 13" checks which bits are in common between the two, and has the value 00000000000000000000000000000101 (4+1==5).
In comparison, the result of &&, || or ^^ is always either 0 or 1.

Also, this is why "2^bit" is used. In binary, 2^0 is 0, 2^1 is 10, 2^2 is 100, 2^3 is 1000...
Last edited by TMC on Wed Aug 17, 2016 11:15 am, edited 1 time in total.
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

Now I get how you could store 32 individual bits inside the number. So, when I get 2^4 = 16 the 'and' operator actually reads it out as binary 10000 or 1 * 2^4. I never thought of any of this before. Man, that's tricky. I'm pretty new to reading binary and had to brush up on it again. So, the 32 bits are used as an 0 indexed list of 1's and 0's and the 'bit' argument is basically referencing where the '1' is placed in the 32 bit line up. I'm really glad I finally posted here. You guys are a great help. I feel so much better knowing that I understand this the correct way then just going along with my own assumptions. Thank you TMC for the extra clarity.

Oh, one last thing. when you wrote "7, and, 13" does HS return '1' because it found at least one common bit between the two values or does it actually grab the common bits and return their sum. You were right when you said I was confused by this. What about "4, and, 3" in HS. Wouldn't this return '0' since they have no bits in common or will it return '1' if both
values have at least one of their bits return 1. I realize that when using "(n := n, and, 2^bit)" the values '4,and, 3' would never come up but this is more for future reference when I see the bit wise operators used again elsewhere.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

The bitwise operators return integers, not 0 or 1 (false/true). So "7, and, 13" is equal to 5 in HS, and "4, and, 3" is equal to 0. And actually "3, and, 4" would come up in that script as 2^2==4.

It ought to be made easier, but currently the easiest way to test out bits of code yourself is to use the tracevalue command, which takes a variable number of arguments and prints out their values to the g_debug.txt file. For example save the following script as a .hss file, create a new blank RPG, import the file (hint: press F5 on the main menu) and then set the script as the new game script in General Game Data -> Special Plotscripts and run the game with Test Game (go past the title screen before closing it).

Code: Select all

plotscript, the newgame script, begin
  trace($0="Testing bitwise operators")
  trace value(15, and, 7)
  trace value(2^4, (255, and, 2^4))
  trace value(15, xor, 7)
end
Then when you open g_debug.txt in the same directory you'll see at the end:

Code: Select all

! TRACE: Testing bitwise operators
! TRACE: 15, and, 7 = 7
! TRACE: 2^4 = 16, (255, and, 2^4) = 16
! TRACE: 15, xor, 7 = 8
Last edited by TMC on Thu Aug 18, 2016 12:17 am, edited 4 times in total.
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

Thank you so much. Trace value worked great. I didn't realize that each time 'set exbit' was called that if the 'value=1' then
the 'n' variable was added to each time. So, according to the 'dont eat soap' script if 'bit:hero' and 'bit:nograv' were
set then n's value would be '24' which in binary is 011000.

When 'get exbit' is called 'bit:hero' becomes 16 and 'bit:nograv' becomes 8 because of 2^bit which both have common bitwise values with
n which is 24. Now I know how meta's extra 2 data is returning specific true or false values based on variable n's bit values.
I really do appreciate the help. Hopefully I can put something together myself. I have a lot of great ideas I'd love to try out. :)
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Right, sounds like you fully understand everything. Pleased to help!

Also, on the topic of storing data in slices (and working around engine limitations), this article might also be useful: Fake arrays
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

That is one thing that makes the ohhrpgce engine so appealing; the use of slices. Being able to create a 0-based array index by sorting through child slices of a parent slice (acting as the array) makes handling data so convenient. You can just set and retrieve your stored data through a couple of short helper scripts. Reading the data back out of the extra fields in any of the child slices becomes as simple as knowing their position relative to your own sort order. When I first realized that you could set a container slices x value to a script ID I honestly lol for a minute to myself. This whole slice thing is just really neat.

As far as global variable arrays, when I commented out James Paige's Baby Bob.hss it helped me to see how you could set aside a chunk of globals to write and read as long as you knew the length of your array in advanced. The array used there was the active slices(critters) and their independent x and y values. That way you could easy find any critters location on the map. I also read somewhere on here a append script for items and the length of the items array. It took me a while to realize how that one worked.

I actually find Ohhrpgce rewarding when thinking up how to write certain scripts. Having to create work-arounds forces you to be creative and intuitive instead of just relying on pre-existing modules or functions.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Heh, yes, figuring out how to work around limitations by repurposing things like slices is honestly pretty fun, and limitations are good for creativity (and for forcing yourself to aim for more realistic goals). That's why 48 hour contests are so appealing to me: I just attempt something crazy as a personal challenge instead of trying to make a good game.

However, the intent of the engine is to create RPGs, so not having arrays is a misfeature. James makes it look easy because he has written very well organised scripts, but it's too big of a hurdle for most people, who are just trying to make the game they want, and aren't professional programmers.
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

Jame's script writing in Bell of Chaos goes very very deep. I think out of every script file I've looked through that one and Cry Wolf are just so impressive considering that yes, this is an rpg engine and that somehow Cry Wolf was written and finished as a 48 hour game (if I remember correctly)!! Honestly, just wow! All I know is, I am going to work really hard at putting something together. It's just that sometimes I have trouble staying focused on one feature or idea before moving on to the next. If I can get that nailed down and finish up some of these tilesets and characters I'd be ready to go.
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

So, I've returned for a little more guidance on plotscripting. I've come across the function 'run script by Id' and was wondering what happens if you add an extra argument that the script originally doesn't consider.

ex:
-----------------------------------------
Original script:

script, create npc slice, ref, who, begin
#
#
end

Now called from another script using 'run script by id':

script, create npc slice copy, mRef, num, begin
# run script by id(@create npc slice, mRef, sl, num)
end

----------------------------
num is a new third argument passed to a script that only takes two. So, how is this new argument considered?
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Good question. I've edited the documentation for that command to specify:

If you pass too few arguments, the unspecified ones will have value zero instead of taking their default values from the script declaration.
If you pass too many (which does not cause an error), the extra ones are ignored.
User avatar
Inqualls901
Slime
Posts: 16
Joined: Wed Aug 17, 2016 12:32 am

Post by Inqualls901 »

Thanks. I was going to test it out and run a trace on a few variables to see if anything would change. You've been an awesome help TMC. I didn't expect an answer so quickly. Now I can move on without hesitation for the time being.
Post Reply