Progress

General discussion for players of Oolite.

Moderators: winston, another_commander

User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Post by Svengali »

Griff wrote:
if you can't afford 3d software but you have a digital camera and a torch:
http://www.zarria.net/nrmphoto/nrmphoto.html
:)
Very cool. Now I need some 2KW Fresnels to do it properly .-)
User avatar
Frame
---- E L I T E ----
---- E L I T E ----
Posts: 1477
Joined: Fri Mar 30, 2007 8:32 am
Location: Witchspace

Post by Frame »

Griff wrote:
if you can't afford 3d software but you have a digital camera and a torch:

http://www.zarria.net/nrmphoto/nrmphoto.html
:)
Cool... now all i need is to find the nearest space ship hull plating ;-)...

no, really, very nice....
Bounty Scanner
Number 935
User avatar
DaddyHoggy
Intergalactic Spam Assassin
Intergalactic Spam Assassin
Posts: 8515
Joined: Tue Dec 05, 2006 9:43 pm
Location: Newbury, UK
Contact:

Post by DaddyHoggy »

Nice one Griff - that's a cracking little tutorial that you've found there!
Selezen wrote:
Apparently I was having a DaddyHoggy moment.
Oolite Life is now revealed here
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

I just noticed that the OXP verifier is broken in 1.72; it skips most shipdata.plist checks. This is fixed for 1.73.

For Mac users, various “secret” settings are now exposed through the Secrets preference pane. (If you already have Secrets installed, you may need to click “Update Secrets” for Oolite to appear in the application list.) I intend to document these tweaks and how to edit them on all platforms on EliteWiki.
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

*spins the wheel of unexpected new features*

And this week’s grand prize is… data-driven crosshairs. This means that crosshair shapes are now loaded from a config file. But that’s not all! They can also be overridden by any HUD plist by adding a crosshairs dictionary. But that’s not all! The size, thickness and colour of crosshairs can also be overridden by any HUD plist with the keys crosshair_scale (default: 32), crosshair_width (default: 1.5) and crosshair_color (default: greenColor) respectively. But that’s not all! Oh wait, yes it is. Except for the minor detail that crosshair width is now proportional to window size, just like everything else.

The format of the crosshairs.plist entry is simple: each entry is an array, whose elements are arrays of six numbers, each such array representing a line segment. The first three numbers are alpha, x and y for one end of the line segment, the other three numbers are alpha, x and y for (surprise!) the other end.
User avatar
Commander McLane
---- E L I T E ----
---- 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:

Post by Commander McLane »

Nice!

(And what about all the expected/requested new features?) :wink:
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Hey, customizable crosshairs have been requested. At least twice.

I actually wrote about half of this change several months ago, and having bits of incomplete code lying around is messy.
User avatar
Commander McLane
---- E L I T E ----
---- 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:

Post by Commander McLane »

I'm not complaining. :D

Just wanted to give a small reminder, as far as other open requests are concerned (and you will have noticed, I even shamelessly added a completely new one to the mix (the last link) :wink: ).
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

As for the specific things you linked to… fulfilling new scripting requests is currently a low priority. In fact, my priorities right now are:
  • Graphics fixes, specifically fixing a reworking of mesh drawing code that I started on a couple of weeks ago and getting the lighting and shadow model to work properly with shaders. This could also lead to a pretty nifty upgrade to the lighting rig, but no guarantees.
  • Urgent scripting fixes, specifically stuff that is currently done with the legacy scripting engine and has no JS equivalent. I’ll be starting a new thread for this.
  • Bug fixes.
  • Competition for new higher-resolution icon – I’ve been putting this off for about a year(!), should get that started at some point…
  • Stable release in late spring/early summer.
  • Work on a completely unrelated iPhone app in summer.
Stuff like the data-driven crosshairs just happens between priorities when I don’t feel up to working on the priority stuff and the alternative would be to play games or have a life.
User avatar
Commander McLane
---- E L I T E ----
---- 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:

Post by Commander McLane »

Ahruman wrote:
... or have a life.
I do think, however, that you should try this one out at some point. :wink:
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Implemented new AI method, scanForNearestShipMatchingPredicate:. This method’s parameter is a JavaScript expression, which should evaluate to a boolean. In the context of the expression, ship means the ship being evaluated, and this means the script object associated with the same ship as the AI. Some examples:

Code: Select all

"scanForNearestShipMatchingPredicate: ship.isWeapon" // Simple case
"scanForNearestShipMatchingPredicate: this.complicatedPredicate()" // Call a function in the ship script
"scanForNearestShipMatchingPredicate: function () { if (ship.isPolice) return false; return !ship.isPlayer; } ()" // anonymous function allows multiple statements
I was somewhat leery of mixing JavaScript code into AI code, and was considering using a function name to be called instead. However, this would only work when the ship has a known script, making it impossible to use the new method in generic AIs.

Technical note: for efficiency, the generated function’s scope is the global object. This has the effect that you must qualify references to the ship script’s properties with this.. The benefit of this is that the compiled function can be reused without taking different ship scripts into account.

Due to details of AI parsing, calling a function in the ship script is likely to be more efficient than complex inline expressions. In particular, every AI (or legacy script) command has overhead proportional to the number of spaces in it.
User avatar
DaddyHoggy
Intergalactic Spam Assassin
Intergalactic Spam Assassin
Posts: 8515
Joined: Tue Dec 05, 2006 9:43 pm
Location: Newbury, UK
Contact:

Post by DaddyHoggy »

I have no idea what that means but it sounds great - the AI-using scripters will be all a twitter now! :)
Selezen wrote:
Apparently I was having a DaddyHoggy moment.
Oolite Life is now revealed here
User avatar
Commander McLane
---- E L I T E ----
---- 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:

Post by Commander McLane »

Ahruman wrote:
Implemented new AI method, scanForNearestShipMatchingPredicate:. ...

Code: Select all

"scanForNearestShipMatchingPredicate: this.complicatedPredicate()" // Call a function in the ship script
Practically, is there a difference between this and a simple "sendScriptMessage: this.complicatedPredicate"; and then have the ship script perform the search and end with a reactToAIMessage("TARGET_FOUND")?

So, should I from the next release on prefer scanForNearestShipMatchingPredicate: over the sendScriptMessage: approach which is already viable?
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

The AI search mechanism is somewhat more efficient, since it only calls the predicated for ships within scanner range rather than all entities in the system. It also expresses intention more clearly, which makes it easier to understand what you’re doing. Lastly, you forgot about NOTHING_FOUND. :-)

But the most important difference is that, for the simple cases, this doesn’t depend on the ship script, so the AI remains independent. Obviously the this.complicatedPredicate() form abandons that advantage.

Overall, I wouldn’t say it provides an overwhelming reason to rewrite working code.

(On a nitpicky note, it would be wrong for this.complicatedPredicate() to send AI messages; “predicate” indicates a function which returns a boolean and has no side effects.)
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Added delay parameter to playerStartedJumpCountdown event, as discussed elsewhere. Here is an example of use. Note the necessity of accounting for non-integer delays. (Delays less than one are also possible, and should work fine – the timer will be cancelled before it gets called.)

Also note that witchspace countdowns can end four ways: through cancellation, through failure (mass locked, out of fue l), by the player dying, or by entering witchspace. A general playerJumpCountdownStopped event to catch this and any new cases would probably be a good idea.

Code: Select all

this.hyperspaceCountdownTimer = null;
this.hythis.hyperspaceCountdownTimer = null;
this.hyperspaceCountdownSecondsRemaining = 0;

this.hyperspaceCountdownTimerFunc = function ()
{
    log("Hyperspace in " + this.hyperspaceCountdownSecondsRemaining + " seconds.");
    this.hyperspaceCountdownSecondsRemaining--;
}


this.stopHyperspaceCountdownTimer = function ()
{
    if (this.hyperspaceCountdownTimer)
    {
        this.hyperspaceCountdownTimer.stop();
        this.hyperspaceCountdownTimer = null;
    }
}


// Called when player initiates witchspace countdown.
this.playerStartedJumpCountdown = function (type, delay)
{
    // Get number of whole seconds until jump.
    this.hyperspaceCountdownSecondsRemaining = Math.floor(delay);
    
    // Get fractional part of delay, if any.
    var initialDelay = delay - this.hyperspaceCountdownSecondsRemaining;
    
    if (initialDelay == 0)
    {
        // If no fractional time, call countdown function immediately
        // and use timer for subsequent seconds.
        this.hyperspaceCountdownTimerFunc();
        initialDelay = 1.0;
        this.hyperspaceCountdownSecondsRemaining--;
    }
    
    // Call timer function every 1.0 seconds after initialDelay.
    this.hyperspaceCountdownTimer =
        new Timer(this, this.hyperspaceCountdownTimerFunc, initialDelay, 1.0);
}


this.playerCancelledJumpCountdown = function ()
{
    this.stopHyperspaceCountdownTimer();
}


this.playerJumpFailed = function (reason)
{
    this.stopHyperspaceCountdownTimer();
}


this.shipWillEnterWitchspace = function (type)
{
    this.stopHyperspaceCountdownTimer();
}


this.shipDied = function (type)
{
    this.stopHyperspaceCountdownTimer();
}
Backwards compatibility note: if you use this script in a pre-1.73 version of Oolite, delay will be undefined. This is true in general: if your function accepts more arguments than the caller passes, the extra ones will be undefined. The backwards-compatible way of dealing this would be to start playerStartedJumpCountdown() with if (delay == undefined) delay = 15; – although I don’t particularly recommend aiming for backwards-compatibility with earlier test releases.
Post Reply