Page 17 of 138

Posted: Sun Aug 31, 2008 1:34 am
by JensAyton
Some time last year I started fiddling with the idea of automatically translating legacy scripts to JavaScript. I wrote the beginnings of a proof of concept, but it never actually translated any code.

Yesterday, I watched a bunch of presentations about compiler architectures. None of it is directly applicable to my design, but it was inspiring anyway.

So now I have code that can translate the legacy scripts from Oolite 1.70 to something quite close to usable JavaScript. Not bad for a mere five hours of frenzied hacking…

There are a number of limitations, of course:
  • It only supports selectors that are used in the script I was testing on. Fixing this is mostly drudgery, not very complicated.
  • It only supports selectors that have JavaScript equivalents (call() doesn’t count).
  • It doesn’t support all of the syntax of the legacy script engine. In particular, it would break on a condition with more than two spaces in it, like something_string equal two words.
  • In its current state, it would do the wrong thing for non-player ship scripts.
  • The legacy scripting engine’s text expansion thing is pretty wacky. In particular, it rewrites all of every statement except the leftmost word before execution. When text expansion is used in a sane way, the translator can handle it – for instance, foo [local_a] bar %R [local_b] baz translates to "foo " + this.local_a + expandDescription(" bar %R ") + this.local_b + " baz". What it can’t deal with is variables being used to specify multiple parameters at once:

    Code: Select all

    ("set: local_thing foo 1", "addShips: my_[local_thing]")
    // Equivalent to:
    ("addShips: my_foo 1")
    I’d consider that pretty bad style, but if anyone is actually doing it I’d like to know. :-)
  • There’s room for optimization, in particular turning STATUS_EXITING_WITCHSPACE, STATUS_LAUNCHING and STATUS_DOCKING conditions into event handlers, and adding separate tickleDocked and tickleInFlight handlers for STATUS_DOCKED/STATUS_IN_FLIGHT conditions. Manually rewriting scripts to use appropriate event handlers will always be better, though.
I don’t intend to translate legacy code to JS in or before the MNSR, but I might roll this in as a command-line option for testing in 1.73 or so. It’s certainly not a priority, more a random hack that happens to have some relevance to Oolite.

Posted: Mon Sep 01, 2008 5:20 pm
by JensAyton
  • Added JS player.rank.
  • Added player.legalStatus (Clean/Offender/Fugitive, equivalent to legacy commanderLegalStatus_string; legalStatus_number is player.bounty).
  • Renamed Ship.shipDescription to Ship.name. (This no longer conflicts with player.name because of the player/player.ship split.)
  • Renamed Ship.shipDisplayName to Ship.displayName.
  • system.countShipsWithRole() now takes optional relativeTo and range arguments, like the other search methods.
  • Added system.countShipsWithPrimaryRole() for a pleasing symmetry.
  • Added system.pseudoRandomNumber (per-system number, less than 1; precision is 24 bits), system.pseudoRandom100 (per-system integer, less than 100 – the same as legacy pseudoFixedD100_number) and system.pseudoRandom256 (per-system integer, less than 256 – the same as legacy pseudoFixedD256_number).
    Note: The legacy versions reset the PRNG used to generate various other numbers, and pseudoRandom100/pseudoRandom256 preserve this behaviour; pseudoRandomNumber does not.

Posted: Mon Sep 01, 2008 5:34 pm
by another_commander
Ahruman wrote:
  • :tnearest role – sets the player’s target to the closest ship with the specified role. Example. :tnearest coriolis
  • :find expression – sets result to an array of entities matching expression, which is a predicate using the variable entity. For example, to find all planets, use: :find entity.isPlanet
  • :findS expression – similar to :find, but only looks for ships. Example: :findS ship.scanClass == "CLASS_BUOY"
  • :target expression – like :findS, but sets the player’s target to the closest found object.
This does not seem to work as expected under Windows, at least. When I use :tnearest coriolis, I just get echoed on the console:
player.ship.target = system.shipsWithRole("coriolis\n", player.ship)[0]. Note the newline in the role string. However, if I type the actual command fully (without the newline) instead of the macro, targeting the Coriolis works.

Posted: Mon Sep 01, 2008 6:13 pm
by JensAyton
Ahh, nasty. The Python console should be stripping that newline, but it’s an easy fix for the console script to do it redundantly.

Posted: Mon Sep 01, 2008 6:26 pm
by JensAyton
Incidentally, the script converter can now fully convert the following world scripts:
  • Oolite 1.65
  • Oolite 1.70
  • Assassins 1.3
  • Asteroid Storm 3.46
  • Ionics 1.2.1
Assassins doesn’t convert properly because of bona fide errors. Whether the converted scripts actually work is a different, harder question. :-)

Posted: Mon Sep 01, 2008 10:11 pm
by LittleBear
Will fix the two typos Master and Commander. Its on my things to do list, after sorting out USI trial for Wed and going though ten handed Internet Brothel case. To many RL uncompleted missions on my F5 screen ATM! Think both are C&P errors by me though, rather than a conversion problem.

Posted: Tue Sep 02, 2008 9:07 am
by Star Gazer
LittleBear wrote:
...ten handed Internet Brothel case...
:shock:

...must be the virtual equivalent of a moment in my mispent youth of 5 people in the same bed... :oops:

...

Posted: Tue Sep 02, 2008 10:17 am
by Lestradae
Star Gazer wrote:
... my mispent youth of 5 people in the same bed...
Misspent? Why misspent? :lol:

Posted: Fri Sep 26, 2008 8:54 am
by JensAyton
Fixed missile collision bug (thanks to Eric Walch).

Posted: Sun Sep 28, 2008 5:18 pm
by JensAyton
New shader uniform types in shipdata.plist:
  • randomFloat (a random number is generated when the ship is spawned, like the entityPersonality binding, but you can have as many as you want).
  • randomUnitVector (a vec3 of length 1, in a random direction, equivalent to JavaScript Vector.randomDirection())
  • randomVectorSpacial (a random vec3 with the same distribution as Vector.random())
  • randomVectorRadial (a random vec3 with the same distribution as Vector.randomDirectionAndLength())
  • randomQuaternion (a random unit quaternion, as a mat4x4, or vec4 if asMatrix is set to no)
All of these except randomQuaternion can be scaled using the scale key in the uniform definition dictionary. For example, this sets up a random vector with a magnitude of five:

Code: Select all

uniforms =
{
    uRandomFive =
    {
        type = "randomUnitVector";
        scale = 5.0;
    }
}
Additionally, in 1.72 it will be possible to specify a vec3 uniform as an array, as in:

Code: Select all

uniforms =
{
    uVector = (1, 2, 3);
    // Equivalent that works in 1.71:
    uVector2 =
    {
        type = "vector";  // "vec3" also works
        value = (1, 2, 3);
    }
}

Posted: Mon Sep 29, 2008 9:48 am
by JensAyton
Under Linux, log output is now written to ~/.Oolite/Logs/Latest.log (backing up the last log to Previous.log), rather than sending it to stderr and hoping someone’s listening. OXP verifier logs will also appear at ~/.Oolite/Logs/<OXP name>.log. I intend to do the same under Windows, once we work out an appropriate location for the log files.

Posted: Mon Sep 29, 2008 12:39 pm
by Micha
Shouldn't all per-user files under Windows go into the users app-data directory?
ie:
C:\Documents and Settings\{username}\Application Data\Oolite\*

Of course this would need to be read from the registry in case it's been changed.



As a sidestep, would it make sense under Linux to move the ~/oolite-saves directory to ~/.Oolite/Saves to reduce homedir clutter?

Posted: Mon Sep 29, 2008 12:49 pm
by another_commander
I am generally a fan of programs that contain themeselves in their own little space and don't spread files all over the place.

For this reason (as I have already stated in the internal), I would prefer if the log file of the Windows version could simply go to the Oolite root folder (e.g. d:\games\oolite).

Posted: Mon Sep 29, 2008 12:56 pm
by Thargoid
Why not make a new sub-folder out of the Oolite root and put all the logging in there (including StdErr and StdOut)?

Would be a lot simpler and more collected. I would also support the idea of not using the Windows route of using docs & settings, always find that a pain when apps use it and you have to chase down a whole other branch of the drive tree to find anything.

Posted: Mon Sep 29, 2008 4:03 pm
by Micha
another_commander wrote:
I am generally a fan of programs that contain themeselves in their own little space and don't spread files all over the place.
In general I definitely agree with you there, however imho user-generated content (in this case save-games and preferences, and possibly the log files) should be stored in the users home directory (whatever that may be for the current platform). After all, if I uninstall the program I don't want to lose my content.

Furthermore if I'm on a multi-user machine, I don't necessarily want other users to access my content.

As for not spreading files around, I've just spent 2 days and finally gotten oolite setup to compile on my Windows laptop so I can hack while I'm out and about and it's defaulting to save in C:\oolite-saves.. I'm guessing this is not what it should be doing?


<EDIT>
I just worked out that GNUstep under Windows uses the HOMEPATH, which wasn't being set in my dev environment, hence, c:\.
And for an installed Oolite, it's a simple matter of editing the RunOolite.bat file to set

Code: Select all

HOMEPATH=%APPDATA%\Oolite
</EDIT>