Important Message

You are browsing the archived Lancers Reactor forums. You cannot register or login.
The content may be outdated and links may not be functional.


To get the latest in Freelancer news, mods, modding and downloads, go to
The-Starport

Making Path ini files?

The general place to discuss MOD''ing Freelancer!

Post Wed Sep 19, 2007 8:46 pm

In the New York System (in my mod) I've re-created a few old bases that were either destroyed in the story line or just remnants from an older time. Also I placed the Osiris above plane as another base.
(total: 4 new bases)
I also put in 3 connections to 3 new systems. One jumphole out past Detroit Munitions, a Jump Gate to another system near the star and another jump gate near the Alaska Gate (in the mine field with clearing adjusted to accomodate the new gate)
(total: 3 new system connections)

I haven't had any problems with it so far and everything seems to be working fine.
I used the FLEx to create the new systems and connections. The entries into the path ini files was automatic.
However, as of this date; I still get the dreaded CTD when attempting to set path coordinates from one system to another. (not point to point within a system though)

Edited by - Rankor on 9/19/2007 9:50:16 PM

Post Wed Sep 19, 2007 9:55 pm

ROFL, yes the New York rumor
And yes, we added more things/bases to New York beside this Jumpgate.
Perhaps, there was an error in the new system ?
Interesting was, that the error came up, when the path led through New York. Perhaps, I made an error in the path-files...
After setting the connection to Colorado, it was ok. As we see, the pathfile-things is complex and sometimes cryptic.

Post Wed Sep 19, 2007 11:37 pm

DwnUnder: Thanks for the chart, its a very interesting comparison. I discovered FL Error Checker only this week, and I need to decompress all the remaining ini files for it to work, but I will do it as I want to clean up my mod as much as possible.

I removed the ST systems from the path files only, I haven't removed them from the game. But it didn't make a difference still.

I will still plod on, if anyone else with the same problem makes headway please let me know, I will too if I find the cause, and that will help all of us to save lots and lots of time! lol

Chips - if you can complete your path generator and make it available to us it will be absolutely super of you, and if you can include a couple of messages to tell us what it's parsing, and what's wrong that it finds as it is building, that will help bug-finding tremendously.

Depending on you pal! lol

Edited by - StarTrader on 9/20/2007 12:39:11 AM

Post Thu Sep 20, 2007 8:03 am

It's pretty good chances that I could figure out the problem if somebody provided a bug report.

If you're interested, please provide a minimal test case. Something like the following:

1) Start with a fresh install of Freelancer, and install SDK 1.3
2) Create a new system, and a connection to there from (New York?)
a) Open Freelancer Explorer (version?).
b) ...
c) ...
3) Create updated path.ini files:
a) Open FLScan.
b) ...
c) ...
4) Start Freelancer.exe, and travel to the (Colorado?) system. Go to the "universe" map and select (California)? Select an arbitrary point on the map and try to set a path. This should immediately crash to the desktop.

In other words, directions to recreate the bug you're finding, pared down to the bare minimal.

It might be possible for me to find the bug if you just sent me your mod, but it's much preferable to create instructions for generating a minimal test case that generates the bug. -- That would make things *much* easier.

Post Thu Sep 20, 2007 10:35 am

Well, first incarnation of the very first parse (that worked) is just for Li01, and it's a true "systems_shortest_path" - going via ANY connection at all.


li01,li01,li01
li01,li04,li01,li04
li01,li02,li01,li02
li01,li03,li01,li03
li01,iw03,li01,iw03
li01,li05,li01,li05
li01,iw01,li01,li04,iw01
li01,iw02,li01,li04,iw02
li01,iw04,li01,li02,iw04
li01,iw05,li01,li03,iw05
li01,iw06,li01,li03,iw06
li01,br02,li01,iw03,br02
li01,br04,li01,iw03,br04
li01,rh02,li01,li04,iw01,rh02
li01,ku02,li01,li03,iw05,ku02
li01,br01,li01,iw03,br02,br01
li01,br05,li01,iw03,br04,br05
li01,br03,li01,iw03,br04,br03
li01,br06,li01,iw03,br04,br06
li01,bw10,li01,iw03,br04,bw10
li01,rh04,li01,li04,iw01,rh02,rh04
li01,rh01,li01,li04,iw01,rh02,rh01
li01,ku01,li01,li03,iw05,ku02,ku01
li01,ku03,li01,li03,iw05,ku02,ku03
li01,bw02,li01,iw03,br04,br03,bw02
li01,bw01,li01,iw03,br04,br03,bw01
li01,bw08,li01,iw03,br04,bw10,bw08
li01,bw09,li01,iw03,br04,bw10,bw09
li01,rh05,li01,li04,iw01,rh02,rh04,rh05
li01,bw05,li01,li04,iw01,rh02,rh04,bw05
li01,rh03,li01,li04,iw01,rh02,rh01,rh03
li01,ku04,li01,li03,iw05,ku02,ku01,ku04
li01,ku05,li01,li03,iw05,ku02,ku01,ku05
li01,bw03,li01,iw03,br04,br03,bw02,bw03
li01,ew03,li01,iw03,br04,br03,bw02,ew03
li01,bw04,li01,iw03,br04,br03,bw02,bw04
li01,ew01,li01,iw03,br04,bw10,bw08,ew01
li01,bw07,li01,li04,iw01,rh02,rh04,bw05,bw07
li01,ku06,li01,li04,iw01,rh02,rh04,bw05,ku06
li01,bw06,li01,li04,iw01,rh02,rh04,bw05,bw06
li01,ku07,li01,li03,iw05,ku02,ku01,ku05,ku07
li01,ew04,li01,iw03,br04,br03,bw02,ew03,ew04
li01,hi02,li01,iw03,br04,br03,bw02,ew03,hi02
li01,hi01,li01,iw03,br04,bw10,bw08,ew01,hi01
li01,ew02,li01,li04,iw01,rh02,rh04,bw05,bw07,ew02
li01,ew06,li01,iw03,br04,br03,bw02,ew03,hi02,ew06
li01,ew05,li01,iw03,br04,bw10,bw08,ew01,hi01,ew05



Hmm, going to write another parser over the weekend that will compare the existing links, and see if this matches or not. Can't be arsed to visually verify the paths with existing ones.

I can switch between legal and illegal fairly simply. I do get an issue to current design when i start to iterate over all systems, but that's to do with how I am making "paths" so to speak.

Basically, it's messy and probs very poor coding - any suggestions are welcome.

<pre><font size=1 face=Courier>
while(queue.peek()){ //check something actually is in queue before getting it!
try{
SSystem system = queue.getFront();//get from queue.
visited.add(system); //add it to visited (visited is a set, so duplicates are ignored).
System.out.println(system.getPath(original));
Set<SSystem> s = system.getShortest(); //set union of both legal and illegal, removes duplicates.
Iterator<SSystem> i = s.iterator();
while(i.hasNext()){
SSystem sts = i.next(); //get the system from collection
if(!visited.contains(sts)){ //check not visited...
sts.setParent(system); //sets the systems parent (from) system.
queue.addElement(sts); //add to queue
visited.add(sts); //add to visited, stops cockups.
}
}
} catch (Exception e){
System.out.println("Exiting due to exceptiohn";
System.exit(0);
}
}</font></pre>

Yeah, i know stacks are more associated with "peek", but since my "hasNext" is essentially a peek, I went with it as a name for the method

A few fills...
SSystem class has a "setParent" method... it's just a link to the parent system object that reached this current system. The reason for this is clear when calling the path out...

<pre><font size=1 face=Courier>public String getParents(){
if(parent == null){ //if no parent, starting system - return it's id (ie li01, or br01 etc).
return id;
}
return parent.getParents() + "," + id; //otherwise... recursion... but add your own system name to it.
}</font></pre>

<pre><font size=1 face=Courier>
public String getPath(String original){
return original + "," + id + "," + getParents();
}
</font></pre>

I know that it's probs got some "poor form" going on, but meh
The "original" is the original starting system... so in the starter, it's li01.
It does li01, then adds it's own system name (so for li01 itself... it'd add li01), and then does the "getParents method" - so will return li01 for the first system (being li01) - giving li01, li01, li01.


My problem in the design at first (erm, what design Very poor form see!) is that it's got references littered to places all over! So to make this truly recursive, i have to quickly iterate over all systems and remove all links to parents etc... not an issue really, quite quick on modern comps

Any hints, thoughts, tips AND suggestions etc are welcome I will post up all code if people are interested, the language is Java.

Post Thu Sep 20, 2007 10:39 am

Neglected to mention, it doesn't check locked gates at this present moment.... more interested in getting a working algorithm going

However, if you did spot an error in the first bit - sing!

Needless to say, it's all done on shortest path at the moment - but as i've said, it does NOT take into account the locked gates.

Furthermore, execution time
This time includes parsing the universe.ini file, creating all the system objects corresponding to them - then visiting each file in turn, opening - parsing, constructing the connections for that system, closing and moving on...

followed by going through the systems collected, for each system going through the recursive path generation - followed by a complete iteration over the systems again to remove all parent references, before moving onto the next system and generating paths to all systems followed by resetting all systems parents again - for all systems in turn, comes out with an execution time of: 875ms

Not too bad, thought it'd be super slow. Mind you, it very well could be on older systems (core 2 duo 6750 processor).


Edited by - Chips on 9/20/2007 12:08:01 PM

Post Thu Sep 20, 2007 11:22 am

Chips:

I notice the original path files have a space after each comma;

Path = Li01, Li02, Li01, Li02

So before you get too far...!

Well done, pal.

Post Thu Sep 20, 2007 6:06 pm

I'm not sure if you meant "it doesn't check for locked gates" means it currently ignores their existance, or ignores if it is locked. Your last one:

li01,ew05,li01,iw03,br04,bw10,bw08,ew01,hi01,ew05

IS going through a locked gate from li01 to Iw03. Just fwi. If someone was running a mod that did not explicitly open those gates, I think the player would come up against the locked gate and not be able to continue (or crash?).

Edited by - DwnUndr on 9/20/2007 7:08:19 PM

Post Thu Sep 20, 2007 6:15 pm

Chips meant that he's not filtering locked gates, which means he's permitting their traversal.

Keep in mind that this is a compile-time database, so it doesn't know whether or not a gate has become unlocked.

Post Thu Sep 20, 2007 7:23 pm

You see, in Vanilla Freelancer what ever systems are already visible on the nav map can have a path set to some point within any of those systems. Most times, you'll get a nice purple line showing the actual paths.
However...
Some paths might not actually show up (in purple lines) system to system until you actually travel to the system. I think the reason behind this is because some systems have more than one available path to them. So, only the path you take is the one that "unveils" itself on the nav map.
Even when you get to a system that's accessable only by jump holes (during the story line) and you reach the next mission requirement, the engine produces a nice waypoint marker in the system you're in..all the way to where you're suppose to meet Juni. (Normally, you don't get this during exploration/free time, but get that "no best path" indicator instead)

The problem I'm experiencing is simply just trying to set a "legal" path into the next "opened" system and these are the primary systems with jump gates. Well, forget about trying to set a path several systems away. (If I can't get one to the neighboring system, it sure won't work for ones further out)

So, it's incredibly perplexing and aggravating to say the least.

Start point A, Desitination point B, Search for shortest path (via trade lanes through jump gates)
(I suppose that would be the Shortest "legal" path)

So the search engine rifles through all the system.ini files for jump gates and trade lanes and builds a path from one point to the next until it reaches the chosen destination. (simple, right?)

Post Thu Sep 20, 2007 8:40 pm


Chips meant that he's not filtering locked gates, which means he's permitting their traversal.


In that case, Chips has successfully gotten the game to use holes for shortest path! Sweet!

Post Fri Sep 21, 2007 12:07 am

I'm going to hash up each jumpgate's/jumpholes name (if I can find the right algorithm) and then start a hashmap of locked gates/holes.

When parsing connections in systems files, it'll check whether the gate/hole is in this hashmap (very quick check) and discard it as a link if it is. May be funny though, due to some mods having "1 way" jumpholes/gates. Anyone knows what the algorithm is, it'd help out a lot

I did notice that the li01->iw03 gets used a lot - for example, check the path to ew04!! Goes through Bretonia due to this

Once i implement that, the paths should look more familiar. Funnily enough though, for the games current paths i don't match. Example - going to Ku01. I go through... erm, iw05 or something and it uses iw06. Not sure if jumpgate distance is therefore taken into account when they made the games actual paths. Then again, looking at their order in the file - they didn't do a bredth first search... maybe it's a proper search algorithm and they just feed in the end system, to which it finds the very shortest path possible?

Post Fri Sep 21, 2007 2:26 am

Chips, you do it the way you think is right and we will check it for you don't you worry.

We need your genius programming skills more than you need to do it the way DA did it!! lol

If your path files help find my system ini pathing problems so I can fix them to prevent crashing then you'll have done it bud, for me at any rate.

As for locked doors - won't be the first time someone directed me through a one-way street the wrong way! lol

All the best pal, waiting with bated breath for you to post your alpha version for us to try.

Post Fri Sep 21, 2007 2:57 am

No genius about it mate, it's all very simple and low level programming. Nothing flash at all.

Post Fri Sep 21, 2007 4:40 am

Chips -- you may be underestimating a little bit how powerful your algorithm is.

I'd need to see the whole program before I could offer "correct" commentary, but it's my impression your algorithm works like this:

1. Populate the queue with the Root System (Li01 in your test), mark it as visited, and mark its Parent as 'null'.

2. Pull the first system from the queue. (This is initially just the Root System, but by the time you return to this point, the queue will have been populated, below.) This is the "Current System." Print its path by recursively iterating its parents, parents' parents, etc., until you reach the root system with its 'null' parent.

3. For each system to which the "Current System" connects, do the following:
<pre><font size=1 face=Courier>
- if it has been visited, return to #3 and get the next connected system.
- it hasn't been visited, so proceed: first, tell it who its parent is
- then add it to the queue
- then mark it as visited
</font></pre>
(end of #3 loop: you've iterated over all the Current System's children. Proceed back to #2.)

(end of #2 loop: the queue is empty: you've exhausted possible destinations.)

This a textbook "breadth first" search, perfectly represented here -- very nicely done. Good job combining the search with the printing; good job with recursion also.

The "breadth first" search has a number of virtues, but I'll only name two that a person might have trouble conceptualizing.

==

You're always going to get the shortest path. (Or, more precisely, you're always going to get "a" shortest path. We say this because two shortest paths can be the same length, and this algorithm will choose one of those shortest paths arbitrarily. Which one is chosen will depend on the order in which a parent names its children, which is arbitrary.)

We define "shortest path" for this application as "fewest systems traversed." It's possible for "fewest systems" to take up more time, depending on tradelanes and gate/hole distance (intra-system travel time). But for this application we're ignoring intra-system search, which is a separate search altogether.

If you visualize what you're doing -- look at it from the right perspective -- it will become clear that you're guaranteed to get the shortest-path.

1) The first thing you do: you're adding each system directly connected to the root. (These are called the "children" of the root.) You know that you have the shortest path to those children because the distance is 1.

2) Second you're adding each child system directly connected to those you gathered in #1. (The children of the root's children, if you like: the root's grandchildren.) Their distances are 2. The only way their distance could be less is if the root connected to them directly. But you know it does not because you already checked all the systems it connects to.

3) Third you're adding each child of those you gathered in #2. (The root's great-grandchildren if you like.) Their distances are 3. The only way their distance could be less is if the root connected to them directly, or the root's children connected to them. But you know neither situation is the case, because you already checked the root and you already checked all of its children.

Abstract the general pattern and you'll see that whenever you add a system to the queue, you could not have added it any sooner. You always get the shortest path.

==

One-way connections are no problem. The algorithm is already perfectly sensitive to this issue.

To add a child, you ask the parent what children it connects to. You never ask the child if it connects to the parent. Thus, whenever you traverse a one-way connection, you're traversing it in the correct direction. The missing reverse-connection never becomes an issue, simply because it's not considered a connection.

==

Please do forgive me if at any point I'm belaboring the obvious. Once you get good at this stuff, the above becomes relatively obvious. But when you're learning it can be genuinely mysterious, a learning process filled with exciting "Ah ha! That's why it works" moments.


Edited by - breslin on 9/21/2007 6:19:28 AM

Return to Freelancer General Editing Forum