How To Determine A Ship's Score?
- Aeonic
- Militia Commander
- Posts: 469
- Joined: Sun Jun 14, 2009 1:05 am
- Location: Designing his dream ship.
Does anyone have any methods for determining what a custom ship's score should be?
Last Cause Of Death: Destroyed by Karl Svalbard's last Lucifer missile, right after I blew him up. And the crowd cheers.


-
- Developer
- Posts: 2998
- Joined: Thu Jul 24, 2003 9:53 pm
- Contact:
Run TransData:
transdata /shiptable /score
transdata /shiptable /score
-
- Developer
- Posts: 2998
- Joined: Thu Jul 24, 2003 9:53 pm
- Contact:
It's not a very sophisticated algorithm, and it could certainly use some help:Atarlost wrote:What does transdata use to compute scores?
Code: Select all
int CShipClass::ComputeScore (const CDeviceDescList &Devices,
int iArmorLevel,
int iPrimaryWeapon,
int iSpeed,
int iThrust,
int iManeuver,
bool bPrimaryIsLauncher)
// ComputeScore
//
// Compute the score of the class based on equipment
{
int i;
int iSpecial = 0;
int iExceptional = 0;
int iDrawback = 0;
int iStdLevel = iArmorLevel;
int iWeaponLevel = (iPrimaryWeapon == -1 ? 0 : ComputeDeviceLevel(Devices.GetDeviceDesc(iPrimaryWeapon)));
// If our weapon is better than our armor then adjust the level
// depending on the difference.
if (iWeaponLevel > iArmorLevel)
{
switch (iWeaponLevel - iArmorLevel)
{
case 1:
iStdLevel = iWeaponLevel;
iDrawback++;
break;
case 3:
iStdLevel = iWeaponLevel - 2;
iSpecial += 2;
break;
default:
iStdLevel = (iWeaponLevel + iArmorLevel) / 2;
}
}
// If our best weapon is 2 or more levels below our standard
// level then take drawbacks exponentially.
if (iStdLevel > iWeaponLevel + 1)
iDrawback += min(16, (1 << (iStdLevel - (iWeaponLevel + 2))));
else if (iStdLevel > iWeaponLevel)
iDrawback++;
// If all movement stats are high then this counts as an
// exceptional ability
if (iSpeed == enumHigh && iThrust == enumHigh && iManeuver == enumHigh)
iExceptional++;
// Otherwise, treat them as special abilities or drawbacks
else
{
if (iSpeed == enumLow)
iDrawback++;
else if (iSpeed == enumHigh)
iSpecial++;
if (iThrust == enumLow)
iDrawback++;
else if (iThrust == enumHigh)
iSpecial++;
if (iManeuver == enumLow)
iDrawback++;
else if (iManeuver == enumHigh)
iSpecial++;
}
// 1 armor segment is a drawback
int iArmorSections = GetHullSectionCount();
if (iArmorSections <= 1)
iDrawback++;
// 2-3 armor segments is normal
else if (iArmorSections < 4)
;
// 4 or more armor segments is special
else if (iArmorSections < 8 )
iSpecial++;
else if (iArmorSections < 16)
iSpecial += 2;
else if (iArmorSections < 32)
iSpecial += 3;
else if (iArmorSections < 64)
iSpecial += 4;
else
iSpecial += 5;
// Checkout all the devices
bool bDirectionalBonus = false;
bool bGoodSecondary = false;
int iDirectionalBonus = 0;
for (i = 0; i < Devices.GetCount(); i++)
{
const SDeviceDesc &Dev = Devices.GetDeviceDesc(i);
CDeviceClass *pDevice = Dev.Item.GetType()->GetDeviceClass();
int iDeviceLevel = ComputeDeviceLevel(Dev);
// Specific devices
switch (pDevice->GetCategory())
{
case itemcatWeapon:
case itemcatLauncher:
{
int iWeaponAdj = (iDeviceLevel - iStdLevel);
// If this is a secondary weapon, then add it to the score
if (i != iPrimaryWeapon)
{
// Calculate any potential bonus based on the weapon level
// compared to the base level
iSpecial += max(iWeaponAdj + 3, 0);
}
// Compute fire arc
int iFireArc = (Dev.bOmnidirectional ? 360 : AngleRange(Dev.iMinFireArc, Dev.iMaxFireArc));
// Adjust for turret-mount
iDirectionalBonus += (max(iWeaponAdj + 3, 0) * iFireArc);
break;
}
case itemcatReactor:
// Reactors don't count as improvements
break;
default:
{
// Other devices are special abilities depending on level
if (iDeviceLevel > iStdLevel+1)
iExceptional++;
else if (iDeviceLevel > iStdLevel)
iSpecial += 4;
else if (iDeviceLevel >= iStdLevel-1)
iSpecial += 2;
else
iSpecial++;
}
}
}
// If we have no weapons then we have some drawbacks
if (iPrimaryWeapon == -1)
iDrawback += 3;
// Add bonus if weapon is omnidirectional
iSpecial += (int)((iDirectionalBonus / 270.0) + 0.5);
// Checkout AI settings
const SAISettings &AI = GetAISettings();
int iFireAccuracyScore, iFireRateScore;
if (AI.iFireAccuracy > 97)
iFireAccuracyScore = 5;
else if (AI.iFireAccuracy >= 93)
iFireAccuracyScore = 4;
else if (AI.iFireAccuracy >= 90)
iFireAccuracyScore = 3;
else if (AI.iFireAccuracy < 75)
iFireAccuracyScore = 1;
else
iFireAccuracyScore = 2;
if (AI.iFireRateAdj <= 10)
iFireRateScore = 5;
else if (AI.iFireRateAdj <= 20)
iFireRateScore = 4;
else if (AI.iFireRateAdj <= 30)
iFireRateScore = 3;
else if (AI.iFireRateAdj >= 60)
iFireRateScore = 1;
else
iFireRateScore = 2;
int iFireControlScore = iFireRateScore * iFireAccuracyScore;
if (iFireControlScore >= 20)
iExceptional++;
else if (iFireControlScore > 6)
iSpecial += ((iFireControlScore - 5) / 2);
else if (iFireControlScore < 2)
iDrawback += 4;
else if (iFireControlScore < 4)
iDrawback += 2;
// Compute final score
ScoreDesc *pBase = &g_XP[iStdLevel-1];
int iScore = pBase->iBaseXP
+ iSpecial * pBase->iSpecialXP
+ iExceptional * pBase->iExceptionalXP
+ iDrawback * pBase->iDrawbackXP;
return iScore;
}
-
- Developer
- Posts: 2998
- Joined: Thu Jul 24, 2003 9:53 pm
- Contact:
And here is the score table:
Code: Select all
static ScoreDesc g_XP[] =
{
// Base Score
// Special Ability
// Exceptional Ability
// Drawback
// Level Score
{ 20, 5, 20, 0, 50 }, // I
{ 50, 10, 50, -5, 100 }, // II
{ 115, 15, 100, -10, 200 }, // III
{ 200, 20, 170, -20, 350 }, // IV
{ 340, 30, 260, -35, 600 }, // V
{ 500, 45, 370, -50, 900 }, // VI
{ 750, 60, 500, -65, 1400 }, // VII
{ 1050, 80, 650, -85, 1900 }, // VIII
{ 1450, 100, 820, -105, 2600 }, // IX
{ 1900, 125, 1010, -130, 3250 }, // X
{ 2400, 150, 1220, -155, 4200 }, // XI
{ 3000, 180, 1450, -185, 5500 }, // XII
{ 3600, 210, 1700, -215, 6750 }, // XIII
{ 4250, 245, 1970, -250, 8250 }, // XIV
{ 5000, 280, 2260, -285, 10000 }, // XV
{ 6000, 320, 2570, -325, 11500 }, // XVI
{ 7000, 360, 2900, -365, 13250 }, // XVII
{ 8000, 405, 3250, -410, 15000 }, // XVIII
{ 9000, 450, 3620, -455, 16750 }, // XIX
{ 10000, 500, 4010, -505, 18500 }, // XX
{ 11000, 550, 4420, -555, 20500 }, // XXI
{ 12000, 605, 4850, -610, 22500 }, // XXII
{ 13000, 660, 5300, -665, 25000 }, // XXIII
{ 14000, 720, 5770, -725, 26500 }, // XXIV
{ 15000, 780, 6260, -785, 30000 }, // XXV
};
- Aury
- Fleet Admiral
- Posts: 5528
- Joined: Tue Feb 05, 2008 1:10 am
- Location: At the VSS Shipyards in the frontier, designing new ships.
Thanks george!
I'll need to put this on the wiki later...
I'll need to put this on the wiki later...
(shpOrder gPlayership 'barrelRoll)
<New tutorials, modding resources, and official extension stuff coming to this space soon!>
<New tutorials, modding resources, and official extension stuff coming to this space soon!>
- Aeonic
- Militia Commander
- Posts: 469
- Joined: Sun Jun 14, 2009 1:05 am
- Location: Designing his dream ship.
Slapping that into a batch file and running it causes a crash, so I'm assuming I need to replace those arguments with something else? But I'm not sure what.george moromisato wrote:Run TransData:
transdata /shiptable /score
Last Cause Of Death: Destroyed by Karl Svalbard's last Lucifer missile, right after I blew him up. And the crowd cheers.


-
- Developer
- Posts: 2998
- Joined: Thu Jul 24, 2003 9:53 pm
- Contact:
Try downloading TransData 1.7:Aeonic wrote:Slapping that into a batch file and running it causes a crash, so I'm assuming I need to replace those arguments with something else? But I'm not sure what.george moromisato wrote:Run TransData:
transdata /shiptable /score
http://www.neurohack.com/downloads/TransData17.zip
Perhaps the old version (1.6) is not compatible with RC2
- Aeonic
- Militia Commander
- Posts: 469
- Joined: Sun Jun 14, 2009 1:05 am
- Location: Designing his dream ship.
Okay that works.
So what's the difference between the score and the score in parenthesis?
So what's the difference between the score and the score in parenthesis?
Last Cause Of Death: Destroyed by Karl Svalbard's last Lucifer missile, right after I blew him up. And the crowd cheers.


-
- Developer
- Posts: 2998
- Joined: Thu Jul 24, 2003 9:53 pm
- Contact:
The score in parenthesis is the score that is listed under score= in the <ShipClass> element.Aeonic wrote:Okay that works.
So what's the difference between the score and the score in parenthesis?
Sometimes it helps to override the computed score (but in practice, I think the computed score is better than my subjective score)
- Aeonic
- Militia Commander
- Posts: 469
- Joined: Sun Jun 14, 2009 1:05 am
- Location: Designing his dream ship.
Does that mean if we don't define any score= in the ship class, then the game will compute its own score?
Last Cause Of Death: Destroyed by Karl Svalbard's last Lucifer missile, right after I blew him up. And the crowd cheers.


-
- Developer
- Posts: 2998
- Joined: Thu Jul 24, 2003 9:53 pm
- Contact:
Yes!Aeonic wrote:Does that mean if we don't define any score= in the ship class, then the game will compute its own score?
-
- Commonwealth Pilot
- Posts: 86
- Joined: Fri Dec 04, 2009 1:46 am
I tried using Transdata 1.7 with RC4 to generate a score list, but I can't get it to work:
What am I missing?C:\temp\Trans10RC4>transdata /shiptable /score
TransData v1.7
Copyright (c) 2001-2009 by George Moromisato. All Rights Reserved.
Loading...
Unable to load module (Antarctica.xml): (commonwealth settlement): <Ships>: Unknown ship generator: Lookup
Vaiyo A-O
A Home Va Ya Ray
Vaiyo A-Rah
Jerhume Brunnen G


A Home Va Ya Ray
Vaiyo A-Rah
Jerhume Brunnen G

