SiN Consoles - Part I
by Eutectic


1. Introduction

Everybody knows how cool in-game consoles are in SiN. But how do they work? How can we make those great looking consoles and make them do things in our maps? Sure there are docs, but what do all those commands mean? How do we use them? When? Why? So many questions...

The goal of this tutorial is to answer all these questions and make consoles accessible to everyone who is interested in making them. It will be a multi-part tutorial in which I will try to cover all the most important features of consoles from basic to advanced. You will be guided through a step-by-step set of instructions to make your first console and I will explain what you just did as we're going along.

Of course, I'm assuming here that you are familiar with the basics of map editing with SinEd: making brushes, texturing them, using surf inspector and that you at least know how to make a basic room, how to insert entities in it and how to make an entity out of a brush. The tutorial also involves scripting so make sure you have some basic notions of that as well.

And of course, I'm assuming you have SinEd installed and running plus a text editor for your script and menus. Any text editor will do of course but I highly recommend using UltraEdit32 and my custom Uedit wordfile for command coloring. This is really useful to help you avoid typos and for debugging.


2. Getting started

Launch SinEd.

Make a basic room 256 x 256 x 256 in size just like the one in the basic room tutorial. Load the generic/misc texture folder. I'll be using it in this tutorial but you can choose any texture folder you like. I chose this one because it has a good assortment of uniform color textures like black, white, red and green. A console brush should always have a uniform texture but it's also possible to use a glass texture and make it translucid for an exotic looking console. Let's stick to a regular black console for now. Select black. This is the most commonly used texture for consoles and the one we'll be working with.

XY View - Drawing brushYZ View - Drawing brush

Next, draw a brush 60 high x 60 wide x 4 thick and place it against the east wall of your room about 32 units above the floor.




Entity Menu - Making brush into console

RightClick over the selected brush and make it a console entity. Hit N to call up the entity dialog and set the following key/value pairs for the console entity:

consolename: con_testcon1
cols: 20
rows: 20
virtualheight: 60
virtualwidth: 60


Entity dialog - basic keys




Camera View - selecting brush face

Deselect the console brush by hitting ESC, go to the Camera view and navigate until you face the console brush. Select the 60 x 60 brush face (Ctrl-Shift-LeftClick) that is accessible (away from the wall).

Notice the white arrow on the brush face is pointing towards the right. You will be using this arrow as a guide for all the console surfaces you make in the future.


Surf Inspector - setting console properties



Hit S to open Surface Inspector and set the following properties for the brush face:

 Horizontal stretch: -1.00

 Group: con_testcon1

 console flag: set


Click Apply, then OK.

A quick explanation: setting the console flag tells the game to display a console on this brush face. The name you typed in the Group field tells the game which console to display on the brush face.

This is the main distinction between the console entity and the console display. More on this later.
Camera View - selecting brush face



Notice how the white arrow on the brush face is now pointing towards the left. This is because you just changed the texture's horizontal scale to -1 and therefore mirrored it. I made you do this because in this particular example, the console display would have been from right to left instead of from left to right. Deselect the brush face and save your map as consoles.map.


What we have now is a basic functional console. But if you compile the map an look at it in the game, it will look like an ordinary black brush and nothing will be displayed on it. The only thing you will be able to do is to Use it but nothing will happen apart from the fact that the player won't be able to move (only look around). Your player will unfreeze when you hit the ESC key.

The reason for this is that now in order to get something to be displayed on it, you will need to write a script and/or menu file(s) with special commands called layout strings and menu commands.

But before we get to that, I think it's important to take a look at what we just did and make some sense out of it before we go on.


3. The meaning behind the console entity's keys

  • consolename


  • This one's easy. The console needs a name so you refer to it in a script. The only thing to remember about them is that this name has to start with con for the script to recognize it. This is why I named the one above con_testcon1

  • cols & rows


  • Here's where it gets interesting. This defines the maximum number of columns and rows of text that can be displayed on the console's surface. So this, along with the size of the console brush face, also determines the character size of the text displayed on the console face as a direct consequence.

    Console display - cols & rowsLet me explain: the console brush you made is 60 wide x 60 high right? And you set both cols and rows to 20. So the console will fit 20 columns of text or if you like 20 characters in a brush that's 60 units wide. So how wide will your characters be?

    60 divided by 20 = 3 units wide

    And since we set the rows at 20 and the brush is also 60 units high, the characters on the console will also be 3 units high. So the more text you fit on your console brush, the smaller it will be.

    One thing worth noting here is that it's possible to use cols and rows values that don't divide your brush evenly or produce "stretched" characters (more tall than wide or vice versa). This won't prevent your comsole from working properly but your console characters will look sharper and better if you stick with values that divide evenly.


  • virtualheight and virtualwidth


  • These 2 keys define a coordinate system for the console's surface. Just think of it as your console's grid. The only difference is that you can define the vertical and horizontal values separately and have different values for each. Here again, I set both values at 60 on purpose to keep things simple. This means that the console surface will be divided in 60 equal parts both vertically and horizontally. Like rows and cols, the resulting grid spacing is relative to the console brush face's dimensions. So the effective grid spacing in our case will be:

    Console display - Vertical & Horizontal gridBrush face width divided by Virtualwidth =
    Horizontal grid spacing

    60 units divided by 60 = 1 unit horizontal or X grid

    Brush face height divided by Virtualheight =
    Vertical grid spacing

    60 units divided by 60 = 1 unit vertical or Y grid

    This grid is used only as a way to position layout strings and menu items on the console on any of those grid points. Note that unlike cols and rows, it has no effect on the character size of your text.

    I represented the grid on the left with blue lines but this grid is, of course, invisible in the game.


    4. Displaying text on the console


    The console entity now has all the essential keys it needs so it knows what size text and what grid size to use. One of the console's brush faces has all the necessary surface properties it needs to be able to display console information. The only thing missing now is something to display. The simplest way to do this is by writing layout string commands in a script.

    For those of you who are familiar with writing web pages, layout strings are not unlike HTML tags. They are a series of mini-commmands or abreviations used to tell the script what text or image to display, where and in what color. There's a lot of variants to these and they are covered in much detail in Scott Alden's Console Black Magic document so we will only look at the ones which are the most likely to be used often.

    First, open your favorite text editor and create a script file named consoles.scr. You can do this by clicking on the Open SCR button in the toolbar: Open SCR button


    Type the following commands:

    thread testcon1_layouttest
    end

    testcon1_layouttest:
    wait 5
    %con_testcon1 conlayout "xl 3 yt -33 fc 0 0 1 1 string \"LAYOUT STRING\""
    end


    Save your script and your map. Compile your map and copy both consoles.bsp and consoles.scr to your game's maps folder. Launch SiN and open your map. Look at your console and after a 5 second delay, a blue text string will appear on your console. You just made your first working console :)


  • What did we just do here?


  • The blue text was displayed by this command in the testcon1_layouttest thread:

    %con_testcon1 conlayout "xl 3 yt -33 fc 0 0 1 1 string \"LAYOUT STRING\""

    What it says is to display the layout string "xl 3 yt -33 fc 0 0 1 1 string \"LAYOUT STRING\"" on the console named con_testcon1. But what does the layout string mean? Well, it's sort of a command by itself. Let me break it down in smaller pieces so you can better understand what it means:

    Console display - Layout string First, the complete layout string must always be enclosed between double-quotes (highlighted in red):

    "xl 3 yt -33 fc 0 0 1 1 string \"LAYOUT STRING\""

    The xl and yt parameters define the position of the string on the console:

    "xl 3 yt -33 fc 0 0 1 1 string \"LAYOUT STRING\""

    xl is the x grid coordinate from left edge of the console.
    yt is the y grid coordinate from top edge of the console.

    The fc (foreground color) parameter defines the RGB color and alpha (translucency) of the string:

    "xl 3 yt -33 fc 0 0 1 1 string \"LAYOUT STRING\""



    The first 3 digits (0 0 1) define the color (blue) and the last digit (1) defines the translucency. A translucency value of 0 is completely transparent (thus invisible) and 1 is completely opaque. The default value for fc is 1 1 1 1 (white and completely opaque).

    The string parameter tells the layout to display the following text string enclosed between special \" delimiters with the preceding position and color parameters:

    "xl 3 yt -33 fc 0 0 1 1 string \"LAYOUT STRING\""


  • Other positioning variants


  • There are many ways to position your layout strings on a console. I think it's important to take a look at those at this point: they provide a lot of flexibility which can be very useful. Depending on what you want to display, where and how you want it positionned, one method might prove easier than another.

  • Positioning in relation to the edges of the console


  • The method we used above (xl and yt) position the string in relation to the left and top edges of the console. You can also position the layout string from the right and bottom edges of the console by using:

    xr: x grid coordinate from right edge of the console.
    yb: y grid coordinate from bottom edge of the console.

    So if, for example, you had used the following layout string:

    %con_testcon1 conlayout "xr -57 yb 27 fc 0 0 1 1 string \"LAYOUT STRING\""

    Console display - Layout string

    As you can see in the image on the left, the result would have been exactly the same and your text string would have been in the same position as the one in the previous example.


  • Positioning in relation to the center of the console


  • You can also position a layout string in relation to the center of the console by using the following parameters:

    xv: x grid coordinate from the horizontal center of the console.
    yv: y grid coordinate from the vertical center of the console.

    So if you had used the following layout string:

    %con_testcon1 conlayout "xv -27 yv -3 fc 0 0 1 1 string \"LAYOUT STRING\""

    Console display - Layout string

    As you can see in the image on the left, the result would also have been exactly the same as in the previous 2 examples.



  • Centering the positional origin of the layout string


  • So far in the previous examples, the origin of the layout string, represented in the previous images by a yellow crosshair, was always at the lower-leftmost corner. That's where it is by default but it's possible to change it so it will be centered either horizontally, vertically or both by using the following:

    jcx: x origin of layout string is justified to center and the string is centered horizontally on the console.
    jcy: y origin of layout string is justified to center and the string is centered vertically on the console.

    Confused? Let's use an example and look at the results so you can understand how this works. Consider the following layout string and the result on the console display:

    %con_testcon1 conlayout "jcx yb 20 fc 0 0 1 1 string \"LAYOUT STRING\""

    Console display - Layout string

    Here, the jcx parameter is used for horizontal positioning. Please note that you don't type a value after the jcx parameter, it implicitly means center the layout string horizontally so adding a value will simply have no effect. For vertical positioning, I used an ordinary yb 20 parameter.

    As you can see, the origin of the layout string is now centered horizontally based on its width. Notice the dashed centerline in the middle of the console. As long as jcx is used, the layout string will be always be centered horizontally on the console. The following yb, yt or yv parameter then determines the vertical position of the layout string along that centerline.


    Now let's take a look at what jcy does. Consider the following layout string and the result on the console display:

    %con_testcon1 conlayout "xl 10 jcy fc 0 0 1 1 string \"LAYOUT STRING\""

    Console display - Layout string

    Here, the jcy parameter is used for vertical positioning. Please note that you don't type a value after the jcy parameter, it implicitly means center the layout string vertically so adding a value will simply have no effect. For horizontal positioning, I used an ordinary xl 10 parameter.

    As you can see, the origin of the layout string is now centered vertically based on its height. Notice the dashed centerline in the middle of the console. As long as jcy is used, the layout string will be always be centered vertically on the console. The preceding xl, xr or xv parameter then determines the horizontal position of the layout string along that centerline.


    If you use both the jcx and jcy parameters in your layout string command such as:

    %con_testcon1 conlayout "jcx jcy fc 0 0 1 1 string \"LAYOUT STRING\""

    Console display - Layout string

    The origin of the layout string will be centered both vertically and horizontally based on its height and width. And of course, the layout string will be positioned dead center on the console. This can be really useful in the case where all you need is a small console with only one layout string displayed in the center.




  • Positioning in relation to the edges of the console


  • It's also possible to position a layout string in relation to the edges of the console by using the following parameters:

    jl: layout string is justified to the left edge of the console.
    jr: layout string is justified to the right edge of the console.
    jb: layout string is justified to the bottom edge of the console.
    jt: layout string is justified to the top edge of the console.

    Let's just take a quick look at how those work:

    "jl <y parameter> fc 0 0 1 1 string \"LAYOUT STRING\""             "jr <y parameter> fc 0 0 1 1 string \"LAYOUT STRING\""

    Console display - Layout stringConsole display - Layout string


    Console display - Layout stringConsole display - Layout string

    "<x parameter> jb fc 0 0 1 1 string \"LAYOUT STRING\""            "<x parameter> jt fc 0 0 1 1 string \"LAYOUT STRING\""


    This about sums it up for ways of positioning your layout strings on a console. Even though I described all of those in separate sections, keep in mind that you can use any possible combination of x and y parameters you want. As you can see, there are many ways to acheive the same result but in the end it's mainly a matter of using what is the simplest or most convenient for the particular console layout you have in mind.

    One thing that you must be aware of though: you should always pay close attention when using x and y parameters which require console grid coordinate input such as xl, xr, xv and yb, yt, yv. Why? Because it's possible to position your layout strings so that they end up outside of the console surface.

    For example, try this quick experiment to see what I mean. Edit the conlayout command line in your script so it reads like this:

    %con_testcon1 conlayout "jcx yt 20 fc 0 0 1 1 string \"LAYOUT STRING\""

    Notice the yt 20 parameter? This will make the layout string be centered horizontally but it will end up being displayed 20 console grid units above the console's top edge. Go ahead, try it! Save your script, copy it to your sin\base\maps folder and run your map. If there are no brushes above your console like in this example map, you will see the error right away but if your console brush is recessed inside a wall, you won't see it and this could keep you wondering "where is that layout string?" for a while. So always check those parameters and coordinates.


    5. Various other types of strings

    So far, I have used a plain text string as the type of layout string in the examples, but there are variations to the basic text string. The text string can also be enhanced by making it a blinking text string or encasing it in a box, etc. What follows is a simple visual reference to let you see at a glance what each of these variations look like on the console.

    On the left is the layout string syntax and on the right, an image of the actual result on the console. I didn't include bstring because it's just a plain string that blinks. Keep in mind that only the most common ones are shown here and that the list is by no means complete:


    Console display - Plain string

    "jcx jcy fc 1 1 1 1 string \"LAYOUT STRING\""

    Console display - Boxstring
    "jcx jcy fc 1 1 1 1 boxstring \"LAYOUT STRING\""

    NOTE: The box is blue by default.

    Console display - Boxtext
    "jcx jcy fc 1 1 1 1 boxtext \"LAYOUT STRING\""

    NOTE: The box is blue by default.

    Console display - Cursor string
    "jcx jcy fc 1 1 1 1 cursor string \"LAYOUT STRING\""

    NOTE: The cursor blinks.

    Console display - Cursor bstring
    "jcx jcy fc 1 1 1 1 cursor bstring \"LAYOUT STRING\""

    NOTE: The cursor and text string blink.

    Console display - Box
    "jcx jcy fc 1 1 1 1 box 13 1"

    SYNTAX: box <width> <height> in characters.
    NOTE: The box is blue by default.

    Console display - Border
    "jcx jcy fc 1 1 1 1 border 49 9"

    SYNTAX: border <width> <height> in pixels.


    The box and border type strings are useful when you want to have a text string of certain color enclosed in a box or border of a different color. They are an interesting alternative to boxstring or boxtext in which the color of the box "follows" the color of the text string. In order to do this though, you will need to use 2 separate layout string commands: one for the text string and one for the box or border. There are several ways to do this which I will discuss later on.

    There are also a couple of built-in, easy to use, display functions for layout strings. Those are kinda cool so I just had to include them here: date and time which will display the present date and time:



    Console display - Date
    "jcx jcy fc 1 1 1 1 date"

    NOTE: date format is MM/DD/YY.

    Console display - Time
    "jcx jcy fc 1 1 1 1 time"

    NOTE: time format is HH:MM:SS.


    5. Displaying images on the console


    Another great thing about consoles is that you can to display images on them. The syntax of the layout string for images is pretty much the same as with text strings and there's only 2 variations: picn and spicn. You can display any image you want on a console and there's only 2 restrictions:

    They must be in TGA format and they must be in the game's sin\base\pics folder or one of its sub-folders.


    The picn command stands for picture name. Let's try that first and see what happens. Edit the conlayout command line in your script so it reads like this:

    %con_testcon1 conlayout "jcx jcy picn a_helmet"

    The picn command is followed by the name of the image (a_helmet.tga in this example) but the .tga file extension is always omitted. If the image is in a sub-folder under sin\base\pics, the sub-folder name must be specified before the image name. For example, if you want to display the image sin\base\pics\tom\cp_dam_offline.tga on your console, the command would have to be:

    %con_testcon1 conlayout "jcx jcy picn tom/cp_dam_offline"

    Save your script, copy it to your Sin\base\maps folder and run your map. This is what you should see:


    Console display - Images: picn

    Hmmm... Interesting but the image is kinda large isn't it? This is because the console's face is 60 x 60 map units or pixels and this image (sin/base/pics/a_helmet.tga) is 32 pixels wide X 32 pixels high. Not much room for anything else on this console with a picture that size huh? This type of image would be be more suitable if used as a small icon to enhance a console's looks rather than have it as the "main feature" right?

    Fortunately, there is a way to do scale a picture on the console with the spicn command.




    The spicn command stands for scaled picture name. Edit the conlayout command line in your script again so it now reads like this:

    %con_testcon1 conlayout "jcx jcy spicn a_helmet 0.25 0.25"

    Save your script, copy it to your Sin/base/maps folder and run your map. This is what you should see now:


    Console display - Images: picn

    Ahh! Much better now isn't it? What you just did was to scale down the picture horizontally and vertically to 1/4 of it's original size. The basic syntax for this command is as follows:

    "<X pos> <Y pos> spicn <pic name> <X scale> <Y scale>"

    Here we scaled the picture down but you can also scale a picture up to enlarge it if you want by using <X scale> and <Y scale> values above 1.


    It's also worth noting that the fc parameter can also be used with picn and spicn. If you use an RGB color value other than 1 1 1 (white), the picture will be modulated to that color (meaning: the fc color is superimposed on the picture's original colors). Doing this usually looks ugly but the interesting part of fc for pictures is the 4th number: translucency. You can give your pictures a translucid look by setting this figure to a value between 0 and 1 (just like for text strings). Let's try a quick experiment:


    Add the fc parameter in the conlayout command line in your script so it reads like this:

    %con_testcon1 conlayout "jcx jcy fc 1 1 1 0.1 spicn a_helmet 0.25 0.25"

    Save your script, copy it to your Sin/base/maps folder and run your map. This is what you should see now:


    Console display - Images: picn

    If you compare with the previous image, you can see the picture looks darker. This is because it's translucid and the console's texture is black. But if your console brush was textured with a glass texture with the translucent flag set, you would be able to see through the glass and the picture.


    6. How to have multiple layout commands in a script


    Remember what I mentionned about the box and border commands earlier and how those can be used for displaying a different color of box and text? And how this must be done with 2 separate layout commands? This is what we're going to do here.

    Edit the conlayout command line in your script so it reads like this:

    %con_testcon1 conlayout "jcx yv -5 fc 0 1 0 1 box 13 1"

    Right after this line, add another one that reads like this:

    %con_testcon1 conlayout "jcx jcy fc 1 0 0 1 string \"LAYOUT STRING\""

    So if you interpreted the above layout strings correctly, you should have a red colored text string enclosed in a thick bordered, 13 character wide by 1 character high blue box modulated to the color green right? Save your script, copy it to your Sin/base/maps folder and run your map.


    Console display - Red string, no box "Hey! Where's the box?"

    Ah! This is because you used 2 consecutive conlayout commands. I made you do this on purpose to make you understand something.


    Every conlayout command overwrites the previous one. So if for example, you had 10 consecutive conlayout commands in your script, only the layout string in the last command would be displayed on the console. In order to display more than one layout string on your console, you have to use the conapplayout command which stands for console append to layout. So the first layout command for your console should be a conlayout command and all the ones that follow should be conapplayout commands.

    So let's change the second conlayout command to conapplayout as follows:

    %con_testcon1 conlayout "jcx yv -5 fc 0 1 0 1 box 13 1"
    %con_testcon1 conapplayout "jcx jcy fc 1 0 0 1 string \"LAYOUT STRING\""


    Save your script once again, copy it to your Sin/base/maps folder and run your map.


    Console display - Red string, no box

    And there you have it: a red text string enclosed in a green tinted thick bordered box 13 characters wide by 1 character high.


    Finally, you can clear a layout by using the command:

    %con_testcon1 conclearlayout

    All the layout strings displayed by the previous conlayout and conapplayout commands will be erased from the console display.


    7. Summary

    This about sums it up for the basic things you need to know about the console and layout strings. So far, all I did was to show you how to display text and images on the console therefore limiting it to a purely passive console: IOW, a console which doesn't take user input during the game to actually do things in your map (unlock doors, turn off lights, etc.).

    While I admit that Part I of this tutorial may seem a bit long, I feel it's essential that you understand how layout strings work thouroughly before moving on to the next step which is to make your console interactive.

    This will be the subject of Part II of this tutorial: how to set up a command prompt and/or menus on a console.


    Part II