Help with Tycoon Style Game
by Night Fox · in Torque Game Builder · 12/29/2008 (8:56 am) · 53 replies
Like the title says I've been assigned to do a Tycoon style game.
I've chosen TGB to design it and have the basic art necessary to make it works.
Heres the concept.
A player is given time and 4 team members to create a final product for a client.
The player may put team members into 3 different buildings, or place them all into one single building, each building offers a special function.
Reserch Building - When a member is placed here they earn RP. The more members placed here the more RP is accrued.
RP is neccesary to unlock the Development Building, and to Remove Troubleshooting Points or TP for short.
1 RP is earned for every Second (For now)
Development Building - Members placed here spend RP to earn DP. Once Dp = 100 points the product is complete and the player wins.
Let us say it cost 100 RP to unlock the doors to the Dev Building, then it cost 2 RP to gain 1 DP.
Now Development alwasy has kinks so I thought up Trouble Shooting Points or TP.
Troubleshoot Building - Members placed here spend RP to remove TP. When TP appears Development is halted until TP is removed. To keep it simple, it cost 2 RP to remove 1 TP. Once TP is fully removed Development points can be acquired again.
TP points are random ranging from 10 to 100. For now it can happen only once, later I'd like to have it happen at random intervals, maybe after Dev Points are being earned the game will see if trouble happens on a 1 minute basis.
So thats the gist of the game I've concepted and need to finish, I've got about a month to do it and would really appreciate any help possible!
I've chosen TGB to design it and have the basic art necessary to make it works.
Heres the concept.
A player is given time and 4 team members to create a final product for a client.
The player may put team members into 3 different buildings, or place them all into one single building, each building offers a special function.
Reserch Building - When a member is placed here they earn RP. The more members placed here the more RP is accrued.
RP is neccesary to unlock the Development Building, and to Remove Troubleshooting Points or TP for short.
1 RP is earned for every Second (For now)
Development Building - Members placed here spend RP to earn DP. Once Dp = 100 points the product is complete and the player wins.
Let us say it cost 100 RP to unlock the doors to the Dev Building, then it cost 2 RP to gain 1 DP.
Now Development alwasy has kinks so I thought up Trouble Shooting Points or TP.
Troubleshoot Building - Members placed here spend RP to remove TP. When TP appears Development is halted until TP is removed. To keep it simple, it cost 2 RP to remove 1 TP. Once TP is fully removed Development points can be acquired again.
TP points are random ranging from 10 to 100. For now it can happen only once, later I'd like to have it happen at random intervals, maybe after Dev Points are being earned the game will see if trouble happens on a 1 minute basis.
So thats the gist of the game I've concepted and need to finish, I've got about a month to do it and would really appreciate any help possible!
About the author
#42
Ahh that is exactly what was needed, thanks for the help!!!
Now all I need to do is have tpoints added in at a random time.
Currently I'm using the countdown till damage behaviour
so I'm thinking
Where N is a random interger selected by the game between the numbers 5 to 75
How would I have the game pull a random number for this particular function?
Also for those who might be reading this I did change the code for the troubleshooting schedule.
The above change not only makes it possible to stop tpoints after it hits 0 but it also allows the reserach points to continue to count up just in case the player forgets to pull his team members out of the troubleshooting department!
01/07/2009 (1:05 pm)
Woot! Its working!!!Ahh that is exactly what was needed, thanks for the help!!!
Now all I need to do is have tpoints added in at a random time.
Currently I'm using the countdown till damage behaviour
so I'm thinking
if (DevPoints.getvalue == N)
{
tpoints.setvalue(100);
}Where N is a random interger selected by the game between the numbers 5 to 75
How would I have the game pull a random number for this particular function?
Also for those who might be reading this I did change the code for the troubleshooting schedule.
From this
function t2dSceneGraph::updateScoreboardTimer3A(%this)
{
if(TroubleA.Visible == true)
{
// reschedule this function for 1 second
%this.timerSchedule = %this.schedule(1000, updateScoreboardTimer3A);
}
else
{
// increment scoreboard time field
researchPoints.setValue(researchPoints.getValue() - 2);
tPoints.setValue(tPoints.getValue() - 1);
if(tPoints.getValue() <= 0)
{
tPoints.setValue(0);
}
if(researchPoints.getValue() <= 0)
{
researchPoints.setValue(0);
}
// reschedule this function for 1 second
%this.timerSchedule = %this.schedule(1000, updateScoreboardTimer3A);
}
}
to this
function t2dSceneGraph::updateScoreboardTimer3A(%this)
{
if(TroubleToggledA.Visible == true && researchPoints.getValue() >=4)
{
// increment scoreboard time field
tPoints.setValue(tPoints.getValue() - 1);
if(tPoints.getValue() <= 0)
{
tPoints.setValue(0);
researchPoints.setValue(researchPoints.getValue() + 0);
}
else
{
researchPoints.setValue(researchPoints.getValue() - 3);
}
if(researchPoints.getValue() <= 0)
{
researchPoints.setValue(0);
}
// reschedule this function for 1 second
%this.timerSchedule = %this.schedule(1000, updateScoreboardTimer3A);
}
else
{
%this.timerSchedule = %this.schedule(1000, updateScoreboardTimer3A);
}
}The above change not only makes it possible to stop tpoints after it hits 0 but it also allows the reserach points to continue to count up just in case the player forgets to pull his team members out of the troubleshooting department!
#43
01/07/2009 (1:16 pm)
Quote:Couldn't be more simple really...
How would I have the game pull a random number for this particular function?
%N = getRandom(5,75);
#44
It works when embedded inside of the updatescoreboardtime but keeps updating the number making it impossible to win.
When put in the function startgame it doesn't seem to get called.
Will I need to create a new function for this, because leaving it stand alone doesn't seem to activate it either!
01/08/2009 (8:51 am)
Alright currently the code is sitting by itself like so%N = getRandom(5,75);
if(devPoints.getValue() >= %N)
{
tPoints.setValue("100");
}It works when embedded inside of the updatescoreboardtime but keeps updating the number making it impossible to win.
When put in the function startgame it doesn't seem to get called.
Will I need to create a new function for this, because leaving it stand alone doesn't seem to activate it either!
#45
Again, not the best way, but the easy route here is to instantiate your %N in the startGame() function as a global variable ($N), then it will be accessible anywhere in your code.
'Patrick
01/08/2009 (9:03 am)
Quote:It works when embedded inside of the updatescoreboardtime but keeps updating the number making it impossible to win.That's because it keeps getting called, thus keeps generating a random number.
Quote:When put in the function startgame it doesn't seem to get called.This is a scope issue. If you create a local variable (%N) it is only valid withing the block of code in which it was created. Basically, within the curly braces that it was created in:
function exampleFunction()
{
%exampleVariable = 666;
echo(%exampleVariable);
}
function exampleFunction2()
{
echo(%exampleVariable);
}The first function will echo 666, but the second function would echo null.Again, not the best way, but the easy route here is to instantiate your %N in the startGame() function as a global variable ($N), then it will be accessible anywhere in your code.
'Patrick
#46
I'm going to try and make a function then I'll use a stop(); command to keep it from calling upon the function again after tPoints = 100. that way I won't need to add a global to startGame. Hopefully this should work then!
what I'm thinking is something like this
01/08/2009 (9:28 am)
Hmm I see.I'm going to try and make a function then I'll use a stop(); command to keep it from calling upon the function again after tPoints = 100. that way I won't need to add a global to startGame. Hopefully this should work then!
what I'm thinking is something like this
function t2dSceneGraph::tpointsAdd(%this)
{
%N = getRandom(5,10);
if(devPoints.getValue() >= %N)
{
tPoints.setValue("100");
}
if (tPoints.getValue() == 100)
{
stop();
}
}I just need to figure out what the stop(); or quit command is
#47
Note: This may not be that important if it's only called periodically, but if you call it on every frame, it could make the difference between bogging down your game and it running smoothly.
01/08/2009 (9:55 am)
function t2dSceneGraph::tpointsAdd(%this)
{
%N = getRandom(5,10);
if(devPoints.getValue() >= %N)
{
tPoints.setValue("100");
}
if (tPoints.getValue() == 100)
{
stop();
}
}...is the same thing as...function t2dSceneGraph::tpointsAdd(%this)
{
%N = getRandom(5,10);
if(devPoints.getValue() >= %N)
{
tPoints.setValue("100");
stop();
}
}...since you set tPoints to "100" the next statement will always evaluate to true, so you might as well save yourself the cycles and put it in the same if statement. Note: This may not be that important if it's only called periodically, but if you call it on every frame, it could make the difference between bogging down your game and it running smoothly.
#48
So currently I'm running the function you shown above and I've been trying to figure out why the stop(); function that seems to work on other programs, won't work here.
If anything this is more or less the final part of the code that needs to be done so that the basic demo of the game is completed. Then I can expand upon the GUI Main menu System.
I've tried the global jsut to be sure and it still got no results, so far this has become rather frustrating as the last piece of code that I need to stare at (who am I kidding it won't be the last!)
01/08/2009 (12:42 pm)
Hmmm I want to avoid using the Globals if for anything as a practive to not rely on them, since they can cause problems in the future.So currently I'm running the function you shown above and I've been trying to figure out why the stop(); function that seems to work on other programs, won't work here.
If anything this is more or less the final part of the code that needs to be done so that the basic demo of the game is completed. Then I can expand upon the GUI Main menu System.
I've tried the global jsut to be sure and it still got no results, so far this has become rather frustrating as the last piece of code that I need to stare at (who am I kidding it won't be the last!)
#49
The problem with global variables is that they can easily be mistaken for a local variable and attempting to access one as such gives unexpected results. Torquescript overcomes this somewhat by forcing the user to use a $ in front of global variables, still it's not a good thing.
A better reason (and there are more reasons, but you're going to have to google those yourself) is that you can have two different parts of your code accessing the same global variable and it can introduce unpredictable results due to one part affecting the variable in a way that is unexpected in the other part. This is called "Action at a Distance" and you can read all about it here.
So, thanks professor... What's the solution? Namespaces. You're already using them in your code you grabbed from the timer/score tutorial. They look like this:
Namespaces can be very confusing so I suggest you do some homework on this, but in a nutshell...
They are imaginary containers that you can create to hold data that is associated with an object, such as an image, button, animation, etc...
Let's use your example above as an example:
First, you'd want to assign tPoints a class. Easiest way is in the scripting rollout in TGB, let's use PointsClass. Now you can use a namespace...
Now, in Torsion, do a global search for "PointsClass". It should show a result in untitled.t2d (or whatever you named your level). Between the curly braces {} for the object, add a field called "tPoints" and set it equal to it's initial value. (We could get into datablocks here, but we're not...) You should have something like this now:
Now, what you want to do is create the namespace functions that allow you get/set the tPoints field you created above.
Now, wash, rinse, repeat for each of your global variables...
Well, that was semi-exhausting and I'm sure there are a flock of great programmers out there huddled around this post, pointing and laughing, but I hope it helps you out. (As if anyone would read this whole thread...)
Long and short, stick with the globals until you have the bugs worked out, then convert back, or next time start with the namespace approach.
'Patrick
01/08/2009 (1:50 pm)
I would try to figure out why it's not working with the global variable, then once you have a working solution, go back and get rid of those global variables. The problem with global variables is that they can easily be mistaken for a local variable and attempting to access one as such gives unexpected results. Torquescript overcomes this somewhat by forcing the user to use a $ in front of global variables, still it's not a good thing.
A better reason (and there are more reasons, but you're going to have to google those yourself) is that you can have two different parts of your code accessing the same global variable and it can introduce unpredictable results due to one part affecting the variable in a way that is unexpected in the other part. This is called "Action at a Distance" and you can read all about it here.
So, thanks professor... What's the solution? Namespaces. You're already using them in your code you grabbed from the timer/score tutorial. They look like this:
function t2dSceneGraph::tpointsAdd(%this)
{
%N = getRandom(5,10);
if(devPoints.getValue() >= %N)
{
tPoints.setValue("100");
}
if (tPoints.getValue() == 100)
{
stop();
}
}Namespaces can be very confusing so I suggest you do some homework on this, but in a nutshell...
They are imaginary containers that you can create to hold data that is associated with an object, such as an image, button, animation, etc...
Let's use your example above as an example:
First, you'd want to assign tPoints a class. Easiest way is in the scripting rollout in TGB, let's use PointsClass. Now you can use a namespace...
Now, in Torsion, do a global search for "PointsClass". It should show a result in untitled.t2d (or whatever you named your level). Between the curly braces {} for the object, add a field called "tPoints" and set it equal to it's initial value. (We could get into datablocks here, but we're not...) You should have something like this now:
new t2dSceneObject()
{
Name = "tPoints"
Position = "20.3423 15.232"
tPoints = 0;
...
}Now, what you want to do is create the namespace functions that allow you get/set the tPoints field you created above.
function PointsClass::setTpoints(%this, %newValue)
{
%this.tPoints = %newValue;
}
function PointsClass::getTpoints(%this)
{
return %this.tPoints;
}Now, wash, rinse, repeat for each of your global variables...
Well, that was semi-exhausting and I'm sure there are a flock of great programmers out there huddled around this post, pointing and laughing, but I hope it helps you out. (As if anyone would read this whole thread...)
Long and short, stick with the globals until you have the bugs worked out, then convert back, or next time start with the namespace approach.
'Patrick
#50
I'll start with the above functions and work my way through globals to see where I can pinpoint the error and get it working!
01/09/2009 (5:55 am)
Alright I'm going to start hammering the nails till I got back on track!I'll start with the above functions and work my way through globals to see where I can pinpoint the error and get it working!
#51
01/09/2009 (7:37 am)
Have fun!
#52
I know that this function could definetly be shortened, and I think I know how to do that, but right now I'm just excited that its working!!!
01/09/2009 (10:21 am)
WOOO! So with the below code I was able to get the main functions of the game back on track!$tpoints = true;
function t2dSceneGraph::tpointsAdd(%this)
{
%this.timerSchedule = %this.schedule(1000, tpointsAdd);
%N = getRandom(5,10);
if(tPoints.getValue() != 100 && $tpoints == true)
{
if(devPoints.getValue() >= %N)
{
tPoints.setValue("100");
$tpoints = false;
}
}
}I know that this function could definetly be shortened, and I think I know how to do that, but right now I'm just excited that its working!!!
#53
Glad you're on track, it's fun watching it come along!
01/09/2009 (10:39 am)
I don't think it would matter too much performance wise, it's the same as the following since there is no else statement being evaluated:$tpoints = true;
function t2dSceneGraph::tpointsAdd(%this)
{
%this.timerSchedule = %this.schedule(1000, tpointsAdd);
%N = getRandom(5,10);
if(tPoints.getValue() != 100 && $tpoints == true && devPoints.getValue() >= %N)
{
tPoints.setValue("100");
$tpoints = false;
}
}Glad you're on track, it's fun watching it come along!
Torque Owner Night Fox