BSL:Tutorial/Scratch

From OniGalore
Jump to: navigation, search

This page is a short tutorial on how to get started on simple scripts for those who have had no experience with scripting before. It will teach you, step by step, how to write a simple script. By the end of this tutorial, you will be able to move on to more advanced scripts.

Starting off

Open up your IGMD and look for the following folder: EnvWarehouse. Open it up, and we'll take a look at how it it laid out. There should be several files in here. Open using NOTEPAD, the one titled warehouse_main.bsl. It should look like this:

func void main(void)
{
    env_show 2010 0
    gl_fog_blue=.15
    gl_fog_red=.15
    gl_fog_green=.15
    gl_fog_start=.99
    gs_farclipplane_set 5000
    obj_create 20 20
    level_start
}

This is an example of a main file. It contains the information of how the level starts.

Ignore the contents of the script for now, and notice that the contents of the function main are enclosed by a set of brackets ({ and }).

All functions must be enclosed in this set of brackets or it will not be executed.

Close the file, and rename the folder "EnvWarehouse" "EnvWarehouse_original". Then, create a folder called "EnvWarehouse" and create a script file inside and name it "Tutorial". We will be using this file to show various examples of scripts and finally, write a small script of your own.

Each command in this tutorial should have a link behind it the first time it's used in some sample BSL. Click that link to learn more about the command, or for a complete list of commands, see BSL:List.

First script

This section will teach you how to write a very basic script (fighting script). It will start you off in the Final Training Room, where you practiced firing weapons in the original game. With this script, the room will appear very empty.

Let's open up the "Tutorial.bsl" file and start writing the script.

First, declare it the "main" portion of the script by typing "func void main(void) at the very beginning of the file. This tells the game which function it is. The "main" function is the function that the game looks at first to determine what is to be executed.

Below that line, type {. This tells the game that the function has started.

Add a space, and then type chr_teleport 0 7010. This function teleports Konoko (her id is always 0) to the flag 7010. It is located in the final training room.

Finish the function "main" by typing } on the next line.

It should look like this:

func void main(void)
{
   chr_teleport 0 7010
}

Save the file, load up Oni, and click "New Game". You should be standing in the center of the final combat training room.

You are now on your way!

Adding NPCs (AIs)

Before we begin, notice that there are two types of AI. AI created from character objects, and AI created from memory. AI created from character objects are created by the function call ai2_spawn (name), where (name) is the name of the AI. AI created from memory are created by the function call chr_create (ai_number) start,. These AI do not have combat logic, and thus will not attack you physically but can still use weapons.

Now, we are going to add 2 enemy AI to our script that we wrote in the last section. Open it up, and lets add some enemies for Konoko to fight.

To recap, it should look like this:

func void main(void)
{
    chr_teleport 0 7010
}

After the function call chr_teleport 0 7010, add the following 2 commands on separate lines: ai2_spawn Top_Striker_1 and ai2_spawn Top_Comguy_1. These two commands tell the game to create 2 characters: Top_Striker_1, and Top_Comguy_1.

Since that these characters do not spawn in the room, they must be teleported there. Using the chr_teleport command used earlier to teleport yourself, modify it to teleport the 2 AI using their names instead of "0". Teleport them to the flags "7008" and "7009" respectively. Refer to the example above or the list of function calls above to write this in.

It should now look like this:

func void main(void)
{
   chr_teleport 0 7010
   ai2_spawn Top_Striker_1
   ai2_spawn Top_Comguy_1
   chr_teleport Top_Striker_1 7008
   chr_teleport Top_Comguy_1 7009
}

This script will now teleport you into the final training room and face you off against 2 Strikers.

This fight too easy? In the next section, we will learn how to spice up the fight, and let you develop your own script.

Customization

Here, you will be able to split off and customize your script. Each subsection will represent a way to customize the above script.

Weapons and powerups

These are the easiest things to add into a battle. Weapons can be spawned on the ground or given to characters.

Giving characters weapons

Giving characters weapons is very easy. Simply use the command chr_giveweapon to give a character a weapon.

Here are the list of the weapon codes. For the purpose of this example, we will use w3_phr, the plasma rifle. This command will give the two strikers plasma rifles.

Add the commands chr_giveweapon Top_Striker w3_phr and chr_giveweapon Top_Comguy w3_phr on separate lines beneath what you have already. Be sure to add it BEFORE the } or it will not execute.

Spawning weapons on the ground

Spawning weapons is simple. Use the command weapon_spawn to spawn a weapon.

Add the commands weapon_spawn w3_phr 7008 and weapon_spawn w3_phr 7009 on separate lines beneath what you have already. Be sure to add it BEFORE the } or it will not execute. This command will spawn 2 plasma rifles, one under each striker's feet. AI will automatically pick up weapons with ammo or empty weapons they have ammo for.

Giving characters powerups

Giving characters powerups is much like giving characters weapons. Use the command chr_givepowerup to give a character a powerup.

The powerups you can give a character are :

  • shield : Gives a force shield
  • invis : Gives a phase cloak
  • ammo : Gives a ballistic ammo
  • cell : Gives an energy cell.

For the purpose of this example, we will give the characters invisibilities.

Add the commands chr_givepowerup Top_Striker invis -1 and chr_givepowerup Top_Comguy invis -1 on separate lines beneath what you have already. Be sure to add it BEFORE the } or it will not execute. This command will make the strikers permanently invisible. To make then visible after 30 seconds, erase "-1".

Spawning powerups on the ground

Spawning powerups are simple. Use the command powerup_spawn to spawn a powerup.

Add the commands powerup_spawn invis 7008 and powerup_spawn invis 7009 on separate lines beneath what you have already. Be sure to add it BEFORE the } or it will not execute. This command will spawn 2 phase cloaks beneath the striker's feet. Since AI will not pick up powerups, this is for you only.

Extra characters

Adding extra characters to the script is easy. Just follow the steps for adding the first AI and follow the procedure, look for AI names here. (Wiki page not here yet. Use ssg's tables instead.)

Adding enemies

Look at the chart for what teams the AI are on. Most of the time, adding enemies simply involve spawning and teleporting the AI. As long as the team in "Syndicate", it will be an enemy. If you want to add an emeny from an allied team, use the chr_changeteam command to changet their team to "Syndicate" like this:

chr_changeteam griffin Syndicate

Adding allies

Look at the chart for what teams the AI are on. As long as the team is "TCTF" or "Konoko", it will be an ally for you in this script. If you want to add an ally from the enemy team, use the chr_changeteam command to changet their team to "TCTF" or "Konoko" like this:

chr_changeteam WH_Striker_D TCTF

Overpower

Use the chr_set_health command to set a character's health. Note that each character has a base health that may not be the same. For example, konoko's base health is 200, while a brown striker's is only 50. Keep this in mind when setting character's health. Setting it over their base health will send them into overpower - like using a hypo at full health. The health will drain at 1 point per tick (1/60 of a second), even for AIs. This example sets Konoko's health to 400 - overpower.

chr_set_health 0 400

This following example shows everything listed above added.

func void main(void)
{
    chr_teleport 0 7010
    powerup_spawn hypo 7010

    ai2_spawn Top_Striker_1
    ai2_spawn Top_Comguy_1

    chr_teleport Top_Striker_1 7008
    chr_teleport Top_Comguy_1 7009

    chr_givepowerup Top_Striker_1 invis -1
    chr_givepowerup Top_Comguy_1 invis -1
    powerup_spawn invis 7007
    powerup_spawn invis 7009

    chr_giveweapon Top_Striker_1 w7_scc
    chr_giveweapon Top_Comguy_1 w3_phr
    chr_givepowerup Top_Striker_1 ammo 15
    chr_givepowerup Top_Comguy_1 cell 30

    weapon_spawn w2_sap 7045
    powerup_spawn ammo 7008

    ai2_spawn OutroTCTF01
    chr_teleport OutroTCTF01 7007
    # OutroTCTF01 is team Switzerland by default
    # we have to change that so he can fight
    chr_changeteam OutroTCTF01 TCTF

    ai2_spawn A_t47
    chr_changeteam A_t47 TCTF
    chr_teleport A_t47 7007

    ai2_spawn griffin
    chr_changeteam griffin Syndicate
    chr_teleport griffin 7008
    chr_set_health griffin 3900
}

Delay

To wait for some time before executing a command, use sleep. To wait for approximately 5 seconds before spawning an extra drone:

sleep 300
ai2_spawn dum_train_block
chr_teleport dum_train_block 7010

To wait for a Striker to die and then spawn some drones:

chr_wait_health Top_Striker 0
ai2_spawn dum_train_block
chr_teleport dum_train_block 7010

Forking and separate functions

This is the part where we start moving commands out of "main". Create a new function called "logic" like this : type "func logic" two lines below the } of "main". Type { and copy out everything inside "main" into "logic". Type fork logic in main. It should look like this:

func void main(void)
{
   fork logic
}

func logic
{
   ...
}

with "..." being whatever you had in "main" before. Add chr_wait_health griffin 0 at the end of "logic", then type fork logic2. Create the function "logic2". In "logic2" you can write whatever you want that you have learned before. For the purpose of this example, ... will represent whatever you had, .. will represent whatever you want, and the typed text will represent the thing that must be included.

func void main(void)
{
   fork logic
}

func logic
{
   ...
   chr_wait_health griffin 0
   fork logic2
}

func logic2
{
   ..
}

Extra: multiple forking

More than one function can be forked in the same function. Look at ths example:

func void main(void)
{
   fork logicA
   fork logicB
}

func logicA
{
   ..
}

func logicB
{
   ..
}

Both "logicA" and "logicB" are executed at the same time. If chr_wait_health griffin 0 were to be removed, likewise, both "logic" and "logic2" are executed at the same time.

Variables and save points

Ever wondered why there is no folder for the Training level? The truth is that it is actually part of the Warehouse level and is kept separate using save points.

This is the beginning of the "level_start" which is forked from "main" in the original level scripts.

func void level_start(string ai_name)
{
   if (save_point eq 0)
   {
      ...
   }

   if (save_point eq 1)
   {
      ...
   }
}

Using forking, you can link save points to functions. Like so:

func void main(void)
{
   if (save_point eq 0)
   {    
      fork logic
   }

   if (save_point eq 1)
   {
      fork logic2
   }
}

When save point 0 is loaded (TCTF Training), the function "logic" is executed. If save point 1 is loaded (Syndicate Warehouse), "logic2" is executed. Note that in Warehouse, the save point number in the script is one higher than in the level load list, because "TCTF Training" is SP0.