* Extendible database via [text file](https://www.youtube.com/watch?v=Pz0_RGwgfaY) or a [lua script](https://github.com/dvdvideo1234/TrackAssemblyTool/blob/master/data/autosave/z_autorun_add_pieces.lua)
* Extendible database via [text file load list](https://github.com/dvdvideo1234/TrackAssemblyTool/blob/master/data/trackassembly/trackasmlib_dsv.txt) and [list prefixes](https://github.com/dvdvideo1234/TrackAssemblyTool/blob/master/data/trackassembly/dsv/Test_s_track_packTRACKASSEMBLY_PIECES.txt) [categories](https://github.com/dvdvideo1234/TrackAssemblyTool/blob/master/data/trackassembly/dsv/Test_s_track_packTRACKASSEMBLY_CATEGORY.txt)
Will stack as many pieces as shown by the slider `Pieces count`.
1. Pressing ATTACK2 ( Default: Right mouse button )
* Will select the trace model to use as a piece for building a track.
2. Pressing USE ( Default: E ) + ATTACK2 ( Default: Right mouse button )
* When pointing to the world will open the `Frequent pieces by <PLAYER_NAME_HERE>` frame, from where
you can select your routine pieces to use again in the track building process
as well as [searching in the table](https://github.com/dvdvideo1234/TrackAssemblyTool#hey-there-is-a-text-box-and-a-drop-down-menu-next-to-the-exportdb-button-what-are-these-for-) either by `MODEL`, `TYPE`, `NAME`, `LAST_USED` to obtain the piece
you want to continue your track with.
3. Pressing RELOAD ( Default: R )
* When used in the world exports the database if the console variable `trackassembly_exportdb` is set to <>0,
* When used on trace it removes it, if it's a track piece.
* Ron's 56 gauge rails ( Removed by the addon owner and [discontinued](https://github.com/dvdvideo1234/TrackAssemblyTool/tree/master/data/discontinued/owner-discontinued) )
* [Ron's 2ft track pack](https://steamcommunity.com/sharedfiles/filedetails/?id=634000136) ( [Maintained by the owner](https://github.com/dvdvideo1234/TrackAssemblyTool/tree/master/data/discontinued/owner-maintained) )
* PHX Tubes **(INCLUDED)**
* [Magnum's second track pack](https://steamcommunity.com/sharedfiles/filedetails/?id=391016040) ( Ignore, not designed as prop )
models/props_phx/trains/track_128.mdl ( Here, the category "straight" is not present at all )
```
#### Hey, remember that roller coaster assistant addon, that was snapping pieces when you got them close to each other and they magically connect. Does this script has a feature like this ?
Other value will be treated as `LOG`. But remember young samurai, this variable is only server side,
and because of that you can only access it via single player or set it in the `server.vdf` gmod
start-up file. May the force be with you and your server !
*<br>Note: The error is logged if the logs are enabled !*
#### Is there any feature which can be used to control which log messages can show up and which will not?
You can easily do that by creating settings for the logs. These are nothing more than
text files, where contents are matched to the logs you want to skip. The location that you
must create these files in is located here: `data/trackassembly/trackasmlib_sl<suffix>.txt`
There are the types of logging settings, where the file `<suffix>` matches it with down casing:
*`skip` (`trackasmlib_slskip.txt`): If a log message is found persisting in this list,
it won't show in the output (a.k.a black listed).
This is good when a function is called many times and floods
*`only` (`trackasmlib_slonly.txt`): All other log messages will be blocked besides the ones
in this list (a.k.a only ones white listed)
This is good when you want to see only one single thing
These are [mine](https://github.com/dvdvideo1234/TrackAssemblyTool/blob/master/data/trackassembly/trackasmlib_slskip.txt) if you want to take a look how to create one.
#### Does this thing have any wire extensions and how can I control then when my clients are abusing them ?
Yes it does. You can enable/disable the wire extension using the
convar `trackassembly_enwiremod` and set it to `0` to disable the wire
extension and `1` to enable it.
#### What do the tool versions represent?
The first number will get an increase when a new major update has arrived.
The second number is the commit number in the repository, related to
some smaller changes and fixes. For example rearranging the code, new features,
performance optimizations, doing the same thing, but in more elegant
way and such.
#### I want to use custom tweaks for my server. Could you recommend appropriate cvars ?
Here is the list of the maximum value tweaks and settings ( prefixed with "trackassembly_" of course ):
Maximum values controlling local process:
```
maxtrmarg - Controls the maximum time needed to perform a new player-cached trace
maxmass - Controls the mass upper limit of the piece spawned ( the lower bound is "1" )
maxlinear - Controls the maximum offset that can be applied by next x,y,z linear offsets
maxforce - Controls the force limit upper border on the welds made between pieces
maxactrad - Controls the vastness of the active point search area
maxstcnt - Controls the maximum pieces that can be spawned in stacking mode
maxfruse - Controls the maximum records that can be located under the frequent pieces list
sbox_maxprops - The maximum props on the server ( Gmod default control )
sbox_maxasmtracks - A variable for the maximum things spawned via TA
```
You can trigger these limits independently from one another. For example:
* Value `maxprops` is `50` and `maxasmtracks` is `30` will trigger maxasmtracks
* Value `maxprops` is `30` and `maxasmtracks` is `50` will trigger maxprops
* Value `maxprops` is `50` and `maxasmtracks` is `50` will trigger maxasmtracks
*Note: If you want a server with many props and fewer tracks, then lower maxasmtracks
Default value is 1500 for `maxasmtracks` to rely on the props limit.*
#### I want to use Lua mode because I've got third-party SQLite server. How can I switch to Lua mode ?
You can do the following:
1. On the tool screen next to holder's model validation you shall see the database mode.
2. Bring up the console and write `trackassembly_modedb LUA` ( or `SQL` to go to SQL mode respectively ).
3. Press enter and restart Gmod.
4. Look at the tool screen. After holder's model validation, it shall write the new mode.
5. Done. You are now in `LUA` mode.
Using `SQL` mode is still the best option for using the tool with for servers, because only a few models have to
stay in the cache for a given amount of time, rather than the whole database forever ( till the server
is up that is ), so please use `SQL` mode when possible if you want to save some amount of RAM.
`LUA` mode is used as a default option, because some people have third party SQL servers, which messes with
the `sql.*` library of the game and does not allow me to create the needed SQL tables and records properly.
#### Can I do something about my server's performance and how can I configure the memory manager properly?
You can choose a memory management algorithm by setting `trackassembly_timermode` to `mode@life@clear@collect`
for any table sequentially divided by `/`. First of all the memory manager is available only in `SQL` mode,
because in `LUA` mode, all the records are already in the memory and thus, there is no need to manage ( delete )
anything automatically. An example timer setting looks something like this: `CQT@1800@1@1/CQT@900@1@1/CQT@600@1@1`.
Here `mode` setting is the memory management algorithm to be used ( either `CQT` or `OBJ` ) for the table.
These are explained below what they do. The `life` in the cache for the record is how much time in seconds
the data will spend sitting in the cache, until it gets deleted to save some memory ( For the example above
a half an hour for `PIECES`, 15 minutes for `ADDITIONS` and 10 minutes for `PHYSPROPERTIES` ).
The greater the number, the more persistent are the records and fewer queries will be used to retrieve the data.
Setting this to `0` will turn off the memory management for the table.
The `clear` setting if different than `0`, assigns a `nil` to the record, marking it for
deletion by Lua's garbage collector. The `collect` setting if different than `0` calls the garbage collector when a
record is marked or equal to `0` leaves it to the game's garbage collector. It's pretty much for you to decide because
every setting has its pros and cons.
1.`CQT` - The memory management is called every time a new piece is requested from the cache and
not found. Therefore a query should be processed to retrieve it from the database, so
as it does at the end it runs a "for k, v pairs(Cache)" cycle, inspecting which record is
old enough ( not used for given amount of time ) to be deleted and marks it for deletion.
* Pros: Lighter algorithm.
No need for additional memory allocation for timers.
Garbage collector ( `collect` different than `0` ) is called once to process all the obsolete records.
* Cons: Uses particular points in time when a record is used/loaded and judges by these how old is it.
Records do not get deleted from the cache at the exact moment when the life in the cache runs out.
* Used: When there is no need of many timer objects to store in the memory ***OR***
they cannot be created due to some reasons not related to the TA tool ***OR***
the time precision does not matter when the record gets deleted ***OR***
the server will run out of memory when creating too many objects ( timers ).
2.`OBJ` - It attaches a timer object ( That's why the `OBJ` xD ) to every record
created in the cache with one repetition for given amount of time ( The life )
in seconds. After the time is passed, the record is marked for deletion, and the timer is destroyed.
* Pros: Obsolete ( not so frequently used ) records are deleted at the exact given time when processed.
The timer is deleted with the record.
It uses a running process, rather than points in time to control the memory management.
* Cons: Heavier algorithm.
Needs additional memory for the timers.
Garbage collector ( `collect` different than `0` ) is called on every timer function call.
* Used: When server has enough memory for the timers ***OR***
the record has to be deleted at the exact moment the life passes.
#### Does this script store the created queries for later use ?
Yes. That way it performs faster statements generation with very little memory consumed.
Statement storage is based on caller name. Good example is `CacheQueryPiece` where
the program tries to retrieve the generated query, without going trough the trouble to
concatenate all the fields. For the most expensive function `CacheQueryPiece`, the request
is done using the model, so in the statement it is substituted as an argument provided
to `SQLCacheStmt(<hash>, <stmt>, <arguments>)`. That way the base statement
is stored once and formatted every time it needs to be used.
#### Hey, there is a text-box and a drop-down menu next to the `ExportDB` button. What are these for ?
Well, when a server owners set the `trackassembly_maxfruse` to a higher value, a slider appears.
If the client has used many pieces during his/her routine, he/she cannot possibly locate the ones
he/she needs, especially, when they are at the bottom of the list as not `frequently used` pieces.
That's why it was needed some kind of a filter. With the drop-down menu, you can chose whatever
field to filter the data on (`<SearchBY>` either `Model`, `Type`, `Name`, `Act`). Do not bother that
the name is not displayed in the pieces list. [That's normal](https://theportalwiki.com/wiki/Cave_Johnson). For 95% of the
models, it is dynamically generated using the `*.mdl` file, so there is really no point in viewing
that parameter on the pieces panel. In the text-box, to search you have to enter a pattern that
you want to perform the filtering with. The result will populate the list view, only with these
pieces, whatever desired field value is matched by the pattern given. The pattern is a standard
Lua one, which is supported by the `string.*` library and you can also [google it](http://lmgtfy.com/?q=lua+string+library+pattern+matching) ;)
#### May I become a volunteer to translate the script to my native language and how can I use translations ?
Yes you may, though always make sure to use the abbreviation for the language codes provided
If you want to translate it into [Bulgarian](https://en.wikipedia.org/wiki/Bulgarian_language) for example ( my [native](https://en.wikipedia.org/wiki/First_language) ) you must duplicate all the
translations like seen below. I took English translation and translated it to Bulgarian.
```
English : asmlib.SetLocalify("en","tool."..gsToolNameL..".activrad_con" , "Active radius:")
* [Excel 2010] Save as type: `Text (Tab delimited)(*.txt)`
* [Excel 2010] Replace it if you must (don't worry you can always generate it again ( points 3) and 4) )
* [Excel 2010] It will prompt you that the file you are saving does contain features not compatible with `TAB Delimited` format
* [Excel 2010] Click `Yes` and close Excel
* [Excel 2010] It will want you to save it again, so just click `Don't Save`
* [Excel 2010] You are good to go
If you have trouble with this step by step tutorial, maybe [this](https://www.youtube.com/watch?v=Pz0_RGwgfaY) will help
2. The second method involves personal `DSV` database. This option is mostly used when you want to
separate your own stuff from the general data pool. The track pack creators use this method to
add their custom track models in the database via [Lua script](https://github.com/dvdvideo1234/TrackAssemblyTool#how-how-can-i-make-a-script-which-synchronizes-the-database-of-my-track-pack-). Let's call the `<database_prefix>``MyStuff_`
( what's added ) and your addon name `John Doe's trackpack` ( who has added it a.k.a the data exporter )
* Navigate to `..common/GarrysMod/garrysmod/data/trackassembly`
* Open the file `trackasmlib_dsv.txt`. If it does not exist then just create it.
* You can always comment an addon to prevent it loading its pieces to the database via `#`
a hash tag symbol in front of the line which you want disabled.
* Inside the file you just have to add the content `<database_prefix>[TAB symbol]<data_exporter>`
* For the example above you will have `MyStuff_[-->]John Doe's trackpack`
* The second value is optional, but you will need a tab symbol to separate these
two if you put it there. If you don't put it, you need only the prefix
* Open the file `dsv/MyStuff_TRACKASSEMBLY_PIECES.txt`
If it does not exist then just create it. This file is mandatory. Now insert
and they will be loaded during the tool initialization
* Open the file `dsv/MyStuff_TRACKASSEMBLY_CATEGORY.txt`. If it does not exist then just create it.
This is optional ! It is done when you want to use classification categories for your database
The format contains open definition delimiter, closing one and a separator.
Between these you must have your addon name and a function defined as a string. The token
opening the definition is `[===[``(1)`. The token used for delimiter is `===``(2)`. The closing
sequence for the definition is `]===]``(3)` and it means that the definition ends.
Between `(1)` and `(2)` you must have the addon name (ex. John Doe's trackpack)
Between `(2)` and `(3)` you must have an actual Lua function written as string
`function(m) ( do some stuff ) end`, where the `m` parameter is dynamically populated
with the track piece model path. You must use that value to extract the category
you need. Usually this is one of the
[sub-directories of the model](https://github.com/dvdvideo1234/TrackAssemblyTool/blob/master/data/trackassembly/dsv/Test_s_track_packTRACKASSEMBLY_CATEGORY.txt)
path or piece prefix/suffix
* Open the file `dsv/MyStuff_TRACKASSEMBLY_ADDITIONS.txt`
This is optional ! If it does not exist then just create it. This file hold definitions of what props
must be spawned with the track pieces. These are like scenery, buttons and stuff.
A good example for an addon which uses [ADDITIONS](https://github.com/dvdvideo1234/TrackAssemblyTool/blob/master/data/trackassembly/dsv/cl_TRACKASSEMBLY_ADDITIONS.txt) parameters is `Shinji's track pack`