Making a System

This is a moderated forum that collects tutorials, guides, and references for creating Transcendence extensions and scripts.
Post Reply
Drako Slyith
Fleet Officer
Fleet Officer
Posts: 1036
Joined: Wed Feb 03, 2010 4:28 am
Location: Researching how to make St. Kats star go supernova.
Contact:

RPC recently requested this; a tutorial on how to make a system. I'll have a lot of examples from &ssEridani
After you have the start tag:

Code: Select all

<SystemType UNID="&ssStartonEridani;">
you have the option to set some tables:

Code: Select all

	 <Tables>
                    <DanteStations>
				<Table>
					<Station chance="45"	type="&stMiningColony;"/>
					<Station chance="25"	type="&stCentauriCamp;"/>
					<Station chance="10"	type="&stCharonPirateOutpost;"/>
					<Station chance="5"		type="&stCommonwealthSlums;"/>
					<Station chance="5"		type="&stFuelDepot;"/>
					<Null	 chance="10" />
				</Table>
			</DanteStations>
                    </Tables>
These can be drawn later for simplicity.
Next, you make the actual system. Begin with a

Code: Select all

<SystemGroup>
to set the start of the system itself.
Every system needs a central point. In all vanilla systems, this is a star.

Code: Select all

<Station type="&stG-TypeStar;" name="Epsilon Eridani"/>
Notice you have the option to name it. This doesn't really do anything now, but it's a nice touch.

To put a planet in orbit you need to have the <Orbitals> tag:

Code: Select all

<Orbitals distance="50" angle="random">
Distance can be changed to anything. Another option is

Code: Select all

distance="5" scale="lightyear"
I believe this has equal distance to the "50". This puts a point where you can put in new stations.

Now you can put in groups to put in planets. <Group> is used to put an imaginary marker in the spot where you can have multiple stations. Put this in an <Orbitals> tag.
The <Group> tag can (but does not have to) have the same descriptions as <Orbitals>. This would put it a distance away from the point put there by the <Orbitals> tag.
Group tags then can have a tag <Primary> This can have a station under it. It puts the station on the point placed by the Group/Orbitals tags.
Then you have another <Orbitals> tag with the distance and angle information in it.
Under this tag you can put in the stations, or draw a list from the <Tables> section.

To but a moon in, under the second <Orbitals> tag put in a second planet. To put stations in orbit have this:

Code: Select all

<Station type="&stPlanetoid;">
               <Orbitals distance="5" angle="random">
                         <Station type="&stStation;"/>
               </Orbitals>
          </Station>
You can continue to put in the planets until you're satisfied.

To put in an asteroid belt, it helps to have a <Table> stored with several asteroids.

Code: Select all

						<Group chance="50">
							<Trojan>
								<Lookup table="StJohnTrojans"/>

								<Orbitals distance="1d8+6" angle="random">
									<Station type="&stRaisuStation;" />
								</Orbitals>
							</Trojan>

							<AntiTrojan>
								<Lookup table="StJohnTrojans"/>

								<Orbitals distance="1d8+6" angle="random">
									<Lookup table="StJohnTrojanStations"/>
								</Orbitals>
							</AntiTrojan>
						</Group>
For some reason it seems all <Trojan>s need to have an <AntiTrojan> Alternatively, you can have

Code: Select all

<Orbitals distance="5d8" angle="random" count="10d10">
            <Station type="&stStation;"/>
</Orbitals>
This makes between 10-100 &stStation;s 5-40 distance away at a random angle. <Trojans> seem to be a cleaner way to do it. <Orbitals> seems to have a limited range.



Another type of system you can create is a random station. This is used a lot in vanilla Transcendence.
These usually have no tables inside them. It just goes right to <SystemGroup>
The example here will come from the Transcendence standard system.
Each one has a base type:

Code: Select all

<Lookup table="YellowStarSystem"/>
That in of itself deals with the planets of the system, placing them randomly.

Then, tell the game to make the stargates:

Code: Select all

			<RandomLocation locationCriteria="++OuterSystem,-asteroids,-gasgiant">
				<Lookup table="StargateInbound"/>
			</RandomLocation>

			<RandomLocation locationCriteria="++InnerSystem,-asteroids,-gasgiant">
				<Lookup table="StargateOutbound"/>
			</RandomLocation>
You can actually use this format to make any station at all. i.e.

Code: Select all

<RandomLocation locationCriteria="!Planet,--asteroids,++void">
            <Station type="&stStation;"/>
         </RandomLocation>
This makes a &stStation; away from a planet, rarely in an asteroid belt an very likely in an empty space. I think you can also use <Group> to make a preset group of stations.

You can also use the above <RandomLocation> to put in random stations:

Code: Select all

<RandomLocation probability="90" locationCriteria="++LifeZone,*planet">
				<RandomStation stationCriteria="*friendly,*primary"/>
	</RandomLocation>
This has a 90% chance of making a <RandomStation> in the life zone and next to a planet. The <RandomStation> is a station with the "primary" and "friendly" attributes.

Another useful tag is the <FillLocations> tag.

Code: Select all

			<FillLocations
					percentFull=		"80" 
					stationCriteria=	"!primary,!debris,+envWater,-envAvoidsWater" 
					percentEnemies=		"65"
					separateEnemies=	"true"
					/>
This fills the system 80 of what the system considers full. The stations have the attributes in stationCriteria. You can customize the percent of stations that are enemies, and whether to group the sovereigns together.

Last, you can have a simple <Orbitals> tag to have groups orbit the star. You can put certain stations or random stations.

Just some extra information:
-All systems must have two stargates unless they are special systems, only Eridani in vanilla.
-All systems need to have a central point. Though it seems like it would work without it, it doesn't. If you want to have nothing there, make a station without an image as a background object.
-All systems should have some friendly station in them. Otherwise, fuel runs out or the player is hunted down by enemies.
-Don't put too many warring factions in the same map; it tends to lag computers with all the fighting
-Don't make the map much larger than 15 light seconds radius. Missions become too long, and it's hard for the player to go where they need to

Of course, the best way to learn this is by searching through systems in the Transcendence.xml and subsequent files.
Image
Image
Play in over 100 systems in a network. Play the 2011 Mod Of the Year
and the highest rated mod on Xelerus, The Network.
Play the July Mod of the Month, Fellow Pilgrims!
Play My other mods as well
(Drako Slyith)* I am a person
(Eliza chatbot)> Do you believe it is normal to be a person?
RPC
Fleet Admiral
Fleet Admiral
Posts: 2876
Joined: Thu Feb 03, 2011 5:21 am
Location: Hmm... I'm confused. Anybody have a starmap to the Core?

Thanks! So to recap it's:
I will use[optional][/optional] to denote optional tags.

Code: Select all

<systemtype UNID="">
	[optionaltag]
	<Tables>
		;for asteroids
		<Tablename>
			<Group>
				<Trojan>
					<Orbitals>
					</Orbitals>
				</Trojan>
				<AntiTrojan>
					<Orbitals>
					</Orbitals>
				</AntiTrojan>
			</Group>
		</Tablename>
	</Tables>
	[/optionaltag]
	<systemGroup>
		<station type="thestar" name"">
		[optional]
			<RandomLocation locationCriteria="">
				<Lookup table="StargateInbound">
			</RandomLocation>
			<RandomLocation locationCriteria="">
				<Lookup table="StargateOutbound">
			</RandomLocation>
			<FillLocations
					percentFull=		""
					stationCriteria=	"" 
					percentEnemies=		""
					separateEnemies=	""
					/>
		[/optional]
		<Orbitals distance="" [optional]scale="lightyear"[/optional] angle="">
		[optional]
			<Group[optional] distance="" angle=""[/optional]>
				;place planets/etc in here
				[optional]
					<Primary>
						<Orbitals>
							<Group>
								<Lookup table="table name within the Table tag">
							</Group>
						</Orbitals>
					</Primary>
				[/optional]
			</Group>
		[/optional]		
		</Orbitals>
	</systemGroup>
</systemtype>
So Orbitals are where to place the station from a point, whether it be the sun or another orbital.
Groups are used to specify what stations are made together.
So if I can place <Orbitals> within <Orbitals>, doesn't that mean I can make an orbital, then put in another, and another.....

As I was looking at the .tdb I noticed that some of the Criteria were earth, wind, fire, water. What does that thematically mean and how am I supposed to use that?
I know that some factions have that as attributes, but I don't want to remember that! So, if they are red, like the Ares, then the are fire and dark, like the Ranx is earth?
Wait... no. Apparently the Ares Outpost has these attributes: "envAir,envEarth,envFire,envWater,". Now I'm confused.
I think that you can have <Marker objName="Start"/> within any orbital.

What does Siblings, arcInc, and radiusInc mean?
So... you can specify a table within the <table> tags by saying <tablenamehere>

Code: Select all

			<StJohnTrojans>
				<Group>
					<Siblings count="2d20" arcInc="2d205-206" radiusInc="-4-4">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>

					<Siblings count="2d20" arcInc="2d159-160" radiusInc="-6-6">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>

					<Siblings count="2d16" arcInc="2d109-110" radiusInc="-8-8">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>

					<Siblings count="2d12" arcInc="2d49-50" radiusInc="-12-12">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>
				</Group>
			</StJohnTrojans>
Tutorial List on the Wiki and Installing Mods
Get on Discord for mod help and general chat
Image
Image
Der Tod ist der zeitlose Frieden und das leben ist der Krieg
Wir müssen wissen — wir werden wissen!
I don't want any sort of copyright on my Transcendence mods. Feel free to take/modify whatever you want.
Drako Slyith
Fleet Officer
Fleet Officer
Posts: 1036
Joined: Wed Feb 03, 2010 4:28 am
Location: Researching how to make St. Kats star go supernova.
Contact:

RPC wrote: As I was looking at the .tdb I noticed that some of the Criteria were earth, wind, fire, water. What does that thematically mean and how am I supposed to use that?
I know that some factions have that as attributes, but I don't want to remember that! So, if they are red, like the Ares, then the are fire and dark, like the Ranx is earth?
Wait... no. Apparently the Ares Outpost has these attributes: "envAir,envEarth,envFire,envWater,". Now I'm confused.
envEarth, envFire, envAir and envWater are tags used to separate sovereigns. Some enemies are less likely to be seen in the same systems as others. i.e. &ssEarthSpaceAsteroids is ++envEarth, and --envAvoidsEarth. Stations having the attribute "envEarth" will be common.
RPC wrote: What does Siblings, arcInc, and radiusInc mean?
Siblings are similar to orbitals, but you can put the exact coordinates relative to the center point. From Transcendence.xml:

Code: Select all

		<StargateInbound>
			<Stargate objName="Inbound" type="&stStargate;">
				<Satellites>
					<Station type="&stStargateBeacon;" xOffset="130" yOffset="0" />
					<Station type="&stStargateBeacon;" xOffset="0" yOffset="-130" />
				</Satellites>
			</Stargate>
		</StargateInbound>
This puts two stargate beacons, one 130 to the right, one 130 to the "south". It can be helpful in circumstances where you don't want to have to find complicated <Orbitals distance angle> to get a station where you want it.
As for the arcInc and radiusInc, I have to confess I have no idea.
RPC wrote: So... you can specify a table within the <table> tags by saying <tablenamehere>

Code: Select all

			<StJohnTrojans>
				<Group>
					<Siblings count="2d20" arcInc="2d205-206" radiusInc="-4-4">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>

					<Siblings count="2d20" arcInc="2d159-160" radiusInc="-6-6">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>

					<Siblings count="2d16" arcInc="2d109-110" radiusInc="-8-8">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>

					<Siblings count="2d12" arcInc="2d49-50" radiusInc="-12-12">
						<Lookup table="StJohnAsteroid"/>
					</Siblings>
				</Group>
			</StJohnTrojans>
Yes, so you can use <Lookup table="StJohnTrojans"> to draw all the data under that tag. It's much easier than putting all that information under a <Group> tag.
Image
Image
Play in over 100 systems in a network. Play the 2011 Mod Of the Year
and the highest rated mod on Xelerus, The Network.
Play the July Mod of the Month, Fellow Pilgrims!
Play My other mods as well
(Drako Slyith)* I am a person
(Eliza chatbot)> Do you believe it is normal to be a person?
george moromisato
Developer
Developer
Posts: 2997
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

Awesome tutorial. Let me fill in a few pieces:

There are two kinds of tags (XML elements) in a system definition. There are "creation" tags and there are "location" tags. A creation tag is something that creates an object in the system. For example:

Code: Select all

   <Station type="..."/>
This creates a station of the given type. But where does it create it? It creates it wherever the parent "location" tag says. A location tag is an element that specifies a particular location in the system.

The outermost tag is a location tag:

Code: Select all

<SystemGroup>
   <!-- anything inside the outermost tag is placed at the exact
      center of the system: coordinates 0,0 -->

   <Station type="..."/>
</SystemGroup>
In the code above, since the Station tag is inside the SystemGroup tag, the station gets created at the SystemGroup's location, which is 0,0.

In general, the purpose of a location tag is to offset from its parent's location to some new location.

The Orbitals tag is a location tag that offsets from some center to a point on an orbit:

Code: Select all

<SystemGroup>
   <Orbitals distance="10" angle="90">
      <Station type="..."/>
   </Orbitals>
</SystemGroup>
The "distance" attribute is the radius of the orbit (unless otherwise specified, all distances are expressed in light-seconds). The "angle" is (no surprise) the angle around the orbit (as in standard trig, angle=0 is along the positive X axis). In this example, an angle of 90 is straight up.

Remember that the Orbitals tag is relative to its parent. It just so happens that its parent is the SystemGroup, so the parent location is 0,0. But if the Orbitals were inside a different location, it would be relative to that.

For example:

Code: Select all

<SystemGroup>
   <Orbitals distance="10" angle="90">
      <Orbitals distance="5" angle="0">
         <Station type="..."/>
      </Orbitals>
   </Orbitals>
</SystemGroup>
Notice that there are two orbital definitions. The outermost, offsets from its parent (0,0) to a point 10 light-seconds in the 90 degrees direction (straight up). Then the inner Orbitals offset from its parent 5 light-seconds in the 0 degrees direction (to the right). The station will therefore be placed 10 light-seconds up and 5 light-seconds to the right from 0,0.

Orbitals has many additional attributes to define its behavior, but in the end, it's all about positioning things on an orbit.

The "count" attribute creates multiple of whatever orbitals element contains. If you've specified an absolute location (as above) it will just create multiple stations in the same spot. But you can specify a random location. By adding the "random" keyword as an angle, you create a station at a random angle on the orbit. When multiple stations are created (with the count attribute) each station will be placed at a different (random) angle.

There are other kinds of tags that offset the location:

Siblings: This tag moves along the orbit of its parent. You can use the arcInc and radiusInc attributes to move along the orbit of the parent. Or you can pick a random angle on the parent's orbit.

Trojan and AntiTrojan and just special cases of the Siblings tag. They always move 60 degrees forward or 60 degrees back on their parent's orbit. In practice they are identical to Siblings with angleInc="60" and angleInc="-60" [BTW: arcInc moves along the orbit in light-seconds. angleInc moves in degrees.]

Offset: This tag offsets in cartessian (x,y) instead of orbital coordinates.

There are two other special tags that require explanation. First is Lookup.

The Lookup tag is just a way to share portions of the system definition. It is like a macro.

Code: Select all

<SystemPartTable unid="...">
   <MyCoolStuff>
      <Orbitals distance="10" angle="90">
         <Station type="..."/>
      </Orbitals>
   </MyCoolStuff>
</SystemPartTable>

<SystemType unid="...">
   <SystemGroup>
      <Lookup table="MyCoolStuff"/>
   </SystemGroup>
</SystemType>
When the above is processed, the <Lookup...> element will be replaced with the contents defined in the SystemPartTable; the result is:

Code: Select all

<SystemType unid="...">
   <SystemGroup>
      <Orbitals distance="10" angle="90">
         <Station type="..."/>
      </Orbitals>
   </SystemGroup>
</SystemType>
The other interesting tag is Label. A label is like a placeholder location that later gets filled in with something.

When the system places planets, it also positions labels around the planets. For example:

Code: Select all

...
<Group>
   <Station type="&stIcePlanet;" showOrbit="true"/>

   <Orbitals distance="2d6+10" angle="random">
      <Label attributes="planet,planetary,frost"/>
   </Orbitals>
</Group>
...
The above creates an ice planet with a label in orbit around it at 2d6+10 light-seconds. What's in the label? Nothing yet. Later, there are other tags that "fill" labels with stations:

Code: Select all

...
<RandomLocation locationCriteria="+planet">
   <Station type="..."/>
</RandomLocation>
...
The RandomLocation tag loops over all free labels and picks one randomly. The locationCriteria attribute is a way of preferring particular labels (+planet means prefer labels with the "planet" attribute).

Once we pick a label, we use that as the location for anything inside the RandomLocation tag. In this case, we create a station at that location.

But what if you want to create a random station? Then you can use:

Code: Select all

...
<RandomLocation locationCriteria="+planet">
   <RandomStation stationCriteria="*friendly"/>
</RandomLocation>
...
The RandomStation tag chooses a random station that matches the stationCriteria and the attributes of the location.

The full picture looks like this:

1. When planets are generated a bunch of labels are created. Each label has a set of attributes describing something about the location of the label (e.g., a label will have the "planet" attribute if it is around a planet.)

2. The RandomLocation tag picks a random label. It uses the locationCriteria specified in the RandomLocation tag to pick a label. In the example above, we prefer labels that have the "planet" attribute.

3. Let's say that we pick a random label with the following attributes: "planet, planetary, frost". These attributes now get associated (temporarily) with the label's location.

4. Now that we've picked a label and location, we process the RandomStation tag. We loop over every single StationType and assign each station a probability of being at this location. We compute the probability as follows:

a. We compare the stationCriteria against the attributes of the station. If the station does not match, we exclude it. Otherwise, we adjust the probability accordingly. In the example above, we make sure that the station has the "friendly" attribute.

b. Next we check the levelFrequency attribute on the StationType and compare against the level of the system. (Any station that does not have a levelFrequency is considered not random and is excluded).

c. Finally we check the locationCriteria attribute on the StationType and compare it against the attributes at the label's location (most of the attributes come from the label itself, but we also take any attributes in the system into account).

5. Once we've computed the probability of all stations, we roll a random number and choose a station.

There are other tags that work on similar principles. The FillLocations tag is an iterated version of the above. It loops over all empty labels and proceeds to pick random stations to fill them.
User avatar
ThePrivateer
Militia Captain
Militia Captain
Posts: 943
Joined: Tue Oct 12, 2010 5:12 am
Location: Starton Australia

Fabulous tutorial Drako -- I wish something like this had existed a while ago when I started modding. :D

This is great! :D
User avatar
Song
Fleet Admiral
Fleet Admiral
Posts: 2801
Joined: Mon Aug 17, 2009 4:27 am

Thanks Drako, and George. I've never tried making a system but maybe now I'll think about it....now that there's a good explanation of the way the coding works.
Mischievous local moderator. She/Her pronouns.
Post Reply