Progress

General discussion for players of Oolite.

Moderators: winston, another_commander

User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Progress

Post by JensAyton » Fri Mar 09, 2007 7:14 pm

Stuff I’ve done since 1.67-mac:
  • Fixed yaw control. (Keyboard only; default to , and ., aka < and > on US and UK keyboards.) Disabled in strict mode.
  • Reimplemented data cache.
  • Tightened the retaining bolts on laser cannons, which had worked loose. (This affected AIs too, incidentally.)
  • Advanced Navigation Array can now actually be purchased (for any ship).
Stuff to do this weekend:
  • Fix streaming-audio crash bug.
  • Work out why mouse control sometimes isn’t working.
  • Bug-fix release 1.67.1-mac.
  • Look at dajt’s JavaScript branch.
What the new data cache means to you:
  • The data cache will be rebuilt when OXPs are added or removed. Specifically, it will be rebuilt if the folders Oolite searches for files change, or if any of their modification dates change. Adding or removing a file within an OXP should trigger this; changing a file generally won’t, so OXP developers may still hit stale cache problems, but users will not.
  • The cache has changed format (as if you care) and, under Mac OS X only, moved to ~/Library/Caches/org.aegidian.oolite/Data Cache.plist. The old cache will be deleted.
  • The cache is now flushed (written to disk) after startup loading and every time you dock, rather than when you save the game. I only mention this because someone once expressed bafflement at getting repeated “data cache must be rebuilt” messages.

drumz
Competent
Competent
Posts: 36
Joined: Thu Jan 18, 2007 6:18 am

Post by drumz » Sat Mar 10, 2007 6:48 am

I wrote some code a while back that added joystick support for yaw a while back (about a month ago). Last time I tried it it didn't work. Not sure why, but I haven't had the time to fix it yet. I also added view control via the hat switch that worked as of a couple of weeks ago. If anyone wants to look at it check it out over in this thread:

http://www.aegidian.org/bb/viewtopic.ph ... c&start=60

There is one problem: I added so many options to the joystick config page they no longer all fit on the screen. Haven't looked into fixing this, either.

I have one suggestion on the yaw (don't know if this is the right place): make it much less effective than pitch. Dogfighting was WAY to easy, at least with a joystick. I could see where the keyboard would be a bit more difficult, but I still think yaw effectiveness should be reduced.

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 » Sat Mar 31, 2007 5:04 pm

I now – finally – actually have PList and JavaScript scripts running side by side.

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 » Sat Mar 31, 2007 10:41 pm

I’ve been fiddling around with the JavaScript environment, and updated the relevant wiki page. I don’t think this should affect anyone, since as far as I’m aware the only JavaScript OXP scripts are my and dajt’s test scripts. Summary of changes:
  • Changed and unified capatalization conventions. All identifiers are written in camelCase. Methods, properties and global variables start with a lowercase letter. Classes and global functions start with a capital.
  • Standardized on USAlien spelling, as is the norm in programming (and in Oolite internally). The only case I noticed was Initialise -> initialize. (Hey, that’s how the OED spells it, too.)
  • Renamed some methods.
  • Changed some semantics. In particular, player.call(), Log(), LogWithClass(), mission.markSystems() and mission.unmarkSystems() can now take an arbitrary number of parameters, and awardCargo() now takes the type before the quantity (although ideally this would be exposed as player.cargo[type] += quantity instead).
I also added notes on things that are likely to change, and cases where I’m not sure of the design.

I’d like to be able to release an example of a reasonably big script converted to JavaScript. In order to do this, I’d need a test suite, i.e. a set of pilot files ready to activate each stage of the script. Anyone have something like that?

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 » Sun Apr 01, 2007 2:11 am

I’ve been spending most of the night changing the event handling. Instead of calling event handlers called STATUS_WHATEVER whenever the old script mechanism would run all the scripts, events are sent as and when noteworthy things happen. I won’t update the Wiki page now, what with it being four in the morning, but here’s my current test script. Almost all of it is known to actually work. Hopefully scripters will get some idea of how much more control this provides than the old "status_string equal STATUS_WHATEVER" approach. It’s also significantly more efficient. The “tickle” method is called at all the old polling opportunities, so if you do need that behaviour, or just idle updates, that’s possible too. (Remember, though, about the efficiency thing.)

Handlers for events that have an instantaneous effect are called didFoo(). For events that take time – mostly tunnel effects – there are willFoo()/didFoo() pairs.

Code: Select all

// This was originally written by dajt, but almost all the original script has been replaced.
this.name           = "JavaScript-test";
this.author         = "Jens Ayton";
this.copyright      = "This work is hereby placed in the public domain.";
this.description    = "A test OXP written using JavaScript. Based on a test script by dajt.";
this.version        = "2.0";


// Called after all OXPs are launched, before the game has begun.
this.startUp = function()
{
    LogWithClass("jstest.startUp", "Script startUp called.");
}


// Called when saved game is loaded, or player respawns after dying.
this.reset = function()
{
    LogWithClass("jstest.reset", "Script reset called.");
}


// Called when alert status changes.
this.alertConditionChanged = function()
{ 
    LogWithClass("jstest.alert", "Player alert condition changed to " + player.alertCondition + ", alert flags: " + player.alertFlags);
}


// Called before launch tunnel effect.
this.willDock = function()
{
    LogWithClass("jstest.dock.begin", "Player is docking.");
}


// Called at end of docking tunnel effect.
this.didDock = function()
{
    LogWithClass("jstest.dock.complete", "Player docked at" + stationName + ", which " + (dockedAtMainStation ? "is" : "is not") + " the system's main station.");
}


// Called before launch tunnel effect.
this.willLaunch = function()
{
    LogWithClass("jstest.launch.begin", "Player is launching.");
}


// Called after launch tunnel effect.
this.didLaunch = function()
{
    LogWithClass("jstest.launch.complete", "Player \"" + player.name + "\" has launched in a " + player.shipDescription + " into galaxy " + galaxyNumber + ", planet " + planetNumber + " (\"" + system.name + "\"), govt = " + system.governmentID + ", economy = " + system.economyID + ", tech level = " + system.techLevel);
}


// Called when player initiates witchspace countdown.
this.didBeginJumpCountDown = function(type)	// Type is one of: "standard", "galactic". Others may be added in future.
{
    LogWithClass("jstest.witchSpace.started", "Jump to " + type + " witchspace started.");
}


// Called if player cancels witchspace countdown.
this.didCancelJumpCountDown = function()
{
    LogWithClass("jstest.witchSpace.cancelled", "Jump to witchspace cancelled.");
}


// Called at end of witchspace countdown, if unsuccessful.
this.didFailToJump = function(reason)	// Reason is one of: "blocked", "too far", "insufficient fuel". Others may be added in future.
{
    LogWithClass("jstest.witchSpace.failed", "Jump to witchspace failed. Reason: " + reason);
}


// Called at end of witchspace countdown, if successful, or on entring wormhole.
this.willEnterWitchSpace = function(cause)	// cause is one of: "standard jump", "galactic jump", "wormhole". Others may be added in future.
{
    LogWithClass("jstest.witchSpace.begin", "Player is entering witchspace. Cause: " + cause);
}


// Called at beginning of witchspace tunnel effect; the destination system is already set up at this time.
this.willExitWitchSpace = function()
{
    LogWithClass("jstest.witchSpace.arrive", "Player is exiting witchspace.");
}


// Called after witchspace tunnel effect.
this.didExitWitchSpace = function()
{
    LogWithClass("jstest.witchSpace.complete", "Player exited witchspace into galaxy " + galaxyNumber + ", planet " + planetNumber + " (\"" + system.name + "\"), govt = " + system.governmentID + ", economy = " + system.economyID + ", tech level = " + system.techLevel);
}


// Called when auto-docking sequence begins (but not for insta-dock).
this.didStartAutoPilot = function()
{
    LogWithClass("jstest.autoPilot.on", "Player enabled autopilot.");
}


// Called when player cancels auto-docking sequence.
this.didAbortAutoPilot = function()
{
    LogWithClass("jstest.autoPilot.cancelled", "Player cancelled autopilot.");
}


// Station says player can't dock on account of being naughty.
this.didRecieveDockingRefusal = function()
{
    LogWithClass("jstest.autoPilot.refused", "Station refused autopilot docking.");
}


// Escape pod launched.
this.didLaunchEscapePod = function()
{
    LogWithClass("jstest.escapePod", "Player ejected... the sissy.");
}


// Player died.
this.didBecomeDead = function()
{
    LogWithClass("jstest.died", "Player died.");
}


// Called periodically, more or less.
this.tickle = function(status)
{
    LogWithClass("jstest.idle", "Ping! Status is: " + status);
}


LogWithClass("jstest.loaded", "Script loaded.");
Currently broken: willLaunch().
Known to be missing: enter/exit aegis; target changed; cloaking device events. What else?

User avatar
Flying_Circus
Dangerous
Dangerous
Posts: 118
Joined: Thu Dec 09, 2004 10:04 pm
Location: Hexham, UK

Post by Flying_Circus » Sun Apr 01, 2007 7:38 am

Excellent work, if I may say so.
And so I gave myself to God. There was a pregnant pause before He said "OK"
Image

User avatar
Star Gazer
---- E L I T E ----
---- E L I T E ----
Posts: 633
Joined: Sat Aug 14, 2004 4:55 pm
Location: North Norfolk, UK, (Average Agricultural, Feudal States,Tech Level 8)

Post by Star Gazer » Sun Apr 01, 2007 12:28 pm

Good grief... it's...The Life of Brian...!!!...
// Station says player can't dock on account of being naughty.
:lol: :lol:
Very funny, Scotty, now beam down my clothes...

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 » Sun Apr 01, 2007 1:29 pm

Not specifically LoB… it’s an overexposure to Terry Pratchett fans that makes me write like that, although there’s certainly a lot of Monty Python culture in that crowd.

In a completely un-scripting-related move, I’ve experimented with additive blending of glowy effects. This basically means that glowy bits can’t make things darker, which increases realism and mostly makes things look subtly better, although the engine glow will need adjusting and I expect to get complaints about the lasers.

It also has the potential to be faster than alpha blending.

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 » Sun Apr 01, 2007 2:33 pm

More fun with minor fix-ups: I’ve noticably improved performance of startup, respawn and script execution with about five lines of code. Specifically, for any passing coders, by caching the return value of -[Universe generateSystemData]. Who’d’a thunk it? Those profiler thingies are useful. :-) This should reduce periodic, combat, and ship-spawn stutter somewhat.

another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 5394
Joined: Wed Feb 28, 2007 7:54 am

Post by another_commander » Sun Apr 01, 2007 4:53 pm

How exactly would one go about installing the example script posted above? I tried following the wiki instructions, i.e. copying the script code into a file called script.js, which I put in the Config directory, but when I run the latest SVN snapshot, I get this error message:

Code: Select all

2007-04-01 16:50:38.000 oolite.exe[6176] [script.load.javaScript]: Trying to load JavaScript script oolite.app/Resources/Config/script.js
2007-04-01 16:50:38.000 oolite.exe[6176]   [script.javaScript.error]: ***** JavaScript error: can't open o: No such file or directory
2007-04-01 16:50:38.000 oolite.exe[6176]   [script.javaScript.error.details]: (null), line 0: (null)
2007-04-01 16:50:38.000 oolite.exe[6176]   [script.javaScript.compile.failed]: Failed to compile JavaScript script oolite.app/Resources/Config/script.js
2007-04-01 16:50:38.000 oolite.exe[6176]   [script.load.parseError]: *** Failed to load JavaScript script oolite.app/Resources/Config/script.js
The same error occurs even with the simple script template shown in the wiki page. Any ideas?

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 » Sun Apr 01, 2007 5:48 pm

Firstly, the idea is to put it in an OXP, not in Oolite itself. Doing that will effectively replace the standard script, which is not generally desireable. That’s not the source of your problem, though.

”can't open o:” seems to be the gist of it. It’s getting “o” instead of “oolite.app/Resources/Config/script.js”. The most likely reason I can see is that -[NSString fileSystemRepresentation] is doing the wrong thing… which is weird, since (looking at the GNUstep source) it appears to be doing the right thing, or at least something insufficiently wrong for that problem to occur.

Try this: in -[OOJSScript initWithPath:andContext:] (src/Core/Scripting/OOJSScript.m, around line 80), add:

Code: Select all

OOLog(@"temp.jsload", @"Loading JS from \"%@\", fileSystemRepresentation is \"%s\".", path, [path fileSystemRepresentation]);
You should get the same string twice. (Make sure you’re up to date first, I’ve made quite a few commits today.)

another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 5394
Joined: Wed Feb 28, 2007 7:54 am

Post by another_commander » Sun Apr 01, 2007 6:19 pm

Updated to latest svn (btw, ten commits in less than a day? Man, that's what I call productivity :-)). Tried your check, but unfortunately this is what I get:

Code: Select all

2007-04-01 18:05:34.000 oolite.exe[6648] [temp.jsload]: Loading JS from "oolite.app/Resources/Config/script.js", fileSystemRepresentation is "o".
2007-04-01 18:05:34.000 oolite.exe[6648] [script.javaScript.error]: ***** JavaScript error: can't open o: No such file or directory
2007-04-01 18:05:34.000 oolite.exe[6648] [script.javaScript.error.details]: (null), line 0: (null)
2007-04-01 18:05:34.000 oolite.exe[6648] [script.javaScript.compile.failed]: Failed to compile JavaScript script oolite.app/Resources/Config/script.js
As you see, the two strings are not the same. I also tried to place script.js in a "myoxp.oxp" folder and I got this:

Code: Select all

2007-04-01 18:05:34.000 oolite.exe[6648] [script.javaScript.error]: ***** JavaScript error: can't open A: No such file or directory
There seems to be a pattern. The path name of the script to load seems to be getting set to its first character only. So, oolite.app\etc.etc would become "o" and Addons\myoxp.oxp\etc.etc. would become "A". Not sure if this helps at all, though.

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 » Sun Apr 01, 2007 6:21 pm

That’s… pretty damn weird. Is your GNUstep-base up to date?

A few lines down in OOJSScript.m, try changing JS_CompileFile(context, obj, [path fileSystemRepresentation]); to JS_CompileFile(context, obj, [path UTF8String]);

another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 5394
Joined: Wed Feb 28, 2007 7:54 am

Post by another_commander » Sun Apr 01, 2007 6:37 pm

Success! UTF8String does the trick. Script loads and executes flawlessly. Thanks Ahruman. For the record, I am using GNUstep-base version 1.13.0.

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 » Sun Apr 01, 2007 7:04 pm

In the interest of hunting this down, here’s a test case I’d like you to run. Replacing main.m in Oolite should do it (make backups, yadda yadda).

Code: Select all

// main.m
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    [[NSAutoreleasePool alloc] init];
    
    NSString    *string = @"This is a/fake path/for testing.";
    const char  *utf8 = [string UTF8String];
    const char  *fsr = [string fileSystemRepresentation];
    
    NSLog(@"Strings should be identical.\nstring:  %@\n  utf8:  %s\n   frs:  %s", string, utf8, fsr);
    
    return 0;
}

Post Reply