BMR's Simple Slice Tutorial

Make games! Discuss those games here.

Moderators: Bob the Hamster, marionline, SDHawk

Post Reply
User avatar
BMR
Metal King Slime
Posts: 3310
Joined: Mon Feb 27, 2012 2:46 pm
Location: The Philippines
Contact:

BMR's Simple Slice Tutorial

Post by BMR »

BMR's Simple Slice Tutorial
Part I - Loading and Moving Slices

Hello, and welcome to this short little tutorial. In this tutorial, we'll cover the bare-bones basics of slices and how to use them in a game. We'll cover loading slices up, moving them around, destroying them, and a few other nifty things.

This won't cover absolutely everything though, as there are simply far too many things that you can do with slices for all of them to be covered here. Instead, this should serve as a solid starting point from which a newcomer to slices will be able to build upon before moving on to some of the more advanced (and fun!) aspects of slices. Specifically, we'll cover what slices are, manipulating slices, parent-child slices, moving slices around, and removing them. We'll touch on slice collections, sorting slices, and special slices, but we won't go too in-depth with them. It will also be divided into different parts, to keep things short and easily "digestible".

This tutorial assumes that you already have an average grasp of plotscripting, so we won't be going too much into how to script. We will, of course, go over how to use the specific commands and their proper syntax, but we won't be discussing how to compile your slice-movement script or how to go about writing a script.

Anyways, that's enough for the introduction, so without further ado, let's get started!


I - What is a Slice?

First off, what exactly is this "slice" thing everyone's ranting and raving about? In a nutshell, a slice is pretty much anything that's drawn to the screen like sprites, layers, etc... This means that all graphics, the sprite attached to your hero, the layer he/she's walking around in, etc... are all slices. That's certainly a bit overwhelming though, so we'll talk about those special slices later on.

It would be easier, perhaps, to think of a slice as anything you load up and slap onto the screen to get some sort of effect or functionality. If you've worked with the OHRRPGCE for any amount of time, you've probably grown accustomed to thinking of things on the screen in terms of tiles. It's easy to move the hero to (3, 12) or have a fireplace at (4,1) animating nicely. Slices, on the other hand, do not operate by tiles. They operate fairly independently from tiles, and instead of such, they are pretty much always worked on by addressing the actual pixel coordinates.

Think of them then as free-floating images that you load and place on top of the main gameplay. Take the following image, for example:

Image

In that image, the four sprites in the center are all standard NPCs that can be moved about using simple commands like walk npc. The other elements though, the health/magic/stamina bars, the portrait, and the weapon info, are all slices which have been placed on top of the basic gameplay, as illustrated below:

Image

With this, the slices are all placed on top of the main action. This means that they operate independently of everything moving below them. A walk hero command will not interfere with any of the slices used here. They all exist unattached to any of the standard gameplay elements right now. Moving slices about and manipulating them thus allows you to do all sorts of fantabulous things with slices. A few examples would be a mouse cursor, a combat engine (shown in the pictures), a HUD similar to SNES Legend of Zelda games, and a whole bunch of other things.

With that done, let's go on to how to actually create a slice.



II - Loading Slices

The first thing that must be understood when working with slices is just how they behave and how they're manipulated. If, for example, I wanted to move my barbarian hero (the long-haired dude in a loincloth in the picture above) it would be extremely simple:

Code: Select all

  script, move belor west, begin
    walk hero(hero:Belor, west, 6)
  end
What you'll notice is that it's trivially easy to grab the hero and move him around by referring to him as hero:Belor. One of the most confusing things when starting out with slices then, is just how are you supposed to refer to them? How are you supposed to tell your script which slice to move left, which one to move in circles, and which one to get rid of? The answer is simple, you have to use slice handles.

All slices have a handle. This is the specific identifier that is used to... well, identify that slice and single it out from all of the other slices that you may be using. Just about every single command for slices will take a slice handle as an argument, so it's important to keep track of these.

That does not, however, mean that when a slice is created, you'll automagically get a number which you have to write down. Instead, slice handles can be stored in variables, the same way as any other value. All slice functions that load a slice up will return a slice handle. Now, you don't absolutely have to store this value if you're just going to load it once and never touch it again. That, however, is rather unlikely, so you'd create a variable the way you'd normally create variables, and then store the returned number in that variable.

Code: Select all

  script, my first slice thingy, begin
    variable(sl)

    sl := load portrait sprite(4)
  end
Take note, in this example, we've used sl as the name for the slice handle. A lot of the examples in the plotscripting dictionary and the wiki also use sl, but this is by no means something that you have to do. sl is not some magical variable that has to be used with slices. If you have your own naming conventions (you really should have some sort of naming convention, if only to keep organized) then by all means, rename your variable to whatever you want. The above example works just as well as this one (though I can hardly see anyone actually using that as a variable name):

Code: Select all

  script, my second slice thingy, begin
    variable(oogyboogyslicehandle)

    oogyboogyslicehandle := load portrait sprite(4)
  end
What this particular little script does is loads portrait 4 (as defined by you in Custom) and stores the handle of that particular slice in variable sl. This is important, because that handle refers only to that specific instance of portrait #4. If I were to load portrait #4 again for some reason, it would have a different handle and would have to be stored in another variable.

Code: Select all

  script, my first slice thingy, begin
    variable(sl1, sl2)

    sl1 := load portrait sprite(4)
    sl2 := load portrait sprite(4)
  end
In that example, we would have two slices loaded to the screen which happen to be identical in appearance. They would, despite being the same portrait, have different slice handles. This means that they can be (and indeed, should be) manipulated as separate, distinct, entities.

There are a whole bunch of different commands to load a slice up. They are all in the plotscripting dictionary and all typically take the form load X sprite(num, palette). Now, you may be wondering why even portraits, borders, etc... are all called "sprites" when all your experience with Custom has told you that sprites only refer to walkabouts and battle graphics. While this may be true normally, when working with slices, pretty much all of these graphics, portraits, enemy sprites, weapons, borders, etc... are all referred to as sprites. This will come into play later on, but for now, suffice to say that they are all "sprites" when it comes to slices.

So, now that we know how to load a slice and what a handle is, let's get on to moving slices around.



III - Moving Slices Around

Let's go back to the example of moving the barbarian hero around:

Code: Select all

  script, move belor west, begin
    walk hero(hero:Belor, west, 6)
  end
In that example, we know that the hero is referred to as hero:Belor. We also know, that to refer to a slice in the same way, we would have to first store the slice's handle before we can do anything to it. Once you've got the handle stored in a variable, it's easy to refer to it and move it anywhere and anyway you want.

There are a whole bunch of different ways to move slices; far too many to cover each in detail. Here, however, are a few of the more common ones:
  • put slice(handle, x, y)
  • set slice x(handle, x)
  • set slice y(handle, y)
Perhaps the one that you'll be using the most often, is put slice. What that does, is it moves the slice you're referring to, to a specific (x, y) coordinates. Now remember, when working with slices, you're going to be using pixel coordinates, not tile coordinates.

Code: Select all

  script, my thid slice thingy, begin
    variable(sl)

    sl := load portrait sprite(4)

    put slice(sl, 10, 10)
  end
What this little bit of code does is it loads up portrait #4, stores the handle of that slice in variable sl, and then puts that slice at pixel coordinates (10, 10). The set slice x and set slice y commands are similar, but instead of specifying a certain (x, y) coordinates, you can instead change only the x or the y coordinates.

There are a whole bunch of other methods to move slices around, and they're all documented in the plotscripting dictionary, so feel free to experiment.


Closing

And that's all for this part for now. Next time, tune in for Text Slices, Containers, and Parent-Child slices!

BMR out!
Last edited by BMR on Mon Dec 30, 2019 5:20 am, edited 5 times in total.
Being from the third world, I reserve the right to speak in the third person.

Using Editor version wip 20170527 gfx_sdl+fb music_sdl
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

Good article, BMR.

This reminds me that Slime Salad really could use a subforum for articles, so that people looking for quick information will have an easier time finding this stuff.

Might fit nicely under the one we have called "Reviews."

Since we have a subforum for Reviews, we should also, probably, have a subforum for Articles, since, you know, people might want to find these things quickly, and since, you know, there are no more updates to HamsterSpeak to centralize these articles for us.

Just a thought.
Place Obligatory Signature Here
User avatar
marionline
Metal Slime
Posts: 673
Joined: Sat Feb 26, 2011 9:23 pm

Post by marionline »

Thanks for the helpfull tutorial! :D
I think, it's really good!

It explains in a easy to understand way and is certainly a good addition to the other articles about slices on the wiki.
Could it be added to the wiki's new howto-section?

(Offtopic: I'd support Pepsi Ranger's idea to make an section for articles/tutorials ect. In the game making section they easly get lost in the amount of other threads.)
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Awesome tutorial. I can't wait for the more advanced stuff to come!

I too agree that an article section of the forum would be nice. Then anyone could host their own little how-to's. I'm sure a lot of people have stuff that they're passionate about teaching in regards to coding, art, etc... It would be nice to have things like this in one easy to locate place rather than the tutorials being spread throughout the internet, or throughout the forum as they are now.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
BMR
Metal King Slime
Posts: 3310
Joined: Mon Feb 27, 2012 2:46 pm
Location: The Philippines
Contact:

Post by BMR »

BMR's Simple Slice Tutorial
Part II - Text, Parent/Children, and Containers

Welcome back to my little slice tutorial! Last time, we went over just what those pesky "slice" things are, how to load them up, how to refer to them, and how to move them around. Previously, we only worked with graphics, or sprites as they're termed when working with slices. This time around, we'll be covering how to load up and use text slices, and using parent/child relationships.

Now, as we're going to be working with text, this article assumes that you already have a working knowledge of strings, i.e. how to create them, how to change them, combining strings, etc... We'll skim a bit through how to use strings as a sort of refresher, but for the most part it's understood that strings are something you're already familiar with.

Anyways, without any further ado, let's get started!


I - Text Slices

Now, putting images onto the screen is all well and good, but what if you want to make a HUD and have to put some text onto the screen to show that the player is currently in World IV Level 2? Prior to encountering slices, you've probably been used to the idea that text boxes are the only way to stick text onto the screen. Sure, it's possible to stick globals in there, or player stats, or other values, but using text boxes for this purpose would be extremely cumbersome and impractical. Enter, the text slice.

Now, it's important to understand that other than working with text, text slices are pretty much identical to any other slice. They can be moved around with put slice, they have to be referred to by their handle, and they act in just about the same way as the slices we previously covered.

The main way to get text onto the screen with slices is the create text command. When you use it you will get a slice with no text in it, meaning it will be invisible. Similarly to when you load a portrait or an enemy sprite to the screen, create text returns the slice handle of that particular slice. Because you'll want to change the text of that particular slice, you'll want to store the handle like so:

Code: Select all

  script, hello world, begin
    variable(sl)

    sl := create text
  end
See? It's a simple matter and is absolutely identical to getting the handle of any other slice. We've created the text slice, and stored the slice handle for that particular slice in variable sl. Now, to actually add text to that slice, you're going to need to do three things:
  1. Create a string
  2. Add a value to that string
  3. Put that string into the text slice
Creating and adding a value to a string is fairly simple, and while they may be a bit different from how variables are handled, they're still fairly similar. Once you've created your text, you add it to a text slice with the command set slice text(handle, string id). This command takes two arguments, the first is the handle of the slice you want to work with, and the second is the ID of the string you want to use. You would thus get something like this:

Code: Select all

  script, hello world, begin
    variable(sl)

    $1 = "Hello world"

    sl := create text

    set slice text(sl, 1)

    put slice(sl, 50, 50)
  end
What this does is it creates a string with ID 1, creates a text slice and stores its handle in variable sl (remember, sl is not special, you could use varTxtSliceHndle01 if you wanted to, it wouldn't matter), sets the slice text to be the string with ID 1 with set slice text, and then uses put slice to place it at coordinates (50, 50). What you'll get with this (when running from a completely empty .rpg file with no sprites or anything) is something like this:

Image

And that's about it for text slices! You can have multiple text slices on the screen at any point, and you can use them for all sorts of things. There are a bunch of other things you can do with text slices, like changing their color, changing the letter borders, wrap text within a specific block, etc... This tutorial though, only covers the very basic parts of text slices, and it's up to you to experiment and tinker with them. For now though, on to parents and children!


II - Parents and Children

Slices certainly are pretty neat. You can do a lot with them, and you can have a whole bunch of them on the screen doing different things. What happens then if you've got a whole bunch of different slices on the screen at once and you need to move them around? Let's take the example of the combat engine screen from the previous part of the tutorial, here' we've got the different slices marked in dotted boxes:

Image

There are quite a lot of slices there (the menu is special, that's for another tutorial). Specifically:
  • Combatant Portrait (cPor)
  • Weapon Info Box (wInf)
  • Weapon Name and AP (wNme)
  • Weapon Damage (wDmg)
  • HP Bar (barH)
  • MP Bar (barM)
  • AP Bar (barA)
  • HP Icon (icoH)
  • MP Icon (icoM)
  • AP Icon (icoA)
  • HP Text (txtH)
  • MP Text (txtM)
  • AP Text (txtA)
All in all, that's 13 different slices. Suppose I had to (for some strange reason) move everything 5 pixels to the left? I would first have to use slice x to get the x position of said slice, and then shift it 5 pixels to the left. Now, I could be barbaric and do it like this (Note, I'm using the variable names in the above list. Just assume that they're globals and that they hold the handles of those specific slices.):

Code: Select all

  script, barbarically move things left, begin
    put slice(cPor, slice x(cPor) -- 5, slice y(cPor))
    put slice(wInf, slice x(wInf) -- 5, slice y(wInf))
    put slice(wNme, slice x(wNme) -- 5, slice y(wNme))
    put slice(wDmg, slice x(wDmg) -- 5, slice y(wDmg))
    put slice(barH, slice x(barH) -- 5, slice y(barH))
    put slice(barM, slice x(barM) -- 5, slice y(barM))
    put slice(barA, slice x(barA) -- 5, slice y(barA))
    put slice(icoH, slice x(icoH) -- 5, slice y(icoH))
    put slice(icoM, slice x(icoM) -- 5, slice y(icoM))
    put slice(icoA, slice x(icoA) -- 5, slice y(icoA))
    put slice(txtH, slice x(txtH) -- 5, slice y(txtH))
    put slice(txtM, slice x(txtM) -- 5, slice y(txtM))
    put slice(txtA, slice x(txtA) -- 5, slice y(txtA))
  end
I mean, sure, it works, but it's ugly, and it's inefficient. What happens when you've got twice as many slices on the screen? Three times as many? You'd pretty much go insane. The solution to this, is to use the set parent command.

In order to understand how to use this command, you first have to understand how the parent/child relationship works. When a slice is drawn to the screen, it is a freely wandering and individual slice (Well, not exactly true, but it's true enough for what we're covering here. We'll get to the why this isn't exactly true in a later article) which isn't attached to anything. It is, however, possible to get one slice, and set it so that it has a parent slice. When this is done, you can move the parent around and this will also move the child around. When this is done, the slice that was attached becomes a child slice.

It is possible to attach any type of slice to any other type of slice. There are no restrictions as to what can be parented or child-ed. We've already covered text slices, and sprite slices, so it's time to introduce another type of slice. One of the more useful types of slice, is the container slice. Again, this slice acts like any other slice, it requires a handle to work with, it can be moved around with the standard slice commands, etc... To create a container slice, we use the create container(width, height). This command takes two arguments, width and height. This is important, and you can do all sorts of neat things with width and height, but for now we'll stick to 320�200.

To set one slice as the parent of the other, the command is set parent(handle, parent handle). This also takes two arguments, the first argument is the handle of the slice we want to attach. The second argument is the handle of the slice we want to turn into a parent. What we're going to do, is create a container slice that is 320�200 pixels (the dimensions of a standard OHR game), and then use put slice to place it at (0, 0). We will then parent all of the other slices to it. We'll use the variable pSlc to hold the handle of the container. (Remember, we're assuming that all of the handles of the other slices are stored in globals. We're also assuming that pSlc is a global.)

Code: Select all

  script, family reunion, begin
    pSlc := create container(320, 200)

    put slice(pSlc, 0, 0)

    set parent(cPor, pSlc)
    set parent(wInf, pSlc)
    set parent(wNme, pSlc)
    set parent(wDmg, pSlc)
    set parent(barH, pSlc)
    set parent(barM, pSlc)
    set parent(barA, pSlc)
    set parent(icoH, pSlc)
    set parent(icoM, pSlc)
    set parent(icoA, pSlc)
    set parent(txtH, pSlc)
    set parent(txtM, pSlc)
    set parent(txtA, pSlc)
  end

Now, everything is parented to pSlc, and if we were to visualize it, it would look something like this:

Image

As you can see, pSlc, which is an invisible container slice 320 pixels wide and 200 pixels tall, is now a parent for the portrait, status bars, status icons, status text, and weapon info. They are now all child slices or children of pSlc. Moving pSlc will also move around the children, as they are "within" that container. Moving the child slices around though, will not affect anything else. Take note though, that now that they are child slices, the put slice command will work a bit differently now, as the coordinates are now relative to the parent slice. That's not something we need to worry about for now though, as the container slice has the same dimensions as the standard screen.

But wait, there's more! Right now, everything is in one container. What if I wanted to only move the status bars around? That's the nifty thing, remember how we said that it is possible to attach any type of slice to any other type of slice? And that there were no restrictions? That means it's possible to take those status bars, set their parent to a smaller container, and then set that container's parent to be pSlc. First, we'd do exactly what we did before, but with a smaller container, this time bSlc:

Code: Select all

  script, status bar container, begin
    bSlc := create container(87, 32) #The size of the status bars and icons

    put slice(bSlc, 233, 82) #The location of status bars

    set parent(barH, bSlc)
    set parent(barM, bSlc)
    set parent(barA, bSlc)
    set parent(icoH, bSlc)
    set parent(icoM, bSlc)
    set parent(icoA, bSlc)
    set parent(txtH, bSlc)
    set parent(txtM, bSlc)
    set parent(txtA, bSlc)
  end
That does exactly what we did before, but this time we're only adding the status bars, icons, and text. We will thus have a little container where only those are placed. Rather than moving all of those elements one by one, we can move the entire group anywhere we want. It would thus look like this (assuming that we haven't done the creation of pSlc yet):

Image

As you can see, bSlc is a much smaller container than we created before. It contains the bars, icons, and text in a small little container. We can thus move it around wherever we want as one whole group. If we wanted it at the top left, it would be a simple matter to use put slice to move it where we want it to go. For now though, we'll leave it where it is.

With that done, we can attach bSlc to pSlc like so:

Code: Select all

  script, family reunion, begin
    pSlc := create container(320, 200)

    put slice(pSlc, 0, 0)

    set parent(cPor, pSlc)
    set parent(wInf, pSlc)
    set parent(wNme, pSlc)
    set parent(wDmg, pSlc)
    set parent(bSlc, pSlc)
  end
What this does, is it attaches the other things we hadn't linked up yet, and connects them to pSlc as child slices. It also connects bSlc also as a child slice of pSlc. This means that bSlc is both a child slice, and a parent slice. It is a child slice of pSlc, and a parent slice to the status bars, icons, and text. And it would wind up looking like this:

Image

And that's it for containers, parents, and children! There are a whole bunch of different things you can do with the parent/child relationship, like cycling through all the children with a single while loop, or sorting them as a sort of list/array, or any other number of fun and spiffy things. But that's for another tutorial.


IV - Closing

And that about it for this batch! As we've covered the basics of loading slices, parenting them, moving them around, next time we'll cover something just as important as creating them: removing slices. Also, now that you know how to script these slices into existence, we'll cover the use of the collection editor, which will make a bunch of this a whole lot easier. See you then!

BMR out!
Last edited by BMR on Mon Dec 30, 2019 5:22 am, edited 5 times in total.
Being from the third world, I reserve the right to speak in the third person.

Using Editor version wip 20170527 gfx_sdl+fb music_sdl
Post Reply