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:

Post by JensAyton » Sun Aug 05, 2007 1:59 pm

I now have ship scripts reacting to events and talking to each other. My test case involves a ship with three escorts. When the mothership is attacked (by anyone), it tells its escorts to attack the main station. Which, er, is obviously something all script makers have wanted to do since, like, forever. The fun part here is that it’s calling a custom method on the escorts’ scripts, with no specific support from Oolite.

Log chatter:
[scriptTest.mothership]: Telling 3 escorts to attack <StationEntity Coriolis Station 105>.
[scriptTest.escort]: Receiving orders from mothership - attacking <StationEntity Coriolis Station 105>!
[scriptTest.escort]: Receiving orders from mothership - attacking <StationEntity Coriolis Station 105>!
[scriptTest.escort]: Receiving orders from mothership - attacking <StationEntity Coriolis Station 105>!
Mothership script:

Code: Select all

this.beingAttacked = function()
{
	var escorts = this.ship.escorts;
	if (escorts)
	{
		LogWithClass("scriptTest.mothership", "Telling " + escorts.length + " escorts to attack " + system.mainStation + ".");
		
		function callEscortMethod(escort)
		{
			escort.script.scriptTestEscortAttack(system.mainStation);
		}
		escorts.forEach(callEscortMethod, this);
	}
	else
	{
		LogWithClass("scriptTest.mothership", "No escorts for me.");
	}
}
Escort script:

Code: Select all

this.scriptTestEscortAttack = function(target)
{
	// Method to be called by mothership script
	LogWithClass("scriptTest.escort", "Receiving orders from mothership - attacking " + target + "!");
	
	this.ship.target = target;
	this.ship.setAI("interceptAI.plist");
}
There are several bugs, including a confusing potential crasher, but the basic mechanism works.

I’ve also put up some documentation on the Script class.

User avatar
Commander McLane
Intergalactic Spam Assassin
Intergalactic Spam Assassin
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Re: Munge

Post by Commander McLane » Tue Aug 07, 2007 11:57 am

*cat wrote:I like the idea of Cmdr Mclane "munging" through the JS!
Wow! It really IS a word:
Mung (or munge) is computer jargon for "to make repeated changes which individually may be reversible, yet which ultimately result in an unintentional irreversible destruction of large portions of the original item." It was coined in 1958 at the Tech Model Railroad Club, at the Massachusetts Institute of Technology.

OR

"Dirt and vegetation that fills a crack."
Oh, thanks for the lesson! Actually it was just a mis-spelling for "munch", though. :oops:

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 » Tue Aug 07, 2007 2:29 pm

:lol: :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 Aug 26, 2007 8:19 pm

I’ve been somewhat off Oolite work recently. Rather than procrastinate or go off and do something completely different, I’ve been working on something peripheral: the Mac-only debug OXP.

In 1.69, Debug Menu.oxp works as an enabler – its presence, and the support files it contains, activates debugging code in Oolite. In the next release, it will contain the debug code itself, working like a plug-in. This means I can add loads of stuff to it without complicating the Oolite application much.

I’ve now added to items of stuff. The first is F-Script. This is not yet another OXP scripting language; rather, it’s a dynamic scripting language which works directly with Objective-C objects. This makes it a very powerful (and very dangerous) debugging tool.

The other is an interactive JavaScript console. This makes it a lot easier to poke around at the JavaScript runtime: rather than writing a ship script, running Oolite, waiting for it to start, creating the appropriate ship type (the existing Debug Menu OXP already has a Create Ship… command) and looking to see what’s going on in the log, I can call methods and inspect properties in any ship’s script or Oolite-provided scriptable object. I expect this to be useful for OXP development as well as for implementing scripting support. :-) For extra fun, the console is partly implemented in JavaScript. Specifically, commands entered into the console are passed, unmodified, to a method in the script “oolite-mac-console.js”, which is part of Debug.oxp but can be overridden, allowing for a great deal of customization. It looks like this:

Image
Bold lines prefixed with > are commands. In this example all the other lines are responses to the commands, but in general use warnings, errors and long messages pertaining to other scripts running in the game will also appear in the console.

The first three commands in the screen shot are your basic using-an-interactive-shell-as-a-calculator example. The first one uses invalid syntax to generate a warning (although the warning is somewhat unhelpful since it always points at an eval command in the JavaScript part of the console implementation; a custom warning for this case would probably be helpful). The fourth command, :dl player.position, is not JavaScript; it’s a macro.
Macros are (in this context) shortcuts for JavaScript commands. The line after the command shows the expansion of the macro, that is, the code it’s translated to: dumpObjectLong(eval("player.position")). This is followed by the results of running the dumpObjectLong function. The next command, :showM dl, shows the definition of the dl macro. The macro could have been defined using the macro :setM dl dumpObjectLong(eval(PARAM)), but this was not needed since it’s predefined in the console script. Macros provide a simple way to abbreviate commonly-used commands, and the macro system is implemented entirely in JavaScript for easy customization or replacement.

The sixth command simply demonstrates the ability to enter multi-line commands. This can be done by pressing option-return (this works in most Cocoa text fields, incidentally) or by pasting multiple lines.

The last one demonstrates the ability to get a colourful and unhelpful error message for typing something other than valid JavaScript code (or a macro).

Oh, those strange people who are addicted to white-on-black consoles will be relieved to know that the colours can be customized in a plist. ;-)

On matter of Mac-onliness:
Mac-only features obviously suck, but making these features cross-platform would require a great deal of extra work. It would either require me to implement a relatively complex UI system within Oolite, or to write a separate application to communicate with a debugger object within Oolite. The latter might end up being a good idea for the Mac side anyway, but porting such an application would require more active Linux and Windows developers with a greater familiarity with GNUstep. As it is, the debug OXP consists of tools that are useful to me in working on Oolite, which also happen to be useful for developing OXPs.

dajt
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 365
Joined: Tue Aug 17, 2004 7:05 am
Location: Orange, NSW, Australia
Contact:

Post by dajt » Mon Aug 27, 2007 12:02 am

Very cool.

The separate app for the console communicating via TCP/IP or something sounds like the way to go. At least then it is available to be ported on Win32 and Linux, rather than there being no option at all.

Simple TCP/IP code might just compile and run under GNUstep[*]. The GUI would be a different matter of course.

I guess F-Script is a problem for us non-Mac people too.


[*] As if anything useful just compiles and runs under GNUstep.
Regards,
David Taylor.

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 » Mon Aug 27, 2007 12:59 pm

dajt wrote:Very cool.

The separate app for the console communicating via TCP/IP or something sounds like the way to go. At least then it is available to be ported on Win32 and Linux, rather than there being no option at all.
Actually, I was thinking Distributed Objects, assuming this works with GNUstep Foundation. It shouldn’t be a problem (hah) to combine Foundation code with a native UI. Or, of course, a GNUstep UI. (*listens to the sweet screams of dismay*)

Anyway, when it’s finished-ish, I’ll look into what parts would need to be in Oolite and what parts would be moved to the console app, at which point I’ll have a concrete idea of the communication needs.
I guess F-Script is a problem for us non-Mac people too.
Yep. The F-Script links page mentions Guile; see the bottom of the GNUstep developer tools page.

I suspect porting F-Script would be problematic due to the bugs in GNUstep’s implementation of NSMethodSignature I discovered in implementing GLSL bindings (as grumbled about here, under “But, er… what is it?”).

dajt
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 365
Joined: Tue Aug 17, 2004 7:05 am
Location: Orange, NSW, Australia
Contact:

Post by dajt » Tue Aug 28, 2007 6:46 am

Ahruman wrote:Actually, I was thinking Distributed Objects, assuming this works with GNUstep Foundation.
There is a reason I didn't mention them. And it isn't because I don't know what they're for.

I think when we're talking cross-platform code and one of those platforms is GNUstep, plain old TCP/IP with a simple text-based protocol would be the quickest and most reliable thing to get going.

You Mac people with your fancy ideas. Just because it works on *your* platform!
Regards,
David Taylor.

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 » Tue Aug 28, 2007 8:22 am

dajt wrote:There is a reason I didn't mention them. And it isn't because I don't know what they're for.
Heh.

Distributed Objects are a conceptually simple RPC mechanism: cast a magic spell, then talk to objects in another process (possibly on another machine). Client code (adapted from src/Cocoa/Groolite.m):

Code: Select all

NSConnection *connection;
id <OOJavaScriptConsoleServer> server = nil;

connection = [NSConnection connectionWithRegisteredName:@"org.aegidian.oolite.javascriptconsole" host:nil];
if (connection != nil)
{
    server = [connection rootProxy];
    // Server is a proxy for an object in other process which can be treated like any old object
    if ([server registerClient:self])
    {
        [server retain];
    }
    else
    {
        server = nil;
    }
}
Server code (adapted from Growl):

Code: Select all

NSConnection *connection;
connection = [[NSConnection alloc] initWithReceivePort:[NSPort port] sendPort:nil];
[connection setRootObject:self];
if (![connection registerName:@"org.aegidian.oolite.javascriptconsole"])
{
    // Handle error here
}
In use, the client (an object in Oolite) would do things like:

Code: Select all

[server appendLogMessage:message];
Still, a TCP/IP protocol wouldn’t be a significant problem; it looks like a simple opcode + UTF-16 string protocol would cover it.

(Followup-To: oolite-linux-devs)

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 » Fri Sep 07, 2007 5:31 pm

As per elsewhere: reworking of Role system. Each ship now has a set of roles its type can have, as well as a “primary role”, which is the role for which the specific ship was spawned. Previously there was confusion (within Oolite’s own code) about which of these purposes the “roles” property served at runtime, and in fact it could be either depending on how the ship was created.

Additionally, the tests used to identify thargoids and police have been standardized (they were done differently in different parts of the code) and made sensible. scanForThargoid and scanForNonThargoid should work as expected in the next release.

Regarding the previous messages in this thread, the JavaScript console support has been modified to use a client-serverish model, providing a path by which non-Mac versions could be implemented. No-one is working on that at the moment, though. Note to passing programmers: a console would not have to be implemented in Objective-C.

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 » Fri Sep 14, 2007 11:22 pm

Work on timers for JavaScript.

A timer will call a given function after a specified delay, and optionally repeatedly after that at a specified interval. By default, timers will stop firing when the game resets (i.e., when the player dies or loads a new game), but it is possible to override this by specifying that the timer should be persistent.

A timer can be explicitly stopped with the stop() method, and restarted with the start() method. The stopping when the game resets is equivalent to calling stop(), and can be restarted the same way. If a repeating timer is stopped and restarted, it will continue to run in rhythm, that is, the next time it fires after the restart will be a multiple of the interval after the first fire time.

Timers are not guaranteed; if more than one interval is missed, the timer will only fire once. Since frame rate is finite, they will tend to fire slightly after the “correct” time.

Examples:

Code: Select all

this.doSomething = function()
{
   // Do something here
}

this.doSomethingElse = function()
{
   // Do something else here
}

// Call this.doSomething() after one second
this.timerA = new Timer(this, this.doSomething, 1)

// Call this.doSomethingElse() every five seconds, even if the game resets.
this.timerB = new Timer(this, this.doSomethingElse, 5, 5)
this.timerB.isPersistent = true

// Increment this.counter every 3 seconds, starting one minute from now
this.counter = 0
this.timerC = new Timer(this, function() { this.counter++ }, 60, 3)
I haven’t decided yet what the lowest permissible timer interval will be, but probably a quarter of a second. Timers should be used for essentially anything that can’t be done with an event handler, and in particular should be preferred to tickle() in all cases.

Unlike tickle() and legacy scripts, timers can fire in almost any context, including on the load screen, the demo screens at startup etc. They can’t fire when the game real time clock is frozen, i.e. when paused but also in Mac OS X load/save dialogue boxes and menu handling.

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 Sep 15, 2007 2:27 pm

Timer implementation complete, and documented.

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 Sep 15, 2007 3:32 pm

Implemented and documented global object '''clock'''. This dump should be largely self-explanatory:

Code: Select all

2084004:17:13:42:
    absoluteSeconds = 7.0918959975242615
    seconds = 180058007622.0922
    minutes = 3000966793
    hours = 50016113
    days = 2084004
    secondsComponent = 42
    minutesComponent = 13
    hoursComponent = 17
    daysComponent = 2084004
    clockString = 2084004:17:13:42
    isAdjusting = false

User avatar
Arexack_Heretic
Dangerous Subversive Element
Dangerous Subversive Element
Posts: 1878
Joined: Tue Jun 07, 2005 7:32 pm
Location: [%H] = Earth surface, Lattitude 52°10'58.19"N, longtitude 4°30'0.25"E.
Contact:

Post by Arexack_Heretic » Fri Sep 28, 2007 10:10 pm

page6:

Thorgorn Threat ships get shaders from Freaky Thargoids, which shouldn’t be happening any more. Actually, this is due to the use of like_ship.

This was partly intentional.
Giles was freaked out about it, so I want to see it.
I use the same texture, hence the same shaders can apply.
Did you 'fix' this?
If so, I'll have to make a specific 'freaky Thargorns' OXP. ;)
http://aegidian.org/bb/viewtopic.php?t= ... c&start=75
Riding the Rocket!

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 Sep 29, 2007 8:54 am

Arexack_Heretic wrote:I use the same texture, hence the same shaders can apply.
Did you 'fix' this?
Using the same texture will not, by itself, have this effect. using like_ship and then using a texture name (or rather, material key) used in the ship you’re like_shiping from will have this effect unless you override materials/shaders, which is expected. It’s simply like_ship working in the usual way.

I thought crossing it out was a hint that I no longer considered it to be a bug. :-)

User avatar
Arexack_Heretic
Dangerous Subversive Element
Dangerous Subversive Element
Posts: 1878
Joined: Tue Jun 07, 2005 7:32 pm
Location: [%H] = Earth surface, Lattitude 52°10'58.19"N, longtitude 4°30'0.25"E.
Contact:

Post by Arexack_Heretic » Sat Sep 29, 2007 3:47 pm

yeah. It's cool. 8)
Riding the Rocket!

Post Reply