Page 1 of 1

Request: Tractor Beam

Posted: Mon May 30, 2016 12:23 am
by Captain Obvious
Hello everybody. I've been playing on and off for a while and finally joined the forums. I was thinking that a simple and practical mechanism to help gather crap would be a tractor beam -- this is especially true when the cargo is travelling faster than your max speed. This would likely have to replace the gravity-like effect of the fuel scoops, which ends up causing me a lot of grief when items get flung or when they end up hitting me in the rear after I miss them.

The physics will have to be fudged a little since in real space there is no maximum speed except C (speed of light). What we would really deal with is kinetic energy of which there is no maximum. Each object would have a set mass and the tractor beam would have a certain amount of pull. So if you were 10 tonnes and the object you were pulling was 1 tonne, you would be pulled towards it by 1/10th that it would be pulled towards you, etc.

So to make this work well in oolite, it would probably be fair to say that you can only use tractor beams on objects w/o shields. I don't suppose objects (ships, asteroids, bases, cargo, splinters, escape pods, etc.) currently have a "mass" value do they? If not, then the first step would be just to make it work on scoopables and give them all a mass of one tonne. The second step would be to fake a mass for ships (presuming derelict ships?) based upon their price and then just treat your own ship as immovable (for the sake of easy incorporation with game physics).

Anyway, it should probably have a maximum distance at which it is effective and then a maximum pull strength that it can apply. So perhaps your selected target must be a maximum of 8km for there to be any affect at all and an optimal range of 500m where the beam reaches full strength. The maximum affect would be to change the vector of the object in the direction of the delta of the two vectors (so the difference in between your ships location and the object's location) and by a maximum force that would change the velocity of a one tonne object by 5km/s or some such (again, using simplified physics). Of course, the beam should emit from your fuel scoop so as to pull in that direction.

The math is basically as follows:
Adjust the ship's coordinates to the mouth of the fuel scoop (I'm not sure exactly where that is or how it's calculated). So o is the object's vector and s is the ship's vector

Code: Select all

// constants
TRACTOR_MAX_PULL = 5000 // per second
TRACTOR_ENERGY_BASE = 1 // cost per second just for having it active (I don't know actual units used for energy)
TRACTOR_ENERGY_PULL = 20 // cost per second for pulling with max force
GAME_FRAMES_PER_SECOND = 60?

delta[x, y, z] = [o.x - s.x, o.y - s.y, o.z - s.z]
distance = sqrt(o.x * s.x + o.y * s.y + o.z * s.z)

if distance > 8000 then
    // no effect
    force = 0
else if distance < 500
    // maximum possible effect
    force = 1
else
    // apply law of inverse squares
    force = distance / 500
endif

delta.w *= force * TRACTOR_MAX_PULL  / GAME_FRAMES_PER_SECOND
energy_used = (TRACTOR_ENERGY_BASE + TRACTOR_ENERGY_PULL * force) / GAME_FRAMES_PER_SECOND
// apply delta
// consume energy
Then you apply that delta to the object's vector, but it's been a while since I've done game programming and I've forgotten the math for that particular operation. :) And again, this skips the physics of mass, so assume it's for a one tonne object and for larger objects, divide delta.w by the mass of the larger object. This would make pulling ships very slow however, so another option is to allow for greater force of more massive objects as the cost of increased energy, but that's the basic idea.

EDIT: Changed energy to have a min usage per second and a consumption per force pulled.

Re: Request: Tractor Beam

Posted: Tue May 31, 2016 11:32 am
by Norby
Fun to see your idea just a few days after I implemented one in [wiki]Star Destroyer[/wiki] to help fighters arrive back into the dock below the hull. Otherwise the core AI refuse to enter into the collisionRadius of mothership which is a very large sphere around this huge ship.

Your idea is much more detailed and I do not know whether I will take this job once, but if you are interested then you can take a look on my simpler solution within StarDestroyer_1.4.oxz in Scripts/stardestroyer-fighter.js near line 170.
The most relevant lines:

Code: Select all

//apply "tractor beam" to pull this fighter to the scoop
var v = scooppos.subtract(ship.position); //the lenght follow the distance from the scoop
ship.velocity = v.direction().multiply(200).add(v.multiply(0.4)).add(owner.velocity);
The force is inversion of the distance to slow down near the dock but has a base value (200) to do not slow down too much at the end. I adjusted the constants in many retries until I got these which pull fighers enough fast but without smashing them into the dock. Must add the owner's velocity also to follow the mother's movement.

Figuring out the current absolute coordinates of scoop position is longer:

Code: Select all

        var scooppos = owner.position;
        var sp = this.$OwnerScoopPos;
        if( !sp ) { //first time read scoop pos from shipdata.plist
            var shipdata = Ship.shipDataForKey(owner.dataKey);
            if( shipdata ) {
                sp = shipdata["scoop_position"];
                if(sp && sp != "undefined") {
                    sp = sp.split(" ",3);
                    if( sp && sp.length == 3 ) {
                        this.$OwnerScoopPos = sp;
                        //log(this.name, owner.name+" scoop_position:"+sp); //debug
                    }
                }
            }
            if( !this.$OwnerScoopPos ) { //no scoop pos in shipdata so make one
                this.$OwnerScoopPos = [];
                this.$OwnerScoopPos[0] = 0;
                this.$OwnerScoopPos[1] = -20;
                this.$OwnerScoopPos[2] = 0;
                sp = this.$OwnerScoopPos;
            }
        }
        scooppos = scooppos.add(owner.vectorRight.multiply(sp[0]))
                            .add(owner.vectorUp.multiply(sp[1]))
                            .add(owner.heading.multiply(sp[2]));
The reason is performance, I store the values from shipdata into an array in the ship script as a cache.
I hope this help. ;)

Re: Request: Tractor Beam

Posted: Wed Jun 01, 2016 11:55 am
by Captain Obvious
Wow, I don't know anything about openapp / gnustep or oolite's sources or add-ons other than it's based off of what became coccoa and I'm guessing that means' it's Objective C. I haven't learned Objective C yet and I had originally thought that it would go away, but I guess it hasn't and wont' if that's what Apple is using for their "apps" (a term I've always hated). However, what you posted looks like JavaScript, is that what it is? Anyway, I remember how to calculate an offset now based upon rotation using a 4x4 matrices, although I haven't done that in a while.

I saw the Star Destroyer mod and I'm impressed by the scope that you've taken on there! I haven't tried it yet. For a simple tractor beam used by a player, we don't need to slow the item down as long as we aren't slinging it into the windshield. :)

EDIT: btw, how do you get a wiki account to edit pages on the wiki?

Re: Request: Tractor Beam

Posted: Wed Jun 01, 2016 11:59 am
by Cody
Message the Wiki Wizard for a Wiki account* - and yes, JavaScript is used.


*Please edit respectfully. I ask that as the other day I found someone had edited my user page, something which I object to!

Re: Request: Tractor Beam

Posted: Wed Jun 01, 2016 3:04 pm
by Norby
Yes, the core game is in ObjC but [EliteWiki] addons are in .plist and .js files.
My most used wiki page is [wiki]Oolite JavaScript object model[/wiki], the content looks addictive. ;)

Perforating windshield is a nice problem, I used the AI script before triggering the beam to go below the mothership, using waypoints offered by the core around the ship to avoid collision. It is possible to make something similar in js without AI also but maybe simpler to turn on the beam only if the target is below the horizont.

Another thing is arrival detection, maybe the core feature will work well if you manage to always hit the first half of the bottom hull. If it is not enough (in my case this was not enough) then a function called in a timer can check the distance often and do pickup if the target is enough near. Too near mean less than the pod can travel between timer checks including the movement of the mother if arrive frontwise. Could be tricky if the player wanna scoop when using injectors, and probably there are other rare cases what simpler to left out than implement.

It is a good game to think about possible cases and try to make solutions on them. :)

Re: Request: Tractor Beam

Posted: Thu Jun 02, 2016 12:33 pm
by Captain Obvious
Cody wrote:
Message the Wiki Wizard for a Wiki account* - and yes, JavaScript is used.
Thanks!
Cody wrote:
*Please edit respectfully. I ask that as the other day I found someone had edited my user page, something which I object to!
Well that's not nice! Be sure that you watch pages like that so that you get an email if they are changed so you can undo vandalism.

Re: Request: Tractor Beam

Posted: Thu Jun 02, 2016 12:39 pm
by Captain Obvious
Norby wrote:
Yes, the core game is in ObjC but [EliteWiki] addons are in .plist and .js files.
My most used wiki page is [wiki]Oolite JavaScript object model[/wiki], the content looks addictive. ;)
That's cool. When I was working on Glest, we added a Lua interface and I was working with this library that made neat wrappers for your C++ classes, but I didn't get to finish that part. When playing I'm sometimes getting low frame rate, often it's *right* when I'm trying to pick up a piece of cargo and need the split-second reaction from my keypresses, so I hope that's not some performance flaw from something eating CPU in javascript.

Thanks for the reference!
Norby wrote:
Could be tricky if the player wanna scoop when using injectors, and probably there are other rare cases what simpler to left out than implement.
hehe, well if they want that then good luck to them. :)