Skip to content
This repository has been archived by the owner on Apr 17, 2022. It is now read-only.

NullBot research choices #4688

Open
wzdev-ci opened this issue Dec 28, 2017 · 8 comments
Open

NullBot research choices #4688

wzdev-ci opened this issue Dec 28, 2017 · 8 comments

Comments

@wzdev-ci
Copy link
Contributor

type_patch (an actual patch, not a request for one) | by darkling


I was digging into nullbot code and noticed some code which I don't think is behaving as intended. There's a function whose roll is to identify available research for different objectTypes (tank, template, vtol of defence) however objectType isn't passed to it so the default option is always called which is that the research is available.

Line numbers are for nullbot 3.06 on master, but the issue was noticed using an older version

Line 75 of research.js calls several functions:
var list = weaponStatsToResList(chooseAvailableWeaponPathByRoleRatings(personality.weaponPaths, chooseWeaponRole()), objType);

the issue crops us with the call to chooseAvailableWeaponPathByRoleRatings (located at line 134 in stats.js). The actual function asks for 4 (paths, rating, objectType, defrole) values whereas 2 are given (paths, rating).

At line 137 of stats.js the chooseAvailableWeaponPathByRoleRatings function calls the function weaponPathIsAvailable which asks for three variables (path, objectType, defrole).

weaponPathIsAvailable uses objectType to pick between research options but since that is not specified it always calls the default option (I think).

Fixing it looks a little bit more involved since just including objectType in the initial function call looks like it will make switching weapon research difficult since the function weaponPathIsAvailable tests using componentAvailable.

I've attached a version of the function that I wrote for my mod of nullbot. objectType is included in the initial call to chooseAvailableWeaponPathByRoleRatings so that it is then passed to weaponPathIsAvailable. It doesn't use defrole so you may need to make some changes if you want to include that variable.


Issue migrated from trac:4688 at 2022-04-16 12:58:28 -0700

@wzdev-ci
Copy link
Contributor Author

darkling uploaded file weaponPathIsAvailable.js (1.2 KiB)

alternative function

@wzdev-ci
Copy link
Contributor Author

NoQ commented


At a glance, this works correctly, even though i agree that the code looks weird. I see that weaponPathIsAvailable() without specified objectType always returns true... i think. Which is fine for us, because why would we care if the weapon is available (i.e. has some items already researched) when we are merely choosing what to research? I even suspect that this is exactly what i was trying to say with the "// research" comment in weaponPathIsAvailable(). But, again, i agree that it'd be much better to specify this behavior expliticly in the code, i.e. always pass the correct number of arguments to all functions.

@wzdev-ci
Copy link
Contributor Author

darkling commented


Interestingly it didn't really worry me that the function wasn't being called without all the arguments being called since the default was specified. It's just that as far as I can see the function weaponPathIsAvailable is only called in that one place, which was why I wasn't sure if it was doing what it was supposed to be doing. Otherwise the default is probably fine at least computationally (calling findResearch on a research item that is a long way from being researched is apparently not very efficient).

I can see two reasons for testing whether a path is available, firstly to make sure it doesn't try researching lasers right from the start (24 minutes to the first weapon from teh weapons guide) and then to make sure it doesn't get stuck trying to research a completed path. Although if a path is completed it's because it thinks it's the best one so will most likely be picking weapons from it anyway.

@wzdev-ci
Copy link
Contributor Author

wzdev-ci commented Jan 4, 2018

Berserk Cyborg changed blocking which not transferred by tractive

@wzdev-ci
Copy link
Contributor Author

wzdev-ci commented Jan 4, 2018

Berserk Cyborg changed blockedby which not transferred by tractive

@wzdev-ci
Copy link
Contributor Author

wzdev-ci commented Jan 4, 2018

Berserk Cyborg commented


How about this?

function weaponPathIsAvailable(path, objectType, defrole) {
	var pathType;
	switch (objectType) {
		case 0:
			pathType = path.weapons; break;
		case 1: //cyborg
			pathType = path.templates; break;
		case 2:
			pathType = path.defenses; break;
		case 3:
			pathType = path.vtols; break;
		default: // research
			return true;
	}
	if (pathType.length > 0) {
		var minR = findResearch(pathType[0].res).length;
		var maxR = findResearch(pathType[pathType.length - 1].res).length;
		if (maxR > 0 && minR < 2)
			return true;
		if (defined(defrole) && objectType === 2) //defenses
			return pathType.some(function(val) { return val.defrole === defrole && isAvailable(val.stat); });
	}
	return false;
}

@wzdev-ci
Copy link
Contributor Author

wzdev-ci commented Jan 6, 2018

darkling commented


For my own mod of NullBot I implemented a less elegant version of that. One thing I noticed was that calling findResearch added a fraction of a second to the execution time when there's a lot of items that need researching (maxR > 100). It might not be noticeable on a modern system but if you're running a lot of AIs on a map then it could stutter occasionally. In the end I used componentAvailable (or isStructureAvailable) for the last items because they were faster. So it counts how much research is needed for the first item in the path and whether the last item is available (true/false).

However for NullBot, I'm not so sure that it's necessary. Nullbot makes its weapon and research choices based on the ratio of observed enemy troop types. So the weaponPath it's choosing to research (except for a small random element) will be the weapon types that it will be deploying. So with nullbot I don't know if it gains anything from researching additional paths (if it's not going to deploy them).

It might be enough to just include the test for minR and remove the test for maxR (or change maxR to a true/false test for availability of the last item).

One alternative change that's related to this and might be useful to implement is in the weaponStatsToResList function. This function pulls together the list of research items that are then passed to the lab.

_global.weaponStatsToResList = function(path, objType) {
	if (!defined(path))
		return [];
	var ret = [];
	switch(objType) {
		case 0:
			ret = statsToResList(path.weapons); break;
		case 1:
			ret = statsToResList(path.templates); break;
		case 2:
			ret = statsToResList(path.defenses); break;
		case 3:
			ret = statsToResList(path.vtols); break;
	}
	if (ret.length === 0)
		ret = ret.concat(
			statsToResList(path.weapons),
			statsToResList(path.templates),
			statsToResList(path.defenses),
			statsToResList(path.vtols)
		);
        ret = ret.concat(path.extras);
	return ret;
}

I just added the line

        ret = ret.concat(path.extras);

to it. extras is a defined field in weaponStats and most of teh weapon paths have extras listed but I don't think they're used anywhere in Nullbot currently. so including them here should help nullbot get the most out of its chosen weaponpath.

@wzdev-ci
Copy link
Contributor Author

Berserk Cyborg commented


Hmm, yeah I guess Nullbot misses a few research items then if it does not use the extras. Unfortunately, my version of weaponPathIsAvailable does not work too well on T1 advanced bases because Nullbot tries to research the incendiary mortar while using completely different weapons. :/

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant