Introducing Convenience Functions for the OHR: Volume 1

Make games! Discuss those games here.

Moderators: Bob the Hamster, marionline, SDHawk

Post Reply
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Introducing Convenience Functions for the OHR: Volume 1

Post by Pepsi Ranger »

Heart of the OHR 2020 is just a couple of weeks away. Have you started your game yet? Have you been ignoring it due to laziness?

Then give Convenience Functions a try!

These functions will speed up many basic script commands by eliminating redundancy. Some of them will also consolidate more complex features, like character animation, into a single line.

This Volume 1 pack includes some of my best all-purpose functions since the days of Hamster Speak Magazine while introducing plenty of new ones, like smoother turning and group movement commands.

Check it out if you want some inspiration!

And stay tuned for the official Heart of the OHR 2020 announcement coming soon.
Place Obligatory Signature Here
ArtimusBena
Slime Knight
Posts: 251
Joined: Thu Nov 16, 2017 5:22 am

Post by ArtimusBena »

Nice xD I love the description.
User avatar
Rue
Slime Knight
Posts: 135
Joined: Sun Dec 09, 2007 4:01 am
Location: Bellevue, WA
Contact:

Post by Rue »

Nothing in the script other than including plotscr.hsd, scancode, your hsi, and your functions.

I also tried just compiling just movement shortcuts.txt (your example file) and got the same error.

Code: Select all

reading c:\ohrrpgce\plotscr.hsd
including c:\ohrrpgce\scancode.hsi
reading test-script.txt
including movement shortcuts.hsi
including convenience functions.txt
4186 lines read from 5 files
preliminary pass
parsing top-level
compiling scripts...........................................................................................................................................................................................
ERROR: in script waitequivalent on line 42 in convenience functions.txt
 wait ((tick * fpstimer) / 18)
               ^
Unrecognised name fpstimer. It has not been defined as script, constant,
variable, or anything else
Does it require a specific version of hspeak or something? It's been a while since I've mucked around with hspeak.
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

You have to make sure you define the global variables that the guide tells you to define. I think there are ten of them.

I'd use the latest version of HSPEAK just to be sure.

Here's a clip from the instruction guide:
Convenience Functions for the OHR.doc wrote:Important Global Variables:

Remember to include these global variables in your game’s plotscript before you compile. The “convenience functions� depend on them to work. (See “Movement Shortcuts.txt� for usage example.)

# num, fpstimer
# num, waitsecs start
# num, waitsecs counter
# num, npc original picture
# num, npc original palette
# num, npc original direction
# num, npc original frame
# num, store npc original
# num, px plus
# num, py plus
# num, npc behavior
So you would define them as:

Code: Select all

global variable, begin
 0, fpstimer
 1, waitsecs start
 ...
 10, npc behavior
end
I started on Volume 2 right after I posted Volume 1, but I've gotten sidetracked with book editing, and then Heart of the OHR stuff, so I kinda forgot about it. The new volume will have moon-walking and stair-walking as functions (so far). I'll update and upload it sometime in the near future.

Anyway, let me know if that fixes it.

EDIT: Also, you don't need to include movement shortcuts into your own script. That's reserved for the test file I packaged with the functions. It would be like me trying to import your game's HSI into my game. It's not necessary. You only need "convenience functions.txt" and the eleven global variables for this to work.

EDIT 2: You also need to make sure you assign a value to "fpstimer" in whatever script launches your game. The value you assign it should equal your frame rate. "Wait Equivalent" reads this value as the number of ticks you're using per second. It allows you to maintain consistency in your character movements and animations regardless what frame rate you're running. You'll keep using "wait" if you want movement and animations to match the current frame rate (i.e. a frame rate of 30 will speed up animations that were originally written for 18 fps). Hopefully, TMC will allow adjustable frame rates within plotscript to mitigate the need to constantly update this value manually.
Last edited by Pepsi Ranger on Sat May 02, 2020 9:47 pm, edited 4 times in total.
Place Obligatory Signature Here
User avatar
Rue
Slime Knight
Posts: 135
Joined: Sun Dec 09, 2007 4:01 am
Location: Bellevue, WA
Contact:

Post by Rue »

Oh. My mistake. I don't have a DOC reader on my machine.

A case of rtfm then, huh?
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

Do you have a PDF reader? I could convert the document to a PDF for you if you want.
Place Obligatory Signature Here
User avatar
Rue
Slime Knight
Posts: 135
Joined: Sun Dec 09, 2007 4:01 am
Location: Bellevue, WA
Contact:

Post by Rue »

Nah, that's probably not necessary. I can pop it in Google docs or something. Thank you though!

Maybe include the readme in plaintext in the next iteration?
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

Rue wrote:Nah, that's probably not necessary. I can pop it in Google docs or something. Thank you though!

Maybe include the readme in plaintext in the next iteration?
I started on a PDF version anyway because I wanted to try out Affinity Publisher, and I figured why not make a cool brochure out of the convenience functions. I still haven't completed that PDF because I'm still learning Affinity's layout system, but I do hope to make it more pleasant to read (and more accessible for all readers) whenever I do finish it. That said, I'll also post an RTF version whenever I'm done.

I've got the second volume in progress and near completion, so look for that soon. I'll update all documents whenever I release the new volume.

The next volume will be primarily movement-based, with individual and group sets for moonwalking, side-stepping, and elemental reactions (getting blown across the screen) being its main features.

It will also have individual shape movement patterns including spins, staircases, squares, rectangles, and diamonds, each with custom depth control. Staircases will also have two types: smooth and rough. Smooth will essentially send the hero or npc up a diagonal path. Rough will "draw" the shape of a staircase with the selected character's movement.

I also have supplemental functions for swapping heroes with npcs (and vice versa) in case you want a quick function that allows you to "talk" to your squadmates before going back into battle.

I hope to have the pack ready in the next few days. In all, I'm on course to developing close to 140 new functions (most of them subsets of the features I described above, so there aren't any cool new surprises among that 140). What's there should cover the rest of your movement needs though. As of now, I have no plans for creating circular or triangular movements, but that will likely change if/when pixel movement becomes better supported.

I'll probably post a third convenience pack sometime in June. That one will be much smaller, but it should come with more convenient access and storage functions, especially with zones.
Place Obligatory Signature Here
User avatar
guo
Metal Slime
Posts: 749
Joined: Fri Dec 04, 2009 9:12 pm

Post by guo »

Great stuff, Pepsi. These sound really helpful.
vvight.wordpress.com
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

Just a quick update since "in a few days" was over two months ago.

I've been adding to the current set of functions featured in Volume 1, as well as Volume 2, and the animation sets. Basically, I'm losing track of what's new, so I'll probably release everything at once (including Volume 3, which was to feature all of my zone-related functions) in a single mega volume. I'm also adding to the convenience set as I need them for my own game, so I'll likely hold off putting the complete volume together until I'm sure I've got most of what I want in play.

I can't imagine this would take long, but it might.

Just to give you an idea what I've added since the last message, I've included "smart turn" to heroes and npcs, which turns a character at the end of a directional or x/y movement by tick, via the shortest turn to the target direction. Most of the time, this won't be needed, but its main purpose is to end the character's movement in the proper direction while allowing some turn animation to occur (instead of snapping the character to the end direction--most commonly noticeable when the character turns in the opposite direction). I've got several redundant commands like "hero 180 turn" and "npc opposite direction" as well, but the "smart turn" functions take the guesswork out while the others are there for fine-tuning (basically, if you have a specific script you want heroes or npcs to follow).

I've also got a few "mass" functions like setting up to 12 tags at once and stopping up to 12 timers or sound effects at once.

Finally, I've got some conversation shortcuts that allow you up to eight dialogue trees mixed with "pauses" (waits) for quick conversation scripting. "Basic conversation" just delivers the conversation; "npc conversation" forces a moving npc to stop and face the hero before initiating a conversation, then continues on his merry way when the conversation is over.

If demand is high, I'll rush these out sooner then later. Otherwise, hang in there. I'm still adding to the sets. I think I'm up to about 300+ functions (mostly special moves and shortcuts for heroes, npcs, and hero groups).
Last edited by Pepsi Ranger on Tue Jul 28, 2020 6:32 am, edited 1 time in total.
Place Obligatory Signature Here
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

Just a quick update: I'm finished with the second edition of functions, and let me tell you there are a lot of them now. I just have to finish writing up the instructions on how to use everything, but because there are so many, this may also take me a few days to complete (I've spent about four hours today just writing the instructions for the first section). But I think it'll be worth it. You'll be able to accomplish almost any stage direction you can think of from this pack as well as perform simplified value checks for various number ranges and roulettes, and some other interesting things.

For those of you trying to get some momentum on your Heart of the OHR projects, this may help speed things up.

I hope to have all this done by early next week.

For now, here's a sample of what you'll get:

Code: Select all

script, fair random, value = 10, begin
 variable (r1, r2)
 r1 := random (1, value)
 r2 := random (1, value)
 if (r1 == r2) then(
  exit returning (true)
 )
 exit returning (false)
end
fair random (value)
-A scale for keeping random numbers fairly balanced. It rolls two numbers between 1 and the value and attempts to match them, then returns true or false based on the result. Works as a condition and is best used within a for/do or while block that counts each failure to match and breaks on success, using the final count as the designated “random value.� The lower the value, the better the results. Defaults to 10.

Example:

Code: Select all

script, how many pizzas I have, begin
  variable (f)
  global match := 0
  for (f, 1, 50) do(
    if (fair random (20)) then(
      global match := f
      show text box (1)  #I have 12 pizzas
      wait for text box
      break
    )
  )
  if (global match == 0) then(
    show text box (2)  #I have no pizzas
    wait for text box
  )
end
In the above example, “global match� is a global variable embedded in textbox (1) that reports how many pizzas I have. Instead of picking any number at random between 1 and 20 to represent my pizza count, the script runs a loop as many as fifty times to attempt to match two random values between 1 and 20, and it manages to make that match on the 12th loop. So I have 12 pizzas. Alternatively, if I run through 50 loops without a match, then the script will run the second textbox, declaring that I have no pizzas.

Note that this is just one way to use “fair random.� It can just as easily be used in a nuanced pass/fail situation. It can also be used in a double for/do loop where the outer loop records the count and the inner loop (of say 10 cycles) will count only if a match is made before the loop expires. So, if the g loop (outer loop) runs 50 times, but the f loop (inner loop) runs only 10 times and fails on most loops, then the g loop may end up counting only three or four f loop successes, meaning that I have only three or four pizzas. So, “fair random� should be used in whichever way best suits the “fairness� of the script’s value determination.

Code: Select all

script, walk hero to x then y, who, x, y, begin
 walk hero to x (who, x)
 wait for hero (who)
 walk hero to y (who, y)
 wait for hero (who)
end
walk hero to x then y (who, x, y)
-Moves hero to x coordinate before moving to y. Triggers “wait for hero� after each move.

Code: Select all

script, ghost walk npc, who, direction, distance, begin
 variable (test1, test2)
 test1 := get npc ignores walls (who)
 test2 := get npc obstructs (who) 
 if (test1 == false) then(
  set npc ignores walls (who, true)
 )
 if (test2 == false) then(
  set npc obstructs (who, false)
 )
 walk npc (who, direction, distance)
 wait for npc (who)
 if (test1 == false) then(
  set npc ignores walls (who, false)
 )
 if (test2 == false) then(
  set npc obstructs (who, true)
 )
end
ghost walk npc (who, direction, distance)
-Allows an NPC to walk through any wall or obstruction before returning it to its normal, non-passable state.

Code: Select all

script, hero blocks npc, who, which hero = 0, begin
 store current npc position (who)
 if (check position (forwardnpcx, forwardnpcy, which hero)) then(
  exit returning (true)
 )
 exit returning (false)
end
hero blocks npc (who, which hero)
-Checks the tile ahead of the NPC (determined by NPC direction) to see if the hero is standing in its way. Useful for organically determining whether an NPC must be moved to an unobstructed and adjacent tile before marching it across the room past the hero's position.

And that's just a small taste of things to come. Look forward to these and the other 369 convenience functions and shortcuts that are coming your way soon.
Place Obligatory Signature Here
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

The complete Volume 1 is now live.

Get it here.

This final version of Volume 1 includes nearly 400 functions to simplify basic scripting needs, saving you lots of time and hassle when making your games. This pack should also up your presentation game by handling the minutia of actions that make character interactions more dynamic and interesting without you having to handle the complex scripting to make it work.

For example, would you prefer that NPCs with script-triggering on contact (like those with random text, for example) stop and face the hero when they talk instead of wandering off? Try "npc talk." Want to add dramatic pauses to your dialogue without having to script a bunch of "show text box / wait for text box + wait" commands? Try "basic conversation." Want to have your heroes moonwalk or strafe? Yep, you can do that, too. Convert NPCs to heroes and back again? Volume 1 has you covered.

And a lot more!

Go check it out, and if you have any issues with a particular function, let me know and I'll look into it.

Good luck.
Place Obligatory Signature Here
Post Reply