ponscripter — Ponscripter overview
Ponscripter is an interpreter for visual-novel-type games, derived from the NScripter design but modified significantly to improve support for Western languages (at the cost of diminished support for Japanese).
Ponscripter documentation is split into a number of sections.
This page provides an overview of Ponscripter itself and the overall structure of a game.
The other sections are:
NScripter is a popular novel-game engine written by Naoki Takahashi. It's available at no cost even for commercial use, but its source code is not free, and it's only supported on Microsoft Windows. Since it has been used to drive a large number of popular commercial and amateur games, this has inspired a number of open-source cloning efforts. As the original implementation, it serves as the definition of the NScripter standard; sadly its documentation leaves something to be desired.
Ogapee's ONScripter is the most significant of the clones. It supports a wide range of platforms, including handheld devices. When the attention of the English-speaking fan translation community turned to NScripter games, ONScripter was the interpreter we chose to adapt to better support the English language. The official ONScripter source code can be compiled with basic English support; since ONScripter development is aimed more at supporting new Japanese games and new platforms than at supporting localisation, the English-speaking community also maintains a branch called ONScripter-En which has a number of improvements of interest to us, including better English support as standard.
Ponscripter is a fork of ONScripter-En that drops any attempt to remain in synch with the upstream source code, and instead concentrates on providing the best possible support for Western languages. It is no longer fully NScripter-compatible, but remains an easy target to port NScripter games to when localising them.
The main enhancements are support for Unicode and for formatted text, including multiple fonts and styles, with proportional spacing, kerning, ligatures, arbitrary text size and position, etc.
Ponscripter games consist of a directory containing scripts,
either in NScripter format or an extended derived format, plus
other files (graphics, sound, fonts, etc) on which the script
depends; these may be packed into archives in the NScripter
NSA
or SAR
formats.
Unlike other NScripter-derived interpreters, which attempt to a greater or lesser degree to support Japanese filenames, Ponscripter requires that all files have plain ASCII names. It's the only way to be portable.
Ponscripter is able to read two styles of script: native and legacy. Native scripts are encoded in UTF-8, and provide all the features documented below. Legacy scripts are an attempt to provide a modicum of backwards-compatibility: they are NScripter-format scripts, in CP932 (Microsoft's version of Shift_JIS) with some of the same extensions as provided by ONScripter-En. Many Ponscripter features are disabled when processing a legacy script. There is little reason to use them, unless you want to try to play an unported NScripter game using proportional fonts. It's better to port where possible.
Script formats are distinguished by filename. The following filenames are sought, in this order:
0.utf
Native script in human-readable form.
Human-readable scripts can be multipart: the engine checks all numbers from 1 to 99 (both with and without leading zeroes, for numbers below 10), and appends them to script 0.
0.txt
nscr_sec.dat
79 57 0D 80 04
.
nscript.___
Legacy script, trivially obfuscated using a key file.
The key must be supplied using the
--key-exe
parameter to Invocation.
This file is used to construct a simple permutation
table holding the plaintext equivalents to each byte
of the obfuscated file.
pscript.dat
Native script, trivially obfuscated by xoring against
the constant byte 0x84
.
This is the only form of obfuscation supported for native scripts. It does not pretend to provide any security, but protects careless tinkerers from accidental spoilers.
nscript.dat
pscript.dat
.
Scripts are conventionally divided into three sections: directives, define, and game.
In reality these are parsing modes, rather than lexical
sections, and control flow can be mixed up with unscrupulous
use of goto
and skip
commands, but best practice is to keep concerns strictly
separate.
A skeleton script has the following form:
; directives*define
; define sectiongame
*start
; game sectionend
The directives section is optional. It consists of one or two directive lines at the very top of the first script file; these are processed during interpreter initialisation.
The first directive line begins with a semicolon and contains one or more comma-separated tags:
mode
NUM
NUM
.
Values recognised are 800
(by 600),
640
(by 480),
400
(by 300), and
320
(by 240). The default is
640
.
value
NUM
NUM
will become globals if
the globalon
command is used.
The default is 200
.
-*-
anything
-*-
Tags of this format are used by popular text editors such as Emacs to identify the format of a file.
Ponscripter ignores everything between the
-*-
delimiters, so users of such
editors can use this feature as expected.
The second directive line, if present, has the form
;gameid text
This is used to specify the name of the game. The
gameid thus defined is used when
automatically selecting a path for saved games and other
variable data (see --save
in
Invocation).
Ideally you should always specify a gameid with this
directive. If you don't, Ponscripter tries to determine the
name of the game by looking for a caption
or versionstr
command; if that also
fails, a semi-unique identifier is generated based on the
length of the script.
A complete directives section might thus have the form
;mode800,value500,-*- ponscripter -*- ;gameid My Ponscripter game
which would specify a game called “My Ponscripter game” that used an 800x600 display, treated all variables indexed 500 and above as globals, and would be easily identified as a Ponscripter script.
The define section is mandatory, and is typically placed at the start of the first script file, after any directives section and before the game section.
It is introduced with the label *define
, and
continues until a game
command is
encountered.
Code in this section is evaluated non-interactively at
startup, and then only touched again if the
definereset
command is used. It contains
definitions of things like aliases, arrays, windows,
subroutines, and fonts. Most of the commands valid in this
section are invalid in game code, and vice versa.
The game section is mandatory, and makes up the bulk of the script. It typically follows the define section.
It is introduced with the game
command,
which transfers control immediately to the
*start
label (which must exist, and is
normally the next thing in the script).
Processing then remains in game mode until an
end
command, which terminates the
program, or a definereset
command, which
returns processing to define mode at the
*define
label.
Invocation, Syntax, Extensions
Existing NScripter documentation, for a description of the basic operation of NScripter-style games and documentation of most of the functionality supported. Most NScripter references are only available in Japanese, but there is some English-language documentation at http://nscripter.insani.org.