Thursday, March 20, 2008
Still Learning Second Life Script
http://www.lslwiki.net/lslwiki/wakka.php?wakka=examples
I was digging through these and found a full example of building a Tic-Tac-Toe game. Had I known this existed, I probably wouldn't have read it before hand anyways because I sometimes like to figure stuff out then compare to how others solve the same problems.
http://www.lslwiki.net/lslwiki/wakka.php?wakka=ExampleTicTacToe
As I expected, we went about it in different ways, but I do think that both solutions are fairly equal. I did force people to sit at the table and after I was done thought it would be better to have people simply click to choose sides. He did the later and it is a lot easier to setup than the code I did to watch for people that sit down. Good learning experience though.
One of the best parts of this example is the discussion on Version Control. (http://www.lslwiki.net/lslwiki/wakka.php?wakka=ExampleTicTacToeVersionControl) This is something I struggled with early on and he has a very elegant solution to keep all the scripts in the root prim and copy them out to the child prims when you type "/1 listen" into chat. I spent a lot of time reading this section of the example and will probably be implementing something similar for a future game. A full example isn't given and it glosses over some of the aspects that make this a general use solution so this is definitely going to be home grown.
I haven't really gotten past that page yet and I'll have to spend some time to finish it. Very worthwhile reading.
Monday, March 3, 2008
My Web Comic Turned 50
http://facebigelow.blogspot.com
Monday, February 4, 2008
Video Gaming Causes Decline In National Park Activity
I'm not sure if this is good news or bad news since I both like video games and I'm an avid backpacker. It means both that there will be more games to play, and less people and trash on the trails.
On the other hand it probably means less maintenance on trails and less protection in the long run, since people will be less likely to fight to save a resource they don't have any interest in. Let's just hope it means more games and less people and not the consequences for public lands and conservation.
Thursday, January 24, 2008
Torque Closer To Browser Based Games
http://www.instantaction.com/
There still isn't a lot of information on how this works, the business model or if independent developers will be able to launch titles on the site. At least I have not found much. It is looking more like it might be the equivalent to the next generation gaming console right in your browser so it looks like something interesting to watch. Stay tuned.
Tuesday, January 22, 2008
Second Life Wiki Of Choice
The Independent Wiki http://www.lslwiki.net/lslwiki/wakka.php?wakka=HomePage
The Linden Labs Wiki http://wiki.secondlife.com/wiki/LSL_Portal
When I have added content, I have tried to add it to both sites, but it seems more people use the lslwiki.
One issue with the independent Wiki is ownership. It isn't clear if people who have posted to the wiki have given up their copyrights while the Linden Labs Wiki puts all information posted to the wiki in the public domain. I wonder if there will be some kind of crazy court case concerning intellectual property and public wiki's in the future? It seems inherent to me that if you post something on a wiki you are giving up your copyright, but I do see that it needs to be clearly stated or some kind of legal settlement needs to happen.
Monday, January 21, 2008
My Next Second Life Creation
In this next game I'm thinking it will have a bunch of moving parts. So instead of creating all the objects at build time, I think they need to be generated programatically instead of creating them at build time. So, I found myself looking into Inventory functions and specifically llRezObject.
My initial attempts were flawed. I called my object "puck" and linked it to the object that had the script. This is the way I did it in Tic-Tac-Toe. Then I called
llRezObject("puck", llGetPos(), ZERO_VECTOR, ZERO_ROTATION, 1);
Thinking it would create the new puck object. No luck and no error and nothing at all happened.
Then I found that inventory page and read it more closely. "SL has two kinds of inventories, one for users and one for objects".
I finally read somewhere else, I can't find it now. That an object's inventory is actually under the "contents" tab when editing. So I unlinked the puck. Took it into my own inventory, then dragged the puck to my game's contents. Wala! It was there with the main script and sure enough the script created a new puck at the center of my other object with I touched a lever I had setup to test this. Overall, a good learning experience.
Thursday, January 10, 2008
Building A Second Life Checkers Game #9

One thing I don't think that shows here is that the green triangles point in the direction of the player who's move it is. When the player makes a move I change the rotation of all the green triangles like this.
RotateBtns(integer xoro)
{
integer itmp;
integer btnnum=0;
integer btnlinknum;
integer pos = 0;
rotation rot;
if (xoro==1)
{
rot = rot0;
}
else
{
rot = rot180;
}
for (;pos<9;pos++)
{
itmp = llList2Integer(btnpositions,pos);
if (itmp>=0)
{
llSetLinkPrimitiveParams(itmp,[PRIM_ROTATION,rot]);
}
}
}
This may look pretty simple, but it has a trick. I originally tried to just rotate 180 around the z axis, but as I should have known before I started this would not work as rotations are cumulative and coming up with a rotation axis is not trivial piece of math. Quaternians are simply a vector associated with a rotation angle around that vector. They can be hard to calculate programatically.
The solution? Find the two rotation angles at build time and use them as static values.
vector eul = <0,77,0>; //0 degrees around the z-axis, in Euler form
eul *= DEG_TO_RAD; //convert to radians
rot0 = llEuler2Rot(eul); //convert to quaternion
eul = <3.9,283.0,184.45>; //180 degrees around the z-axis, in Euler form
eul *= DEG_TO_RAD; //convert to radians
rot180 = llEuler2Rot(eul); //convert to quaternion
Cheating I know, but most programming is about getting something to work, even though it might not be the most elegant solution. At least that is how I work. Why not the elegant solution you ask? One takes hours and hours and one just a few minutes and schedule is usually the most important element of all. Also, if it really needs to be elegant, it is better to get it working and come back in later if it really needs it.
Wednesday, January 9, 2008
Building A Second Life Checkers Game #8

Success. I finally got to the point where I could do some testing. Finding someone to help you test is incredibly hard. I have about 30 people listed as friends and of course no one is online. I start asking around at various sand boxes and no one will even lift a finger. Finally one of my friends logs on and it is the person who was harassing me just a while back. I ask him and he is more than eager to help.
So it really pays to try and make friends even when someone is being rude.
There were a couple of small problems, but overall it is working. The next step is to redo the "programmer art" and make it look a little more professional. I've been watching HGTV to try and decide on a color scheme for the game that will fit in most residences. Yeah right.
Tuesday, January 8, 2008
Building A Second Life Checkers Game #7

The pieces are placed in order as the green traingles are touched. The peices are stored in a box below the table and the triangles are swapped to that location when the triangle is touched. Next I'm starting to work on the seating and makeing the game play depended on two avatars seated on the "chairs". The little green button on the left resets the entire board.
Here is some code to move a piece to a specific location on the board.
MoveLinkToPos(integer iLinkNum, integer posWhere)
{
key rootKey = llGetLinkKey(1);
list params = llGetPrimitiveParams([PRIM_SIZE]);
vector sz = llList2Vector(params,0);
//llOwnerSay("area size = "+(string)sz);
integer px = posWhere / 3;
integer py = posWhere % 3;
//llOwnerSay(" px="+(string)px+" py="+(string)py);
// set the position of the piece to 0,0
float sqr_x_size = sz.x / 3;
float sqr_y_size = sz.y / 3;
//llOwnerSay(" sqr_x_size="+(string)sqr_x_size+" sqr_y_size="+(string)sqr_y_size);
vector p = < (sqr_x_size * px) - (sz.x/2) + (sqr_x_size/2),
(sqr_y_size * py) - (sz.y/2) + (sqr_y_size/2),
0.051 >;
//llOwnerSay(" new pos = "+(string)p);
llSetLinkPrimitiveParams(iLinkNum,[PRIM_POSITION,p]);
}
Most of this code was outlined in post #4. I just consolidated it into a function.
And some code to move a piece into the storage box.
MoveLinkToStorage(integer iLinkNum)
{
llSetLinkPrimitiveParams(iLinkNum,[PRIM_POSITION,vStorage]);
}
When the game starts up I store the location of all the buttons.
for (i=2;i<=iNumPrims+1;i++)
{
string stName = llGetLinkName(i);
key keyObj = llGetLinkKey(i);
list a = llGetObjectDetails(keyObj,([OBJECT_POS]));
vector p = llList2Vector(a,0) - regionPos;
if (stName=="movebtn")
{
btnlinks = llListInsertList(btnlinks,[i],0);
}
else if (stName=="xtile") ....
}
ShowAllBtns();
Here is the ShowAllBtns function.
ShowAllBtns()
{
integer itmp;
integer btnnum=0;
integer btnlinknum;
integer pos = 0;
vector v;
for (;pos<9;pos++)
{
itmp = llList2Integer(board,pos);
if (itmp==-1)
{
btnlinknum = llList2Integer(btnlinks,btnnum);
//llOwnerSay("move linkbtn="+(string)btnlinknum+" to pos="+(string)pos);
MoveLinkToPos(btnlinknum,pos);
btnnum++;
}
else
{
btnlinknum = -1;
}
//llOwnerSay(" adding btnlinknum="+(string)btnlinknum+" at pos="+(string)pos);
btnpositions = llListReplaceList(btnpositions,[btnlinknum],pos,pos);
}
//llOwnerSay("btnpositions="+(string)btnpositions);
// move the rest of the buttons to the storage
for (;btnnum<9;btnnum++)
{
btnlinknum = llList2Integer(btnlinks,btnnum);
MoveLineToStorage(btnlinknum);
}
}
I'm going through all the board positions looking for a -1 meaning that the location doesn't already have a piece. If it doesn't, I move the first (then next) button to that location and save which button is at that point in the btnpositions list. At the end I move the rest of the buttons that were not used to storage so they are not visible. Using this list, when a button is touched we can convert the link number given by the touch event into a position on the board by traversing the btnpositions list.
integer FindBtnPos(integer iLinkNum)
{
integer count = llGetListLength(btnpositions);
integer itmp;
integer i=0;
for (;i<9;i++)
{
itmp = llList2Integer(btnpositions,i);
//llOwnerSay("btn at pos "+(string)i+" = "+(string)itmp);
if (itmp==iLinkNum)
{
return i;
}
}
return -1;
}
Monday, January 7, 2008
Building A Second Life Checkers Game #6

The green triangles will be the location to click on to place the actual piece during play. The texture for the board is the same as the checker board, a 2x2 grid repeated the correct number of times. In the case of checkers it was repeated 4 times in the x and y direction. In the case of tic-tac-toe it is repeated 1.5 times in each direction then I had to offset the u and v direction by 0.75. I'm not smart, I just fiddled with it until it worked.
That said, I think this step back will actually be a step forward since I'll be able to do most of the work for the checkers game in a scaled down fashion, then take that knowledge to the larger game.
Wednesday, January 2, 2008
Building A Second Life Checkers Game #5
What really makes this a puzzler is that setting the size is pretty darn simple. So I'll look at that first.
I used this same call in the last post to set the position
llSetLinkPrimitiveParams(pieceLinkNum,[PRIM_POSITION, vectPos]);
It is the same call you would use to set the size.
llSetLinkPrimitiveParams(pieceLinkNum,[PRIM_SIZE, vectSize]);
So what's the big problem? Well, there is no llGetLinkPrimitiveParams. What!?! But what about this code to get the location using the object key.
key pieceKey = llGetLinkKey(pieceLinkNum);
list d = llGetObjectDetails(pieceKey,[OBJECT_POS]);
vector vPos = llList2Vector(d,0);
That seems simple enough, except when you look closer at llGetObjectDetails it is not llGetPrimitiveParams. Object details are only a few parameters like name, description and size. Then if you dig for an hour like I did, you find that there is no 'easy' way to get PrimitiveParams given a link number or an object key. You will find it on a Wish List of functions and can just give up until someone finally decides to implement this function that seems so useful, but seems to have been overlooked.
Or you could be like me and figure out a way to get it done, knowing the mantra "There is always a way. There is always a way. There is always a way." I can't seem to find it now, but there was some obscure reference on some wiki page that said it didn't exist and you have to use link messages. So here goes.
Link messages are a way to send messages from one prim to another in a link set (link sets are groups of prims, but group would have been too confusing the Linden folks say). Even though it is frowned upon to have scripts in all the linked objects, this is the only way to get this done.
When I traverse the list of pieces I look for the name of my piece to get the linknum of that piece.
integer i=2;
integer count = llGetNumberOfPrims();
for (;i>count;i++)
{
string stName = llGetLinkName();
if (stName == "thepiece")
{
// send the link message
pieceLinkNum = i;
llMessageLinked(pieceLinkNum,PRIM_SIZE,"43",NULL_KEY);
}
}
I'm sending PRIM_SIZE as the message number just because I don't have any other messages. In good practice I could probably send a number that is associated with some hair brain scheme I came up with on the fly, but since there is only one message to this prim, anything will do. Normally I would chose 42 since that is the most important number in the universe. Which seems strange in that I did use 43 for the message number that will be used when returning the size to this root prim from the linked prim.
Inside the linked prim, I need to setup a way to receive that message. It is the only thing that script does, which is a good thing. Avoid scripts in linked prims if at all possible.
default
{
link_message(integer sender_num, integer num, string ret_num, key id)
{
if (num==PRIM_SIZE)
{
list re_list = llGetPrimitiveParams([PRIM_SIZE]);
//llOwnerSay("re_list = "+(string)re_list);
llMessageLinked(LINK_ROOT,(integer)ret_num, re_list, NULL_KEY);
}
}
}
This gets the size using llGetPrimitiveParams([PRIM_SIZE}) which returns the correct value since this is in the prim we want the size from. I then return this size to the LINK_ROOT using the message number that was passed in the link message.
Back to the root prim, here is the code to receive that message.
link_message(integer sender_num, integer num, string list_argument, key id)
{
if ((sender_num==pieceLinkNum) && (num==43))
{
//llOwnerSay(" list_arg = "+(string) list_argument);
pieceSize = (vector) list_argument;
//llOwnerSay("received pieceSize="+(string)pieceSize);
}
}
I save that size into the global variable pieceSize which I can then use in other calculates.
Note, I went through this whole exercise thinking I needed the size of the piece to calculate it's location on the board because I would have to center the piece somewhere. After all that, and a ton of failed attempts I remembered that the origin is automatically the center and I didn't need a single line of this code. Gotta love programming for the amount of time I've wasted in my life. I'm sure I'll use this elsewhere though.
Monday, December 17, 2007
Building A Second Life Checkers Game #4
Here is a screenshot of my mockup environment.

The positions would be numbered 0-63. The starting location would be 0. Touch the green button and the piece would move to the next position.
The first problem is to find the size of the board. Since it is the root object it's pretty easy to find. To note, if it's not the root prim you are screwed and it is very difficult, and I'll talk about that in the next post. The size (PRIM_SIZE) is the actual size of the object in meters. When calculating the location on that prim with local coordinates, the origin is at the center of the prim.
list params = llGetPrimitiveParams([PRIM_SIZE]);
vector sz = llList2Vector(params,0);
Next is to calculate the x and y row and column. This is also very simple given there are 8 rows and 8 columns.
integer px = curPos / 8;
integer py = curPos % 8;
I then calculate the size of each square and save it.
float sqr_x_size = sz.x / 8;
float sqr_y_size = sz.y / 8;
Once you have all that it is fairly straight forward to calculate the location of that square, but look at all the comments and see how many tests I went through to get it right. Tons of experimentation here.
//llOwnerSay(" sqr_x_size="+(string)sqr_x_size+" sqr_y_size="+(string)sqr_y_size);
vector p = < (sqr_x_size * px) - (sz.x/2) + (sqr_x_size/2),
(sqr_y_size * py) - (sz.y/2) + (sqr_y_size/2),
0.051 >;
//vector p = < (sqr_x_size * px) - (sz.x/2),
// (sqr_y_size * py) - (sz.y/2),
// 0.1 >; // the position without centering on the square
//vector p = < sz.x/2, sz.y/2, 0.1 >; // the origin
//vector p = < -sz.x/2, -sz.y/2, 0.1 >; // the negative origin - this didn't work
//vector p = <0,0,0.1>; // the 0,0 location which is the center of the board
//vector p = <(sqr_x_size/2),(sqr_y_size/2),0.1>; // just a futile experiement to offset from the origin some amount
//llOwnerSay(" new pos = "+(string)p); // the debug message seen over and over and over again
Given all that, the actual calculation that I used can be summed up like this.
For x: The location given the x location minus the offset because the origin is the center + the offset of half a square to center on the square.
For y: Same as x
For z: Just a number which I twiddled to get right.
The last step is to set the actual location. This is pretty simple given that you know the link num for the piece you want to move. This number was retrieved on initialization. After that, change curPos and wait for the next touch.
llSetLinkPrimitiveParams(pieceLinkNum,[PRIM_POSITION,p]);
curPos++;
And yes, this was more work, but as I expected it will be a lot more efficient and easier to work with in the long run.
Friday, December 14, 2007
Building a SecondLife checkers game #3
My checkers game is now receiving a:
Script run-time error
Stack-Heap Collision
I know what the problems are and I know how to fix it, but it does show how flexible software development needs to be. I knew going in that memory constraints on the scripts were going to be tight, I just didn't figure I would hit them this quick. Here is the latest screen shot.
The good news is that I know what the problem is and I may not need to change the design too much.
The green triangles are not visible during game play except to choose the location where you can move a piece. The mechanic is to touch the piece you want to move, then the green triangles appear in locations that are open, then you click on the triangle. I've got all the movement and placement of the triangles working.
The problem occurred when I created enough extra triangles for the number of moves that might be available. For the pieces I'm saving the original location vectors (three floats) in a list. Including the ones in the center which will become the king pieces. Then removing the kings from the board (you can see the storage box in the back which will be moved under the table at the end. These vectors are big and I was also saving the triangles just for testing and that is where I hit the problem. I can really just keep them off the table at all times and don't need their initial locations. So, even though I hit what seems like a big snag, all is not lost yet... And even if it were, there is always a work around. Always.
Thursday, December 13, 2007
Building A Second Life Checkers Game #2
The available LSL data structures are quite limited, but enough to make scripts that do anything.
The biggest thing you learn early on is that there are no arrays. At least not like in other languages. What they do have are lists which are basically arrays, but you have to use special functions to manage the arrays.
As an example, I know my board has 32 spaces so I have a list that contains the piece number at any given space. You first have to allocate space for the 32 spaces.
list board;
InitializeBoard()
{
integer i=0;
for(;i<32;i++)
{
llListInsertList(board, [-1], 0); // -1 means no piece is there
}
}
As I traverse through the linked pieces (see previous entry), I insert them into the board at their location which is defined with a little CSV in their title "r,1,1". The first letter is the color, the second is the piece number and the third is the location which are the same. I may have over designed the piece number and location...
Once you know the piece number you can add it to the data structure (list) holding the locations on the board.
board = llListReplaceList(board,[piece_num],piece_location,piece_location);
One thing to note, ReplaceList creates a whole new list and returns it. You WILL at some point screw this up and not have the board = in there and wonder why your list update didn't occur. It is just part of the learning curve. I'm sure I'll do it again and again and waste more hours. I think the compiler should warn you of this since it seems so necessary and such a common mistake.
When you want to access an element in the list you do so knowing the type that you previously stored in the list. In this case it was an integer and if I want to know what was at location 3, I would do this.
integer pieceAtLocation = llList2Integer(board,3);
For other types stored in lists, there are other functions, llList2String, llList2Vector, llList2Key, etc...
Wednesday, December 12, 2007
Distilling a Second Life harassment incident
Me: Hey, how about we work together on something together instead being disruptive. I find that life is a lot more fun when we help each other and work together.
Me: I think it would be interesting to work on a project with you. I have a lot of programming experience and help on the scripting side of a build.
Mr. Disruptive: You mean a truce?
(I never knew I was at war)
Me: Yeah, sure.
Mr. Disruptive: Okay, cool.
He had left the area and then asked me for a teleport. He never really talked to me again, but he hung out in the area tweaking a spheroid and soon added me as a friend. So as I've found in life and now in virtual life, bad situations can usually be distilled by an offer to work together even when one person is bent on being disruptive. The charity work I do is the most rewarding thing that I have ever done and I'm always looking for ways to continue those efforts. It seems there is even room for this type of work in the virtual world!
I wrote this up a few days ago and he actually came back around to show me some new emotes he had received from a friend. I think he's just a kid, but its much better than the initial interactions.
Tuesday, December 11, 2007
Building a Second Life Checkers Game

The first lesson was where I started out giving each game piece it's own script and sending messages back to a larger script attached to the board. This was using Link Messages (llMessageLinked). It was good that I figured out early that this was the wrong way after reading the section on Script Effeciency. #1 in efficient design: If you need to have a bunch of buttons, don't put a script in each prim, use llDetectedLink number.
I now have only one script in the board. By default, each linked prim has a link number and you can traverse the list of linked prims using something like this:
integer count = llGetNumberOfPrims();
integer i = 2;
for (;i<=count;++i)
{
string stName = llGetLinkName(i);
list namelist = llCSV2List(stName);
string stType = llLink2String(0);
string stPieceNum = llLink2String(1);
if ((stType=="r") || (stType=="b"))
{
llOwnerSay("have a "+stType+" piece numbered "+(string)stPieceNum);
// I also save the link number, color and piece number
// in a list which I'll show later
}
}
I gave each piece on the board an object name of "r,1" or "r,2" which allows me to identify which piece is touched during the move. I then convert this name to a list (llCSV2List()) to separate out the color and piece number. You might note that i started with 2. The board, which is the root prim (the one selected last when linking), is number 1 and I don't include it in the lookup. I don't have the move mechanic completed, but the early design of it is working and I'm refining the movement code now.
There is probably a lot more to talk about and lists are a big part of the design. I'll try and write more on that tomorrow.
Friday, May 18, 2007
Does Anyone Like GridBagLayout??
Thursday, May 17, 2007
Doom Slayer III
Doom Slayer III
http://www.youtube.com/watch?v=PN5E3E_nIhA
I've already posted it, but the final results of the contest are here.
http://www.gamedev360.com/contest07/
Wednesday, May 16, 2007
Game Development Contest Results
http://www.gamedev360.com/contest07
The RailGunner game is an amazing piece of work built in about six weeks. Jess and Noah really outdid themselves. Even the second (T-Orc) and third place (Doom Slayer III) games were very nicely done. Rail Gunner and T-Orc are fully playable. Doom Slayer III while not completely done had a ton of code to it. He even did a trailer that was hillarious and everyone enjoyed. I'm hoping he uploads the trailer for others to see.
All in all I think everyone enjoyed themselves and I think a number of the students will get jobs. There was enough time at the end for the industry folks to mingle with the students and I'm sure a number of them will get calls.
One of the things that became apparent and I had sort of forgotten about it was the fact that half of my class were seniors and half were freshman. I went really fast in the first few classes knowing the freshmen were out of their experience level and hoping they would drop. A number of them did, but a few of them stuck with it and while they didn't have winning games they did have some impressive pieces of work. Although I should mention that Jess (one of the winners) is only a sophmore. Brilliant.
One of the crowd favorites was a freshman game called Beer Sweeper. It was fun to watch as Luis kept raching around the virtual recreation of an actual dorm room (it was very close, I once lived in that same dorm) the keys started to change and it became very hard for him to control. It got some good laughs.
The fourth place game Ork Fight had a ton of AI code and Chris got the orcs to fight on teams with the other players. It was very fun to watch. He had some funny stories about problems while he was working on the AI. Some of the problems sounded almost human.
The fifth place game was a huge endeavor. Given a few more weeks I think Vinnie would have taken first place. He's going to be the Peter Jackson type some day. Double majoring in Film and Philosophy and a minor in computer science he made some major engine modifications and is well on his way to a significant creation.
All in all it was a great semester. I worked way too hard at it and didn't make much money, but I love doing it and I'm looking forward to at least taking a semester off. I'll decided later in the year if I'll do it again.
Tuesday, May 15, 2007
Tonight's Contest
This is how judging will be weighted. It doesn't have anything to do with their grade on the project, just who 'wins' best game.
Completeness: (25 %)
Replay/fun factor (20 %)
Uniqueness (15 %)
Story (10 %)
Graphics (10 %)
Simple graphics that are used in a unique way will also receive high scores here.
Audio: (10 %)
Student Choice: (10%) (max 90 points = 18 students x 5 points each)
I've tried to break completness out into the following sub items: Splash screen, main menu, Scoring, Game has a story, Game controls/play, multiple levels, game ends/menu cycle/quit, high score system.
I have this obscene spreadsheet created which will automatically calculate the winner based on judges input. Once I have the number (1-100) from the judges for each game and category I simply imput them and come up with a winner. I did this last year, but I put the numbers in as I went. I just hope it doesn't take forever to enter the data, but things have a way of working themselves out. I'll report again tomorrow with the winners.
Just as I finish writing this I may dump the spreadsheet and just ask for the judges first, second and third choices for the winner. Hmmm.
Monday, May 14, 2007
Game development class - huge finale
http://www.gamedev360.com/contest07/preview.html
I have about 10 people from five of six of the biggest game companies in the area coming to judge the final presentations. I offered the student with the best game a $100 EB giftcard. Last year they were focused on the gift card, this year I'm sure they are focused on the job so putting them together with people who are looking for talent seems like a win win for everyone. All sides are excited.
I went into the lab on Saturday to help students with last minute problems and I have to say this is one of the best group of students I have ever had. The quality of the work is phenominal. The screenshots on the contest preview are almost three weeks old and the games since then are looking very very polished. A couple of them are going to be standouts.
There was the funniest quote the other day in one of the extra lab sessions. About halfway through the class I stopped assigning homework and allowing the student's to work on their own projects. One of the student's said to me, "Man, when you stopped assigning homework this class got a lot harder!". That has to be one of my all time favorite teaching quotes. The pressure of the final presentation in front of industry seems to have really worked.
I'll try and post results of the contest on Wednesday. I've been spending every minute of my free time on this contest. What am I going to do with all that extra free time?
Wednesday, May 2, 2007
Torque Development Process
I'm betting you could do 99% of your game this way unless you really chose to do something that was out of scope for the actual engine. In that case you would either need to choose a different engine, or make a lot of mods to the C++. In any case, I do like the workflow in developing for Torque. Even those mods are pretty simple.
It is a little strange since I remember at first thinking it was crazy that I had to re-run the engine after every change. It just seemed to go against the grain of what I'm used to, but now that I think back on it, I do tend to re-run everything no matter what platform I'm developing for. Maybe it was just that I wasn't used to the engine actually doing the compile and expected a traditional environment of having to compile before running? In any case, it is a good system.
Tuesday, May 1, 2007
Torque Introductory Tutorial
Anyway, if you are going to use Torque, keep this tutorial handy.
The student's marketing materials are due tonight. Just a simple screen shot and 1 page of html. Just enough for me to get something out to the judges so they can get a preview of the games they will be judging.
Thursday, April 19, 2007
Apples To Apples - Fun Party Game
One of our favorites was a party game called Apples To Apples. It had just come out and is now available everywhere, but I'm sure not everyone has heard about it now? Very very simple to play and a lot of fun and laughes for a group of 4-10.
The basics, one person (let's say my friend Hank) plays a random green card face up. It says "annoying". Everyone else has to play a red card (face down) from their hand that they think Hank will choose for the word 'annoying'. You have a hand of 8 preprinted cards and the choice of card you play would probably be different depending on which person in the group is choosing. The cards in my hand might have things like. "Marilyn Monroe", "My Social Life", "Hockey", "Celine Dion", "Tornados", and "Strawberry Pie". After everyone has played a red card from their hand face down, Hank might end up with cards like: "Craying babies", "The NRA", "My Haircut", "A bar room brawl", and "Celine Dion". (you can see which card I chose. feel free to leave an angry comment. Even though I think the NRA is annoying that person doesn't know Hank is actually a gun lover). Hank turns them up one at a time and reads them out loud. After, he picks the one he think matches "annoying" the best. Now, if Hank thinks the way I think he should think, he'll choose "Celine Dion". If he does, I first give a Homer Simpson Whoooo Hooo, then I get to keep the green card. First one to some number of green cards (typically 4 or 5) wins. See, simple.
Many of the card combinations are hillarious and you'll have a great time with any group. A very fun game and did help build cohesion within our team.
Wednesday, April 18, 2007
Is Torque the best game engine for my project?
For commercial games Unreal is the king and owns about 90% of the market. It is in the $100-200k range to license so it is out of reach for anyone that isn't very very serious. I'm not completely sure on the pricing because it's something that isn't advertised. They price it on a case by case basis and we tried to get a license for Chapman University and that was the range we were given.
The next most popular engine for commercial games is a tie between Quake and Half Life. Both have similar licensing expenses, but rumor has it that the Half Life engine is very hard to understand. I don't know first hand. Of the three I think Unreal is probably the easiest to learn having spent some time with it. Torque has a very strong following, but is mostly seen as a hobbyist engine. That doesn't make it bad by any means, but that is the view. It is well supported and while there is a steep learning curve, it isn't any steeper than the other engines out there. There are a number of commercial games available on it and the company just released a next gen version of the renderer so it is still growing and doing well.
The next thing to keep in mind is the game itself and if the engine supports the type of interface you are designing. Each engine has different specialities and one engine may be best for one design and wrong for another. Torque is best at FPS or third person multiplayer games. There is also a 2D version of the engine which I would also highly recommend.
Torque Game Engine (3D) does not have a good physics engine. I think the others are better, but there are a lot of threads out there on the Torque forums that talk about integrating other physics libraries. The 2D version has a great physics library.