Qs about Roles/AIs
Moderators: winston, another_commander
-
- ---- E L I T E ----
- Posts: 607
- Joined: Wed Feb 20, 2013 1:24 am
- Location: Aboard the D.T.T Snake Charmer: My Xanadu
- Contact:
Qs about Roles/AIs
What I am looking for, is a role/ai that instructs the ship to act as a random wanderer/scavenger around the main space lanes, but does not include docking with any stations etc... Is there anything that does this currently? ( I am a pixel jockey, not a scripter!) Here's what I am working on...
I am making 2-3 different models and would like them to simply be an alien race (or maybe sentient robot life forms?) that wanders the space lanes scavenging and maybe mining? And maybe occasionally go rogue and pirate...? But looking at the included core(?) AIs, and then trying to recover from the resulting migraine, it looks like the scavenger roll makes them go back to the dock when full?
Next question... One of the models I want to make, is going to be carrying a "derelict" Cobra 3 (or at least one of the core spacecraft) around in its claws. Am I allowed to include the core model with my oxp, or can I "call it" within the shipdata.plist in some way... as a subentity perhaps? Not sure how that would work...
I am making 2-3 different models and would like them to simply be an alien race (or maybe sentient robot life forms?) that wanders the space lanes scavenging and maybe mining? And maybe occasionally go rogue and pirate...? But looking at the included core(?) AIs, and then trying to recover from the resulting migraine, it looks like the scavenger roll makes them go back to the dock when full?
Next question... One of the models I want to make, is going to be carrying a "derelict" Cobra 3 (or at least one of the core spacecraft) around in its claws. Am I allowed to include the core model with my oxp, or can I "call it" within the shipdata.plist in some way... as a subentity perhaps? Not sure how that would work...
- Eric Walch
- Slightly Grand Rear Admiral
- Posts: 5536
- Joined: Sat Jun 16, 2007 3:48 pm
- Location: Netherlands
Re: Qs about Roles/AIs
In UPS there are AI's called
Not random, but while traveling to the main station, they scan for loot resp. rocks
route1UpsScavengerAI.plist
and route1UpsMinerAI.plist
Not random, but while traveling to the main station, they scan for loot resp. rocks
UPS-Courier & DeepSpacePirates & others at the box and some older versions
- Commander McLane
- ---- E L I T E ----
- Posts: 9520
- Joined: Thu Dec 14, 2006 9:08 am
- Location: a Hacker Outpost in a moderately remote area
- Contact:
Re: Qs about Roles/AIs
Otherwise you'd have to modify route1patrolAI.plist. It already contains the traveling back and forth the main space lane, but you'd have to rip out the hunter/police-specific behaviour like scanning for offenders and fighting them, and replace it with scavenger-specific behaviour, like scanning for asteroids and loot. Also, you'd need to rip out the docking bits.
-
- ---- E L I T E ----
- Posts: 607
- Joined: Wed Feb 20, 2013 1:24 am
- Location: Aboard the D.T.T Snake Charmer: My Xanadu
- Contact:
Re: Qs about Roles/AIs
Ok, I thank you Commanders! AIs look mainly like "blocks" of code, hopefully they can be cut and paste with just a few pointers being changed.... I hope. If I can pry myself out of Wings3d long enough, I will look at the examples you both gave me again and see if I think I can pull it off. Thank you for your time <salute>! }:]
- Commander McLane
- ---- E L I T E ----
- Posts: 9520
- Joined: Thu Dec 14, 2006 9:08 am
- Location: a Hacker Outpost in a moderately remote area
- Contact:
Re: Qs about Roles/AIs
I've taken the liberty to strip route1patrolAI off everything not needed for your type of ship. Here's the result:
In this form the AI will only scavenge. It won't mine, and it won't attack anything, just fly between planet and witchpoint, and collect everything scoopable in-between. When it's full, it'll still continue to patrol the line. But you should probably make sure to give it enough cargo capacity that it's never going to get full. Alternatively it could jump out (just replace the "HEAD_FOR_…" with "HYPER_OUT" following the "HOLD_FULL" messages).
Code: Select all
{
GLOBAL = {
ENTER = (
"setStateTo: HEAD_FOR_WITCHPOINT"
);
};
"HEAD_FOR_PLANET" = {
"AEGIS_CLOSE_TO_MAIN_PLANET" = (
"setStateTo: HEAD_FOR_WITCHPOINT"
);
ATTACKED = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"ATTACKED_BY_CLOAKED" = (
"setAITo: interceptAI.plist",
"setStateTo: FLEE_FOR_CLOAKED"
);
"ATTACKER_MISSED" = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"CASCADE_WEAPON_DETECTED" = (
"setAITo: fleeQMineAI.plist"
);
"COURSE_OK" = (
setSpeedToCruiseSpeed,
performFlyToRangeFromDestination
);
"DESIRED_RANGE_ACHIEVED" = (
"setStateTo: HEAD_FOR_WITCHPOINT"
);
ENTER = (
setCourseToPlanet,
"setDesiredRangeTo: 50000.0",
checkCourseToDestination
);
"GROUP_ATTACK_TARGET" = (
setTargetToFoundTarget,
"setStateTo: INBOUND_LOOT",
"setAITo: interceptAI.plist"
);
"INCOMING_MISSILE" = (
fightOrFleeMissile,
setTargetToPrimaryAggressor,
deployEscorts,
groupAttackTarget
);
RESTARTED = (
checkAegis
);
"TARGET_FOUND" = (
setTargetToFoundTarget,
"setAITo: collectLootAI.plist"
);
UPDATE = (
setCourseToPlanet,
"setDesiredRangeTo: 50000.0",
checkCourseToDestination,
scanForLoot,
"pauseAI: 10.0"
);
"WAYPOINT_SET" = (
"setAITo: gotoWaypointAI.plist"
);
};
"HEAD_FOR_WITCHPOINT" = {
ATTACKED = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"ATTACKED_BY_CLOAKED" = (
"setAITo: interceptAI.plist",
"setStateTo: FLEE_FOR_CLOAKED"
);
"ATTACKER_MISSED" = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"CASCADE_WEAPON_DETECTED" = (
"setAITo: fleeQMineAI.plist"
);
"COURSE_OK" = (
setSpeedToCruiseSpeed,
performFlyToRangeFromDestination
);
"DESIRED_RANGE_ACHIEVED" = (
"setStateTo: HEAD_FOR_PLANET"
);
ENTER = (
setCourseToWitchpoint,
checkCourseToDestination
);
"GROUP_ATTACK_TARGET" = (
setTargetToFoundTarget,
"setStateTo: OUTBOUND_LOOT",
"setAITo: interceptAI.plist"
);
"INCOMING_MISSILE" = (
fightOrFleeMissile,
setTargetToPrimaryAggressor,
deployEscorts,
groupAttackTarget
);
"TARGET_FOUND" = (
setTargetToFoundTarget,
"setAITo: collectLootAI.plist"
);
UPDATE = (
setCourseToWitchpoint,
checkCourseToDestination,
scanForLoot,
"pauseAI: 10.0"
);
"WAYPOINT_SET" = (
"setAITo: gotoWaypointAI.plist"
);
};
"HYPER_OUT" = {
UPDATE = (
performHyperSpaceExit
);
};
"INBOUND_LOOT" = {
ATTACKED = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"ATTACKER_MISSED" = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"CASCADE_WEAPON_DETECTED" = (
"setAITo: fleeQMineAI.plist"
);
ENTER = (
"setSpeedTo: 0.0",
performIdle
);
"GROUP_ATTACK_TARGET" = (
setTargetToFoundTarget,
"setAITo: interceptAI.plist"
);
"HOLD_FULL" = (
"setStateTo: HEAD_FOR_PLANET"
);
"INCOMING_MISSILE" = (
fightOrFleeMissile,
setTargetToPrimaryAggressor,
deployEscorts,
groupAttackTarget
);
"NOTHING_FOUND" = (
"setStateTo: HEAD_FOR_PLANET"
);
"TARGET_FOUND" = (
setTargetToFoundTarget,
"setAITo: collectLootAI.plist"
);
UPDATE = (
scanForLoot,
"pauseAI: 10.0"
);
};
"OUTBOUND_LOOT" = {
ATTACKED = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"ATTACKER_MISSED" = (
setTargetToPrimaryAggressor,
groupAttackTarget
);
"CASCADE_WEAPON_DETECTED" = (
"setAITo: fleeQMineAI.plist"
);
ENTER = (
"setSpeedTo: 0.0",
performIdle
);
"GROUP_ATTACK_TARGET" = (
setTargetToFoundTarget,
"setAITo: interceptAI.plist"
);
"HOLD_FULL" = (
"setStateTo: HEAD_FOR_WITCHPOINT"
);
"INCOMING_MISSILE" = (
fightOrFleeMissile,
setTargetToPrimaryAggressor,
deployEscorts,
groupAttackTarget
);
"NOTHING_FOUND" = (
"setStateTo: HEAD_FOR_WITCHPOINT"
);
"TARGET_FOUND" = (
setTargetToFoundTarget,
"setAITo: collectLootAI.plist"
);
UPDATE = (
scanForLoot,
"pauseAI: 10.0"
);
};
}
-
- ---- E L I T E ----
- Posts: 607
- Joined: Wed Feb 20, 2013 1:24 am
- Location: Aboard the D.T.T Snake Charmer: My Xanadu
- Contact:
Re: Qs about Roles/AIs
Commander McLane wrote:I've taken the liberty to strip route1patrolAI off everything not needed for your type of ship. Here's the result:
Thank you so very much Commander McLane! I did go ahead and change the two "HEAD_FOR_PLANET"s to "HYPER_OUT"s, but this leads to another question...Commander McLane wrote:In this form the AI will only scavenge. It won't mine, and it won't attack anything, just fly between planet and witchpoint, and collect everything scoopable in-between. When it's full, it'll still continue to patrol the line. But you should probably make sure to give it enough cargo capacity that it's never going to get full. Alternatively it could jump out (just replace the "HEAD_FOR_…" with "HYPER_OUT" following the "HOLD_FULL" messages).
I know you can create a custom "role" for ships, and in this way :spawn them, but after reading System_Populator, I am still fuzzy as to how this works. Let's say I add:
Code: Select all
role = "dox_scavenger (1.0)";
Anyways, thanks again for taking the time to answer my questions and hacking that AI for me!
- Commander McLane
- ---- E L I T E ----
- Posts: 9520
- Joined: Thu Dec 14, 2006 9:08 am
- Location: a Hacker Outpost in a moderately remote area
- Contact:
Re: Qs about Roles/AIs
The key is spelled
Thus, what you need in shipdata, is
Now you can spawn the ship using the :spawn macro in the console. Just type:
Note that you can achieve the same by using the ship's unique shipdata key and putting it in brackets. So, if the shipdata key is "dox-scavenger", you can also type:
This suffices for testing purposes. For your OXP you will need to create a spawning script, because you can't depend on all players using the debug console. The system populator only knows about Oolite's generic
roles
, not role
. And as it's the only ship with your custom role, you don't need to specify a role weight (the parameter in parenthesis).Thus, what you need in shipdata, is
Code: Select all
roles = "dox_scavenger";
Code: Select all
:spawn dox_scavenger
Code: Select all
:spawn [dox-scavenger]
roles
, and only spawns ships using those roles
. It cannot spawn anything that only has a custom role.-
- ---- E L I T E ----
- Posts: 607
- Joined: Wed Feb 20, 2013 1:24 am
- Location: Aboard the D.T.T Snake Charmer: My Xanadu
- Contact:
Re: Qs about Roles/AIs
Spelling mistake on my part, though I didn't know about the weight. Thanks for that info!Commander McLane wrote:The key is spelled roles, not role. And as it's the only ship with your custom role, you don't need to specify a role weight (the parameter in parenthesis).
That's the part I was dreading to hear... <whimper> Ok, looks like I will have to take a look at some other oxps and see if I can figure that part out. First finish Heavy Metal, then hopefully by then I will have some feedback on the DTT Wraith, then I will get back to this. Thanks once again for the info Commander!Commander McLane wrote:This suffices for testing purposes. For your OXP you will need to create a spawning script, because you can't depend on all players using the debug console. The system populator only knows about Oolite's generic roles, and only spawns ships using those roles. It cannot spawn anything that only has a custom role.
- Commander McLane
- ---- E L I T E ----
- Posts: 9520
- Joined: Thu Dec 14, 2006 9:08 am
- Location: a Hacker Outpost in a moderately remote area
- Contact:
Re: Qs about Roles/AIs
We haven't yet answered this question. The answer is "yes" on all accounts.Paradox wrote:Next question... One of the models I want to make, is going to be carrying a "derelict" Cobra 3 (or at least one of the core spacecraft) around in its claws. Am I allowed to include the core model with my oxp, or can I "call it" within the shipdata.plist in some way... as a subentity perhaps? Not sure how that would work...
Yes, you are allowed to use all core models in your OXP; and yes, you can simply use them as subentities. From a game point of view, there is no technical difference between a main entity and a subentity, thus everything that has a shipdata-representation can be used as a subentity. There is one caveat: subentities cannot have subentities themselves. Thus, the core ships you want to use would automatically lose their subentities when spawned as subentities themselves. Having said that, you can immediately disregard it for the core ships, because none of them has subentities. But, for players who use a replacement shipset that overrides the original set, this could make an optical difference.
Thus, to be on the safe side, you should create clones of those ships you want to use. Create shipdata entries for the ships you want to use, and define only those keys that are necessary for them to function as a subentity (for instance, you don't need a max_speed, or an exhaust, or view- and weapon-positions). You also need clones of your scavenger for each possible carried ship, differing only in their
subentities
-key. The Salvager Tugger from [wiki]Anarchies OXP[/wiki] is a good example for what you need, because it's doing the exact same thing, only that it's tugging various ships of the core set instead of holding them in its claws. Feel free to butcher its shipdata. -
- ---- E L I T E ----
- Posts: 607
- Joined: Wed Feb 20, 2013 1:24 am
- Location: Aboard the D.T.T Snake Charmer: My Xanadu
- Contact:
Re: Qs about Roles/AIs
OK, I think I understand all that. };] Will have to give this part more thought as I am also thinking of showing damage/parts missing from the ships, which will mean basically a new model or a modification of the core model anyways. Well, thank you for the information, and addressing the re-use question! };]Commander McLane wrote:Thus, to be on the safe side, you should create clones of those ships you want to use. Create shipdata entries for the ships you want to use, and define only those keys that are necessary for them to function as a subentity (for instance, you don't need a max_speed, or an exhaust, or view- and weapon-positions). You also need clones of your scavenger for each possible carried ship, differing only in their subentities-key. The Salvager Tugger from Anarchies OXP is a good example for what you need, because it's doing the exact same thing, only that it's tugging various ships of the core set instead of holding them in its claws. Feel free to butcher its shipdata.
- Commander McLane
- ---- E L I T E ----
- Posts: 9520
- Joined: Thu Dec 14, 2006 9:08 am
- Location: a Hacker Outpost in a moderately remote area
- Contact:
Re: Qs about Roles/AIs
Yep.Paradox wrote:Will have to give this part more thought as I am also thinking of showing damage/parts missing from the ships, which will mean basically a new model or a modification of the core model anyways.
You're welcome.Paradox wrote:Well, thank you for the information, and addressing the re-use question! };]
- Commander McLane
- ---- E L I T E ----
- Posts: 9520
- Joined: Thu Dec 14, 2006 9:08 am
- Location: a Hacker Outpost in a moderately remote area
- Contact:
Re: Qs about Roles/AIs
Okay, next step: spawning script.
First of all: Don't Panic! Writing scripts is no rocket science. For standard tasks (like spawning ships) it's actually quite straightforward. You simply tell the game engine what it has to do and when. You just have to use the right language to do so.
You need a world script (that's a script attached to the game universe as a whole, as opposed to a script attached to a specific ship and only existing while that ship is also existing; you can also think of a world script as being attached to the player, because the game universe only exists inasmuch as the player is there). The simplest way of creating one is to create a simple text file and save it in the Config-folder of your OXP (right next to your shipdata.plist) under the name of "script.js".
Here's what it has to contain:
Let's go through it line by line:
The first line tells the JavaScript-engine that we're conforming to some standard. I don't know any details, I just know that each script should have it right at the beginning.
Then comes a group of six lines that contain meta-information about the script. For the most part they're exactly that: convenient meta-information, but not strictly necessary. However, there's one exception: theis mandatory. Also, the name has to be unique (just like shipdata keys of your ship), because this is how the JavaScript-engine actually distinguishes all the various scripts. It doesn't use file names for that. Therefore each OXP can contain a "script.js" in its Config-folder without confusing the scripting engine, as long as they all have a unique
The last seven lines are the actual script code.
is an event handler. It tells the scripting engine when to perform the commands enclosed in the following curly brackets. In this case, we want the action each time when the player exited from witchspace and has entered a new system. There is a list of all existing event handlers on the Wiki that explains when each of them "fires". For the purpose of populating a system with additional ships (or creatures) the moment when the player enters the system is of course the logical choice.
But I assume that you don't want to spawn one of your scavengers literally every time when the player pops out of witchspace. Thus the spawning code should only be executed under some conditions. Those are defined in the
First of all,
Last of all,
Between those two, the
Finally, if all conditions are met, the part in the innermost curly brackets is executed:
It tells the engine to add a specified amount of ships with a specified role to a specified location along one of the space lanes.
In this case, the role is "dox_scavenger", the amount is 1 of them, the location is at 30 per cent of the way in, and the route is from witchpoint to planet.
Of course, you can modify each of the parameters to your liking:
EDIT: added quotation marks at a vital point in the code example.
First of all: Don't Panic! Writing scripts is no rocket science. For standard tasks (like spawning ships) it's actually quite straightforward. You simply tell the game engine what it has to do and when. You just have to use the right language to do so.
You need a world script (that's a script attached to the game universe as a whole, as opposed to a script attached to a specific ship and only existing while that ship is also existing; you can also think of a world script as being attached to the player, because the game universe only exists inasmuch as the player is there). The simplest way of creating one is to create a simple text file and save it in the Config-folder of your OXP (right next to your shipdata.plist) under the name of "script.js".
Here's what it has to contain:
Code: Select all
"use strict";
this.name = "dox-scavenger";
this.description = "Script for randomly spawning dox scavengers whenever the player enters a new system";
this.author = "Commander McLane";
this.copyright = "© 2013 Commander McLane";
this.license = "CC-by-nc-sa 3.0";
this.version = "1.0";
this.shipExitedWitchspace = function()
{
if(!system.isInterstellarSpace && ... && Math.random() < 0.1)
{
system.addShipsToRoute("dox_scavenger", 1, 0.3, "wp");
}
}
The first line tells the JavaScript-engine that we're conforming to some standard. I don't know any details, I just know that each script should have it right at the beginning.
Then comes a group of six lines that contain meta-information about the script. For the most part they're exactly that: convenient meta-information, but not strictly necessary. However, there's one exception: the
Code: Select all
this.name = "dox-scavenger";
this.name
.The last seven lines are the actual script code.
Code: Select all
this.shipExitedWitchspace
But I assume that you don't want to spawn one of your scavengers literally every time when the player pops out of witchspace. Thus the spawning code should only be executed under some conditions. Those are defined in the
if
clause:
Code: Select all
if(!system.isInterstellarSpace && ... && Math.random() < 0.1)
!system.isInterstellarSpace
checks that the player is in a planetary system (the "!" means "not"). It prevents the scavengers from being spawned in case of a misjump. After all, in interstellar space there is no space lane between witchpoint and planet, and there are no asteroids.Last of all,
Math.random() < 0.1
adds an element of random. Math.random()
creates a random number between 0 and 1. So only ten percent of the time it will be < 0.1, and the condition will be fulfilled. I just filled in this probability arbitrarily, and you can of course decrease or increase the probability by decreasing or increasing the number.Between those two, the
...
stand for any other conditions you can come up with. For instance, you can make the tech level of the system into a condition, or the political affiliation, or the economy, or any other property of the system. So the player would only ever encounter the scavengers in systems that are at least poor industrial, excluding anarchies and feudals, with a tech level not higher than 10. Or whatever combination of conditions allows the scavengers to flourish best. A list of all system-related properties that can be used as conditions is of course also on the Wiki.Finally, if all conditions are met, the part in the innermost curly brackets is executed:
Code: Select all
system.addShipsToRoute("dox_scavenger", 1, 0.3, "wp");
In this case, the role is "dox_scavenger", the amount is 1 of them, the location is at 30 per cent of the way in, and the route is from witchpoint to planet.
Of course, you can modify each of the parameters to your liking:
- Specify another role to spawn a ship/ships of that role.
- Specify another number to spawn more than one ship (the limit is 64, so you can spawn a pretty big cluster of ships with a single command).
- Specify another fraction to move the spawning point forward or back. 0 means (on the main route) exactly the witchpoint position, and 1 means on the surface of the planet. You can also use a negative number to spawn something behind the witchpoint, or a number > 1 to spawn something behind the planet (caution: because 1 means the surface of the planet, chances are that 1.05 will spawn your ship inside the planet). You can even use random here: replacing the 0.3 with
Math.random()
will cause your scavenger to spawn at a random location between the witchpoint and the planet;(Math.random() * 0.8 ) + 0.1
will make sure that it's not too close to either the witchpoint or the planet. - Specify another one of the space lanes. Apart from "wp" (witchpoint to planet) there's also "pw" (planet to witchpoint), "ws" (witchpoint to sun), "sw" (sun to witchpoint), "ps" (planet to sun), and "sp" (sun to planet). If you skip the parameter altogether, the direct line between witchpoint and main station is used.
EDIT: added quotation marks at a vital point in the code example.
Last edited by Commander McLane on Tue Apr 02, 2013 10:06 pm, edited 1 time in total.
-
- ---- E L I T E ----
- Posts: 607
- Joined: Wed Feb 20, 2013 1:24 am
- Location: Aboard the D.T.T Snake Charmer: My Xanadu
- Contact:
Re: Qs about Roles/AIs
Ow wow, he made one just for me!!! }:] :happy_dance: Thank you for this Commander McLane.
But... with that out of the way, let me see if I can mangle this...
That part is easy enough, now the meat and potatoes... Let's say I want to spawn 2 different types of Dox, and want them to appear in a random spot between the witchpoint and planet, only in tech systems of 8 and above, with a 1 out of 4 chance...
So, did I butcher it? Bet you a cheeseburger I did! }:]
The wiki is good at telling you what things do, but not at how to use them in an actual script. Definitions, but not examples.
It's that "right language" part that's the killer. I have spent days trouble shooting Rainmeter code, just to find that one "(" that should have been a "{", or a "," instead of a "."! };] It's not that I can't code/script (although programming is an entirely different matter!), it's that I HATE trying to learn all the new syntaxs and at 51 yrs old, I am mighty thin on hair to pull when I get frustrated! };] And mild ADD means that if I am not really interested in something, I have a he!! of a time concentrating on it.Commander McLane wrote:First of all: Don't Panic! Writing scripts is no rocket science. For standard tasks (like spawning ships) it's actually quite straightforward. You simply tell the game engine what it has to do and when. You just have to use the right language to do so.
But... with that out of the way, let me see if I can mangle this...
Code: Select all
"use strict"; // Need this!
this.name = "dox-scavenger"; //Also Need this, and must be unique(?)
this.description = "Script for randomly spawning dox scavengers whenever the player enters a new system"; //metadata
this.author = "Commander McLane"; //metadata
this.copyright = "© 2013 Commander McLane"; //metadata
this.license = "CC-by-nc-sa 3.0"; //metadata
this.version = "1.0"; //metadata
this.shipExitedWitchspace = function() //This is the condition.
That part is easy enough, now the meat and potatoes... Let's say I want to spawn 2 different types of Dox, and want them to appear in a random spot between the witchpoint and planet, only in tech systems of 8 and above, with a 1 out of 4 chance...
Code: Select all
{
if(!system.isInterstellarSpace && techLevel => 8 && Math.random() < 0.25)
{
system.addShipsToRoute("dox_scavenger1", 1, (Math.random() * 0.8 ) + 0.1, wp);
system.addShipsToRoute("dox_scavenger2", 1, (Math.random() * 0.8 ) + 0.1, wp);
}
}
So, did I butcher it? Bet you a cheeseburger I did! }:]
The wiki is good at telling you what things do, but not at how to use them in an actual script. Definitions, but not examples.
- Commander McLane
- ---- E L I T E ----
- Posts: 9520
- Joined: Thu Dec 14, 2006 9:08 am
- Location: a Hacker Outpost in a moderately remote area
- Contact:
Re: Qs about Roles/AIs
Almost there!Paradox wrote:So, did I butcher it? Bet you a cheeseburger I did! }:]
Some corrections:
Code: Select all
"use strict"; // Need this!
this.name = "dox-scavenger"; //Also Need this, and must be unique(!)
this.description = "Script for randomly spawning dox scavengers whenever the player enters a new system"; //metadata
this.author = "Commander McLane"; //metadata
this.copyright = "© 2013 Commander McLane"; //metadata
this.license = "CC-by-nc-sa 3.0"; //metadata
this.version = "1.0"; //metadata
this.shipExitedWitchspace = function() //This is the event handler.
{
if(!system.isInterstellarSpace && system.techLevel >= 7 && Math.random() < 0.25) //These are the conditions.
{
system.addShipsToRoute("dox_scavenger1", 1, (Math.random() * 0.8) + 0.1, "wp"); //adding one specimen of type1 at a random location between 10-90% into the space lane
system.addShipsToRoute("dox_scavenger2", 1, (Math.random() * 0.8) + 0.1, "wp"); //adding one specimen of type2 at a random location between 10-90% into the space lane
}
}
techLevel
is a property of system
, thus you have to write system.techLevel
, otherwise the engine doesn't know whose techLevel
to check. The comparison operator is written just as you'd also pronounce it: "greater than or equal": >=
(I'm not sure if =>
would work as well). Finally, as in all things computery, the internal counter for techLevel
(as for everything else) starts with 0. Thus, what is displayed to the player as TL 8 is actually internally techLevel 7
. (By the way: you could also write system.techLevel > 6
. As very often, there are many ways to achieve the same result.)Finally, I put quotation marks around the "wp". I forgot those in my post above. Sorry. All strings need to be in quotation marks.
So far, so good. Now for an alternative approach: With this spawning script the player will encounter two different dox in one quarter of all TL8+ systems. They'll always appear in pairs, although not necessarily together. But what if you want more variation, and have sometimes only spawned type1, and other times only type2? In that case you want to handle the two types of dox independent from each other.
That's easily achievable by putting multiple condition clauses in the same event handler. All condition clauses are executed in order, one after the other. So:
Code: Select all
"use strict"; // Need this!
this.name = "dox-scavenger"; //Also Need this, and must be unique(!)
this.description = "Script for randomly spawning dox scavengers whenever the player enters a new system"; //metadata
this.author = "Commander McLane"; //metadata
this.copyright = "© 2013 Commander McLane"; //metadata
this.license = "CC-by-nc-sa 3.0"; //metadata
this.version = "1.0"; //metadata
this.shipExitedWitchspace = function() //This is the event handler.
{
if(!system.isInterstellarSpace && system.techLevel >= 7 && Math.random() < 0.25) //These are the conditions.
{
system.addShipsToRoute("dox_scavenger1", 1, (Math.random() * 0.8) + 0.1, "wp"); //adding one specimen of type1
}
if(!system.isInterstellarSpace && system.techLevel >= 7 && Math.random() < 0.25) //These are the conditions.
{
system.addShipsToRoute("dox_scavenger2", 1, (Math.random() * 0.8) + 0.1, "wp"); //adding one specimen of type2
}
}
addShips
-commands into different if-clauses. The conditions themselves are identical. But this time the random part of the condition is calculated twice with a different random number. So either the first one may be lower than 0.25, or the second one, or both. Accordingly you'll either get a type1 dox, or a type2, or both.Alternatively, you can nest the condition clauses. The script doesn't actually need to check twice whether the player is in interstellar space, or what the system's
techLevel
is. This cannot possible change between the two checks. Thus it makes sense to check for these two first, in an outer condition clause, and then only create the random numbers in an inner condition clause, which is only ever executed if the outer conditions were already true. Thus, nested conditions make the code also run faster, because double checks are avoided, and fewer checks need to be made.Then we get:
Code: Select all
"use strict"; // Need this!
this.name = "dox-scavenger"; //Also Need this, and must be unique(!)
this.description = "Script for randomly spawning dox scavengers whenever the player enters a new system"; //metadata
this.author = "Commander McLane"; //metadata
this.copyright = "© 2013 Commander McLane"; //metadata
this.license = "CC-by-nc-sa 3.0"; //metadata
this.version = "1.0"; //metadata
this.shipExitedWitchspace = function() //This is the event handler.
{
if(!system.isInterstellarSpace && system.techLevel >= 7) //Outer conditions. These need to be true in order to proceed.
{
if(Math.random() < 0.25) //Random element.
{
system.addShipsToRoute("dox_scavenger1", 1, (Math.random() * 0.8) + 0.1, "wp"); //adding one specimen of type1
}
if(Math.random() < 0.25) //Random element.
{
system.addShipsToRoute("dox_scavenger2", 1, (Math.random() * 0.8) + 0.1, "wp"); //adding one specimen of type2
}
}
}
-
- ---- E L I T E ----
- Posts: 607
- Joined: Wed Feb 20, 2013 1:24 am
- Location: Aboard the D.T.T Snake Charmer: My Xanadu
- Contact:
Re: Qs about Roles/AIs
LOLZ! You owe me a cheeseburger.Commander McLane wrote:Paradox wrote:
So, did I butcher it? Bet you a cheeseburger I did! }:]
Almost there!
Noted!Commander McLane wrote:I made a few changes and amendments to the comments.
Yes, that is more the idea I had in mind...Commander McLane wrote:So far, so good. Now for an alternative approach: With this spawning script the player will encounter two different dox in one quarter of all TL8+ systems. They'll always appear in pairs, although not necessarily together. But what if you want more variation, and have sometimes only spawned type1, and other times only type2? In that case you want to handle the two types of dox independent from each other.
OK, left eye is starting to twitch, and my legs have gone numb from the knees down, but I'm not bleeding from the ears yet, so that's a good sign.Commander McLane wrote:That's easily achievable by putting multiple condition clauses in the same event handler. All condition clauses are executed in order, one after the other.
...
Incidentally, spawning two types with a 25%-probability results in an increased overall probability to see at least one: from 1/4 to 7/16. To counteract this, you may want to decrease the probability, let's say to 20% each time, which would result in a 9/25-probability to see at least one.
Furthermore, I actually do understand what you are doing there. Although there was no way I could have come up with any of this from just the wiki alone!
As for the probability, I will turn that down after testing.
I thank you Obi-Wan err.. Commander McLane! I very much appreciate your taking the time to explain this in a way that even I can comprehend!