Creating a worldmap

A worldmap you might have seen in games like Discworld, where you can travel to the places of the game by clicking on a target in a map.

First you need a room that you will use as your map. This one you have to fill with object that will function as your targets.

This is the way to enter the worldmap. In the walkmapscript where you normally enter a beamto command you enter instead :

setfocus (none)
loadroom (worldmap)

The Focus must be set to "none" to prevent the engine from loading the room where your character is.
Now we are on your map. The scripts of the targetobjects now contain :

on (click)
{
  setfocus (last)
  beamto (self ; DestinationRoom ; 12 ; 27 ; 1)
}

With "last" the focus is set back to the character is was set before the last call of setfocus. The beamto command now transports your character to the new room, so the roomchange is done automaticly.

Its also possible to create a worldmap that is bigger than one screen. To move around in such kind of map you have to create scrollbuttons. These should contain the command setpos (room ; x ; y ; FALSE). This command changes the current position on the maproom.


Effects with the roomlight

The command setlight (room ; red ; green ; blue) floods a room with a transparent color. With that you can create effects like lightswitches.
As an example we want to create a blinking light. For this effect we need the on (loop1) event in the roomscript. The Loop1 Part of a roomscript is being processed all the time as long as the room is loaded, independent to the current game situation. Should be used for visuall effects that does not affect your adventure. Here is the example :

on (loop1)
{
  setlight (room ; 50 ; 50 ; 50)
  wait (1)
  setlight (room ; 210 ; 150 ; 50)
  wait (0,1)
}

First the room is set to "dark" for one second and then for only 0,1 seconds it will be colored. You could also enable different effects, depending on some variables. Check out the cellar in the TestAdventure for another example.


Creating a following character.

You might know following characters from games like Sam&Max or Discworld. For such a character we need the Loop2 event in the roomscript. The difference between Loop1 and Loop2 is that Loop2 will stop dependent to the gamesituation. During Cutscenes, Textscenes and if a character is targeted by the player the Loop2 script will be stopped.
The Loop2 Part is supposed for activities running in the background of the game which can be stopped, for example to talk to somebody.

The most important thing for a following character is that you beam it with your maincharacter into the next room. The easiest way is to add these lines to every roomscript :

on (loop2)
{
  follow (followcharacter ; self)
  wait (1)
}

With this the following character walks every second to the current position of your maincharacter, which is not very innovativ. It would be nicer if you make events that are roomdependent. Think of Sam&Max and the weird stuff Max is always doing in many rooms. This means your secondary character does not have to be always there where your maincharacter is. As a little example watch the robo in the TestAdventure who has to reload itself after a few seconds.


Talking Background Characters

Also in the loop2 event we can realize talking background characters. Normally we want to stop the background dialog to talk to one of the characters. Now you could add a speech command and a wait command again and again, but that wouldn't be the best choice :
Everytime the Loop2 event was stopped through a cutscene or a textscene the script will be reset to the beginning. This might be useful if you have a dealer who only shouts a slogan all the time. But not for a real dialog. So we need now number variables.

Next to Booleans which can only be TRUE or FALSE you can set numbers in the script. These numbers doesn't have to be preset in the editor. To set a number you can use the command setnum (name ; number) and for checking it if_num (name ; number). Every Number is "0" when set the first time.
This is an example for a short dialog :

on (loop2)
{
  if_num (talknumber ; 0)
  {
    speech (figure1 ; Dialogtext 1)
    setnum (talknumber ; +1)
    wait (2)
  }
  if_num (talknumber ; 1)
  {
    speech (figure2 ; Dialogtext 2)
    setnum (talknumber ; +1)
    wait (2)
  }
  if_num (talknumber ; 2)
  {
    speech (figure1 ; Dialogtext 3)
    setnum (talknumber ; +1)
    wait (2)
  }
}

After every sentence the number "talknumber" is increased by one. With this number we can save the position of the background dialog even if the Loop2 event was stopped. In the Testadventure you can watch the fruit- and vegetabledealer arguing.


Creating a keypad

You will certainly know the keypads from ZakMcKrackon or Maniac Mansion where you had to enter a 4 number combination. For such a pad you need a new room that will contain this keypad. Fill this room with objects that function as the nunbers from "0" to "9". First we need to enter the Keypad-Room by using an object in another room :

on (use)
{
  taskbar (false)
  setfocus (none)
  loadroom (keypad)
}

If you use a taskbar you have to disable it, because we do not want to see it in the keypad phase. Use the command taskbar (false). Now we are in the keypad room. To reset the keypad usage when entering the keypad room you can use the following part :

on (enter)
  setnum (click_count ; 1)

For our example we want the player to enter 3 numbers. The script of every numberobject in the keypadroom now contains :

on (mouse)
  showinfo(Number 1 ; false)

on (click)
{
  playsound (click)
  if_num (click_count ; 1)
    setnum (number1 ; 1)
  if_num (click_count ; 2)
    setnum (number2 ; 1)
  if_num (click_count ; 3)
    setnum (number3 ; 1)
  setnum (click_count ; +1)
}

Depending on the click count, number1, 2 or 3 is saved. Of course you have to modify this script for each number object. Now we have to check in the loop1 event if the player has entered 3 numbers so we can stop the keypad phase and verify the entered numbers :

on (loop1)
  if_num (click_count ; 4)
  {
    setnum (click_count ; 5)
    if_num (number1 ; 3)
      if_num (number2 ; 7)
        if_num (number3 ; 2)
          {
          cutscene (right)
          break()
          }
    cutscene (wrong)
  }

If click_count was 3 it will be set to 4 to prevent this part from being processed twice.
Next we have to verify the result. You could allow more than one right combination. This time the player had to enter 3,7,2 for playing the cutscene "right", else cutscene "wrong" is played.

To leave the keypad room and get back to the previous room both cutscenes must contain :

setfocus (last)
taskbar (true)

And then add your reaction.


Creating a flashlight effect

For a flashlight effect like in Maniac Mansion, you need an image for that effect. (For example a black image with a gray circle, NOT WHITE). Create a new Object (flashlight) and drag this image on it. Check "additive blend". Put this object in a room that you specify as "everywhere objects"-room in the gamesetup, so your flashlight object can be used everywhere in the game. Change the state of the placed object to "0" so its deactivated when starting your game.

Now you need a boolean variable named "flashlighton" which you set by turning on a flashlight item in your inventory. The mainscript must now contain :

if_bool (flashlighton ; true)
  setobj (flashlight ; 1)
if_bool (flashlighton ; false)
  setobj (flashlight ; 0)

setnum (posx ; [mousex])
setnum (posx ; -50)
setnum (posy ; [mousey])
setnum (posy ; -50)

moveobj (flashlight ; 0+[posx] ; 0+[posy] ; 0)

First it is checked if the flashlighteffect is enabled or not. Then we define the position of the effect. First we use the current mouseposition and then we substract 50 pixels to X and Y. This is for showing the effect in the middle of your mouseicon. (50 should be the half of your flashlight object size.)
At last we move the object to [posx] and to [posy] with Speed "0", which means the object will be instantly at its destination without moving.


Using Variables

Especially for Minigames and all Ideas that are behind the usual adventure gameplay variables are very useful. PaC-DK not only offers Booleans which you can setup in the tool it also comes with the ability to use numbers and textlines as variables. (See in the reference under : if_num and setnum.

Random Numbers : Minigames need to have random events. For that you can use the randomnum (name ; limit) command.

Adding and substracting numbers : The setnum command allows you to add or substract numbers or another variable from a variable :

setnum (number1 ; +[number2])

Here the number1 will be increased by the amount of number2. The brackets define the second entry as a variable. This here is also possible :

setnum (number1 ; [number2] - [number3] * 3)

If the result of such a calculation is not an integer the floating point value will be used for further calculations and in the intructions wait, timer and jiggle. All other intructions will automaticly use a rounded integervalue.
Next to the operators add (+), substract (-), multiply (*) and divide (/) you can also use (:) which also divides two numbers but saves a rounded result. This can be usefull sometimes.

Compare : The if_num command can be also used like this :

if_num (number1 ; >20)

oder

if_num (number1 ; <[number2])

Using strings: With the if_string and setstring instructions you can use textstrings within your scripts :

Display variables on screen : Variables can be displayed with the commands showinfo , speech or offspeech. Example :

offspeech (10 ; 3 ; Your Score : [score])

The brackets are used to declare a variable here, too.

Re-Usage : Numbers and Textstrings can be reused in the most instructions, example :

setstring (room ; firstroom)
setnum (red ; 120)
setnum (green ;200)
setnum (blue ; 25)

setlight ( [room] ; [red] ; [green] ; [blue] )

Predefined Variables : These are some predefined variables that can be used too :

[mousex] and [mousey] are the current mouseposition given in pixels. (can be changed via setnum)
[hour] , [minute], [second] are the current time.
[year], [month], [day] are the current date.
[currentroom] gives back a string with the name of the current loaded room.
[roomx] and [roomy] give back the current position of a room.
[charx] and [chary] are the current position of the active character in Pixels.
[charzoom] return a floatnumber of the current size of the active character. 1 means 100%, 0.5 means 50% and so on. Also you can now get the position and the size of any character by using [charx:name] for example.
[obj:object] returns the current state of an object.
[objx:object] and [objy:object] to read the position of an object.
[actiontext] contains the string a the actiontext used by the game. With this you can output it via textout.
[empty] used to check if a string contains nothing.


Delayed events

To delay a single scriptcommand for an amount of seconds you can use the Timer command :

timer (seconds)
  cutscene (anyblah)

After the specified time in seconds a cutscene will be started. Up to 10 timers can be activ at the same time. Each Timer-Command can only be used with one Scriptcommand!! When cutscenes or textscenes are activ all timers will stop counting down until the game is in normal mode again.


Creating a custom Save/Load menu.

Since Version 1.2 there is a checkbox in the gamesetup "Use Custom menu". This enables you to create your own save/load menu that will appear when pressing ESC.
For this you need another room that you have to specify in the gamesetup also. This room works like a subroom.

With the commands savegame(slot), loadgame(slot), quit(), textspeed and textenabled you can create buttons (with on(click) events) that gives your custom menu its functions. Names for the savegames cannot be used in a custom menu.

Remember that there will be no confirmation when using quit and restart in a custum menu. If you want a confirmation you have to setup one. A click on your quit-button, for example does not call quit directly, it enables other buttonobjects first that function as Yes/No.
Also : The events on(enter) and on(exit) work here too. So you can make sure that your menu is set back when the player opens it.


Create a Coin-Interface.

Create a room named "Coin". Design your interface just as you would do with a Taskbar, so create a background and buttons. Every Button's scipt must contain :

On (click)
command (look)

or another command. Thats it for the room.

In the projectsetup turn on the coin-interface. Enter the roomname.
Autopopup should be enabled otherwise you have to open the coin by yourself everytime. If you want that every object must contain the script :

on (rightclick)
popupcoin ()

The last thing you have to do is to adjust the center of your coinmenu. That is the relative position your coin will appear next to the mouseicon.
Well, thats it. If you want you can also adjust the fading of the coinmenu.


Particle Effects

For a particle effekt you need first an object that contains the particles in its states. The instruction for setting up the effect is (for example) :

setparticles (snow ; 4 ; 148 ; 30 ; 2 ; 35)

"snow" is the used object.
"4" is the speed.
"148" is the amount, the range is 1-151. Only values above 130 make sense!
"30" is the direction. 0 would be straight down and 90 would move the particles to the right.
"2" is the rotation. Each frame a single particle will turn 2 degrees around.
"35" is the variation. When a particle is being created it can be up to 35% faster or slower than the speed value declares.

You can start the effekt with startparticles ()" and stop it with stopparticles ()
Both instructions can be used with a (fast) which enables and disables the particle effect immediatly!

You can also select one of 4 rendermodes for particles using the instruction "Particleview". With this it is possible to display particles only behind a window in the wall.

Particles can slow down the rendering so use them wise ;)


Adding languages

Since Version 2.2 PaC-DK contains a tool which makes a translation of your game very easy. Look into the section : "The Editor" - "Language Tools"


FX Shapes :

With Version 2.3 of the PaC-DK a FX-Shape function was added. These are the different effects that can be activated.

Floormirror : This shape copies a mirrored version of the character into the floor. Of course this effect is a 2D Fake. So the question if this effect will look good depends also on the images you use.

Look closely at the feet of the character. You will see that it has some minor glitches, but usally these aren't very bad.
The floormirror-effect is placed after objects with the viewstyle "BACK". If you wanna place an objekt on the floor (like a carpet for example) you have to add it as an object with the viewstyle "MIDDLE". The character walks over it but the mirrored one will be covered by it.

If you have objects that stand on the floor so they have their own reflections, too, you can use "BACK" Objects now.


Wallmirror : Also the Wallmirror is a 2D Fake. It is a character that is copied turned over into the distance.

You can select the option "depending on roomposition" in the roomwindow, which is highly recommended to make it look more real (You can see on the screen here what i mean). Because the character will be copied into the distance you have to make sure that the depthmap does not end at the bottom of the wall. Otherwise the character won't be mirrored down sized.

Just like an object with the viewstyle "middle" a wallmirror FX-Shape has a middlepoint. This must be placed to the bottom of the mirror where the character stands in front of. If the reflection is to high adjust this middlepoint. Small corrections can be done with the position adjustment you can use when FX-Shapes are enabled in the roomwindow.

The Wallmirror-Effect uses the opposite action that your character has. If he looks to the front and talks he will look back and talk in the mirror. Extra-Animations are always mirrored with a character looking back, because there is no opposite. So better don't let your characters make special animations infront of a wallmirror. Usally it will look stupid.

If you want to place something onto a wallmirror (like a writing for example) you have to use an middle-object. The middlepoint must be on the same level as the one from the FX-Shape, then this object will be exactly between mirror and character.


Particle Barrier : A Particle Barrier "deletes" Particles which collides with it.

As you can see here you can use this FX Shape to adjust a weathereffect around any architecture in your room. The Barrier Shape should be a little bit larger as needed. To avoid seeing a particle disappear at once you can use the instruction "particleview" to set the rendermode for particles to BEHIND "Front"-Objects. Then you can place an object over the area and particles will smoothly vanish behind this object.




Using Script Functions

If your adventure gets bigger it often gets more complicated to script. Sometimes you will have to do some calculations in different locations in your game. Instead of having to copy/paste these Scriptparts over and over again you can use a function.

How does that work? A function is a created script that can be executed with function (scriptname). A cutscenes interrupts the gameplay, a function will not. So functions are supposed to be for calculations and not for game-events.

Example : Imagine you have a game with RPG values like HP and MP.These values will be changed everywhere in the whole game. If you want the display of these values to have a color depending to the values itself (red = low, blue = high) you will have to make some calculations to get the right colorvalue. (the downloadable example "Textout Demo" shows how this is done) So now, to prevend you from copy/pasting these color calculations to all places in the game where the HP/MP Values are changed you can create a function, write the scriptlines into a script called "textcolor" and execute them with function (textcolor) . Et voila.

Looping functions : If you wanna use a scriptpart that loops everywhere in the game you had to use the mainscript. (see the Flashlight Tutorial for example) but, if you want these looping scriptlines to stop from time to time you had to enable/disable them with a variable. The bad news is that with this way your mainscript gets bigger and bigger. The solution is a looping function : function (scriptname ; infinitly) will loop a function until you stop it with stopfunction.


Creating a Gameclock

To create a gameclock you can use a function.
Create a script called gameclock and fill it with this :
setnum (frames ; +1)

if_num (frames ; 50)
  {
  setnum (frames ; 0)
  setnum (seconds ; +1)
  }

if_num (seconds ; 60)
  {
  setnum (seconds ; 0)
  setnum (minutes ; +1)
  }

if_num (minutes ; 60)
  {
  setnum (minutes ; 0)
  setnum (hours ; +1)
  }

Be sure to call these variables seconds, minutes ect and NOT second or minute cause these names are used by pacdk for the current system time.
In your startscript you will have to reset these values :
setnum (frames ; 0)
setnum (seconds ; 0)
setnum (minutes ; 0)
setnum (hours ; 0)

To display this gameclock use :
textout (1 ; Gametime : [hours]:[minutes]:[seconds] ; x ; y... ect)

You can now enable and disable your gameclock by using :
function (gameclock ; infinity) and
stopfunction (gameclock)

To tie events on your clock just check the vars...
if_num (hours ; >1)
for example makes things happen after two hours of playing.



Creating an elevator effect

If you want to create an elevator (or a moving platform) in your game you want to move a character but the character should not "walk".

For this you can use the new instructions Linkchar and Unlinkchar. These will link a character to an object and its movements, which means he will be moved when the object is moved (by "moveobj") but without performing a walk animation. Also the player cannot controll a linked character.

What you have to make sure : To prevent your character from zooming back when he moves up on an elevator use the instruction stopzooming. A linked character can be moved over blocked walkmapareas BUT, when you unlink him be sure that the spot he is standing on is free, otherwise he will be stucked.

The Functiondemo contains a little demo in room 8, which shows you how an elevator can work.


Creating a customized actiontext line

- In the projectsetup turn the standard "Actiontext" off.
- Within your startscript set a textoutline (with the look and position you wish) and make sure it contains the variable [actiontext].
- If you want your line to be binded with the taskbar, coinmenu ect use the bindtext instruction.
- Use textalign for changing the alignment of the textoutline. Thats it.



Using scriptlines in animations

Every animationframe of an item, object or character can have a single line of script.

The simpliest way to use this is to play a soundfile at a certain point of an animation. For this there is an easy way : Just Drag&Drop a soundfile onto a single frame and a playsound instruction will be created.
Other possibilities : A self-coloring object via setobjlight, a character who shakes the screen with every step by using jiggle or an object that moves itself with moveobj.

Remember : For example, if you oszilate the color of an object in its state 2 you have to reset the color in the first frame of all other states its using, because you don't know at which point of an animation the state will change!



Additionals

Moving Objects : With the command Moveobj you can move objects to another location in a room. With if_xobj and if_yobj you can check the current position of an object.

Use the keyboard : With the commands if_keydown and if_keypressed you can access the keyboard for use it in minigames.

Object Groups : With the instruction group you can group up to 20 objects together. This group can be used with setobj and moveobj for moving or changing all objects within a group at once!