Page 101 of 118
Re: Scripters cove
Posted: Mon Dec 06, 2021 3:19 am
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.
Re: Scripters cove
Posted: Mon Dec 06, 2021 10:59 pm
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 ...
Re: Scripters cove
Posted: Thu Jan 06, 2022 12:35 am
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.
Re: Scripters cove
Posted: Thu Jan 06, 2022 2:29 am
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]"));
Re: Scripters cove
Posted: Thu Jan 06, 2022 8:37 pm
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.
Re: Scripters cove
Posted: Thu Jan 06, 2022 10:28 pm
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.
Re: Scripters cove
Posted: Fri Jan 07, 2022 4:22 am
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.
After fixing this problem, the event got triggered.
Re: Scripters cove
Posted: Fri Jan 07, 2022 6:53 am
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.
Re: Scripters cove
Posted: Fri Jan 07, 2022 12:23 pm
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
Re: Scripters cove
Posted: Fri Jan 07, 2022 8:51 pm
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?
Re: Scripters cove
Posted: Fri Jan 07, 2022 9:31 pm
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
Re: Scripters cove
Posted: Fri Jan 07, 2022 11:38 pm
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]");
}
}
Re: Scripters cove
Posted: Sat Jan 08, 2022 6:24 pm
by Redspear
phkb wrote: ↑Fri Jan 07, 2022 11:38 pm
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
Re: riffraff scripting
Posted: Sat Mar 12, 2022 12:12 am
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?
Re: riffraff scripting
Posted: Sat Mar 12, 2022 1:01 am
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.