Game Development Community

Pseudo-code translation request (Warning: Long)

by Trace Kern · in Torque Game Builder · 06/24/2007 (8:52 pm) · 9 replies

Okay folks, I've been looking for a programmer to hire to help me learn my way around TorqueScript, but after a few weeks of just twiddling my thumbs, I realized I probably don't need to hire someone for that.
I was able to follow the old RTS tutorial on TDN fairly well, up till the point no longer worked in 1.5.

My problem isn't that I don't know how to code, it's just that I can't figure out exact syntax and functions needed for what I want to do. So I decided to just start writing out my logic flow and structure in pseudo-code and comment entries, post the script here, and see if the good folks on the forums are willing to help me translate the pseudo-code into actual code syntax.

Without further stalling for time:

Edit: Looks like I've got just a *bit* too much code for a single post. Gonna split things up.

// Entity Classes
new datablock (Entity){
   // Entity Class is placeholder for all in-game objects. Any code 
   // object not visible or 'behind the scenes' will be other than Entity.
}

new datablock (Scenery : Entity){
   // Scenery is any object which is visible, but cannot be selected 
   // or otherwise interacted with.
}

new datablock (Unit : Entity){
   // Unit Class is anything which is selectable
   // In addition, when selected units will display on a selections GUI panel
   // Units will commonly have an associated Actions GUI panel to display
   
   set isSelectable = True
}

new datablock (Building : Unit){
   // Buildings can be selected and interacted with, but do not move.
}

new datablock (Drone : Unit){
   // Drones are the main unit entities. They can be selected, and can move.
   
   set canMove = True
}

// Global Mouse Functions

// --------------------------------------------------------------------
// initMouse()
//
// Here we set the initial values that the mouse settings and functions
// will need
// --------------------------------------------------------------------
function initMouse()
{
   // create the selection container object
   new SimSet(unitSelections);
      
   // this is the limit of the objects you can select
   $selectionLimit = 20;

   // create the selection box object that will be stretched with our
   // selection box lines. This is the "rubber band" box which most
   // RTS systems use for selecting multiple units.
   // Call the createRubberBand function, passing a %name.
   call createRubberBand(RubberBand);
   
   // create the Rubber Band's four line objects that will be positioned
   // in drawBox()
   // Call the createRubberBand function, passing four %name fields, 
   // one for each side of the rubber band box.
   call createRubberBand(LeftLine);
   call createRubberBand(RightLine);
   call createRubberBand(TopLine);
   call createRubberBand(BottomLine);
   
   // create a border box container object, this will hold 
   new SimSet(unitBorderBoxes);
}


// --------------------------------------------------------------------
// createRubberBand()
//
// Here we create a static sprite that will be used as a line in the 
// selection box
// --------------------------------------------------------------------
function createRubberBand(%name)
{
   // store the object
   %obj = new t2dStaticSprite(%name) { scenegraph = $miningScene; };
   // set the object to enabled FALSE
   %obj.setEnabled(false);
   // set the image map for the border piece
   %obj.setImageMap(borderImageMap);
   // set the objects layer to the first
   %obj.setLayer(0);

   // return the object to be further manipulated
   return %obj;
}

#1
06/24/2007 (8:56 pm)
Wow. Sorry for the waaay long thread posts, but I couldn't think of another way to do this:

Part 2

// --------------------------------------------------------------------
// SceneWindow2D::onMouseDown()
//
// This function is triggered from the engine when the mouse is "down"
// --------------------------------------------------------------------
function SceneWindow2D::onMouseDown(%this, %modifier, %worldPos, %mouseClicks)
{
   //Check for existing Selection
   if $unitSelections > 0, then
   {
      //Check for Shift in %modifier
      if %modifier = "shift", then
      {
         // Call the addToSelection function and pass the object clicked
         call addToSelection(%obj);
      }, 
      
      else
      {
         // If shift was not pressed when onMouseDown was called, clear 
         // the current selections and prepare for a new selection set
         call clearSelections();
      }
   }
   then
   // If there is no existing selection when mouse is clicked
   // Check if mouse was clicked on a Unit object
   // If object clicked is Unit class, call that object's onSelected function
   if %this = Unit class
   {
      call %obj.onSelected();
   }
   else
   // store the position clicked for the corner position of
   // the selection box
   $rubberBand::corner = %worldPos;
}


// --------------------------------------------------------------------
// SceneWindow2D::onMouseDragged()
//
// This function is triggered from the engine when the mouse is dragged
// --------------------------------------------------------------------
function SceneWindow2D::onMouseDragged(%this, %modifier, %worldPos, %mouseClicks)
{  
   // Call the updateRubberBand to update the rubber band box as we drag
   call updateRubberBand(%worldPos);
   
   // as well as check if the mouse is on the border for camera panning and easing
   // (No idea how to do this, even in pseudo-code)
}


// --------------------------------------------------------------------
// SceneWindow2D::onMouseUp()
//
// This function is triggered from the engine when the mouse is "up"
// --------------------------------------------------------------------
function SceneWindow2D::onMouseUp(%this, %modifier, %worldPos, %mouseClicks)
{
   // get the selections passing the position the mouse was let up
   call getSelections(%worldPos);
   
   // lets disable our selection boxes
   call disableRubberBand();
}


// --------------------------------------------------------------------
// addToSelection()
//
// This function will add the selected unit to an existing selection
// --------------------------------------------------------------------
function addToSelection(%obj/%this?)
{
   // Add %this to end of current list in container $Selections
   // Call the add() function on the unitSelections simset
   // container, passing the object
   unitSelections.add(%obj);
   
   // Now call the object's onSelected function
   %obj.onSelected();
}


// --------------------------------------------------------------------
// clearSelections()
//
// This function clears all objects from the unitSelections container object
// --------------------------------------------------------------------
function clearSelections()
{
   // Clear the container unitSelections by calling the clear() function on it
   unitSelections.clear();
}

// --------------------------------------------------------------------
// onSelected()
//
// This function is called when one or more Units are selected through
// mouse click or mouse-drag actions. When called, this function
// performs several actions.
//
// First, a selection box object is overlayed over the unit on the
// gameplay area. This is a smaller version of the multi-part "Rubber Band"
// selection box. The box object should be scaled to be slightly larger
// than the unit's own bitmap.
//
// A GUI object is overlayed at the unit's position, offset upwards a
// little. This object is a simple health bar. In addition, a text object
// displays the unit's name/type.
//
// The Action panel is updated with the appropriate action buttons for
// this unit type. In the case of multiple selections, only the buttons
// applicable to all selected units will be active, though all possible
// buttons will still be displayed. Inactive action buttons will be
// visible, but 'greyed out'.
//
// A GUI object is added to the selection GUI panel. This new object is a
// bitmap button, used to display an image or text representing a single
// unit. When multiple units are selected, multiple buttons will be created
// in sequence.
// When clicked, any of these buttons will call the appropriate functions
// to re-select that single unit.
// --------------------------------------------------------------------
function onSelected(%this/%obj?)
{
   // Call the createBorderBox() function, passing %obj
   call createBorderBox(%obj);
   
   // Call the drawHealthBar() function
   call drawHealthBar();
   
   // Read the Unit's datablock to find the appropriate action buttons
   // (Not sure how to structure this yet)
   // Edit: I may want to move this step to another function, one which
   // can handle multiple selections instead of this one, which is only
   // called on a per-unit basis.
   
   // Call the updateActionPanel() function, passing the actions found
   // in previous step
   // Edit: I may want to move this step to another function, one which
   // can handle multiple selections instead of this one, which is only
   // called on a per-unit basis.
   call updateActionPanel(&arg*);
      
   // Call the updateSelectionPanel() function, passing the Unit's data
   // (Again, not sure about structure right here yet)
   call updateSelectionPanel(&arg*);
}
#2
06/24/2007 (8:57 pm)
// --------------------------------------------------------------------
// updateRubberBand()
//
// This function will update the rubber band to the position the mouse
// is dragging... this function will take the positions and order them
// correctly for the drawRubberBand() function so the box will draw in all
// quadrants
// 
// Note: This function is legacy code from the TGB RTS tutorial from TDN.
// This code has been copied here mostly unchanged, as such any
// optimizations or improvements are encouraged.
// --------------------------------------------------------------------
function updateRubberBand(%pos)
{
   // lets reset our selection box(s) first
   resetRubberBand();
   
   // first lets grab the clicked spot we stored in onMouseDown, then
   // store this position in %corner
   %corner = $rubberBand::corner; 
   
   // grab both positions for calculations, seperate the XY string into
   // component strings and store the data in new variables
   %posX = getWord(%pos, 0);
   %posY = getWord(%pos, 1);
   %cornerX = getWord(%corner, 0);
   %cornerY = getWord(%corner, 1);
   
   // we do some checks to make sure the selection box will draw correctly
   // These checks determine if the end corner X/Y value is lower than the
   // start value, if so we swap the values temporarily
   if(%posX < %cornerX)
   {
      %tempX = %posX;
      %posX = %cornerX;
      %cornerX = %tempX; 
   }
   
   if(%posY < %cornerY)
   {
      %tempY = %posY;
      %posY = %cornerY;
      %cornerY = %tempY; 
   }
   
   // piece the positions back together, without the previous step the box will 
   // only draw correctly in one quadrant
   // We take the component values, then toss them back together with a SPC seperator
   %pos = %posX SPC %posY;
   %corner = %cornerX SPC %cornerY;
   
   // time to do some vector calculations to determine the center spot between both points
   // The resulting values are placed into different variables
   %vecBetween = t2dVectorSub(%pos, %corner);
   
   // Following lines are legacy code from TGB RTS tutorial.
   // These may not be needed anymore, will have to check the rest of my code for any references
   %halfVec = t2dVectorScale(%vecBetween, 0.5);
   %finalVec = t2dVectorAdd(%halfVec, %corner);
   
   // call the drawBox command passing the new starting and ending corner position
   // While only %vecBetween is used in this function, the other two variables will be used elsewhere
   drawRubberBand(%corner, %pos, %vecBetween);
   
}


// --------------------------------------------------------------------
// getSelections()
//
// This function will grab all the units beind selected within the rubber band.
// --------------------------------------------------------------------
function getSelections()
{ 
   // grab a list of objects within the rectangle of the selection box
   // All objects within the scenegraph $miningScene, which fall within
   // the rectangle between the position from onMouseDown ($rubberBand::corner)
   // and current %pos, are then dumped into %objList.
   %objList = $miningScene.pickRect($rubberBand::corner, %pos);
   
   // now we get the count of objects within the object list
   %objCount = getWordCount(%objList);
   
   // clear the selections container object
   unitSelections.clear();
   
   // loop through the objects in the selection rectangle list
   for(%i=0;%i<%objCount;%i++)
   {
      // grab the looped object
      %obj = getWord(%objList, %i);
      
      // if the object isSelectable then we want to store it in the
      // Selections container object
      if(%obj.isSelectable)
      {
         unitSelections.add(%obj);
         
         // lets create a selected object border box
         // Edit: More legacy code. In this case we're replacing the 
         // call with a different call to the new onSelected() function.
         //createBorderBox(%obj);
         
         //Call the object's onSelected() function
         %obj.onSelected();
 
         // here we check to see if we have reached our selection limit
         if(Selections.getCount() >= $selectionLimit)
         {
            // if we have reached our limit then set %i to exit the loop
            %i = %objCount;
         } 
      }
   }
   
   // Edit: Not sure, but I *think* I'll be replacing both of these legacy
   // code functions. Instead of calling either of these, which were havily
   // based on the RTS tutorial's code, most of which is now broken in 1.5.
   // Hope this approach works. In case it breaks, I've kept the old code
   // commented out here.
   // 
   // if we have more than one selection we want to call the multiple 
   // selections function and if we only have one we want to call the
   // single selection function
   //if(Selections.getCount() > 1)
   //{
   //   multipleSelections(%pos);      
   //} else if(Selections.getCount() == 1)
   //{
   //   singleSelection(%pos);
   //}
}


// --------------------------------------------------------------------
// disableRubberBand()
//
// This function removes the rubber band from view during onMouseUp.
// This is done so the sprite won't get in the way when not needed.
// --------------------------------------------------------------------
function disableRubberBand()
{
   // to disable the boxes we set them to enabled false and set their size to 
   // "0 0" so they are not visible (just in case we re-enable them incorrectly)

   %obj = RubberBand;
   %obj.setEnabled(false);
   %obj.setSize("0 0");

   %obj = LeftLine;
   %obj.setEnabled(false);
   %obj.setSize("0 0"); 
   
   %obj = RightLine;
   %obj.setEnabled(false);
   %obj.setSize("0 0"); 
   
   %obj = TopLine;
   %obj.setEnabled(false);
   %obj.setSize("0 0"); 
   
   %obj = BottomLine;
   %obj.setEnabled(false);
   %obj.setSize("0 0");    
}
#3
06/24/2007 (8:57 pm)
// --------------------------------------------------------------------
// createBorderBox()
//
// This function is what will create and display a border sprite overlayed
// onto selected units. This should probably be re-written using the
// overlay object behavior, but for now I've kept the RTS legacy code
// since it still seems to get the job done.
// --------------------------------------------------------------------
function createBorderBox()
{
   // lets get the ammount of border boxes presently created
   %count = unitBorderBoxes.getCount();
   
   // compare the count to the selectionLimit we have already set in our initMouse() function
   if(%count > $selectionLimit)
   {
      // we already reached our limit of border boxes so we won't add any more
      return;
   }
   
   // create a new static sprite
   %box = new t2dStaticSprite() { scenegraph = $miningScene; };

   // set its image map to the border image
   %box.setImageMap(borderImageMap);

   // set its layer to the selected objects layer
   %box.setLayer(%obj.getLayer());
   
   // move it to the front of the layer
   $strategyScene.setLayerDrawOrder(%box, FRONT);
   
   //get the size numbers to set the border box 
   %size = %obj.getSize();
   %sizeX = getWord(%size, 0);
   %sizeY = getWord(%size, 1);
   
   // these are the values of how much taller and wider the selection box will be than
   // the selected object
   %taller = 0.25;
   %wider = 0.25;

   // mount the box to the selected object and size it slightly larger than it
   %box.mount(%obj);
   %box.setSize((%sizeX + %wider) SPC (%sizeY + %taller));
   
   // now we add this newly created border box to our SimSet for management
   unitBorderBoxes.add(%box);
}


// --------------------------------------------------------------------
// drawHealthBar()
//
// This is a function to create, scale, and position a small sprite to
// represent a health bar. This may be best implemented as a Behavior, but
// this function is here as a placeholder, just in case.
// In addition to the health bar sprite, a text object will be displayed
// showing the unit's name or other data such as unit type or special conditions.
// --------------------------------------------------------------------
function drawHealthBar()
{
   
}


// --------------------------------------------------------------------
// updateActionPanel()
//
// This function is a placeholder for when I have all the drone classes
// defined, and assigned actions to each datablock. The number, type,
// and placement of each button in the panel is fixed.
// Each button has three states: disabled, inactive, and active. Disabled
// mean the button will not be visible, this is for when the currently
// selected unit/s do not possess that action. Inactive will be used
// during multiple selections, for when not all selected units share that
// action. Active is when all selected units share that action.
// --------------------------------------------------------------------
function updateActionPanel()
{
   
}


// --------------------------------------------------------------------
// updateSelectionPanel()
//
// This function is another placeholder. When finished this function
// will handle the unit selections panel. The panel itself will be
// divided into cells, within which a single unit GUI element can be
// displayed. Unit GUIs can be simple buttons, buttons with text, or
// images for that unit type.
// All cells should be able to display the image (if any), and a scaled
// health bar for that unit. Each cell acts as a button, which when
// clicked clears the selection, and re-selectes that single unit.
// Right clicking on a unit cell will focus the camera on that unit.
// The panel will have "scroll" buttons, allowing the player to select
// more units than the number of cells. Each scroll button will "page"
// through current selections.
// --------------------------------------------------------------------
function updateSelectionPanel()
{
   
}


// --------------------------------------------------------------------
// drawRubberBand()
//
// This function will draw the correct rubber band box when passed
// the proper positions... the positions are ordered in updateRubberBand()
// and passed to this function
// 
// Edit: Yet more legacy code functions. But as before, this code works,
// so I'm using it unless shown a better method.
// --------------------------------------------------------------------
function drawRubberBand()
{
   // we grab the x and y positions to get the width and height
   %x = getWord(%vecBetween, 0);
   %y = getWord(%vecBetween, 1);
   
   // divide up the starting corner position
   %cornerX = getWord(%corner, 0);
   %cornerY = getWord(%corner, 1);

   // divide up the ending corner position
   %posX = getWord(%pos, 0);
   %posY = getWord(%pos, 1);
   
   // specify a line thickness
   %lineThickness = "0.5";
   
   // left line
   // assign a box line object and set its size appropriately
   %obj = LeftLine;
   %obj.setSize(%lineThickness SPC %y);
   
   // calculate the center position needing to be set
   %leftY = %cornerY + (%y/2);
   %leftX = %cornerX + %lineThickness/2;
   
   // set the left line box position
   %obj.setPosition(%leftX SPC %leftY);
   
   // right line
   // assign a box line object and set its size appropriately
   %obj = RightLine;
   %obj.setSize(%lineThickness SPC %y);

   // calculate the center position needing to be set
   %rightY = %cornerY + (%y/2);
   %rightX = %cornerX + %x + %lineThickness/2;

   // set the right line box position
   %obj.setPosition(%rightX SPC %rightY); 
   
   // top line
   // assign a box line object and set its size appropriately
   %obj = TopLine;
   %obj.setSize(%x + %lineThickness SPC %lineThickness);

   // calculate the center position needing to be set
   %topX = %cornerX + (%x/2) + (%lineThickness/2);
   %topY = %cornerY + %lineThickness/2;

   // set the top line box position
   %obj.setPosition(%topX SPC %topY);  

   // bottom line
   // assign a box line object and set its size appropriately
   %obj = BottomLine;
   %obj.setSize(%x + %lineThickness SPC %lineThickness);

   // calculate the center position needing to be set
   %bottomX = %cornerX + (%x/2) + (%lineThickness/2);
   %bottomY = %cornerY + %y + %lineThickness/2;

   // set the bottom line box position
   %obj.setPosition(%bottomX SPC %bottomY); 
}


// --------------------------------------------------------------------
// resetRubberBand()
//
// This will reset the four objects that make up the lines of the
// selection box
// --------------------------------------------------------------------
function resetRubberBand()
{  
   // this is for the left line of the selection box border
   %obj = LeftLine;
   %obj.setPosition("0 0");
   %obj.setSize("0 0");
   %obj.setEnabled(true); 
   // this is for the right line of the selection box border
   %obj = RightLine;
   %obj.setPosition("0 0");
   %obj.setSize("0 0");
   %obj.setEnabled(true); 
   // this is for the top line of the selection box border
   %obj = TopLine;
   %obj.setPosition("0 0");
   %obj.setSize("0 0");
   %obj.setEnabled(true); 
   // this is for the bottom line of the selection box border
   %obj = BottomLine;
   %obj.setPosition("0 0");
   %obj.setSize("0 0");
   %obj.setEnabled(true); 
}
#4
06/25/2007 (8:11 am)
This might be better done posting a link to the section on the RTS tutorial and maybe I'll get some time to update it to the latest version (most TorqueScript functions have not changed even in 1 1/2 years, so probably some simple changes)...

though here's some additional info

dhere are some TorqueScript syntax notes:


call clearSelections();

can be done with

clearSelections();


if %modifier = "shift", then
      {

can be done with (note $= is for a "string" compare, == is for numerical compare), a modifier of 1 is "Left Shift" and 2 is "Right Shift".

if((%modifier == 1) || (%modifier == 2))
      {
#5
06/25/2007 (11:35 am)
Hey Matt, thanks for the reply. Here's the RTS tutorial in question. Note that there are no internal links from one 'chapter' to the next, so I linked to a page with the chapter list.
When using this tutorial with 1.5 the code seems to break down in chapter 4 (Setting up a Unit Creation System and Moving New Units). Primarily of concern is that none of the code dealing with dynamic (read: script-created) GUI elements seems to work.
The health bar, dynamic buttons on the unit panel, and other GUI objects never appear in game. I've chased these problems down, and it seems that the 1.5 GUI editor has changed alot of object classes around (used the term classes cause dunno what else to use).
tdn.garagegames.com/wiki/TGB/ScriptGenreTutorials

As for the "call " all over the code, that was an oversight. I knew about that syntax, but had put the Call in the initial pseudo-code as a reminder to myself. I've updated my code to remove those Call X, to just X.

Ahhh, are the %modifier values documented anywhere? I couldn't find out how that variable was valued.
So, that if statement would read:
If %modifier equals 1 OR 2, then
Correct?

If that's the case, i'll update that segment right away.

Just to let you know, I was using the RTS tutorial to learn becuase my project is closest in function and control to an RTS system, but my game won't have much of the same functionality of your traditional RTS.
For all the above code blocks, I'm trying to implement an RTS-style mouse selection system.

Once I have that working, I'll be trying to move on to RTS movement. Combat and creation won't be part of my project, but I may implement them just to keep learning...

Oh well, either way thanks for the assistance Matt!
#6
06/25/2007 (12:53 pm)
As for the modifier values, I got them out of Input Interaction under "References" in the TGB docs included with the engine.
#7
06/25/2007 (12:54 pm)
Quote:If %modifier equals 1 OR 2, then

correct :)
#8
06/25/2007 (12:55 pm)
Could you post your console.log after trying the failing GUI code... that should give me an idea what is causing the problem as well as the info you've already given.
#9
06/25/2007 (10:26 pm)
Matt: I'll need to run through that chapter and follow along in my code again. I ended up commenting out a lot of the non-functional GUI stuff.
Soon as I know everything's the same as the tutorial I'll do a test run and post up the console log. Probably later tonight.

Thanks again for the help.

Edit:
Okay Matt, just checked and made sure that all my scripts were back to the last working point. Unfortunately I can't remember exactly where I was at in Chapter 4 of the tutorial before I stopped. Throughout that chapter some things would work and some wouldn't, and while I was working I tried to experiment to get things working.

Here's part of the console log where I got errors, this was just on startup:

Torque Game Builder (v1.5 Beta 3) initialized...
Activating DirectInput...
t2dStaticSprite::setFrame() - Cannot set Frame without existing t2dImageMapDatablock Datablock!
Error, cannot unlink namespace parent linkage for Base for t2dSceneObjectDatablock.
Error: cannot change namespace parent linkage for Base from t2dSceneObjectDatablock to t2dStaticSprite.
t2dStaticSprite::setFrame() - Cannot set Frame without existing t2dImageMapDatablock Datablock!
Error, cannot unlink namespace parent linkage for Base for t2dSceneObjectDatablock.
Error: cannot change namespace parent linkage for Base from t2dSceneObjectDatablock to t2dStaticSprite.
t2dStaticSprite::setFrame() - Cannot set Frame without existing t2dImageMapDatablock Datablock!
Error, cannot unlink namespace parent linkage for Soldier for t2dSceneObjectDatablock.
Error, cannot unlink namespace parent linkage for Soldier for t2dSceneObjectDatablock.
Error: cannot change namespace parent linkage for Entity from t2dSceneObjectDatablock to t2dStaticSprite.
Error: cannot change namespace parent linkage for Soldier from t2dSceneObjectDatablock to t2dStaticSprite.
t2dStaticSprite::setFrame() - Cannot set Frame without existing t2dImageMapDatablock Datablock!
Error, cannot unlink namespace parent linkage for Worker for t2dSceneObjectDatablock.
Error, cannot unlink namespace parent linkage for Worker for t2dSceneObjectDatablock.
Error: cannot change namespace parent linkage for Entity from t2dSceneObjectDatablock to t2dStaticSprite.
Error: cannot change namespace parent linkage for Worker from t2dSceneObjectDatablock to t2dStaticSprite.
t2dStaticSprite::setFrame() - Cannot set Frame without existing t2dImageMapDatablock Datablock!
Error, cannot unlink namespace parent linkage for Soldier for t2dSceneObjectDatablock.
Error, cannot unlink namespace parent linkage for Soldier for t2dSceneObjectDatablock.
Error: cannot change namespace parent linkage for Entity from t2dSceneObjectDatablock to t2dStaticSprite.
Error: cannot change namespace parent linkage for Soldier from t2dSceneObjectDatablock to t2dStaticSprite.
t2dStaticSprite::setFrame() - Cannot set Frame without existing t2dImageMapDatablock Datablock!
Error, cannot unlink namespace parent linkage for Worker for t2dSceneObjectDatablock.
Error, cannot unlink namespace parent linkage for Worker for t2dSceneObjectDatablock.
Error: cannot change namespace parent linkage for Entity from t2dSceneObjectDatablock to t2dStaticSprite.
Error: cannot change namespace parent linkage for Worker from t2dSceneObjectDatablock to t2dStaticSprite.
It's on!

Honestly, I'm not sure how helpful this will be, might be more revealing to try and walk through the tutorial again and find out the first part where things fail in 1.5.
I can try and do that later tonight or tomorrow at work.