[RELz] tes3cmd, a small tool for modifying TES3 plugins

Post » Mon Aug 23, 2010 1:20 am

(Updated for Version 0.34)

tes3cmd is a little multi-tool program for examining and changing plugins.
Wiki page with download instructions here: http://code.google.com/p/mlox/wiki/Tes3cmd
(Requires Perl)

Features:
* dump records from a plugin in readable format.
* find records that are common between 2 plugins.
* batch rename of records (NAME/FNAM values).
* find overlapping dialog between plugins which are a possible source of quest bugs.
* delete records/sub-records.
* find differences between two plugins.
* create a patch for fogbugged CELLs.
* modify the Author/Description fields of the TES3.HEDR record.

While tes3cmd is mostly for the "power user", at least the fogpatch feature is likely to appeal to anyone who suffers from the "fogbug" that turns some internal CELLs black. With one simple command line (described below), tes3cmd will generate a patch to fix all those cells.

Usage

Note that the following usage definitions and examples presume you are prefixing tes3cmd with "perl". You can also write a batch file "wrapper" to encapsulate the command-line, or even make a "shortcut" so you can redo common tasks by dragging and dropping plugins onto it. This is all discussed on the InstallPerl page, and is recommended reading if you are unfamiliar with Perl scripts and command line usage.

Dump Records

Usage: tes3cmd dump OPTIONS plugin...

OPTIONS
-D turn on debug output.
-i ids only print out the records with ids matching the given comma-delimited
list of regular expression patterns.
-l only list the ids of the records to be printed, instead of the entire record.
-m regex only print records that match given regular expression.
-r print raw records, instead of as text.
-s string specify field separator string for single-line output.
-t types only print out the records matching the given comma-delimited
list of record types.

Dumps the plugin to stdout in text form for easy perusal. For large plugins,
the output can be voluminous.

Note: tes3cmd uses Perl regular expressions for matching, the full documentation
can be found here: http://www.perl.com/doc/manual/html/pod/perlre.html
You should at least be aware that the characters "\.?*+|^$()[]{}" have special
meaning in a regular expression and that they are unlike characters used for
matching on a Windows command line.

Examples:

# Dump all records from a plugin (this could generate a lot of output):
tes3cmd dump plugin.esp

# Dump all records with IDs matching "foo":
tes3cmd dump -i foo plugin.esp

# Dump all the CELL records from a plugin:
tes3cmd dump -t cell plugin.esp

# Dump all cells from bradhia_v1_4.esp containing NPC named: "Maeve Jaste"
tes3cmd dump -t cell -m "NAME:.*maeve.jaste" bradhia_v1_4.esp

List Records Common Between Two Plugins

Usage: tes3cmd common OPTIONS plugin1 plugin2

OPTIONS
-D turn on debug output

Prints the IDs of records that the 2 given plugins have in common.

Example:

# Show the records in common between my plugin and Morrowind.esm:
tes3cmd common myplugin.esp Morrowind.esm

Batch Rename Records

Usage: tes3cmd rename OPTIONS RECTYPE.SUBTYPE FROM TO plugin...

This first form of the command renames all records of type RECTYPE, replacing
the Perl regular expression FROM with the value of TO (which may contain
backreferences). The rename only happens if the CELL.NAME subrecord matches
the given FROM regular expression.

Note: tes3cmd uses Perl regular expressions for matching, the full documentation
can be found here: http://www.perl.com/doc/manual/html/pod/perlre.html
You should at least be aware that the characters "\.?*+|^$()[]{}" have special
meaning in a regular expression and that they are unlike characters used for
matching on a Windows command line.

tes3cmd rename -l RECTYPE.SUBTYPE plugin...

When the -l switch is given, records of the given type are only listed. (You
do not give a FROM or TO when using the -l option).

OPTIONS
-D turn on debug output
-i only rename if the record is an interior CELL.
-e only rename if the record is an exterior CELL.
-l just list the records, do not rename them. (This is obsolete, use the "tes3cmd dump" command instead)
-w size of printable window for record contents printed with -l switch.

The original input file is never modified, the changes are made in a new file
"_new.esp". This file is OVERWRITTEN if it exists.

Note that when renaming scripts, you can use either SCPT.SCTX or SCPT.SCHD as
the RECTYPE.SUBTYPE parameter, and the script name is changed in both
subrecords.

Examples:

# rename all exterior cells to the null string:
tes3cmd rename -e CELL.NAME ".*" "" plugin.esp

# do a caseless comparison with the FROM pattern:
tes3cmd rename cell.name "(?i)pelagaid" "Pelagiad" plugin.esp
(This would rename any name that has the string "pelagaid" in it with any form
of capitalization, to "Pelagiad").

# The following command will swap the first and last name of all NPCs using
# substitution backreferences (a very powerful feature of regular expressions):
tes3cmd rename npc_.fnam "^(\S+)\s(\S+)$" "$2 $1" plugin.esp
(Note that on Linux you may need to use single-quotes instead of double-quotes).

Find Overlapping Dialog

Usage: tes3cmd overdial OPTIONS plugin...

OPTIONS
-D turn on debug output
-1 only test to see if dialog in the first plugin is overlapped. (by default
all plugins are checked against all other plugins, which is an n-squared
operation, meaning "possibly very slow").

Prints the IDs of dialog records that overlap from the set of given plugins.

An overlap is defined as a dialog (DIAL) Topic from one plugin that entirely
contains a dialog Topic from another plugin as a substring. For example, the
mod "White Wolf of Lokken" has a dialog topic "to rescue me" which overlaps
with the dialog topic "rescue me" from "Suran Underworld", which causes the
"Special Guest" quest from SU to get stuck because Ylarra won't offer the
topic "rescue me" when you find her in her cell.

Note that overlap is only a potential problem if the plugins are loaded in the
order they are listed in the output.

Example:

# Show dialog overlaps between Lokken and SU:
tes3cmd overdial BT_Whitewolf_2_0.esm Suran_Underworld_2.5.esp

Delete Records

Usage: tes3cmd delete OPTIONS plugin...

OPTIONS
-D turn on debug output
-i ids only delete the records with ids matching the given comma-delimited
list of regular expression patterns.
-m regex only delete records that match given regular expression.
-s only delete the subrecords that matched.
-t types only delete the records matching the given comma-delimited
list of record types.

Deletes records/subrecords from the plugin. You can really damage things with
this command, so be careful!

Note: tes3cmd uses Perl regular expressions for matching, the full documentation
can be found here: http://www.perl.com/doc/manual/html/pod/perlre.html
You should at least be aware that the characters "\.?*+|^$()[]{}" have special
meaning in a regular expression and that they are unlike characters used for
matching on a Windows command line.

Examples:

# Delete all records with IDs matching "foo":
tes3cmd delete -i foo plugin.esp

# Delete all subrecords of type npc_.npc0 that match "Ring des Skeletts" from
# savegame: quicksave.ess
tes3cmd delete -s npc_.npc0 -m "Ring des Skeletts" quicksave.ess

Find Differences Between Two Plugins

Usage: tes3cmd diff OPTIONS plugin1 plugin2

OPTIONS
-D turn on debug output.
-i comma-delimited list of field names to ignore.

Prints a report on the differences between the two TES3 files.
A summary report with up to four sections is printed to standard output
that gives an overview of differences, as lists of record IDs:
- objects in plugin1 that do not exist in plugin2
- objects in plugin2 that do not exist in plugin1
- objects in plugin1 that are equal in plugin2
- objects in plugin1 that are different in plugin2
(Sections that would have no items are not printed).

When objects in plugin1 are different in plugin2, each of these objects
is printed in detail to a file "plugin1.diff" and "plugin2.diff", which
can then be compared textually using a tool such as WinMerge or Emacs'
ediff function.

To reduce a great deal of "uninteresting" differences when diffing savegames,
CELL.FRMR records are automatically ignored when the ModIndex is zero. (Note
that in this case, the ObjIndex appears to only be incremented by one).


Example:

# Print report on differences between 2 savegames:
tes3cmd diff save1000.ess save2000.ess > diff.out

# You can also use the -i switch to ignore further subfields in order to help
# reduce the amount of differences as in the following example.
# Report on differences, but ignore the subfields CREA.AIDT and CELL.ND3D:
tes3cmd diff -i crea.aidt,cell.nd3d testa0000.ess testb0000.ess > diff.out

Patch Fogbugged CELLs

Usage: tes3cmd fogpatch

OPTIONS
-D turn on debug output

Creates a patch plugin to fix all cells in your plugins that would trigger the fogbug.

Examples:

# Create the patch plugin fogpatch.esp
tes3cmd fogpatch

Display/Update the TES3 Header

Usage: tes3cmd header OPTIONS plugin...

OPTIONS
-D turn on debug output
-a XXX set the Author field to the value XXX
-d YYY set the Description field to value YYY
-m multi-line output for listing field contents.

When -a and -d are not given, the current Author/Description field contents
are printed.

Field values are normally replaced by the given string. But if the string
begins with a "+", the existing value is appended with the new given value.

If a given value contains the string "\n", it will be replaced by a CRLF.

Note:
- the Author value should fit in 31 bytes.
- the Description value should fit in 255 bytes.

If the value supplied won't fit into the plugin header field, you will be
warned.

Examples:

# Show the Author/Description fields for a plugin:
tes3cmd header plugin.esp

# Set the Author field to "john.moonsugar":
tes3cmd header -a john.moonsugar plugin.esp

# Append " and friends" to the Author field:
tes3cmd header -a "+ and friends" plugin.esp

# Add a Version number to a plugin Description field:
tes3cmd header -d "+\nVersion: 1.0" plugin.esp
User avatar
Vivien
 
Posts: 3530
Joined: Fri Apr 13, 2007 2:47 pm

Post » Mon Aug 23, 2010 10:14 am

Ah, it's out. :)
User avatar
Amanda Furtado
 
Posts: 3454
Joined: Fri Dec 15, 2006 4:22 pm

Post » Mon Aug 23, 2010 6:21 am

Ah, it's out. :)

It got out of its cage by itself.

Please let me know if you encounter any problems!

And by all means, if there's some kinds of "batch" operations you'd like to perform on an .esp or set of .esps that is difficult/tedious to do with a GUI, let me know, and I'll see what I can do.
User avatar
Marguerite Dabrin
 
Posts: 3546
Joined: Tue Mar 20, 2007 11:33 am

Post » Mon Aug 23, 2010 9:59 am

The latest version in svn has 2 new features:

* Dump the records from a plugin in readable format, records can be selected by type or by ID, or you can just dump the whole kit 'n kaboodle.
* Find the ids of records in common between 2 plugins

The dump records feature is incomplete, many subrecords are decoded, but many still are not. But it's still fun to play with.

This tool is for the adventurous plugin hacker, it's alpha, and may damage your attributes. Caveat downloador.
:)
User avatar
x_JeNnY_x
 
Posts: 3493
Joined: Wed Jul 05, 2006 3:52 pm

Post » Mon Aug 23, 2010 4:27 pm

Hey john, this is exactly what I've been looking. Thank you! :goodjob:

I do seem to be having some problems making it work though; the problem appears to have something to do with Perl. I've never used Perl on a Windows environment, so I'm entirely unsure of how it should work. I don't really understand exactly what you are saying on this line:
Make sure the perl program "perl.exe" is in your execution path (%PATH%) (strawberry Perl should automatically add itself to your path when it installs).



I installed Strawberry Perl to the default installation path, C:\Strawberry.
I then saved tes3cmd.txt into my data files directory.
In the console I cd'd to data files.
Then I entered this: perl tes3cmd rename ALCH.NAME 'fl_cb_*' 'fl_npc_*' RenamedBBNPC.esp
I also tried it with perl.exe.
I always got the error "'perl' is not recongnized as an internal or external command, operable program or batch file."

I'm trying to simply change the prefix in the id on everything in this file.

Any ideas on what I am doing wrong? Thank!
User avatar
Anna Watts
 
Posts: 3476
Joined: Sat Jun 17, 2006 8:31 pm

Post » Mon Aug 23, 2010 12:41 pm

Hey john, this is exactly what I've been looking. Thank you! :goodjob:

I do seem to be having some problems making it work though; the problem appears to have something to do with Perl. I've never used Perl on a Windows environment, so I'm entirely unsure of how it should work. I don't really understand exactly what you are saying on this line:

Make sure the perl program "perl.exe" is in your execution path (%PATH%) (strawberry Perl should automatically add itself to your path when it installs).

I'm a little unfamiliar with the Windows lingo, but basically when you run a command terminal window, and you type in a command, Windows looks for the exe for that command using the environment variable called PATH. When strawberry perl installs itself, it adds to the PATH so that Windows can find perl. You may need to restart your system (or re-login) in order to get the change to your PATH.

I installed Strawberry Perl to the default installation path, C:\Strawberry.
I then saved tes3cmd.txt into my data files directory.

The actual "program" is called tes3cmd, not tes3cmd.txt, maybe on Windows it automatically adds the .txt for some reason, but if it does, it should be renamed to "tes3cmd". I hadn't realized Windows would do such a thing, so I'll make a proper release archive for tes3cmd in the future.

Any ideas on what I am doing wrong? Thank!

See if logging out and logging back in fixed the PATH problem first. After you do that, open a command terminal (Start -> Run -> cmd.exe) and just type "perl". If it just hangs at that point, type a control-C, because it means the PATH worked. If instead it says it didn't find perl, then something went wrong and we'll have to figure that out.

If perl was added to PATH ok, also rename tes3cmd.txt to tes3cmd, and see if the rest of the instructions on the wiki work for you.

Thanks for trying it out! Sorry for any inconvenience.
User avatar
ezra
 
Posts: 3510
Joined: Sun Aug 12, 2007 6:40 pm

Post » Mon Aug 23, 2010 10:43 am

Thank you.

Even after a reboot, nothing worked. Perl simply wasn't recognized, so it wasn't added the path. I uninstalled Strawberry Perl and replaced it with ActivePerl. It specifically gave me the option to install it into the path, and the command hung just as you said. So I then put in the parameters to the program as I did above (after also removing .txt) and it ran. A new esp was spit out just fine. The only problem is that there were no changes, nothing had been renamed. I am assuming it is simply due to the parameters I put. I'll read a bit more how those work.

Thanks for this!

I'll keep reporting back on my progress.
User avatar
LittleMiss
 
Posts: 3412
Joined: Wed Nov 29, 2006 6:22 am

Post » Mon Aug 23, 2010 2:11 pm

The only problem is that there were no changes, nothing had been renamed. I am assuming it is simply due to the parameters I put. I'll read a bit more how those work.

If you like, you can tell me the command line you tried and maybe I can see if you need to change something, or maybe if tes3cmd is broken! :)
User avatar
lillian luna
 
Posts: 3432
Joined: Thu Aug 31, 2006 9:43 pm

Post » Mon Aug 23, 2010 1:44 am

I tried this:
perl tes3cmd rename ALCH.NAME 'fl_cb_*' 'fl_npc_*' RenamedBBNPC.esp


All of the alchemy objects in that file have an id that begins with the prefix fl_cb_name. I want everything in the mod to eventually have the id prefix fl_npc_name...and I really wasn't looking forward to doing it manually. )

I'm pretty sure the problem is the parameters, I don't see anything about a * in the documentation. That was just an early guess.

Edit: Ah yes, it does show * as an expression....
User avatar
Georgia Fullalove
 
Posts: 3390
Joined: Mon Nov 06, 2006 11:48 pm

Post » Mon Aug 23, 2010 10:20 am

I tried this:
perl tes3cmd rename ALCH.NAME 'fl_cb_*' 'fl_npc_*' RenamedBBNPC.esp


All of the alchemy objects in that file have an id that begins with the prefix fl_cb_name. I want everything in the mod to eventually have the id prefix fl_npc_name...and I really wasn't looking forward to doing it manually. )

I'm pretty sure the problem is the parameters, I don't see anything about a * in the documentation. That was just an early guess.

The doc does mention "regular expressions" though, which is what you want, but ... there is a small learning curve if you are not familiar with them.

* is a very special character in regular expressions, so I'll have to get back to that.

But first, lets see if this works:

perl tes3cmd rename ALCH.NAME 'fl_cb_' 'fl_npc_' RenamedBBNPC.esp

It means that any subrecord of type alch.name containing fl_cb_ will have that part changed to fl_npc_.

This should be safe, if all occurrences of the substring fl_cb_ appear in one place (the beginning) of the string.

To use some of the power of regular expressions, you could "anchor" the FROM pattern to the start of the string with ^ (carat):

perl tes3cmd rename ALCH.NAME '^fl_cb_' 'fl_npc_' RenamedBBNPC.esp

This means replace fl_cb_ when it occurs at the start of a string.

The full documentation of regular expressions in perl is here:
http://www.perl.com/doc/manual/html/pod/perlre.html
User avatar
Claire Mclaughlin
 
Posts: 3361
Joined: Mon Jul 31, 2006 6:55 am

Post » Mon Aug 23, 2010 1:59 am

Yeah, I've reading that documentation and realize I don't yet understand much of it...so I'm still reading.

Anyhow, I tried both of the commands you suggested, both to no avail:
perl tes3cmd rename ALCH.NAME 'fl_cb_' 'fl_npc_' RenamedBBNPC.esp
perl tes3cmd rename ALCH.NAME '^fl_cb_' 'fl_npc_' RenamedBBNPC.esp


I ran the first one also the flag -l, and before it listed the records it showed two errors.

Error, 'fl_cb_' name does not end in .esm or esp?
Error. 'fl_npc_' name does not end in ,esm or .esp?
User avatar
Theodore Walling
 
Posts: 3420
Joined: Sat Jun 02, 2007 12:48 pm

Post » Mon Aug 23, 2010 1:39 pm

I ran the first one also the flag -l, and before it listed the records it showed two errors.

Error, 'fl_cb_' name does not end in .esm or esp?
Error. 'fl_npc_' name does not end in ,esm or .esp?

This one should be easy, when you specify the -l flag, you do not put a FROM or TO pattern (because you are not renaming).

The command line for listing records is:
perl rename -l alch.name pluginname.esp

Edit: As for the first problem, could you mail me the plugin, if it isn't too big? I will try it on my XP system.

Edit2: Ah, not bug in tes3cmd, bug in command line! my Oops!

Try this command line, without the singlequotes:

perl tes3cmd rename ALCH.NAME fl_cb_ fl_npc_ RenamedBBNPC.esp

(bloody f***ing Windows! Gah! :))

Edit 3: I just tried the esp you sent, and it seems to work fine without singlequotes:

perl tes3cmd rename ALCH.NAME fl_cb_ fl_npc_ RenamedBBNPC.esp

perl tes3cmd rename -l ALCH.NAME RenamedBBNPC_new.esp

The listing of the modified plugin shows all the renamed records.
Sorry for the trouble! I'll go fix my documentation.

If any windows folks can explain to me why the heck Windows fails when you try to singlequote a string, please let me know. Tanks.
User avatar
Louise
 
Posts: 3407
Joined: Wed Nov 01, 2006 1:06 pm

Post » Mon Aug 23, 2010 7:20 am

Ha ha! It worked perfectly. Thanks so much for this, and for your help this morning. I think you, with this utility, just managed to get credit in MANY of my readmes. ;)

Thanks again. :goodjob:
User avatar
Jade
 
Posts: 3520
Joined: Mon Jul 10, 2006 6:42 am

Post » Mon Aug 23, 2010 3:19 am

I'm glad you got it working! (Be sure to double-check the results in the CS or EE :) tes3cmd is still kinda "Alpha").
If you encounter any problems, let me know.
I gotta go fix the documentation.
User avatar
casey macmillan
 
Posts: 3474
Joined: Fri Feb 09, 2007 7:37 pm

Post » Mon Aug 23, 2010 1:36 pm

I immediately opened it up in EE. Everything looked to be there exactly as I had hoped.
User avatar
Robyn Lena
 
Posts: 3338
Joined: Mon Jan 01, 2007 6:17 am

Post » Mon Aug 23, 2010 8:29 am

Out of morbid curiosity, is there a reason that it won't rename scripts?
User avatar
Sierra Ritsuka
 
Posts: 3506
Joined: Mon Dec 11, 2006 7:56 am

Post » Mon Aug 23, 2010 4:36 pm

Out of morbid curiosity, is there a reason that it won't rename scripts?

I assume because the script name is held within the first 32 bytes of a 52 byte record, rather than having a record that just holds its name in a cstring like most other records.
User avatar
Jade Muggeridge
 
Posts: 3439
Joined: Mon Nov 20, 2006 6:51 pm

Post » Mon Aug 23, 2010 8:17 am

I assume because the script name is held within the first 32 bytes of a 52 byte record, rather than having a record that just holds its name in a cstring like most other records.

Well, it's more because the script name exists in two place, the SCHD as you mention, and the SCTX, so I would have to special case this to get it to work so it correctly updates both, and I just haven't done it yet.

But if you want to be able to rename scripts, let me know and I'll add that ability.
User avatar
Anthony Diaz
 
Posts: 3474
Joined: Thu Aug 09, 2007 11:24 pm

Post » Mon Aug 23, 2010 12:10 pm

It would be nice to have. Also the ability to rename global variables if possible.

It just took me easily 1/4 of the time it should have to rename the ID in every record in this mod. I think that any further improvements and functionality would be welcome! :goodjob: Sure wish I had this back when I was working on Fliggerty's Armor Project....
User avatar
Milad Hajipour
 
Posts: 3482
Joined: Tue May 29, 2007 3:01 am

Post » Mon Aug 23, 2010 3:14 pm

It would be nice to have. Also the ability to rename global variables if possible.

It just took me easily 1/4 of the time it should have to rename the ID in every record in this mod. I think that any further improvements and functionality would be welcome! :goodjob: Sure wish I had this back when I was working on Fliggerty's Armor Project....

I'll go take a look and see what I have to do to enable script renaming. Shouldn't be too hard.

I've updated the wiki for tes3cmd with some minor fixups (including the singlequotes snafu):
http://code.google.com/p/mlox/wiki/Tes3cmd
and added a page that tries to explain running command line perl programs better:
http://code.google.com/p/mlox/wiki/InstallPerl

If anyone wants to advise me on content/presentation or whatever on those pages do let me know! Thanks.

I'll probably make a real "Release" for tes3cmd now so it will come in an archive file instead of from svn. This will probably be available in about half a day.
User avatar
Nikki Hype
 
Posts: 3429
Joined: Mon Jan 01, 2007 12:38 pm

Post » Mon Aug 23, 2010 12:49 pm

The actual "program" is called tes3cmd, not tes3cmd.txt, maybe on Windows it automatically adds the .txt for some reason, but if it does, it should be renamed to "tes3cmd". I hadn't realized Windows would do such a thing, so I'll make a proper release archive for tes3cmd in the future.

Personally, I give them the .pl extension. It's mostly cosmetic, but it means that the Windows file explorer knows that they're to be opened with pnotepad, that they're called "Perl program" rather than just "File", and that they have an icon. :)
User avatar
Chavala
 
Posts: 3355
Joined: Sun Jun 25, 2006 5:28 am

Post » Mon Aug 23, 2010 8:32 am

Personally, I give them the .pl extension. It's mostly cosmetic, but it means that the Windows file explorer knows that they're to be opened with pnotepad, that they're called "Perl program" rather than just "File", and that they have an icon. :)

That'll work too!

Maybe, in the future if it seems like the right thing to do, it will be called "tes3cmd.pl" for the windows version. (the Linux version will remain tes3cmd, though)
User avatar
xemmybx
 
Posts: 3372
Joined: Thu Jun 22, 2006 2:01 pm

Post » Mon Aug 23, 2010 2:22 pm

Bump for new release: tes3cmd-0.31 is now available from the mlox downloads page:
http://code.google.com/p/mlox/downloads/list

New in this release: scripts can now be renamed (using either SCPT.SCHD or SCPT.SCTX)
Also, the documentation and usage have been updated to be current and more helpful, hopefully.

If you run into any problems, do let me know!
Thanks.
User avatar
Steph
 
Posts: 3469
Joined: Sun Nov 19, 2006 7:44 am

Post » Mon Aug 23, 2010 5:20 pm

Thanks so much for this! :goodjob:
User avatar
Erika Ellsworth
 
Posts: 3333
Joined: Sat Jan 06, 2007 5:52 am

Post » Mon Aug 23, 2010 12:42 pm

First, thanks for this!!!!! I didn't know about it until Fliggerty pointed it out to me.
Now, to get it running. I am not a wiz with command line programs, so go easy on me. :)

I tried Strawberry 5.10.0.3. and could not get it to work. It was giving me a "Can't open perl script "tes3cmd": No such file or directory." when I enter C:\strawberry\perl\bin\perl tes3cmd help
I know it's in the "bin" file too. That is where it goes, right.


I'm giving ActivePerl 5.10. a try.

I'll tell you exactly what I will be doing with this. Changing the ID's of armor and body parts for the HELLUVA mods I am working on. Maybe that will help.
I am also very limited on my ability with batch files.
User avatar
LijLuva
 
Posts: 3347
Joined: Wed Sep 20, 2006 1:59 am

Next

Return to III - Morrowind