How To Determine A Ship's Score?

Freeform discussion about anything related to modding Transcendence.
User avatar
Aeonic
Militia Commander
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.
Image
george moromisato
Developer
Developer
Posts: 2998
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

Run TransData:

transdata /shiptable /score
User avatar
Atarlost
Fleet Admiral
Fleet Admiral
Posts: 2391
Joined: Tue Aug 26, 2008 12:02 am

What does transdata use to compute scores?
george moromisato
Developer
Developer
Posts: 2998
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

Atarlost wrote:What does transdata use to compute scores?
It's not a very sophisticated algorithm, and it could certainly use some help:

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;
	}

Note: Probably best if you copy the above to a real editor (or Notepad) for better readability.
george moromisato
Developer
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
	};
User avatar
Aury
Fleet Admiral
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...
(shpOrder gPlayership 'barrelRoll)

<New tutorials, modding resources, and official extension stuff coming to this space soon!>
User avatar
Aeonic
Militia Commander
Militia Commander
Posts: 469
Joined: Sun Jun 14, 2009 1:05 am
Location: Designing his dream ship.

george moromisato wrote:Run TransData:

transdata /shiptable /score
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.
Last Cause Of Death: Destroyed by Karl Svalbard's last Lucifer missile, right after I blew him up. And the crowd cheers.
Image
george moromisato
Developer
Developer
Posts: 2998
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

Aeonic wrote:
george moromisato wrote:Run TransData:

transdata /shiptable /score
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.
Try downloading TransData 1.7:

http://www.neurohack.com/downloads/TransData17.zip

Perhaps the old version (1.6) is not compatible with RC2
User avatar
Aeonic
Militia Commander
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?
Last Cause Of Death: Destroyed by Karl Svalbard's last Lucifer missile, right after I blew him up. And the crowd cheers.
Image
george moromisato
Developer
Developer
Posts: 2998
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

Aeonic wrote:Okay that works.

So what's the difference between the score and the score in parenthesis?
The score in parenthesis is the score that is listed under score= in the <ShipClass> element.

Sometimes it helps to override the computed score (but in practice, I think the computed score is better than my subjective score)
User avatar
Aeonic
Militia Commander
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.
Image
george moromisato
Developer
Developer
Posts: 2998
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

Aeonic wrote:Does that mean if we don't define any score= in the ship class, then the game will compute its own score?
Yes!
TheLastBrunnenG
Commonwealth Pilot
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:
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
What am I missing?
Vaiyo A-O
A Home Va Ya Ray
Vaiyo A-Rah
Jerhume Brunnen G
ImageImage
User avatar
Blitz
Militia Commander
Militia Commander
Posts: 342
Joined: Wed Mar 07, 2007 7:29 am

Hmmm..I don't know - I get the same error. Hold on, I'll attach an screenshot
Image

It's a clean install using RC4 and transdata 1.7
User avatar
alterecco
Fleet Officer
Fleet Officer
Posts: 1658
Joined: Wed Jan 14, 2009 3:08 am
Location: Previously enslaved by the Iocrym

Seems iike TransData needs an update for RC4
Post Reply