OXP howto dockable stations

From Elite Wiki
Buoy Repair GRS station by Svengali

The 4 chapter tutorial was written back in 2009. But the stuff beneath/links are up-to-date (2024).

Introduction

A small tutorial by Svengali about making a Station dockable in Oolite.

I'll try to show you what Oolite expects from you to make a Station-Entity dockable and where the limits are.
A lot of users have asked this question in the past and sometimes it's a bit tricky to get it working. But it's really no magic.

Before we'll start, you should be familiar with modelling and texturing and a bit knowledge about setting up the structure of oxps won't hurt too.

For a deeper understanding you should take a look in the following pages - just in case .-)

Chapter I

Point A - Absolute

The first step is to understand the basics - how Oolite is calculating positions and distances. Don't worry, it's not so hard and we won't explore the Maths behind it. It only needs some practice. So let's begin.

Each Star-System in Oolite (ie every system of the 256 in every galaxy/sector) has a Middle-Point (0,0,0). You can imagine this as the BIGBANG-point.

This is the 'Absolute Middle-Point' (Point A) and is the Reference-point for every single Entity in Oolite. Planets, Moons, Stations and Ships are positioned in relation to this point! Everything is!

You can see the relation to Point A in action by activating the FPS display (see Display Frame Rate).

The displayed coordinates are translated to another Coordinates-System (here 'pwm' instead of 'abs'), but you'll get a feeling for it. For more information about the Coordinate-Systems see

Point E - Entity

Now the fun starts. Let's take a look at the picture "Point E".

Every Entity (Ship, Station, Asteroid, Cargo Cannister, etc.) has its very own Middle-Point (Point E) that is used to determine the Entity's position in space in relation to the Absolute Middle-Point (Point A) and also to calculate the distances and relative positions of these Entities to each other. This point also defines (in conjunction with other parameters such as the Ship's mass) the Entity itself (e.g. Oolite places the model's vertices in relation to that point - and can then check for collisions or laser-beam hits) and is also used to place the Subentities if declared (eg. flashing lights or a docking pad).

The Entity's Middle-Point (Point E) is absolute (0,0,0) for the Entity itself AND relative (e.g. -12356.3, 20582,8, -238.76), because it is set in relation to the Star-Systems Middle-Point (Point A). This means positioning a Entity has to be seen in relation to Point A!

To talk about two middle-points sounds confusing, but it gives Oolite the possibility to calculate everything a lot faster and is easier to handle, because you only have ONE fixed point (Point A) and everything else (or their Point E's) is set in relation to this point!


Let's take a look in one possible way to add a Entity that uses Point A as reference.

 system.legacy_addShipsAt('trader', 1, 'abs', [-10,20,30]);

As you can see we're trying to create 1 trader. The Reference-Point is Point A and we are trying to position the trader at absolute X = -10, Y = 20 and Z = 30. Point A is somewhere near the Witchpoint Beacon, so we would have to move to this point to actually see this ship. So a ship's middle-point (Point E) is related to the Star-System's middle-point (Point A) and we'll get a absolute position for this Entity in the Star-System (e.g. [-10,20,30]).

In Javascript we can access this position, change it or calculate other things in relation to it.

You might think that's it - basics finished.

But, no - wait a moment...

Point D - Docking

My last point is about how Oolite is doing the docking. With all that knowledge packed in, it is fairly simple to see that Oolite checks for positions and distances of Entities (Point E's) to each other. This is probably a time-intensive task, but the development-team is doing a great job and the Math behind it is pretty spectacular for noobs like me. (Thanks, Aegidian and Ahruman).

The docking procedure itself is simply triggered by another Point E, if a ship comes in range. This point is different from the ships' middle-points, so lets call it Point D. It's more a virtual sphere than a point, but as I've said above - no magic .-)

This point is invisible, like the other points, so no player will see this trigger. The docks you can see in the various Oolite stations are only there to give your eyes and brain something to work with. But internally this sphere has some side effects. The collision detection is disabled inside this sphere and reduced in a corridor along the Z-Axis. That's also the reason why a dock has always to be oriented to show along the Z-Axis.

But this can also cause some problems for players trying to dock. The trigger and the corridor are invisible and if you don't have the right angle while approaching you can pass the point where the collision detection is disabled/lowered. The result is then probably a Grande Finale: " - Press Space, Commander! - ".

Another very important note is that the docking-sphere is attached to the Main-Entity, even if a Subentity is used for the visual part!

Basics done. Confused? Don't worry - it will only get worse .-)

Chapter II - The right models

Positioning
Svengali's Notes: A few words about orienting the models!!! (Main-Entity: 0,0,0 and Subent: 0,0,0 or relative to Main)
X/Y have to be centered (in relation to the Main-Entity) and port_radius defines the movement on Z.
A few words about naming the models and naming conventions in general.
And names of textures have to be exactly (case-sensitive) the same as in .dat defined.
Please try to avoid using too many Vertices and Faces for your models - try to find the balance between visual quality and used processing time. The same for the textures - try to reduce the size and help to keep Oolite smooth and fast.
The slits dimensions are fixed (69mx69mx250m), only the visible part can be adjusted with the standard way. Chapter IV will show you two other technics to do it in a more flexible way.

Chapter III - Finalizing

shipdata examples
Svengali's Notes:
Some words about moving the Subentity via Quaternion for finetuning or in general.
Some words about how Oolite is finding the right Subent == dock
a. by role (docking-slit) and if not found
b. by name, so if 'dock' (LOWERCASE!!!) is used in the entityname it will be handled as docking-slit
c. if nothing is found and scan_class = Station Oolite will use a standard slit.
Remember: The slit itself has to be placed on the z-axis (X/Y = 0) and the port_radius defines Z.
Unfortunately all this means that you can't adjust the slits dimensions, only the visible part can be adjusted with the standard way. Chapter IV will show you two other technics to do it in a more flexible way.

Chapter IV - Advanced options

Main Entity
Sub-Entity
Scriptable
Svengali's Notes:
Way 1)
port_radius
port_dimensions
Some words about deprecated, but still working.
Way 2)
Scripted
Pro: Flexible positions
Contra: Slow and not failsafe

Snippets from elsewhere

  • Important: You need to include "station" or "carrier" as one of the "roles" in the Shipdata.plist, or docking will fail dismally, no matter the excellence of the dock itself!
  • Aegidian (2003-6?): Quick and easy instructions for Wings3D.
 1. Make a panel on your main model where the dock entrance will be. A rectangle 192x64 is ideal, but you can go bigger - and use different shapes.

 2. Assign the special material hole to the rectangle.

 3. While you have it selected make a note of the coordinates of the centre of the rectangle.

 4. As a separate model, make a cube then scale it to the dimensions of your rectangle and a depth of 250. So a cube scaled to 192 x 64 x 250.

 5. Select the face of the cube facing the same way as your dock entrance in (1.) and assign it the hole material.

 6. While it's selected choose Tools - Center - All from the menu to move that face to the origin.

 7. Select the object, and from the right-click menu choose Invert to turn the cube 'inside out'.

 8. Texture your new dock. And convert it to an Oolite .dat model file.

 9. Position the new dock as a subentity of the station, at the coordinates you noted down in (3.)

10. You should now be done. You can vary the shape of the dock entrance in stage 1. If you copy and paste the panel into a new model you can even use it to extrude the dock shape.


NOTE: This is specifically written for Wings3D, especially for lines like "Assign the special material 'hole' to the rectangle." Wings3D was written in a way that it couldn't support actual holes or gaps in the mesh at all, so if you wanted a hole in your object, you actually had to put a polygon there and assign it as a material called 'hole' so that when you exported it out of Wings it came out with a proper hole where the polygon with the hole material was - with other apps like blender you can just model your object with missing polygons where you want the holes to be (Griff, 2024)
  • Charlie on the above (2007): For those who prefer to use an alternate 3D package to Wings you don't have to use it for the hole material. Just chopping holes in your model & dock seems to work!
  • Killer Wolf (2022): I actually did a dockable asteroid, the hacker outpost and salvage gang that was incorporated into the Anarchies OXP according to a search. You could fly inside it and then into the docking bay itself so you could probably reverse engineer that if needed. I wrote a post about docks (2009) on page 2 of the "things I wish I knew.." thread. Beyond that stations like the Hathor Trade Station also have docking tunnels that might help.
  • Murgh (2022): For starters you just leave a 192m x 64m slit (material defined as a "hole" in the [station/dockable] model).. always facing the Z axis, with the hole's center at x=0 and y=0 if there will be rotation..
There are of course plenty of fine dock models you can directly borrow or modify, or build a 192x64x250 (or bigger) cube yourself, skinning its insides (In Wings3D, in "body mode", invert the dock's surfaces for UVmapping to look right) to your pleasure.. I'd recommend keeping the two models separate to make it easier (to keep distinct objects with regular and inverted texturing apart), since they will be two different .dat files and the unification of the two happens later in the shipdata.plist.

Some examples of more advanced stuff

Almost all OXZ Javascript scripts are now easily available through Hiran's Oolite Expansion Catalog (if you know which OXZ to look in!).

Docking

  • Tweaking Docking:
Docking sequence: BGS2 Doc (see Docking FX)
Docking experience due to station model: look at Killer Wolf's stations: Salvage Gang, Hathor Trade Station, Isis Interstellar Station
Welcome: HIMSN Naval Bases, SothisTC, Home System. HDBG can provide a welcome screen.
Adding description/depth/possibilities: see Black Monk Monastery, Royal Hunting Lodges & Galactic Navy OXP naval bases
  • Force-field over docking tunnel: see Svengali's BuoyRepair OXP and Cim's Rescue Stations OXP
  • Solid Door preventing docking: this has to be a sub-entity (the "door" in the Deep Space Dredger can be flown through): see TCAT OXP for an example
  • Buoys: There are some impressive Buoys out there. See Buoy (Oolite) for examples.

Invisibility

  • Making your station invisible from ASC/Telescope etc. See HIMSN's naval stations at G1 Xeer & G5 Tetiri. And the docking experience is unfriendly, too!

Activities inside the Station

Tweaking F3 shipyard screens (equipment sales, ship sales)

  • Tweaking TL levels: this is read-only. But see Montana05's multiple models with different TL's as a work around for this in S.I.R.F.
  • Changing Shipyard ships for sale
File:LaveInitialShipyard.oxz adds ships to the Lave shipyard but only at the start of the game, not later on.
Code for replacing all ships for sale with custom selection

Markets

  • Tweaking commodity markets:
See Shipdata.plist: "market", "market_broadcast", "market_capacity", "market_definition", "market_monitored", "market_script"
and the lengthy discussion at Secondary Market Definitions Defined which discusses pitfalls and gives more examples
New Cargoes: see Tianve v2.0 for an example, and the BB thread on updating the SothisTC stations (which includes tweaking New Cargoes and also positioning the station).

Missions

Mission Screens: HDBG and then Library OXP (more sophisticated - see Demos: Animator & Starmap) for better missions screens

Multiple Docking/External Docking Issues

Cim's 2024 response to a couple of issues (taken from here):

•Is the difficulty in allowing External Docking tied in with the dock needing to be along the Z-azis of the station?

That's only strictly true of rotating stations - because if the dock isn't on and aligned with the axis of rotation, the centre of the dock will constantly move in worldspace, so the flight pattern needed to dock with it becomes impossibly complex, unless you "cheat" with a frame callback to reposition the docking ship in a way which simulates the appropriate lateral thrust. (Because launching ships get clear fast enough, off-axis rotating docks can handle launches fine)

The more general case is that the dock needs to be aligned on the Z-axis of the *entity*, which would normally be a station sub-entity, and the sub-entity doesn't need to be aligned the same way as the station main entity. This is just a convention as it provides an easy way to say "which way is the dock pointing" without needing a separate "dock_direction" quaternion property - you sort that bit out when attaching the subentity to the main entity.


•Proximity-checking is a problem: to make a ship look like it's docked it needs to be so close it risks math-rounding error collisions.

This is what the "addCollisionException" function is for. Oolite_JavaScript_Reference:_Ship#addCollisionException

When it gets close enough in the external docking process, add the exception, then remove it once it's clear again.

The SOTL Altmap OXP I used for various experiments has a "resupply shuttle" component where shuttles will launch from a station, dock externally with a nearby freighter (fairly crudely, since I never got around to making custom models for either), transfer cargo, then undock and take the cargo back to the station - with use of that function to cover the loose edges as they get close.


Links

Tutorials:

Documentation:

BB Threads: