Scripters cove

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: another_commander, winston

User avatar
tsoj
Deadly
Deadly
Posts: 199
Joined: Wed May 18, 2016 8:19 pm
Location: Berlin
Contact:

Re: Scripters cove

Post by tsoj »

I have a script that is supposed to run at start up, like this:

Code: Select all

this.startUp = function()
{
	// expensive computations
}
However, sometimes this function takes too long and gets killed:

Code: Select all

04:05:44.136 [script.javaScript.timeLimit]: ***** ERROR: Script "BalancedShipPrices" ran for 9.6251 seconds and has been terminated.
Is there a way to tell Oolite to set a higher time limit for this case? Or maybe someone knows a good workaround? Unfortunately, I don't see a way to make the computation itself cheaper.
User avatar
tsoj
Deadly
Deadly
Posts: 199
Joined: Wed May 18, 2016 8:19 pm
Location: Berlin
Contact:

Re: Scripters cove

Post by tsoj »

Maybe it might be a good idea to change the core code so that the time limit for startUp functions is higher (maybe 30 seconds, or even a minute?), as it doesn't really have any impact on the gameplay. Maybe this could even be a config parameter, but that of course would require a bit more programming ... :roll:
User avatar
Redspear
---- E L I T E ----
---- E L I T E ----
Posts: 2640
Joined: Thu Jun 20, 2013 10:22 pm

Re: Scripters cove

Post by Redspear »

Trying to get stations to broadcast occasional messages based on system inhabitants.

No error reports which might suggest that something is missing...

Code: Select all

this.shipEnteredStationAegis = function()

{
	var birds = /bird/i;
	var felines = /feline/i;
	var frogs = /frog/i;
	var humanoids = /humanoid/i;
	var insects = /insect/i;
    	var lizards = /lizard/i;
	var lobsters = /lobster/i;
	var rodents = /rodent/i;
	var colonials = /colonial/i;
	
	if (player.ship.alertCondition == 2)
	{
		if(system.info.inhabitants.match(birds))
        {
			this.ship.mainStation.commsMessage("[bird-messages]");
		}
	
		if(system.info.inhabitants.match(felines))
        {
			this.ship.mainStation.commsMessage("[feline-messages]");
		}
		
		if(system.info.mainStation.inhabitants.match(frogs))
        {
			this.ship.commsMessage("[frog-messages]");
		}

		if(system.info.inhabitants.match(humanoids))
        {
			this.ship.mainStation.commsMessage("[humanoid-messages]");
		}
		
		if(system.info.inhabitants.match(insects))
        {
			this.ship.mainStation.commsMessage("[insect-messages]");
		}
		
		if(system.info.inhabitants.match(lizards))
        {
			this.ship.mainStation.commsMessage("[lizard-messages]");
		}
		
		if(system.info.inhabitants.match(lobsters))
        {
			this.ship.mainStation.commsMessage("[lobster-messages]");
		}
		
		if(system.info.inhabitants.match(rodents))
        {
			this.ship.mainStation.commsMessage("[rodent-messages]");
		}
		
	reconsider: 40;
	}
	
}	
I realise that within aegis isn't the same as on scanner (is that available?) but shouldn't the reconsider part mean that messages would come up if the player loitered outside the station?

The relevant descriptions.plist has been written.

Any help gratefully received.
User avatar
montana05
---- E L I T E ----
---- E L I T E ----
Posts: 1166
Joined: Mon May 30, 2016 3:54 am
Location: lurking in The Devils Triangle (G1)

Re: Scripters cove

Post by montana05 »

Redspear wrote: Thu Jan 06, 2022 12:35 am
Trying to get stations to broadcast occasional messages based on system inhabitants.

No error reports which might suggest that something is missing...

Code: Select all

this.shipEnteredStationAegis = function()

{
	var birds = /bird/i;
	var felines = /feline/i;
	var frogs = /frog/i;
	var humanoids = /humanoid/i;
	var insects = /insect/i;
    	var lizards = /lizard/i;
	var lobsters = /lobster/i;
	var rodents = /rodent/i;
	var colonials = /colonial/i;
	
	if (player.ship.alertCondition == 2)
	{
		if(system.info.inhabitants.match(birds))
        {
			this.ship.mainStation.commsMessage("[bird-messages]");
		}
	
		if(system.info.inhabitants.match(felines))
        {
			this.ship.mainStation.commsMessage("[feline-messages]");
		}
		
		if(system.info.mainStation.inhabitants.match(frogs))
        {
			this.ship.commsMessage("[frog-messages]");
		}

		if(system.info.inhabitants.match(humanoids))
        {
			this.ship.mainStation.commsMessage("[humanoid-messages]");
		}
		
		if(system.info.inhabitants.match(insects))
        {
			this.ship.mainStation.commsMessage("[insect-messages]");
		}
		
		if(system.info.inhabitants.match(lizards))
        {
			this.ship.mainStation.commsMessage("[lizard-messages]");
		}
		
		if(system.info.inhabitants.match(lobsters))
        {
			this.ship.mainStation.commsMessage("[lobster-messages]");
		}
		
		if(system.info.inhabitants.match(rodents))
        {
			this.ship.mainStation.commsMessage("[rodent-messages]");
		}
		
	reconsider: 40;
	}
	
}	
I realise that within aegis isn't the same as on scanner (is that available?) but shouldn't the reconsider part mean that messages would come up if the player loitered outside the station?

The relevant descriptions.plist has been written.

Any help gratefully received.
You might want to try

Code: Select all

this.ship.commsMessage(expandDescription("[rodent-messages]"));
Scars remind us where we've been. They don't have to dictate where we're going.
User avatar
Redspear
---- E L I T E ----
---- E L I T E ----
Posts: 2640
Joined: Thu Jun 20, 2013 10:22 pm

Re: Scripters cove

Post by Redspear »

montana05 wrote: Thu Jan 06, 2022 2:29 am
You might want to try

Code: Select all

this.ship.commsMessage(expandDescription("[rodent-messages]"));
Good idea but didn't work.

I tried getting rid of the this. part and using system.mainStation as well but no luck.

At least I have another (albeit less desirable) way that I know works.

Thanks.
User avatar
LittleBear
---- E L I T E ----
---- E L I T E ----
Posts: 2866
Joined: Tue Apr 04, 2006 7:02 pm
Location: On a survey mission for GalCop. Ship: Cobra Corvette: Hidden Dragon Rated: Deadly.

Re: Scripters cove

Post by LittleBear »

You could do it by adding a script to the station as it will only detect you when you come within scanner ranger. If you have a look at the station script for the Space Bars in Random Hits, they have some code to send a greetings message (if the player is clean) or a warning message if not:-

Code: Select all

 if (player.ship.bounty > 20)
        {
            this.ship.target = player.ship;
            this.launchPatrol(true);
            this.ship.alertCondition++;
            if (!this.playerWelcomed) this.ship.commsMessage(expandDescription("[spacebar-warning]"));
        }
        if (player.ship.bounty === 0)
        {
            this.ship.alertCondition--;
            if (!this.playerWelcomed) this.ship.commsMessage(expandDescription("[spacebar-greeting]"));
        }
        
  
You want to have different messages based on system inhabits rather than legal status. so having a test for:-

Code: Select all

if (system.inhabitantsDescription.indexOf("Rodent") >= 0) this.ship.commsMessage(expandDescription("[rodent-message]"));
if (system.inhabitantsDescription.indexOf("Frog") >= 0) this.ship.commsMessage(expandDescription("[frog-message]"));

rinse and repeat for the different types of inhabitants. The indexOf is a useful test as it just means "includes the word", so you don't have to worry about whetehr they are furry, harmless, fat etc as it will detect the type of inhabitant as all variations include the word bird, frog, insect etc.
I think just a straight command to send a comms message without the this.ship would do it:-

commsMessage(expandDescription("[spacebar-warning]"));

The message is broadcast to all ships, but the NPCS won't take any notice. ;-)

The Random Hits script needs a target so the hunters know who to attack if the player isn't clean, but I don;t think you need to specify a target ship if you just want to send a comms message.
OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits, The Galactic Almanac, Renegade Pirates can be downloaded from the Elite Wiki here.
User avatar
montana05
---- E L I T E ----
---- E L I T E ----
Posts: 1166
Joined: Mon May 30, 2016 3:54 am
Location: lurking in The Devils Triangle (G1)

Re: Scripters cove

Post by montana05 »

Redspear wrote: Thu Jan 06, 2022 8:37 pm
montana05 wrote: Thu Jan 06, 2022 2:29 am
You might want to try

Code: Select all

this.ship.commsMessage(expandDescription("[rodent-messages]"));
Good idea but didn't work.

I tried getting rid of the this. part and using system.mainStation as well but no luck.

At least I have another (albeit less desirable) way that I know works.

Thanks.
I did some tests this morning, however the result was the same as mentioned here: https://bb.oolite.space/viewtopic.php?f=3&t=5209. I would guess that this error is still pending.

Edit:
I had a script error at another function in the script, therefore never triggering the test. :oops: After fixing this problem, the event got triggered.
Last edited by montana05 on Fri Jan 07, 2022 7:52 am, edited 1 time in total.
Scars remind us where we've been. They don't have to dictate where we're going.
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4646
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Scripters cove

Post by phkb »

Here's what I've found:

this.shipEnteredStationAegis is a world script event that fires when the player ship enters the station aegis. (You could also attach it to a ship script event, but for the purposes you have here, I think you'd only need to see the message for the player).

For the world script event to be processed, it needs to be in a world script file, that is, either in a "script.js" file in the "Config" folder, or in a JS file that is referenced in a "world-scripts.plist" file.

The "reconsider : 40" line has no meaning in this script - that's an AI related statement, and in the context of the world script event, the AI is not being referenced at all. I'd check your log file - one reason you might not be getting any results is that the "reconsider : 40" might be causing the JS compiler to fail and drop the file, meaning the event will never fire.

Also, using "this.ship" in the context of a world script event also has no meaning. There is no ship attached to the script, so you would need to provide the reference directly (and it was the right choice to change this to "system.mainStation").

Wrapping all the comms messages inside the if (player.ship.alertCondition == 2) condition means that messages will only be sent if the status is "Yellow" - but quite often, at the point of entering the aegis, my condition level is green (ie 1), so none of the messages will appear. That could also be preventing your messages from being seen.

Finally, for most of the messages you're checking "system.info.inhabitants", but for frogs you're checking "system.info.mainStation.inhabitants", which is invalid.

Hopefully that will get you going.
User avatar
Redspear
---- E L I T E ----
---- E L I T E ----
Posts: 2640
Joined: Thu Jun 20, 2013 10:22 pm

Re: Scripters cove

Post by Redspear »

LittleBear wrote: Thu Jan 06, 2022 10:28 pm
You could do it by adding a script to the station
Yeah, I already have it working as a station AI...

Code: Select all

/* Comm Broadcasts */
{
	condition:	aiconditionPlayerNearby,
	behaviour: function() {
		if (this.ship.alertCondition !== 3)
			this.ship.commsMessage("bird-messages]");
	},
	reconsider: 40
},
...but I wanted it seperate so that I can temporarily dodge multiple potential licensing isseus aroungd the 8 different oxp station types I would like to ultimately include.

phkb wrote: Fri Jan 07, 2022 6:53 am
The "reconsider : 40" line has no meaning in this script - that's an AI related statement
Yes, I was rather afraid of that... A consequence of my learning javascript purely from mucking about with Oolite...

I'd already realised I didn't need the this. parts and spotted thr frog error with mainstation (a bad cut and paste).
phkb wrote: Fri Jan 07, 2022 6:53 am
Wrapping all the comms messages inside the if (player.ship.alertCondition == 2) condition means that messages will only be sent if the status is "Yellow" - but quite often, at the point of entering the aegis, my condition level is green (ie 1), so none of the messages will appear. That could also be preventing your messages from being seen.
When mass locked by the station however you are yellow - It was my way clumsy way of giving the player a chance to be in scanner range of the station.


Thanks all for the help. I've learnt a thing or two even if we didn't get it to work.
Meanwhile I'll switch back to the AI method and the licensing headaches :D
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4646
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Scripters cove

Post by phkb »

I got the messages to appear when the player ship entered the station aegis. Are you actually aiming for the messages to appear when the station comes inside scanner range?

Also, what licensing headaches relate to using AI?
User avatar
Redspear
---- E L I T E ----
---- E L I T E ----
Posts: 2640
Joined: Thu Jun 20, 2013 10:22 pm

Re: Scripters cove

Post by Redspear »

phkb wrote: Fri Jan 07, 2022 8:51 pm
I got the messages to appear when the player ship entered the station aegis. Are you actually aiming for the messages to appear when the station comes inside scanner range?

Also, what licensing headaches relate to using AI?
I'm working on this.

So the messages are supposed to come from the station therfore min range should be scanner, max aegis (in order to suggest origin).

Licensing relates to the models I would need to attach the AIs to (see pics in that thread for examples - some fine, some not, some ambiguous).

I've just got it working by AI but not quite as posted above (that worked in 2016 but not today apparently), so I changed to the following, hopefully without breaking anything else:

Code: Select all

/* Comm Broadcasts */
		{
			preconfiguration: ai.configurationCheckScanner,
			condition: ai.conditionScannerContainsPlayer,
			//condition: aiconditionPlayerNearby,
			behaviour: function() {
			if (this.ship.alertCondition !== 3)
				this.ship.commsMessage("[bird-messages]");
			},
			reconsider: 40
		},
The reconsider part is important because I want them to broadcast often from a descriptions.plist that has 11 different messages it draws from at 7 different frequency rates (5 in 31 to 1 in 31) - so that the more quirky ones don't become too irritating, too quickly).

If you can get it to perform similar, independently of the station model and with a cyclical repetition, then I'd love to hear more :D
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4646
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Scripters cove

Post by phkb »

Try this:

Code: Select all

this.shipEnteredStationAegis = function(station) {
    if (station.isMainStation) {
        this.$startTimer();
    }
}

this.shipLaunchedFromStation = function(station) {
    if (station.isMainStation) {
        this.$startTimer();
    }
}

this.shipExitedStationAegis = function(station) {
    if (station.isMainStation) {
        this.$stopTimer();
    }
}

this.shipDockedWithStation = function(station) {
    if (station.isMainStation) {
        this.$stopTimer();
    }
}

this.shipDied = function() {
    this.$stopTimer();
}

this.$startTimer = function $startTimer () {
    this.$stopTimer(); // make sure we stop the timer if it's already running
    this._myTimer = new Timer(this, this.$sendMessageTimer, 1, 40); // first timer will fire after 1 sec, but after that will fire every 40 secs
}

this.$stopTimer = function $stopTimer () {
    if (this._myTimer && this._myTimer.isRunning) this._myTimer.stop();
}

this.$sendMessageTimer = function $sendMessageTimer () {
    var p = player.ship;
    var stn = system.mainStation;
    var dist = p.position.distanceTo(stn.position);
    if (dist >= stn.scannerRange && dist < stn.scannerRange * 2) { // only send a message if the player is greater than scanner range and less than aegis range (2 * scanner range) 
        if (p.alertCondition != 3) { // only send if the player is not at condition red
            this.$sendStationMessage();
        }
    }
}

this.$sendStationMessage = function $sendStationMessage () {
    var birds = /bird/i;
    var felines = /feline/i;
    var frogs = /frog/i;
    var humanoids = /humanoid/i;
    var insects = /insect/i;
    var lizards = /lizard/i;
    var lobsters = /lobster/i;
    var rodents = /rodent/i;
    var colonials = /colonial/i;
	
    if(system.info.inhabitants.match(birds))
    {
        system.mainStation.commsMessage("[bird-messages]");
    }
    if(system.info.inhabitants.match(felines))
    {
        system.mainStation.commsMessage("[feline-messages]");
    }
    if(system.info.inhabitants.match(frogs))
    {
        system.mainStation.commsMessage("[frog-messages]");
    }
    if(system.info.inhabitants.match(humanoids))
    {
        system.mainStation.commsMessage("[humanoid-messages]");
    }
    if(system.info.inhabitants.match(insects))
    {
        system.mainStation.commsMessage("[insect-messages]");
    }
    if(system.info.inhabitants.match(lizards))
    {
        system.mainStation.commsMessage("[lizard-messages]");
    }
    if(system.info.inhabitants.match(lobsters))
    {
        system.mainStation.commsMessage("[lobster-messages]");
    }
    if(system.info.inhabitants.match(rodents))
    {
        system.mainStation.commsMessage("[rodent-messages]");
    }		
}
User avatar
Redspear
---- E L I T E ----
---- E L I T E ----
Posts: 2640
Joined: Thu Jun 20, 2013 10:22 pm

Re: Scripters cove

Post by Redspear »

phkb wrote: Fri Jan 07, 2022 11:38 pm
Try this: ...
As written it didn't work BUT...

After a bit more experimentation, it seems that
  • Broadcast messages outside of station range won't happen - no error reports, the player just doesn't get them
  • The very first instance of the timer (on 1 second) didn't fire - don't know why but not a big problem
  • If I change the range to that of the scanner (rather than aegis) then it otherwise works as desired

Thanks so much for your time phkb, LittleBear and montana05. I've certainly learned a few things :)
User avatar
Old Murgh
Wiki Wizard
Wiki Wizard
Posts: 639
Joined: Sat Dec 04, 2021 11:01 pm

Re: riffraff scripting

Post by Old Murgh »

I'm approaching a point when I'll need to write a script or two that I expect ought to be written in js rather than the legacy that I did dabble in (decades ago).. Simple scripts, I'm assuming for those in the know, but I'm standing perplexed at the bottom of a large hill.

The one scriptable item is the shipdata pList entry "condition_script" that will refer to a script that dictates these ships are restricted to lower economy systems.
On the subject that riffraff police vipers be restricted to these lowEcos, Montana kindly gave me this starter:
montana05 wrote: Sat Mar 05, 2022 12:33 pm

Code: Select all

this.allowSpawnShip = function(shipKey) 
{
	var systemGov = system.government;
		
	if(system.isInterstellarSpace || system.sun.isGoingNova || system.sun.hasGoneNova)
	{ 
		return false;
	};

	switch(shipKey) 
	{
		// stable systems will be handled by GalCop police
		case "nephthys_phantom_mark_IF_bhg":
									
			if(systemGov > 2)
			{
				return false;
			};
			break;

		// unstable systems will be handled by BHG, Dictators OXP and Commies OXP got their own police force 
		case "nephthys_phantom_mark_IF_GalCop":
								
			if((systemGov < 3) || (systemGov == 3 && worldScripts["dictators.js"]) || 
			   (systemGov == 4 && worldScripts["communist_population"]))
			{
				return false;
			};
			break;	
			
		default:
			break;
	};
			
	return true;
};
Sadly I'm still dumbfounded. I'm sure there's more to it than replacing "nephthys_phantom_mark_IF_GalCop" with my own unique role name here, but I'm lost.

Now if I wanted to expand the group to a whole set of riffraff ships that are more frequently seen in poor places, would that merit its own separate script or somehow be baked into this one?

–The other script I imagine I might need would be called from the shipyard pList and dictate that the riffraff ships need more frequent maintenance, or can this be satisfactorily be controlled with the "renovation_multiplier"? What would the experienced scripter do?
I was young, I was naïve. [EliteWiki] Jonny Cuba made me do it!
User avatar
montana05
---- E L I T E ----
---- E L I T E ----
Posts: 1166
Joined: Mon May 30, 2016 3:54 am
Location: lurking in The Devils Triangle (G1)

Re: riffraff scripting

Post by montana05 »

Old Murgh wrote: Sat Mar 12, 2022 12:12 am
I'm approaching a point when I'll need to write a script or two that I expect ought to be written in js rather than the legacy that I did dabble in (decades ago).. Simple scripts, I'm assuming for those in the know, but I'm standing perplexed at the bottom of a large hill.

The one scriptable item is the shipdata pList entry "condition_script" that will refer to a script that dictates these ships are restricted to lower economy systems.
On the subject that riffraff police vipers be restricted to these lowEcos

Sadly I'm still dumbfounded. I'm sure there's more to it than replacing "nephthys_phantom_mark_IF_GalCop" with my own unique role name here, but I'm lost.

Now if I wanted to expand the group to a whole set of riffraff ships that are more frequently seen in poor places, would that merit its own separate script or somehow be baked into this one?

–The other script I imagine I might need would be called from the shipyard pList and dictate that the riffraff ships need more frequent maintenance, or can this be satisfactorily be controlled with the "renovation_multiplier"? What would the experienced scripter do?
If you use a random number in the script you can make a ship(s) mainly appear in poor places. Please note that this script is based on key, not on role. The renovation_multiplier should be sufficient for more frequent maintenance. If you pm me more details, I will be happy to make a draft for you. :wink:
Scars remind us where we've been. They don't have to dictate where we're going.
Post Reply