In this article, I will give instructions on how to use cogs to make objectives for your single player level. To write your objectives, go to the episode editor and generate a master.cog, or go to cogstrings.uni and write them yourself like this:
<key>         <unused number>  <text>
"GOAL_01000"  0                "Text for first objective."
"GOAL_01001"  0                "Text for second objective."
First, I'll start of with the symbols part of the cog. For this article, I will use a general objectives cog as an example to help me explain. The symbols section looks like this:

message  taken
thing    key
message  entered
sector   trigger
sound    goalsnd = Accomplish1.wav
Now, for the explanation. The term 'message' refers to an action taking place that causes the cog to start working. There are many different messages, (which you can look up in your JK Specs) but for simplicity I have used two common ones, taken and entered. With taken, the cog starts when you pick up an object. With entered, it starts when you enter a certain sector. Note, the words on the left will always be the general category while the ones on the right will be the specific item, sector, etc. In addition, these words from the right column will be in the gray box in the cog placer in JED (F7), and the words from the right column will be in parentheses to clarify what type of the map mode the input should come from. For example:
key  (thing)  -1
This means that you are going to input the key that triggers the cog, and it is a thing. Next, to keep your cogs a little shorter, you can put an alias for the actual .wav by setting the alias equal to the .wav as seen above. Before I begin the code section, I will give some basic cog background.
First, at the end of each statement, put a ";". A more advanced action is the 'if' statement. It is actually very simple, and I will lay it out below and explain it.
if (x > 1) {
    Print("x is greater than 1");
The item in the parentheses in the first line is being checked; if it is true, then the cog executes the action shown inside the curly brackets. If that is the case, the words will come up on the screen. Now, to take this to a more usable level. This is what your code for the objectives cog will look like: (Note: anything behind // is a comment and doesn't affect the cog.)

Player = GetLocalPlayerThing();
SetGoalFlags(player, 0, 1);
SetGoalFlags(player, 1, 1);


// Player picks up key...

if(GetSenderRef() == key) {
    SetGoalFlags(player, 0, 2);
    PlaySoundThing(goalsnd, player, 1.0, 1, 1, 0x80);
    Print("Mission Objective Accomplished!");


// Player enters sector...

if(GetSenderRef() == trigger) {
    SetGoalFlags(player, 1, 2);
    PlaySoundThing(goalsnd, player, 1.0, 1, 1, 0x80);
    Print("Mission Objective Accomplished!");

Now, to start off with, when you put "player = GetLocalPlayerThing();" it registers you as the player. Then the command "SetGoalFlags()" is used to let the objectives you wrote show up in the game. First put the command, "SetGoalFlags", and then in parentheses put "(player, [goal number], [goal flag])". "player" makes the objectives for the person playing, then put the goal number as it is seen in cogstrings.uni, with the first being 0, the second being 1, and so on. Then put the flag for the goal. 0 is hidden, 1 means shown, and 2 means completed.
Next appears the first message, taken. The command GetSenderRef() ensures that the correct object has been picked up so that you're not achieving an objective with the wrong thing. Notice, this is an 'if' statement, so if the comparison of "if the key is sending the message" is true, then the cog moves on and executes the commands. SetGoalFlags(player, 0, 2) makes the first objective shown as completed on the objectives list in the game. PlaySoundThing() plays the sound that you have up in the symbols list. In the parantheses for PlaySoundThing, use the following arguments: "(alias of *.wav file, volume, player[where it plays], min distance, max distance, flags)". The flag that I have put in makes the sound follow you if you are moving. For a complete list of sound flags, see your Jedi Knight Specs document. Print() makes the string inside the parentheses and quotes come up on the screen.
The last part is the message entered. The GetSenderRef() makes sure that you have entered the correct sector, known as 'trigger' as it is in the symbols list. Then the objective is set to be shown as accomplished, and the sound is played. As before, Print() makes the words come up on the screen.
This was a very basic example of the power of JK's objectives - hopefully it will help get you started. It seems like people have the most trouble with getting the objectives working and other minor problems, so with any luck you should have a better idea of what to do now.
Any questions can be directed to Antilles by email or the forums.