nasher is a command-line tool for converting a Neverwinter Nights module, hak, or erf file into text-based source files and vice versa. This allows git-based version control and team collaboration.
This guide is current as of nasher release 1.0.x.
Note: This is the easiest way to install, and is recommended for most users.
Download latest version
of nasher for your OS and place a pointer to the location of the executable
file in your PATH
environment variable.
In addition, you will need the following tools:
Starting with 1.0.0, nasher's default script compiler is neverwinter.nim's
nwn_script_comp
. If you'd like to use the legacy script compiler nwnsc,
you'll need:
Note: this method is harder to set up, but makes it easier to update.
First, install the following:
Optionally, install nwnsc if you'd like to use the legacy script compiler:
Note: when building nasher, nimble will download and install neverwinter.nim automatically. You do not need to install it yourself.
Now you can have nimble download and install nasher:
$ # Install the latest tagged version (recommended)
$ nimble install nasher
$ # Install the latest version from the master branch
$ nimble install nasher@#head
$ # Install a specific tagged version
$ nimble install nasher@#0.17.4
Alternatively, you can clone the repo and build it yourself (handy if you want to make changes and contribute to development):
$ git clone https://github.com/squattingmonk/nasher.git
$ cd nasher
$ nimble install
You can also run with docker if you want to get fancy with containers, but most people should use the other routes.
Docker commands are run with the same nomenclature as native nasher commands. If you want to use docker, any time you see a native nasher command in this document, you can replace it with the docker command. So the following are equivalent:
$ nasher <command>
$ docker run --rm -it -v ${pwd}:/nasher nwntools/nasher:latest <command>
You can also create an alias in your .bashrc
and just use nasher <command>
:
alias nasher='docker run --rm -it -v ${pwd}:/nasher nwntools/nasher:latest '
nasher will detect neverwinter.nim tools and your chosen script compiler if
they are in your PATH
enviromental variable. You can also use nasher's
config
command to set the proper locations if the tools are not on your
PATH
variable:
$ # Set the path to the script compiler
$ # neverwinter.nim script compiler
$ nasher config nssCompiler "%USERPROFILE%/bin/nwn_script_comp.exe" # Windows
$ nasher config nssCompiler "~/.local/bin/nwn_script_comp" # Posix
$ # or nwnsc (this must be set if you want to use nwnsc with nasher >=0.22.0)
$ nasher config nssCompiler "%USERPROFILE%/bin/nwnsc.exe" # Windows
$ nasher config nssCompiler "~/.local/bin/nwnsc" # Posix
$ # Set the path to nwn_erf
$ nasher config erfUtil "%USERPROFILE%/bin/nwn_erf.exe" # Windows
$ nasher config erfUtil "~/.local/bin/nwn_erf" # Posix
$ # Set the path to nwn_gff
$ nasher config gffUtil "%USERPROFILE%/bin/nwn_gff.exe" # Windows
$ nasher config gffUtil "~/.local/bin/nwn_gff" # Posix
$ # Set the path to nwn_tlk
$ nasher config tlkUtil "%USERPROFILE%/bin/nwn_tlk.exe" # Windows
$ nasher config tlkUtil "~/.local/bin/nwn_tlk" # Posix
nasher will also detect NWN if it was installed by Steam, Beamdog, or GOG. If
you are having issues getting nasher to recognize your NWN install, you can set
the NWN_ROOT
environment variable to the path. Similarly, the NWN_HOME
environment variable should point to the local of your NWN user directory
(i.e., where to install modules, haks, etc.). For example:
# In your .bashrc
export NWN_ROOT="$HOME/.local/share/Steam/steamapps/common/Neverwinter Nights"
export NWN_HOME="$HOME/Documents/Neverwinter Nights"
Further information on configuration can be found below.
$ nasher init myproject
$ cd myproject
When the prompt asks for your target's filename, make sure you put the
filename of the module you want to use for the project (e.g.,
mymodule.mod
)
nasher unpack
nasher install
nasher unpack
Repeat steps 3-7 until you are satisfied with your changes, then commit the files in git and push to your remote repo:
$ git commit -am "My commit message"
$ git push origin master
Now share the repo with your team. They can download the repo and build your module from the source files:
$ git clone https://github.com/myusername/myproject
$ cd myproject
$ nasher install
You can get help for nasher or one of its commands using the --help
flag:
$ nasher --help # General help
$ nasher <command> --help # Command-specific help
If you're still stuck, you can get assistance in several locations:
Nasher can be configured for user-specific settings with the config
command. Configuration keys can be set on a global, per-package, or per-command
basis. See the keys section for available settings.
A nasher package must have a nasher.cfg
file in the package root directory.
This file contains package-specific settings that should be the same across all
instances of the package. It does not vary for different users.
Here is a basic nasher.cfg
that will serve for simple projects:
[package]
[package.sources]
include = "src/**/*.{nss,json}"
[package.rules]
"*" = "src"
[target]
name = "default"
file = "demo.mod"
description = ""
Here is a larger one showing more features that nasher supports:
[package]
name = "Core Framework"
description = "An extensible event management system for Neverwinter Nights"
version = "0.1.0"
author = "Squatting Monk <squattingmonk@gmail.com>"
url = "https://github.com/squattingmonk/nwn-core-framework"
# This key is inherited by targets that don't define it themselves. It uses a
# variable to refer to the target's name, which is resolved for each target
# (e.g., the target "scripts" will have the file "scripts.hak").
file = "$target.hak"
# You can define your own variables to reference in other keys
[package.variables]
sm-utils = "../sm-utils/src"
[package.sources]
include = "${sm-utils}/*.nss" # This variable is expanded
include = "src/**/*.{nss,json}"
exclude = "**/test_*.nss"
skipCompile = "util_i_library.nss"
[package.rules]
"hook_*.nss" = "src/Hooks"
"core_*" = "src/Framework"
"*" = "src"
# The first target is the default target and will be used by most commands when
# no target has been explicitly passed. This should normally be your most
# common operation, such as packing your module file.
[target]
name = "demo"
description = "A demo module showing the system in action"
file = "core_framework.mod"
modName = "Core Framework Demo Module"
modMinGameVersion = "1.69"
# erf, hak, and tlk files can be packed just like a module file.
[target]
name = "framework"
description = "An importable erf for use in new or existing modules"
file = "core_framework.erf"
[target.sources]
exclude = "src/demo/**"
exclude = "**/test_*.nss"
# These targets are members of the "haks" group. You can build them all with one
# command using "nasher pack haks". They all inherit the package-level "file"
# key.
[target]
name = "scripts"
group = "haks"
description = "A hak file containing compiled scripts"
# Filtering optional files, such as .nss, .gic, and .ndb, can greatly reduce
# packed file size
[target.sources]
include = "src/**/*.nss"
filter = "*.nss"
[target]
name = "blueprints"
group = "haks"
description = "A hak file containing blueprints"
[target.sources]
include = "src/blueprints/*.json"
[target]
name = "tlk"
description = "Custom talk file for PW"
file = "myPWtlk.tlk"
[target.sources]
include = "src/tlk/*.json"
While you can write your own configuration file, the init
command will
create one for you. It will show prompts for each section and provide useful
defaults. If you don't want to answer the prompts and just want to quickly
initialize the package, you can pass the --default
flag when running init
.
[package]
This section provides a places to note the package's author, description, name,
version, and url. This data is currently not used by any nasher commands, but
that may change in the future. You can skip it with the --skipPkgInfo
flag.
Field | Repeatable | Description |
---|---|---|
name |
no | package name |
description |
no | package description; """triple quotes for multi-line descriptions""" |
version |
no | package version |
url |
no | web location where the package can be downloaded |
author |
yes | name/email of the author |
Some fields, while optional, are inherited from the package by targets if set in this section:
Field | Repeatable | Description |
---|---|---|
file |
no | filename including extension be created; can optionally include path info |
group |
yes | a group a target may belong to; used to build multiple targets at once |
flags |
yes | command line arguments to send to the script compiler at compile-time |
branch |
no | the git branch to use for source files |
modName |
no | the name to give a module target file |
modMinGameVersion |
no | the minimum game version to run a module target file |
modDescription |
no | the description for a module target file |
Normally, the first target specified in nasher.cfg
will be the default.
However, you can manually specify the target to use as the default in the
[package]
section:
Field | Repeatable | Description |
---|---|---|
default |
no | the name of the default target |
[target]
At least one target must be specified. This section provides a target name,
description, and output filename. Many of these fields will be inherited if they
are not set for this target. Normally, missing values are inherited from the
[package]
section. However, you can instead inherit from another target using
the parent
key. Its value is the name of another target. The parent target
must be specified before the child target.
Field | Repeatable | Inherited | Description |
---|---|---|---|
name |
no | no | name of the target; must be unique among targets |
default |
no | no | whether the target should be the default (true/false) |
description |
no | no | an optional field that describes the target |
parent |
no | no | a target to inherit missing values from (if missing, will inherit from [package] ) |
file |
no | yes | filename including extension be created; can optionally include path info |
group |
yes | yes | a group this target belongs to; used to build multiple targets at once |
flags |
yes | yes | command line arguments to send to the script compiler at compile-time |
branch |
no | yes | the git branch to use for source files |
modName |
no | yes | the name to give a module target file |
modMinGameVersion |
no | yes | the minimum game version to run a module target file |
modDescription |
no | yes | the description for a module target file |
[*.sources]
The sources subsection tells nasher the locations of the source files needed for
a target. It can be set at the package level (i.e., [package.rules]
) or at the
target level (i.e., [target.rules]
). If a target is missing one of these
fields, it will be inherited from the package or parent.
All of these fields are repeatable.
Field | Description |
---|---|
include |
glob pattern matching files to include |
exclude |
glob pattern matching files to exclude |
filter |
glob pattern matching cached files to be excluded after compilation |
skipCompile |
glob pattern matching files to exclude from compilation |
Refer to the source trees section to understand how these fields are used by targets.
[*.rules]
When you unpack
a file, nasher searches the source tree to find
where to put it each of its source files. If the file is not found in the source
tree, it uses the rules in this section.
Rules take the form "pattern" = "path"
. pattern
is a glob pattern matching
a filename. path
is a directory path in which to place the file. All paths
are relative to the package root (i.e., the directory where your nasher.cfg
is
located).
A file is compared to the each rule's pattern
; if it matches, the file is
placed into the rule's path
and the next file is evaluated. Files that fail
to match any rule's pattern are placed into a directory called unknown
in the
project root for you to sort manually. To avoid this, use a catch-all rule
("*" = "path"
) at the end to match any files that did not match other rules.
Targets can define their own [target.rules]
section. If they don't
they will inherit from their parent target (if set) or the [package.rules]
section.
[*.variables]
You can define variables that can be referenced in any target field except for
name
. You can set variables in the [package.variables]
section (to apply to
all targets) or the [target.variables]
section (to apply to a single target).
Child targets may also inherit variables from parent targets. The key is the
variable name, while the value is what it should resolve to. The target
variables table is merged with the inherited variables table to allow missing
keys to be inherited.
If a variable referenced is not found, nasher will also check the environment variables. If a variable is not found in the table or the environment, an error is thrown.
Variables can be referenced using the syntax $variable
or ${variable}
. The
latter syntax allows variables to include non-alphanumeric characters or to be
adjacent to alphanumeric characters that are not part of the variable name
(e.g., ${foo}bar
).
One variable is available by default: $target
resolves to the name of the
current target. This allows some neat things:
# This package has two targets, "foo" and "bar", that yield a file
# named "foo.hak" and "bar.hak", respectively using the source files
# in "src/foo" and "src/bar" respectively.
[package]
file = "$target.hak"
[package.sources]
include = "src/$target/*"
[target]
name = "foo"
[target]
name = "bar"
This feature can also be used to easily reference out-of-tree projects:
[package]
[package.variables]
sm-utils = "../sm-utils/src" # Can be used by any target or rule
[package.sources]
include = "${sm-utils}/*.{nss,json}" # include files in sm-utils
include = "src/**/*.{nss,json}"
[package.rules]
"util_*" = "${sm-utils}" # Unpack util files to sm-utils
"*" = "src/$target" # Unpack unknown file to target's source dir
[target]
name = "demo"
file = "core_framework.mod"
[target]
name = "utils"
file = "sm_utils.erf"
[target.sources]
include = "${sm-utils}/*.{nss,json}" # include only files in sm-utils
Since nasher checks environment variables, you can place user-specific
information in an environment variable. For example, if you want to include a
file in a target using an absolute path, you could place it directly in the
nasher.cfg
, but this would not be useful for other users of your project:
[target]
name = "mymodule"
file = "my_module.mod"
[target.sources]
include = "src/*.{nss,json}"
include = "/home/squattingmonk/.local/src/nwscript/utils/util_i_color.nss"
This makes collaboration difficult, since other users of this project would have
to edit the nasher.cfg
to change the location of the file to where it is on
their system. Instead, you can use an environment variable:
[target]
name = "mymodule"
file = "my_module.mod"
[target.sources]
include = "src/*.{nss,json}"
include = "${SM_UTILS}/util_i_color.nss"
export SM_UTILS=/home/squattingmonk/.local/src/nwscript/utils
Other users can then set the environment variable to the location of their
choice without changing the nasher.cfg
.
A target's source tree is built from the include
, exclude
,filter
and
skipCompile
fields. Remember, each of these are inherited from the
[package.sources]
section if not specified in the [target.sources]
section.
nasher uses glob pattern
matching to identify desired files (e.g., src/**/*.{nss,json}
matches all
.nss
or .json
files in subdirectories of src
).
include
patterns are expanded to a source file list.exclude
pattern; matches are
removed from the list.Pack operations (convert
, compile
, pack
,
install
, and launch
) commands use the source tree as
follows:
convert
and compile
commands process the source files and output to a
cache directory.compile
command will prevent compilation of any files identified by
skipCompile
in nasher.cfg; skipped files may still be used as includes.pack
command is run, each cached file is checked against each
filter
pattern; matches are excluded from the final packaged file. Note
that filters should not have any path information since they are compared to
files in the cache, not the source tree.unpack
uses the source tree as follows:
module.ifo => src/module.ifo.json
).unknown
folder in the
package directory.unpack
operation.src
folder
and create your desired folder structure with your favorite file explorer. It
is rarely necessary to have much more than a single entry in the [*.rules]
section ("*" = "src"
). When a module is packed with nasher, the source
location of each file is noted and unpacked back to that location, so a
detailed [*.rules]
section is usually not necessary.[package.sources]
section as inclusive as possible and
use the [target.sources]
exclude
field to narrow down the included files
needed by the target.haks
group, then run nasher pack haks
to
build only the hak files.The syntax for nasher operation is nasher <command> [options] [<argument>...]
.
You can use the following options with most nasher commands:
Option | Description |
---|---|
-h , --help |
displays help for nasher or a specific command |
--yes |
automatically answer yes to all prompts |
--no |
automatically answer no to all prompts |
--default |
automatically accept the default answer to prompts |
--verbose |
increases the feedback verbosity |
--debug |
enable debug logging (implies --verbose ) |
--quiet |
disable all logging except errors |
--no-color |
disable color output |
nasher config [options] [<key> [<value>]]
nasher config [options] --<key>[:"<value>"]
Gets, sets, or unsets user-defined configuration options. These options can be local (package-specific) or global (across all packages). Regardless, they override default nasher settings.
Global configuration is stored in %APPDATA%\nasher\user.cfg
on Windows or in
$XDG_CONFIG/nasher/user.cfg
on Linux and Mac. These values apply to all
packages.
Local (package-level) configuration is stored in .nasher/user.cfg
in the
package root directory. Any values defined here take precedence over those in
the global config file. This file will be ignored by git.
Global and local configuration options can be overridden on a per-command basis by passing the key/value pair as an option to the command.
Option | Description |
---|---|
--global |
Apply to all packages (default) |
--local |
Apply to the current package only |
--get |
Get the value of <key> (default when <value> is not passed) |
--set |
Set <key> to <value> (default when <value> is passed) |
--unset |
Delete the key/value pair for <key> |
--list |
Lists all key/value pairs in the config file |
userName
: the default name to add to the author section of new packages
userEmail
: the default email used for the author section
nssCompiler
: the path to the script compiler
nwnsc
nwnsc.exe
nssFlags
: the default flags to use on packages
for `nwn_script_comp
, -lowqey
for nwnsc
NWN_ROOT
environment variable to find
your NWN install, it is preferable to use that rather than passing the
location through nssFlags
. If NWN_ROOT
is set (or if nasher can find
your NWN install without it), nwnsc should work fine using the default
values of -lowqey
.nssChunks
: the maximum number of scripts to process with one call to nwnsc
500
erfUtil
: the path to the erf pack/unpack utility
nwn_erf
nwn_erf.exe
erfFlags
: additional flags to pass to the erf utility
gffUtil
: the path to the gff conversion utility
nwn_gff
nwn_gff.exe
gffFlags
: additional flags to pass to the gff utility
gffFormat
: the format to use to store gff files
json
json, nwnt
tlkUtil
: the path to the tlk conversion utility
nwn_gff
nwn_gff.exe
tlkFlags
: additional flags to pass to the tlk utility
tlkFormat
: the format to use to store tlk files
json
json
installDir
: the NWN user directory where built files should be installed
~/.local/share/Neverwinter Nights
~/Documents/Neverwinter Nights
NWN_HOME
environment variable
instead as this can be read by other programs. If NWN_HOME
is not set,
nasher will use the value from this flag to populate it.gameBin
: the path to the nwmain binary
NWN_ROOT
environment variable to the location of your NWN
install makes this setting obsolete for most users.serverBin
: the path to the nwserver binary (if not using default Steam path)
NWN_ROOT
environment variable to the location of your NWN
install makes this setting obsolete for most users.vcs
: the version control system to use when making new packages
git
none
, git
removeUnusedAreas
: whether to prevent areas not present in the source files
from being referenced in module.ifo
.
true
useModuleFolder
: whether to use a subdirectory of the modules
folder to
store unpacked module files. This feature is useful only for NWN:EE users.
true
during install; true
during unpacking unless explicitly
specifying a file to unpacktruncateFloats
: the max number of decimal places to allow after floats in
gff files. Use this to prevent unneeded updates to files due to insignificant
float value changes.
4
1
- 32
onMultipleSources
: an action to perform when multiple source files of the
same name are found for a target.
choose
choose
(choose manually), default
(accept the first choice),
error
(abort with an error message)abortOnCompileError
: whether to automatically abort packing, installing, or
testing a target if nwnsc
encounters errors.
false
true
, false
packUnchanged
: whether to force packing a file if the source files have not
changed since the last pack.
false
true
, false
overwritePackedFile
: automatically answer the "Are you sure you wish to
overwrite?" prompt when an existing file of the same name is found within
the project dir (pack
command only):
ask
ask
(always ask), default
(overwrite only if the existing
file is older than the newest source file), always
(always overwrite),
never
(never overwrite)overwriteInstalledFile
: automatically answer the "Are you sure you wish to
overwrite?" prompt when an existing file of the same name is found within
installDir
(install
command only):
ask
ask
(always ask), default
(overwrite only if the existing
file is older than the newest source file), always
(always overwrite),
never
(never overwrite)skipCompile
: semicolon-delimited list of glob patterns matching files to
skip during compilation. Used to avoid errors when broken scripts are present.
$ # Set the path to nwnsc
$ nasher config nssCompiler ~/.local/bin/nwnsc
$ # Get the path to nwnsc
$ nasher config nssCompiler
~/.local/bin/nwnsc
$ # Unset the path to nwnsc
$ nasher config --unset nssCompiler
$ # List all options set in the config files
$ nasher config --list # global
$ nasher config --list --local # local
--
operator causes all following arguments to be treated as positional
arguments, even if they look like options. This is useful when setting config
keys to values starting with -
: nasher config --nssFlags "-n /opt/nwn"
nssCompiler
and installDir
work best as global optionsmodName
or useModuleFolder
work best as local optionsuser.cfg
files are intentionally ignored by git. Do not include them in
your commits, since other users may require different values than those that
work on your machine--nssFlags
:
-n
.-b
and -i
.
Those flags can be passed to nwnsc per target through nasher.cfg.NWN_ROOT
environment variable with the default
-lowqey
value rather than the -n /path/to/NWN/install
method. This
ensures that nasher, nwnsc, and the neverwinter.nim tools are always
using the same NWN install location.nasher init [options] [<dir> [<file>]]
Creates a new nasher package, launching a dialog to generate a nasher.cfg file and initializing the new package as a git directory.
Flag | Description |
---|---|
--default |
skip the package generation dialog and manually edit |
--vcs:none |
do not initialize as a git repository |
--file:<file> |
unpack the contents of <file> into the new package |
$ # Create a new nasher package in the current directory
$ nasher init
$ # Create a new nasher package in the directory foo
$ nasher init foo
$ # Create a new nasher package from a module file
$ nasher init foo --file:"~/Documents/Neverwinter Nights/modules/foobar.mod"
nasher list [options] [<target>...]
Lists all named <target>
s defined the in nasher.cfg along with
their descriptions, source file patterns, and the name of the file that will be
generated. If a target is not passed, will list all targets. The first listed
target is the default for other commands.
Flag | Description |
---|---|
--quiet |
list only target names |
--verbose |
list source files as well |
nasher unpack [options] [<target> [<file>]]
Unpacks a file into the project source tree for the given target.
If a target is not specified, nasher will use the first target found in the nasher.cfg file. If a file is not specified, nasher will search for the target's file in the NWN install directory.
Each extracted file is checked against the target's source tree (as defined in
the [Target]
section of the nasher.cfg). If the file only exists in one
location, it is copied there, overwriting the existing file. If the file exists
in multiple folders, you will be prompted to select where it should be copied.
If the extracted file does not exist in the source tree already, it is checked
against each pattern listed in the [Rules]
section of the nasher.cfg. If a
match is found, the file is copied to that location.
If, after checking the source tree and rules, a suitable location has not been
found, the file is copied into a folder in the project root called unknown
so
you can manually move it later.
If an unpacked source would overwrite an existing source, its sha1
checksum
is checked against that from the last pack/unpack operation. If the sum is
different, the file has changed. If the source file has not been updated since
the last pack or unpack, the source file will be overwritten by the unpacked
file. Otherwise you will be prompted to overwrite the source file. The default
answer is to keep the existing source file.
Flag | Description |
---|---|
--file |
the file or directory to unpack into the target's source tree |
--removeDeleted |
remove source files not present in the file being unpacked |
--removeDeleted:false |
do not remove source files not present in the file being unpacked |
$ # Unpack the default target's installed file
$ nasher unpack
$ # Unpack the target foo's installed file
$ nasher unpack foo
$ # Unpack the file myModule.mod using the myNWNServer target
$ nasher unpack myNWNServer --file:myModule.mod
nasher convert [options] [(all | <target>...)]
Converts all JSON sources for <target>
into their GFF counterparts. The
output files are placed in .nasher/cache/<target>
.
If not supplied, <target>
will default to the first target defined in the
package's nasher.cfg
. The dummy target all
runs the command
on all defined targets in a loop. You can also specify multiple targets by
separating them with spaces.
Note: this command is called by pack
, so you don't need to run it
separately unless you want to convert files without compiling and packing.
Argument | Description |
---|---|
--clean |
clears the cache before packing |
--modName:<name> |
sets the Mod_Name value in module.ifo to <name> |
--modMinGameVersion:<version> |
sets the Mod_MinGameVersion value in module.ifo to <version> |
--modDescription:<desc> |
sets the Mod_Description value in module.ifo to <desc> |
$ # Convert the first target in nasher.cfg
$ nasher convert
$ # Convert the "demo" target
$ nasher convert demo
$ # Convert the "demo" and "testing" targets
$ nasher convert demo test
nasher compile [options] [(all | <target>...)]
Compiles all nss sources for <target>
. The input and output files are placed
in .nasher/cache/<target>
. nwnsc is used as the compiler and compilation
errors will be displayed with reference to filename, line number, and general
error description.
If not supplied, <target>
will default to the first target defined in the
package's nasher.cfg
. The dummy target all
runs the command
on all defined targets in a loop. You can also specify multiple targets by
separating them with spaces.
nasher will only recompile scripts that have changed since the target was last
compiled or that include scripts that have changed since the last compile
(chained includes are followed). This behavior can be overridden with the
--clean
flag.
A single file can be compiled with the --file:<file>
flag. <file>
can be a
full path to a script, in which case the script must be within the target's
source tree. Alternatively, you can pass just a filename, in which case the
version of the script matched by the target's source rules will be used.
Note: this command is called by pack
, so you don't need to run it
separately unless you want to compile scripts files without packing.
Argument | Description |
---|---|
--clean |
clears the cache before packing |
-f , --file |
compiles specific file; can be repeated |
--skipCompile |
don't compile specific file; can be repeated |
$ # Compile the first target in nasher.cfg
$ nasher compile
$ # Compile the "demo" target
$ nasher compile demo
$ # Compile a single file used by the default target (by full path)
$ nasher compile --file:src/nss/myfile.nss
$ # Compile a single file used by a particular target (by filename)
$ nasher compile demo --file:myfile.nss
nasher pack [options] [(all | <target>...)]
Converts, compiles, and packs all sources for
<target>
into a module, hak, erf, or tlk. The component files are placed in
.nasher/cache/<target>
, but the packed file is placed in the package root.
If not supplied, <target>
will default to the first target defined in the
package's nasher.cfg
. The dummy target all
runs the command
on all defined targets in a loop. You can also specify multiple targets by
separating them with spaces.
If the packed file would overwrite an existing file, you will be prompted to overwrite the file. The newly packaged file will have a modification time equal to the modification time of the newest source file. If the packed file is older than the existing file, the default is to keep the existing file.
Note: this command is called by install
, so you don't need to
run it separately unless you want to pack files without installing.
Argument | Description |
---|---|
--clean |
clears the cache before packing |
--file:<file> |
specify the location for the output file |
--noConvert |
do not convert updated json files |
--noCompile |
do not recompile updated scripts |
--skipCompile:<file> |
don't compile specific file; can be repeated |
--modName:<name> |
sets the Mod_Name value in module.ifo to <name> |
--modMinGameVersion:<version> |
sets the Mod_MinGameVersion value in module.ifo to <version> |
--modDescription:<desc> |
sets the Mod_Description value in module.ifo to <desc> |
--abortOnCompileError |
abort packing if errors encountered during compilation |
--packUnchanged |
continue packing a file if there are no changed files included |
--overwritePackedFile |
how to handle an existing packed file in the project dir |
$ # Pack the first target in nasher.cfg
$ nasher pack
$ # Clear the cache and convert, compile and pack the "demo" target
$ nasher pack demo --clean
$ # Pack the "module" target into "modules/mymodule.mod", setting its name to
$ # "My Module" and its minimum support game version to 1.69
$ nasher pack module --file:"modules/mymodule.mod" --modName:"My Module" --modMinGameVersion:1.69
nasher install [options] [(all | <target>...)]
Converts, compiles, and packs all sources for
<target>
, then installs the packed file into the NWN installation directory.
If not supplied, <target>
will default to the first target defined in the
package's nasher.cfg
. The dummy target all
runs the command
on all defined targets in a loop. You can also specify multiple targets by
separating them with spaces.
If the file to be installed would overwrite an existing file, you will be
prompted to overwrite it. The default answer is to keep the newer file. If the
useModuleFolder
configuration setting is TRUE or not set, a folder containing
all converted and compiled files will be installed into the same directory as
the module (.mod
) file.
Argument | Description |
---|---|
--clean |
clears the cache before packing |
--noConvert |
do not convert updated json files |
--noCompile |
do not recompile updated scripts |
--noPack |
do not re-pack the file (implies --noConvert and --noCompile ) |
--skipCompile:<file> |
don't compile specific file; can be repeated |
--file:<file> |
specify the file to install |
--installDir:<dir> |
the location of the NWN user directory |
--modName:<name> |
sets the Mod_Name value in module.ifo to <name> |
--modMinGameVersion:<version> |
sets the Mod_MinGameVersion value in module.ifo to <version> |
--modDescription:<desc> |
sets the Mod_Description value in module.ifo to <desc> |
--abortOnCompileError |
abort installation if errors encountered during compilation |
--packUnchanged |
continue packing a file if there are no changed files included |
--overwritePackedFile |
how to handle an existing packed file in the project dir |
--overwriteInstalledFile |
how to handle an existing installed file in installDir |
$ # Install the first target in nasher.cfg
$ nasher install
$ # Install the "demo" target to /opt/nwn without re-packing
$ nasher install demo --installDir:"/opt/nwn" --noPack
$ # Special case for Docker usage. When issuing the install and launch commands,
$ # docker requires access to the NWN documents folder, so we attach two volumes:
$ # - the first volume assigns the nasher project folder (source files)
$ # - the second volume assigns the NWN user directory
$ docker run --rm -it -v ${pwd}:/nasher -v "~/Documents/Neverwinter Nights":/nasher/install nwntools/nasher:latest install <target> --yes
nasher (serve|play|test) [options] [<target>...]
Converts, compiles, packs and
installs all sources for <target>
, installs the packed file into
the NWN installation directory, then launches NWN and loads the module. This
command is only valid for module targets.
Argument | Description |
---|---|
--clean |
clears the cache before packing |
--noConvert |
do not convert updated json files |
--noCompile |
do not recompile updated scripts |
--noPack |
do not re-pack the file (implies --noConvert and --noCompile ) |
--skipCompile:<file> |
don't compile specific file; can be repeated |
--file:<file> |
specify the file to install |
--installDir:<dir> |
the location of the NWN user directory |
--modName:<name> |
sets the Mod_Name value in module.ifo to <name> |
--modMinGameVersion:<version> |
sets the Mod_MinGameVersion value in module.ifo to <version> |
--modDescription:<desc> |
sets the Mod_Description value in module.ifo to <desc> |
--abortOnCompileError |
abort launching if errors encountered during compilation |
--packUnchanged |
continue packing a file if there are no changed files included |
--gameBin:<path> |
path to the nwmain binary file |
--serverBin:<path> |
path to the nwserver binary file |
$ # Install the first target in nasher.cfg and launch with nwserver
$ nasher serve
$ # Install the "demo" and play in-game
$ nasher play demo
$ # Install the "demo" target and play using the first character in the localvault
$ nasher test demo
"No source files found for target"
\
Caused by improper sourcing (include =
) in either the [*.sources]
or
[target]
section in your nasher.cfg
.
"This is not a nasher repository. Please run init"
\
Caused by running any nasher command except nasher config --global
before
running nasher init
in the project folder.
Caused by incorrectly referencing the present working directory in the
docker run
command. The reference can be CLI-specific. For example, Bash
wants to see $(pwd)
while PowerShell requires ${pwd}
. Look up the
appropriate reference for your shell. %cd%
only works for Windows
cmd.exe
.
"The following areas do not have matching .git files and will not be accessible in the toolset"
\
When the area list is built during the conversion process, nasher matches the
list of .are
files with .git
files. This warning will list any .are
files that do not have matching .git
files.
"This module does not have a valid starting area!"
\
A module cannot be packed/installed without a valid starting area. Either
extract a valid starting area into the nasher project folder or manually edit
your module.ifo.json
file's Mod_Entry_Area
key to reference an existing
area.
"this answer cannot be blank. Aborting..."
\
Answer to prompt required, but not provided.
"not a valid choice. Aborting..."
\
User selected an invalid multiple-choice answer.
"Could not create {outFile}. Is the destination writeable?"
\
Raised if a destination folder for file conversion does not have write
permissions. Can also be raised if there is another error converting the file
to .json
format. If your permissions are set correctly, the problem is
likely a json source file with invalid syntax.
Can I use absolute or relative paths? \ Yes.
I really need nasher to do something it doesn't. Can you add this feature? \ nasher is actively maintained and new features are constantly added. If your request fits within the scope for nasher, it can likely be added. File an issue and it will be addressed shortly.
I thought using nasher was supposed to be easy, why is it so difficult? \ Getting used to a command-line workflow can be a little daunting if you're used to GUI programs. However, as a rule of thumb, if you're doing more work after installing nasher than you did before, you're likely missing some key piece of information and/or configuration that will make your life a lot easier. If you can't find your answers by re-reading this document, see the Getting Help section.
Bug fixes and new features are greatly appreciated! Here's how to get started:
gh repo fork squattingmonk/nasher && cd nasher
git checkout -b feature/fooBar
git commit -am 'Add some fooBar'
gh pr create
You can also file bug reports and feature requests on the issues page.
You can see the changes between versions in the changelog.
nasher is fully open-source and released under the MIT License.