Tutorial for creating a simple station. (Help needed!)

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: another_commander, winston

Post Reply
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Tutorial for creating a simple station. (Help needed!)

Post by ocz »

Just to prevent any misunderstandings, >>I<< need a simple tutorial to create a station. But there is no reason to not make this a guide for others while we're at it. Maybe some sticky threat might even refer to it. We'll see.

This header posting will be, where the complete tutorial should be in the end.

I already tried to create my own station OXP, read all wiki entries on this I could find and dissected other OXPs to no avail. As I couldn't spawn even one model I couldn't make progress from there on. Even worse: I was unable to find the source of the error. Was it the model, the shipdata.plist entry or did I call the addShips() method wrong? No idea. Looking for something on base of guesses for hours is no fun. It's worse, if success just doesn't come.

This tutorial should include the following steps:
  • Creation of a simple model (a cube) in Wings3D. (done)
  • Exporting and converting it with the python script. (done)
  • Integrating it into an OXP. (done)
  • Creating a shipdata.plist for it. (done)
  • Spawning it.(done)
  • How to place it at certain coordinates and to orientate it (spinning). (just a few simple examples)
  • Adding the standard docking bay of the Coriolis station. Build a own one. (Done)
  • Understanding how to place flashers (optional)
  • Understanding other simple sub-entries. (optional)
This should conclude it.

It's late now. I'll add the description for the cube and its exportation tomorrow. [wiki]OXP howto model[/wiki] already gives clear answere to this, but a short step-by-step summery can't hurt. I'll write that part myself.

EDIT:
Tutorial:
Welcome to our little orbital and interplanetary space station building workshop. In this tutorial we will go through the most important steps to build a very, very plain station. If you feel, that we might have skip an important step for you or haven't gone into the details of a step deeply enough, feel free to complain in the thread below. Who knows? You might even be heard. But we won't describe here detailed stuff, for example how to create a detailed model. There are lots of tutorials, that do that. This tutorials goal it to help you create your first station.

Setup:
Before we begin make sure you have everything you need:
  • We will use Wings 3D as modelling tool. (Offical page)
  • We need the script file Obj2DatTex.py (available here) to convert the created model into a dat-file for Oolite to use.
  • We also need Python 2.7 for running this script. (Official download page) There might actually be big deferences between the version of Python! The scripts won't run on version 3! So please install a version of 2.7 or at least a version 2. off sort.
  • If you haven't already installed it, you really should consider using the OXP Developer release of Oolite (Get it here. (Scroll down. It's there.))
In this tutorial I will use state-of-the-art versions of the software. This means sota now as I'm writing this threat. My versions likely won't be sota when you are reading this. For reference reasons I list the versions I'm using:
  • Wings 3D 1.5.4
  • Python 2.7.10
  • Obj2DatTex.py of 17 Jul 2012
  • Oolite 1.82 OXP Developer release
Modelling (part 1):
Alright. We're set. Start up Wings 3D. There should be a grit on grey background. Right click somewhere on the grit and select "Cube". (It should be the first entry in the menu.)

Did a cube appear? It should have. Good. The default cube you just created has a size of 2x2x2 units³. One unit is considered one meter. A 2m x 2m x 2m sized station is a bit small. We change that.
See these four depictions of cubes at the top center of the Wings 3D GUI? Mark the complete red, most right one, to select whole objects, and mark the cube. It should should have turned red now. Right click, click ".Scale Uniform." and hit the tab key. Has a window named "Numeric Input" appeared? You're doing fine so far. Type in "40000.0". That looks excessive, but your station is 2m wide and this will increase its size to 2m x 400 = 800m.
The cube is gone? Use your mousewheel or whatever you use to zoom to zoom out. There it is again.

We're done with the modelling for now. (That was quick, huh?) A cube is a fine example of elite style space architecture and makes a fine station. (IMO at least.) Keep in mind, that all too detailed models might look out of place for an elite universe structure (that much is just personal taste) and slow down the overall performance of the game.
Save your work somewhere were you'll find it again. Name it, well, "Cube".

Exporting the model (to *.obj):
Its time to export your work. Select the cube again and this time select "File" in the top menu bar and hover your mousepointer over "Export". In this menu you'll find the entry "Wavefront (.obj) ...", but you don't want to click that entry directly. There is a small window icon right beside it. Click on that one. In this new window under the entry "Tesselation" select "Triangulation" and press OK. There should be a file named Cube.obj in the same directory as your saved work.

Converting the model (from *.obj to *.dat):
The next part is tricky to describe as it might differ depending on which operation system (os) you are using. But first copy Obj2DatTex.py into the save working directory as the other files.
In most window based os, like Windows, the py-files (python script) are already linked to the python interpreter. Try to drag and drop Cube.obj onto Obj2DatTex.py and look if a file named Cube.dat appeared. If it did, you are done here and may skip to the next section.
If it didn't you now have to use the shell. I'm not going to describe how to open a command shell for every os here. You have to search for that yourself on the net. Use "how to open a command shell window" + your os name in a search engine of you choice.
In the command line of your shell type "python" and press enter. If you see the Python version number right at the beginning and the command prompt changed to ">>>", you are good. Make sure the version number of Python is 2.6 or 2.7 or at least something with a 2.7+ at the beginning. If the version number is wrong you either have installed the wrong version or another version that stole the spotlight. In this case, yet again, search the net to figure out how to call the right one. Exit the prompt with the command "exit()".
In case the "python" command didn't yield the Python prompt, you should read the Python F.A.Q. and, you guessed it, look yourself for an answer on the internet.
Change the prompt directory to the working directory. A quick way to do that in most os is to type "cd" into the prompt, press the spacebar one time, drag'n'drop Cube.obj onto the shell window and delete the characters "Cube.obj" from the command, leaving only the path behind. Press enter. Now type the command "python Obj2DatTex.py Cube.obj", press enter and see the magic happen. There you go: Cube.dat. If the file still doesn't exist, yepp, search the web for "howto use python scripts" or ask the board.
Time to cram everything into an OXP.

OXP impementation:
And again, I'm not going into the details of how to create an OXP, as there are quite sufficient tutorials and descriptions about this.
Here's a set of instructions for a very small and for our use tailored OXP:
Open the Oolite game folder and open the "AddOns" folder in it. If it doesn't exist, create it. Within create another Folder called "CubeStation.oxp". Yes, the folders name ends with ".oxp" even though it isn't a file. In the OXP's folder create a text file and rename it to "manifest.plist", no ".txt" or anything else after ".plist"
Fill the file with the following code and modify where needed:

Code: Select all

{
	identifier = "oolite.oxp.***yourSignaturInOneWord***.***titleInOneWord***";
	title = "***a fitting title goes in here***";
	author = "***your name goes here***";
	license = "CC BY-NC-SA 4.0"; //Just a suggestion. The license type is your choice.
	version = "0.1.0"; //As this in going to be a very early version, go with a small version number.
	description = "***A fitting description goes in here***";
	category = "Miscellaneous"; //Miscellaneous fits for most bases OXPs.
	tags = ("Miscellaneous", "Station"); // Fill this other tags if you like.
	required_oolite_version = "1.82";
}
A working example (and what I'm going to refer from here on. Don't get confused!):

Code: Select all

{
	identifier = "oolite.oxp.ocz.cubeStation";
	title = "Cube Station";
	author = "ocz";
	license = "CC BY-NC-SA 4.0";
	version = "0.1.0";
	description = "The Cube Station created in that excellent tutorial, that lead you here. :)";
	category = "Miscellaneous";
	tags = ("Miscellaneous", "Station", "Cube Station");
	required_oolite_version = "1.82";
}
Next create a file named "requires.plist" in the same manner and fill it this the following lines:

Code: Select all

{
    "version" = "1.82";
}
Now you have to create a few folders, namely "Config", "Models", "Scripts" and "Textures". At first open "Scripts" and create the file "CubeStationScripts.js" within it. You know the deal by now:

Code: Select all

"use strict";
this.name			= "Cube Station Script";
this.author			= "ocz";
this.copyright		= "2015 ocz";
this.licence		= "CC BY-NC-SA 4.0";

this.addStation = function (offset) {
	var stationPosition = player.ship.position;
		//Sets the stations spawning location directly at the players position.
		
	if (offset) {
			//If an offset vector exists, its values are added to the spawning point.
		stationPosition.x += offset.x;
		stationPosition.y += offset.y;
		stationPosition.z += offset.z;
	}
	
	var cubeStation = system.addShips("cube_station", 1, stationPosition, 0)[0];
	return cubeStation; 
}

this.startUp = function () {
	this.addStation(Vector3D(2000,0,0));
		//Let's add a Cube Station 2000m next to the player's
		//initial position in the Main Station.
}
Please note that this is a script file I wrote and provided! But I hereby allow you to use it and modify it as fit under the terms of the cc by-nc-sa 4.0 license, as this.license already told you. Licenses are important as they, in our communities case, keep beef away form the board. So you better don't use it as is for your presentation for example without mentioning me. :D
But I take it even further! If you use it as a starting point for your own scripts, seeing how general those lines are, I hereby declare, that you don't have to mention my name and/or don't have to share it alike! Same goes for the other lines of code I provide as written examples (the downloadable files excluded!) in this tutorial, which only spans this threats initial post. (This one here, you're reading right now.)
Now, isn't that nice of me? So, change it to your hearts content!


Next open the "Config" folder and create these two files:

"world-scripts.plist"

Code: Select all

(
	CubeStationScripts.js
)
"shipdata.plist"

Code: Select all

{
	"cube" = {
		model = "cube.dat";
		name = "Cube";
		scan_class = "CLASS_STATION";
		roles = "cube_station"; // <- Note that system.addShips() refers to roles.
	};
}
Did you notice the entry model = "cube.dat"; in "shipdata.plist"? That refers to the model you have converted. But it still isn't in our OXP, is it? Copy it from your working directory into the "Models" folder aaaaaaand we're done here.

I also already created that OXP. In case you are lazy and haven't done what I told you in this tutorial, you are in luck. I spoil you: Cube_Station_0.1.0.oxz

Time for a test drive. Start up oolite, load a game or start a new one and launch from the main station. Somewhere on the radar, there is a new signal. Turn and TADAAAA!!!

'Well....Well...It's... ...pink!', I hear you thinking. But the point is, it's there!
Time to return to the drafting table and finish the stations model. Shall we?

Modelling (part2):
Before you open the model file of the cube again, there are some things we should think about now. We want to finish the model this time and at this point the station is just a pink block in space. So what's missing? A texture and you might want to land on it, so we also have to construct a docking bay, which in turn needs a texture, too. I'll provide both textures, but you have to build the bay. First save these little cartoonish goodies somewhere you'll find them again. They'll do for educational purpose:

Textures:
Image
hull.png by ocz cc by-nc-sa 4.0

Image
tutorialbay.png by ocz cc by-nc-sa 4.0

Next start up Wings 3D again or close the cube model, if still running in background. We'll need a clean slate.

We'll create a cube again, but this time a bit different. This time it won't be a cube as the sides won't have the same lengths. Right click on the grit again, but this time don't directly click on "Cube" the the small icon right next to it. Give x and z the value 250, but y only 100. This is going to be the landing bay. "Wait!", you might interrupt, ''Are we going to create the bay as different model?" Yupp, you right, but don't worry. It'll be more convenient for future uses. It's best to do it this way right from the start. And in case the model vanished: Did you zoom out far enough?

The side that faces in direction of the z-vector will be the front side. As we want the use the insides as landing bay, select the object and perform the "Invert" operation, you find in the right-click menu. Next up: some texturing.

Under the entry "Window" in the menu bar at the top of the Wings 3D screen you see the subentry "Outliner". Click it. A window appeared. Now deselect the object in the main view, open the right-click menu again and click on "Material...". Name the new material "Dockingbay" in that popup window that followed. And in the next window keep the materials properties how they are and click OK. Now select under "File" in the menu bar "Import Image..." and find "dockingbay.png" you downloaded a few minutes ago. Both "Dockingbay" (the material) and "dockingbay.png" should have appeared in the Outliner window. Drag'n'drop the png in the menu onto the material and chose "Diffuse" as Texture Type. We're set for the "fun" part. Skinning.

Select the whole object again. Do you still remember the four cube pictograms at the middle top of the screen? Select the one, that indicates face selection. (It's the third one.) Right click onto the object and chose ".Material." and then "Dockingbay". Then right click the object again and chose. ".UV Mapping." (It might be hidden under the "More... ->" entry.)

Oh, this is going to be rich.

Another view window called "AutoUV Segmenting" should have poped up. In it's top there are only tree cube depictions. Chose Edge Selection from among them. (It's the middle one.) Now mark every of the twelve edges, right click on one of them and chose "Mark Edges for Cut". Right click again and chose "Continue". And then "Unfolding". You should see a new window with a colorful picture and the faces of the model on it. For one reason or another Wings 3D decided to just create a new material with this texture without asking beforehand, so close that new window. Map the material "Dockingbay" to the object like you did moments ago. Also get rid of that new material "Cube1_auv" and texture "auvBG" from the Outliner window. First the material, than the picture. (Marking, right clicking and "Delete".) And right click that object again and chose ".UV Mapping." to open the Mapping window again, but this time with the right texture.

Press space to deselect everything. I won't tell you how you should map the faces to the texture. Firstly, this would be unnecessarily complicated and secondly this is something you should do by yourself to get the hang of it. Here are some hints though:
  • You can select, deselect and move the faces in the mapping window.
  • You can see the changes in the main window.
  • You can also select and deselect faces by using the main window. Useful the figure out which face is which and to select a certain one, if they overlap in the mapping window.
  • They may overlap! Make use of that.
  • Right clicking in the mapping window, yields a menu to manipulate the faces.
  • Pressing the Tab key while manipulating opens a dialogue to type in numeric values. Useful to turn a face for exacly 90° for example.
  • Last, but not least: Make sure to deselect a face, when done with it for now. The space bar is very useful in this hind-side.
Also, make sure you don't move the model itself! Use the undo buttons in case you do.

You're done? Good. Two more steps and the bay is finished. Remember which face is the front one? That one that lies in the same direction as the z-vector (the blue one) is pointing. That face has to go. Logical, as we want ships to enter the bay. Mark it, right click and chose ".Hole." Done.

If you're asking yourself, why you had to map a side, that was already going to be eliminated, ask that question the people who wrote the converting script. The face is still there in the model. And if the script finds an unmapped face, the texture mapping won't be computed. If the cube or the bay is still pink after mapping, this might be the reason.

And the last step before exporting: Move the bay along the z-vector, so that the 0,0,0-coordinate point lies exacly within the opened side of the bay. You already know enough at this point to do this by yourself, but I still provide the instructions. Select the whole bay, rightclick and select ".Move." Chose "Z" as we are going to move it along the z-axis. Type the tab key immediately!!! (The positioning must be exactly. Undo your actions, in case you screwed up.)
The numeric value window should be open right now. It is calculation time. The coordinate systems center, is in the center of the bay right now. We want it to be that the center of the bays entrance. The bay spans 250 meters along the z-axis. (It's a 250x250x100 box, remember?) From the center of the box to its end it's....?....Right 125m. We have to move it into the negative directory, so the value we seek it: -125. The three x,y and z axis vectors(red, yellow, blue) should now meet in the center of the opening face, if it still would be visible. Save the file as "dockingbay", export the model and convert it much like before with the cube model. Then copy "dockingbay.dat" into the "Models" folder of the OXP.

You might wonder, why you had to move the bay in the end as you did. We have to put both the cube station and the docking bay together. But this won't be happening in a single model. We'll do this later in the shipdata.plist file. For that reason it is good to align the model of the bay in such a way, that it is easier to predict its position, when doing this with numbers alone.

Now open the cube file in Wings 3D and create a material like before. This this use hull.png as texture.Sadly Wrong. I have to change that later. Also you can change the properties of the material a bit. As it's some sort of metal hull, adding a bit shininess to it might look good. Open the right click menu of the material n the Outliner window and chose "Edit Material...". Increase "Specular" a bit and then "Shininess". Play with both values till they are to your liking.

Before you apply that material to the cube, you should prepare the model for creating the entrance of the station. Mark the face that is facing in the same direction, as the z-axis vector is pointing to, as you did with the face of the docking bay you removed later. Don't remove it now. Open the right click menu for it and chose ".Insert." Type the tab key before committing anything. We have to calculate again. The opening of the docking bay is 250m wide and 100m high. The cube's face is 800m high and wide. 25% of 800 are 200, type (100%-25%=) 75%. That should do.
There is now a 200x200 face in the middle. Mark it and open the right click menu again. This time select ".Scale Axis." and chose ".Y." as we want to modify its height. Hit tab again. it's 200m high and we need only 100m. -> 50%.
The width of the face is still incorrect. Of course you could now just ".Scale Axis."->".X." it, but I want you to do something different. Sometimes it's necessary to place vertices precisely. You're going to do that with the four vertices of that face now. Hit the space bar to deselect everything. From the top cube depictions select the first one for vertices adjustments. Mark one of the vertices, open the right click menu, then click "Absolute Commands" and ".Move."
The z value in the window you see now should be 400. Keep that value in mind, as it will be important, when putting the station and the bay together. The x and y values should be -100 or +100 and -50 or +50. The y values are already correct, as the difference between 50 and -50 is 100. The x values must be changed. currently the width of the face is 200 and the values of 100 and -100 mirror that. You need to change the distance between the vertices to 250. So set the values form either -100 to -125 or +100 to +125.
Instead of calculating the values, you could also have opened the bays model again, selected the vertices of the opening individually and wrote the x and y coordinates of them down.

Now apply the hull material onto the cube station. (Of course you don't invert the model this time. Just saying.) When segmenting the models faces for mapping, only mark the twelve outer edges for cutting and keep the front face in one part. Also increase each face's size to fit the whole texture in the UV-mapping window.

The final step of creating this model is to open up the hole for the docking bays entrance. Mark the central face of the front and ".Hole." it. Then export, convert and copy into "Models".

Let's open that shipdata.plist again:

Code: Select all

{
	"cube" = {
		model = "cube.dat";
		name = "Cube Station";
		scan_class = "CLASS_STATION";
		roles = "cube_station";
		smooth = no;
		subentities = 
		( 
			{ 
				subentity_key = "cube_docking_bay"; 
				orientation = (1, 0, 0, 0);
				position = (0, 0, 400);
				is_dock = true; 
			}
		);
		rotating = yes;
		station_roll = "0.08"; 
		
	};
	
	"cube_docking_bay" = {
		model = "dockingbay.dat";
		name = "Cube Station Dock";
		smooth = no;		
	};
	
}
As you can see, we added the dockingbay.dat model file in the new entity "cube_docking_bay". Also note, the new subentities entry in the cube's entity. The naming of most of what you see written in it's brackets it is self-explanatory.
The orientation shouldn't be of any concern, if you did as I told you, when building the model, as both models are aligned into the direction of the z vector. orientation is interesting, if you want to attach other entities to the station in different angles, like turrets. And that's that on this topic for this tutorial here. If you are interested in this, please look into read [wiki]Quaternions[/wiki] and reverse engineer other OXP's shipdata.plists like of the [wiki]Behemoth[/wiki] OXP for example.
Now the topic on the position entity on the other hand is important for us. position = (0, 0, 400); shifts the position of the subentity relatively to the main model. As you may have already guessed, the three numbers are the values for shifting them in the three main dimensions x,y and z.
In most cases it would be good practise to position the subentities already in Wings 3D at there relatively right position, leaving the entity at a value of position = (0, 0, 0);, but I didn't do this for a quite good reason: When you will create a spectacular model for your own docking bay, you might want to reuse it for different kind of stations, that come in different sizes. You should consider doing this with every subentry you want to reuse for other projects. If the parts are custom made for each other, for example for a complicated space station with different entities for the stations frame and its hull plating, align them right from the beginning.
We aligned the front entry of the bay's model to its 0,0,0-coordinate. The stations entry is not at its 0,0,0-point, but at it's hull. Before I told you to remember the z value of the entrance. It was 400. This makes sense, as the stations form is a cube of 800m per side. And therefore 400 goes at the third position (for the z vector) of the position entity. As the station also rotates now (rotating = yes; station_roll = "0.08";) it's fairly important that the docking bays position is not shifted across the x or y axis. Imaging you would: In this case the bay wouldn't rotate at the center of the rotation, but around it and that would make docking manoeuvres difficult.

When you're done, your OXP should look similar to this one: Cube_Station_0.2.0.oxz

[In-system positioning]

[To be continued]
Last edited by ocz on Fri Jan 29, 2016 5:50 pm, edited 45 times in total.
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: Tutorial for creating a simple station. (Help needed!)

Post by ocz »

Before I write down my steps in detail for the tutorial, here's a summery of what I did. Keep in mind I didn't succeed to spawn anything, so I need your help to point out what I did wrong.
  • Wings 3D 1.5.4 and python 2.7.10 are installed.
  • I created a standard cube (right click and ->cube) in a new file
  • I did not map any textures nor materials to it! (First possible mistake)
  • I exported it like shown in the picture of the wiki tutorial.
  • I converted it like described in the tutorial.
  • I created an OXP structure (It's working.)
  • I put the cube.dat file into the Models directory
  • I wrote a shipdata.plist and put it into the Config directory(Second possible source of error)

    Code: Select all

    {
    	"cube" = {
    		model = "cube.dat";
    		name = "Cube";
    		scan_class = "CLASS_STATION";
           //Are there any entries missing?
    	};
    	
    }
  • I created a startUp method in the main script of the OXP (Third possible source of error)

    Code: Select all

    this.startUp = function () {
    	var _station = system.addShips("cube", 1, Vector3D(0,0, 0.1), 0)[0];	
    }
    [color=#0000BF]Exception: TypeError: system.addShips("cube", 1, Vector3D(0, 0, 0.1), 0) is null
    Active script: Solar Station Script 0.1.0
    SolarStationScripts.js, line 24:
    var _station = system.addShips("cube", 1, Vector3D(0,0, 0.1), 0)[0];[/color]
system.addShips("cube", 1, Vector3D(0,0, 0.1), 0)[0] in the console returns null.

I'm off the write that steps down in detail and anyone find what I missed, please. :(
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6547
Joined: Wed Feb 28, 2007 7:54 am

Re: Tutorial for creating a simple station. (Help needed!)

Post by another_commander »

Try adding a like_ship = "coriolis-station"; entry in your shipdata.plist, so that it inherits from the Coriolis any properties for which you have not provided data.
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: Tutorial for creating a simple station. (Help needed!)

Post by ocz »

another_commander wrote:
Try adding a like_ship = "coriolis-station"; entry in your shipdata.plist, so that it inherits from the Coriolis any properties for which you have not provided data.
Done, but no change. I also tried to spawn other objects like vipers and mambas a month ago, when I tried first. I always took care to NOT use templates. I even tried to spawn a vanilla coriolis station. But I only succeeded with one line: [color=#0000BF]system.addShips("alloy", 1, Vector3D(100,0,0), 0)[0];[/color]
[color=#008000][Ship "Metal fragment" position: (100, 0, 0) scanClass: CLASS_CARGO status: STATUS_IN_FLIGHT][/color]
User avatar
Amah
---- E L I T E ----
---- E L I T E ----
Posts: 485
Joined: Tue Aug 28, 2012 8:05 pm
Location: aboard the Laenina Crowne - Yasen-N class space freighter
Contact:

Re: Tutorial for creating a simple station. (Help needed!)

Post by Amah »

hmmh, shouldn't addShips take "role" as argument to spawn? (http://wiki.alioth.net/index.php/Oolite ... m#addShips)

Could you check the following. Add a line like this to shipdata.plist

Code: Select all

		roles = "cube_station";
and try to spawn with

system.addShips("cube_station", 1, Vector3D(100,0,0), 0)[0];
Amah
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: Tutorial for creating a simple station. (Help needed!)

Post by ocz »

Finally something spawned!

So the roles property is the identifier to use in the addShips method, huh? I would have tried another 2 days until I would have figured that one out, if ever. (I read that documentation and just couldn't link "role" with "roles" in my head.)

I'll see where this is taking me and complain in another post if I hit a wall.
User avatar
Amah
---- E L I T E ----
---- E L I T E ----
Posts: 485
Joined: Tue Aug 28, 2012 8:05 pm
Location: aboard the Laenina Crowne - Yasen-N class space freighter
Contact:

Re: Tutorial for creating a simple station. (Help needed!)

Post by Amah »

Glad it works :-) Now, I gotta get back to work.
Amah
User avatar
Norby
---- E L I T E ----
---- E L I T E ----
Posts: 2577
Joined: Mon May 20, 2013 9:53 pm
Location: Budapest, Hungary (Mainly Agricultural Democracy, TL10)
Contact:

Re: Tutorial for creating a simple station. (Help needed!)

Post by Norby »

Try this:

Code: Select all

this.startUp = function () {
    var _station;
    var s = system.addShips("[cube]", 1, Vector3D(0,0, 0.1), 0);	
    if( s ) _station = s[0];	
    else log(this.name, "Warning: station is not created");
}
-Square brackets allow to spawn a ship via dataKey.
-If you check the result before attempt to access a data within the (sometimes non-existent) returned array then you can avoid a break in the execution of your script.
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6547
Joined: Wed Feb 28, 2007 7:54 am

Re: Tutorial for creating a simple station. (Help needed!)

Post by another_commander »

Pro-tip: If you are using the debug console for your spawn tests, you can save lots of precious time by using the :spawn role macro (note the : at the beginning which signifies a macro), rather than typing constantly system.addShips ... etc. The spawn macro creates a ship of the specified role in the vicinity of the player ship and is just one of the many useful console macros available and defined in the Basic-debug.oxp's debugConfig.plist. While we are at the subject of console macros, check also :d <entity> and - for a humorous moment or two - :qotd (quote of the day).
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: Tutorial for creating a simple station. (Help needed!)

Post by ocz »

80% of the tutorial text is done. Don't bother prove-reading it at this point, as I'm going to review it and expect to rewrite large heaps of it, before I ask for input.(Removing parts I thought were funny (in a sleep deprived state), but are just plain stupid, removing parts, that are going to much into the details, adding stuff into other part, adding pictures, removing confusing stuff and of course eliminating spelling and syntax mistakes.)When I think I have polished it to the point, from where I can't do much more, I'll come begging for help.

(In case you are curious, what's taking me so long to finish it: I'm also working on another OXP including an OXP station. No surprise here, huh?)

Right now something else about this tutorial is bugging me. It's about positioning the stations in planetary orbit. The following code does work:

Code: Select all

this.systemWillPopulate  = function() {
	system.setPopulator("cube_station", {
		callback: function(position) {
			system.addShips("cube_station", 1, position, 0);
		}.bind(this),
		location: "PLANET_ORBIT_LOW"
	});
}
BUT the station always does appear at a different location.

I thought (hoped) the system populator would use the station's identifier or some other value (checksum?) to feed it to a pseudorandom value generator. And than use that return value to place the station in different locations per system, but always in the same location in the same system, similar to the location of the main station. Well, it doesn't, when I dare to load the same game state for a second time.

Also (I might be wrong there) it seems, that the main station's orbit location is always in plain sight from the witchpoint. I would like to reproduce the same behaviour for OXP stations. Of course I can write something that mimics that behaviour (and use up a few hours while doing so), but maybe it's already implemented into vanilla's javascript interface and can be done with a few simple lines of code. (I'm hoping for a simple solution yet again.)

If there is no simple solution to your knowledge, please tell me, as this is important knowledge, too!
User avatar
spara
---- E L I T E ----
---- E L I T E ----
Posts: 2676
Joined: Wed Aug 15, 2012 4:19 am
Location: Finland

Re: Tutorial for creating a simple station. (Help needed!)

Post by spara »

Check [wiki]Oolite System Populator[/wiki]. If you want a random position that sticks, you need to use locationSeed.

If you want to make sure the station is viewable from the witchpoint, then you'll need do some vector calculus. If you want a random position that sticks, then you need to pull random numbers from system.scrambledPseudoRandomNumber(salt).
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: Tutorial for creating a simple station. (Help needed!)

Post by ocz »

... locationSeed... There should be a limit to how blind someone(me) can be. :oops: (This marks the 3rd time I somehow skip information I needed while reading the right wikipage.) Sorry.


Using locationseed looks like the most elegant way of implementing it. I'll see how I implement this tomorrow. Here is my take on this problem: I plan to create a vector witchpoint->location and see if the line it spans through them passes (between location and witchpoint) the planets location closer than the planets radius (piercing it). If it does I create another line through the location and the planets location(core) (location->planet) and use factor 2 to find the exact orbitlocation on its other side. Looks easy enough. I'm sure it will be hell XP.


EDIT: Or even easier, I calculate that twin orbit location right in the beginning and look whichone is closer to the witchpoint. :)

EDIT2: Wow, that was simple.

Code: Select all

this.systemWillPopulate  = function() {
	system.setPopulator("cube_station", {
		callback: function(position) {
			var _spawnPosition = system.planets[0].position.add(system.planets[0].position.subtract(position));
			var _witchpoint = {position: new Vector3D(0,0,0)};
			if (_witchpoint.position.distanceTo(position) < _witchpoint.position.distanceTo(_spawnPosition)) _spawnPosition = position;
			
			system.addShips("cube_station", 1, _spawnPosition, 0);
			
			
		}.bind(this),
		location: "PLANET_ORBIT_LOW",
		locationSeed: *chose your own ;)*
	});
}
Code by ocz. cc nc-sa 4.0 (No by, but it would be nice to mention me. (But you really don't have to.)) Also, only the non-commercial(nc) part of the license is important. If you want to use any other license covering that, ignore the share alike(sa) part.
Post Reply