--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
--- /dev/null
+# ZIL Programming for Interactive Fiction: A Technical Guide
+
+# Introduction
+
+This document provides a structured approach to learning ZIL, catering
+to a technical audience. Each chapter builds upon the previous ones,
+gradually introducing more complex concepts and techniques. This guide
+aims to equip readers with the knowledge and skills necessary to
+create their own interactive fiction games using ZIL.
+
+# Copyright & Licensing
+
+Copyright (C) 2024 Jason Self <j@jxself.org>
+
+You can redistribute and/or modify ZIL Programming for Interactive
+Fiction: A Technical Guide under the terms of the GNU General Public
+License as published by the Free Software Foundation, either version 3
+of the License, or (at your option) any later version.
+
+This book is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this book. If not, see <https://www.gnu.org/licenses/>
+
+# Chapter 1: Introduction to ZIL and Interactive Fiction
+
+Welcome to the world of ZIL programming and interactive fiction (IF)!
+This chapter will introduce you to the fundamental concepts of IF and
+the role ZIL plays in creating these unique narrative experiences.
+We'll explore the basic structure of ZIL code and key elements that
+form the foundation of IF games. Additionally, we'll examine the
+relationship between ZIL, the interpreter, and the game world,
+providing a comprehensive overview for your journey into ZIL
+programming.
+
+## What is Interactive Fiction?
+
+Interactive fiction is a genre of computer games where players
+experience a story through text-based interaction. Unlike traditional
+novels, IF allows players to influence the narrative by typing
+commands and making choices that affect the story's direction and
+outcome. This creates a dynamic and engaging experience where players
+actively participate in shaping the narrative.
+
+## ZIL: The Language of Interactive Fiction
+
+ZIL (Zork Implementation Language) is a specialized programming
+language designed specifically for creating IF games. Developed by
+Infocom in the early 1980s, ZIL offers a powerful and flexible toolset
+for crafting intricate narratives with rich interactivity.
+
+While ZIL shares some similarities with other programming languages,
+it has unique features tailored to the needs of IF development. These
+include:
+
+ Object-oriented structure: ZIL revolves around objects
+ representing rooms, items, and characters within the game world.
+
+ Action routines: Objects have associated action routines that
+ define how they respond to player interaction.
+
+ Parser and syntaxes: ZIL includes a sophisticated parser that
+ interprets player input and maps it to specific actions and
+ objects.
+
+ Event handling: ZIL allows for time-based events and dynamic
+ responses through interrupts and other mechanisms.
+
+By leveraging these features, ZIL empowers developers to create
+immersive and responsive IF experiences.
+
+## The Z-Machine and the Interpreter
+
+ZIL code is compiled into a machine-independent format called Z-code,
+which is then executed by a virtual machine known as the Z-machine.
+This means that ZIL games can be played on various platforms without
+requiring platform-specific modifications. The Z-machine interpreter
+acts as the bridge between the Z-code and the player, reading the
+compiled code and presenting the game world to the player through text
+descriptions and responses to their input.
+
+## Key Concepts in ZIL Programming
+
+As you delve deeper into ZIL, you'll encounter several key concepts
+that are crucial for understanding how IF games are built:
+
+ Objects: These represent the fundamental building blocks of the
+ game world, including rooms, items, and characters.
+
+ Properties: Objects have properties that define their
+ characteristics, such as descriptions, synonyms, and flags.
+
+ Routines: These are sub-programs that perform specific tasks,
+ such as handling player actions or describing objects.
+
+ Parser: The parser interprets player input and identifies the
+ verb, direct object, and indirect object.
+
+ Action routines: These routines are associated with objects and
+ handle player interaction based on the parser's output.
+
+ Events: Events are time-based occurrences or dynamic responses
+ triggered by specific conditions.
+
+This chapter has provided a foundational understanding of ZIL and its
+role in creating interactive fiction. By understanding these core
+concepts, you'll be well-equipped to start building your own
+interactive fiction games using ZIL.
+
+In the following chapters, we'll explore each of these concepts in
+greater detail, equipping you with the knowledge and skills necessary
+to become a proficient ZIL programmer.
+
+# Chapter 2: Data Types and Expressions in ZIL
+
+This chapter dives into the core of ZIL programming: data types and
+expressions. We'll explore the various types of data ZIL uses to
+represent different elements of the game world and how you can
+manipulate them through expressions. By understanding these
+fundamental building blocks, you'll be able to construct the logic and
+mechanics of your interactive fiction game.
+
+## ZIL Data Types
+
+ZIL utilizes a relatively small set of data types, each serving a
+specific purpose in representing and manipulating information within
+the game:
+
+1. FORM:
+
+ A FORM is a fundamental structure in ZIL, representing a
+ collection of objects enclosed within balanced angle brackets
+ (< >).
+
+ It's used to perform operations, either built-in subroutines or
+ user-defined routines.
+
+ The first element of a FORM specifies the operation, while the
+ remaining elements are arguments.
+
+Example:
+
+ <+ 5 3> ; This FORM adds the integers 5 and 3.
+
+2. FIX (Integer):
+
+ FIX represents integers within the range of -32767 to 32767.
+
+ Integers outside this range are illegal, and ZIL doesn't support
+ floating-point numbers.
+
+ Various arithmetic operations work with FIXes:
+
+ + (addition)
+
+ - (subtraction)
+
+ * (multiplication)
+
+ / (division)
+
+ MOD (modulus)
+
+ ABS (absolute value)
+
+ RANDOM (generates a random number within a specified range)
+
+Example:
+
+ <- 10 4> ; This expression subtracts 4 from 10, resulting in 6.
+
+3. ATOM (Variable):
+
+ ATOMs function as variables, storing values that can be referenced
+ and manipulated.
+
+ They are case-sensitive and can contain capital letters, numbers,
+ hyphens, question marks, and dollar signs.
+
+ There are two types of ATOMs:
+
+ LOCAL: These are temporary variables used within routines and
+ are specific to each routine.
+
+ GLOBAL: These variables have values accessible to all routines
+ throughout the game.
+
+Example:
+
+ <SETG player-name "Alice"> ; Sets the GLOBAL ATOM player-name to "Alice".
+
+4. STRING:
+
+ STRINGs represent text data enclosed within double quotes (").
+
+ They are used primarily for displaying text to the player.
+
+ To include a double quote within a string, use a backslash ()
+ before it.
+
+Example:
+
+ <TELL "The troll says, \"Me want food!\"" CR> ; Displays text with a quote.
+
+5. LIST:
+
+ LISTs are collections of objects enclosed within parentheses ( ).
+
+ They are primarily used within routines to improve code
+ readability and structure.
+
+Example:
+
+ (NORTH TO KITCHEN WEST TO BEDROOM) ; LIST of room exits.
+
+6. TABLE:
+
+ TABLEs are similar to arrays in other languages, storing multiple
+ elements of any type.
+
+ They are created at the top level of your code (not within a
+ routine).
+
+ Two types of TABLEs exist:
+
+ TABLE: Stores elements without any additional information.
+
+ LTABLE: The first element automatically stores the number of
+ elements in the table.
+
+Example:
+
+ <LTABLE "apple" "banana" "orange"> ; Creates an LTABLE of fruits.
+
+7. OBJECT:
+
+ OBJECTs represent the core elements of the game world: rooms,
+ items, and characters.
+
+ They are defined with properties like descriptions, synonyms,
+ adjectives, flags, and action routines.
+
+ OBJECTs can be manipulated through operations like MOVE, REMOVE,
+ LOC, FIRST?, and NEXT?.
+
+Example:
+
+ <OBJECT LAMP
+ (DESC "brass lamp")
+ (SYNONYM LIGHT)
+ (FLAGS TAKEBIT ONBIT)>
+
+## Expressions in ZIL
+
+Expressions in ZIL combine data types and operations to perform
+computations and manipulate game elements. ZIL uses prefix notation,
+where the operator comes before the operands.
+
+Example:
+
+ <+ 2 3> ; This expression adds 2 and 3, resulting in 5.
+
+Expressions can be nested to create complex logic and calculations.
+
+Example:
+
+ <G? <- 10 <* 2 3>> 5> ; Checks if (10 - (2 * 3)) is greater than 5.
+
+## Conditional Expressions and Predicates
+
+Conditional expressions evaluate to either true or false and are
+crucial for decision-making in your game. ZIL uses several predicates
+for comparisons and checks:
+
+ EQUAL?: Checks if the first argument is equal to any of the
+ subsequent arguments.
+
+ ZERO?: Checks if the argument is equal to zero.
+
+ LESS?: Checks if the first argument is less than the second
+ argument.
+
+ GRTR?: Checks if the first argument is greater than the second
+ argument.
+
+ FSET?: Checks if a specific flag is set on an object.
+
+ IN?: Checks if an object is located within another object.
+
+These predicates are often used within COND statements to execute
+different code branches based on conditions.
+
+Example:
+
+ <COND
+ (<FSET? ,DOOR ,OPENBIT>
+ <TELL "The door is open." CR>)
+ (T
+ <TELL "The door is closed." CR>)>
+
+This COND statement checks if the OPENBIT flag is set on the DOOR
+object. If true, it prints "The door is open." Otherwise, it prints
+"The door is closed."
+
+## Edge Cases and Considerations
+
+While working with data types and expressions in ZIL, be mindful of
+potential edge cases and specific behaviors:
+
+ Integer range: Remember that FIXes are limited to the range of
+ -32767 to 32767. Exceeding this range will cause errors.
+
+ Truth values: In ZIL, any non-zero value is considered true.
+ However, distinguish between false (zero) and the special token <>
+ used for clarity in representing boolean states.
+
+ Synonym ambiguity: If multiple objects share the same synonym, the
+ parser might require further clarification from the player to
+ identify the intended object.
+
+ Property manipulation: Not all object properties can be directly
+ manipulated with GETP and PUTP. Some require using GETPT and
+ manipulating the resulting property table.
+
+By understanding these data types, expressions, and potential edge
+cases, you'll be able to write robust and efficient ZIL code for
+your interactive fiction game.
+
+This chapter has provided a detailed exploration of ZIL's data types
+and expressions. With this knowledge, you can now start building the
+logic and mechanics of your game, defining how objects interact and
+respond to player actions. In the following chapters, we'll delve
+deeper into specific aspects of ZIL programming, further expanding
+your IF development toolkit.
+
+# Chapter 3: Routines and Control Flow in ZIL
+
+Routines are the workhorses of ZIL programming, serving as
+user-defined subroutines that implement the core logic and
+functionality of your interactive fiction game. This chapter will
+delve into the intricacies of defining, calling, and managing routines
+in ZIL, providing you with the knowledge to structure your code
+effectively and control the flow of your game's execution.
+
+## Defining Routines
+
+A routine is defined using the following syntax:
+
+ <ROUTINE routine-name (argument-list) expression expression ...>
+
+Let's break down each element:
+
+ routine-name: This is a valid ATOM name that uniquely identifies
+ the routine.
+
+ (argument-list): This defines the arguments the routine can
+ receive, which we'll explore in detail shortly.
+
+ expression expression ...: This represents the body of the
+ routine, containing ZIL expressions that are evaluated
+ sequentially when the routine is called. The result of the last
+ expression becomes the return value of the routine.
+
+## Argument List
+
+The argument list within the parentheses specifies the parameters the
+routine can accept. It can be divided into three optional parts:
+
+1. Required Arguments:
+
+ These are LOCAL ATOMs representing mandatory inputs for the routine.
+
+ They are listed first in the argument list, separated by spaces.
+
+Example:
+
+ <ROUTINE MOVE-OBJECT (OBJECT-NAME DESTINATION) ...>
+
+In this example, the MOVE-OBJECT routine requires two arguments:
+OBJECT-NAME and DESTINATION.
+
+2. Optional Arguments:
+
+ These are arguments that the routine can accept but are not
+ mandatory.
+
+ They are indicated by placing the string "OPTIONAL" after the
+ required arguments.
+
+ Each optional argument is defined as a LIST containing a LOCAL
+ ATOM and a default value. If the calling routine doesn't provide a
+ value for an optional argument, the default value is used.
+
+Example:
+
+ <ROUTINE DESCRIBE-OBJECT (OBJECT-NAME "OPTIONAL" (VERBOSE T)) ...>
+
+Here, the DESCRIBE-OBJECT routine takes OBJECT-NAME as a required
+argument and VERBOSE as an optional argument. If VERBOSE isn't
+provided, it defaults to T (true).
+
+3. Auxiliary Arguments (Local Variables):
+
+ These are additional LOCAL ATOMs used as temporary variables
+ within the routine.
+
+ They are declared after the optional arguments, preceded by the
+ string "AUX".
+
+ You can provide an initial value for auxiliary arguments, similar
+ to optional arguments.
+
+Example:
+
+ <ROUTINE COUNT-ITEMS (CONTAINER "AUX" (COUNT 0)) ...>
+
+This routine has one required argument (CONTAINER) and one auxiliary
+argument (COUNT) initialized to 0.
+
+Remember that any LOCAL ATOM used within a routine must be declared in
+its argument list, either as a required argument, optional argument,
+or auxiliary argument.
+
+## Naming Conventions
+
+Choosing meaningful and consistent names for your routines and
+variables significantly improves code readability and maintainability.
+Here are some recommendations:
+
+ Use descriptive names that reflect the routine's purpose (e.g.,
+ COUNT-GRUES, OPEN-DOOR).
+
+ Employ common conventions for frequently used variables (e.g.,
+ OBJ for object, CNT for counter, DIR for direction).
+
+ Maintain consistent naming patterns throughout your codebase.
+
+## Looping with REPEAT
+
+To create loops within your routines, ZIL provides the REPEAT construct:
+
+ <REPEAT () expression expression ...>
+
+The REPEAT evaluates the expressions within its body repeatedly until
+it encounters a RETURN statement. Note that the empty parentheses are
+mandatory.
+
+Example:
+
+ <REPEAT ()
+ <TELL "Ha">
+ <SET CNT <+ .CNT 1>>
+ <COND (<EQUAL? .CNT 5>
+ <TELL "!">
+ <RETURN>)
+ (T
+ <TELL " ">)>>
+
+This loop prints "HA HA HA HA HA!" by incrementing the CNT variable
+and checking if it has reached 5.
+
+## Exiting Routines
+
+Routines typically return the value of the last expression evaluated
+in their body. However, you can explicitly control the return value
+and exit the routine using:
+
+ <RTRUE>: Immediately exits the routine and returns T (true).
+
+ <RFALSE>: Immediately exits the routine and returns <> (false).
+
+ <RETURN anything>: Immediately exits the routine and returns the
+ specified value.
+
+Remember that RETURN within a REPEAT loop only exits the loop, not the
+entire routine.
+
+## Restrictions and Formatting
+
+Be mindful of these limitations when working with routines:
+
+ A routine can take a maximum of three arguments (required and optional combined).
+
+ There can be a maximum of 16 LOCAL ATOMs within a routine.
+
+While ZIL ignores whitespace and formatting characters, using them
+strategically is crucial for code readability. Indentation and
+vertical alignment can help visually distinguish code blocks and
+improve understanding of the routine's structure.
+
+By mastering the concepts of defining, calling, and managing routines,
+you'll be able to construct complex and well-structured ZIL programs
+for your interactive fiction games.
+
+# Chapter 4: Objects and Properties
+
+Objects are the fundamental building blocks of any interactive fiction
+game created with ZIL. They represent everything from physical items
+and locations to abstract concepts and characters. This chapter will
+delve into the intricacies of creating and manipulating objects in
+ZIL, providing a comprehensive understanding of their properties and
+how they interact with the game world.
+
+## Creating Objects
+
+Objects are defined using the OBJECT subroutine, which takes several
+arguments:
+
+ <OBJECT object-name
+ (DESC "short description")
+ (ADJECTIVE adjective-1 adjective-2 ...)
+ (SYNONYM noun-1 noun-2 ...)
+ (property value)
+ ...
+ >
+
+Let's break down each element:
+
+ object-name: This is the internal name used to reference the
+ object within ZIL code. It should be unique and descriptive (e.g.,
+ BRASS_LANTERN, FRONT_DOOR).
+
+ (DESC "short description"): This defines the object's short
+ description, displayed in brief room descriptions and the status
+ line.
+
+ (ADJECTIVE adjective-1 adjective-2 ...): This optional list
+ specifies adjectives that can be used to describe the object
+ (e.g., RED, SHINY).
+
+ (SYNONYM noun-1 noun-2 ...): This list defines nouns that can be
+ used to refer to the object. At least one synonym is required
+ (e.g., LANTERN, LAMP).
+
+ (property value): This represents various properties assigned to
+ the object, such as SIZE, CAPACITY, ACTION, and more. We'll
+ explore these in detail later.
+
+Example:
+
+ <OBJECT BRASS_LANTERN
+ (DESC "brass lantern")
+ (ADJECTIVE BRASS)
+ (SYNONYM LANTERN LAMP LIGHT)
+ (SIZE 15)
+ (ACTION LANTERN_F)
+ >
+
+This defines an object named BRASS_LANTERN with the short description
+"brass lantern." Players can refer to it using "lantern," "lamp," or
+"light," and it has a size of 15. The ACTION property links it to the
+routine LANTERN_F, which handles player interactions with the lantern.
+
+## Object Properties
+
+Properties define various characteristics and behaviors of objects.
+Here's a detailed look at some commonly used properties:
+
+ FLAGS: This property specifies the object's initial state using
+ flags like TAKEBIT (takeable), CONTBIT (container), OPENBIT
+ (open), and many more. Flags can be dynamically set and cleared
+ during gameplay using FSET and FCLEAR.
+
+ ACTION: This property links the object to an action routine that
+ handles player interactions. For example, if the player tries to
+ EAT the APPLE, the APPLE_F routine will be called to handle the
+ action.
+
+ DESCFCN: This property specifies a routine used by the describers
+ to provide a customized description of the object, allowing for
+ dynamic descriptions based on the object's state or location.
+
+ LOC: This property determines the object's location. Initially,
+ it specifies the room where the object is found. As the player
+ interacts with the object, its location can change (e.g., moved to
+ another room or taken by the player).
+
+ SIZE: This property defines the object's size or weight,
+ impacting how many objects the player can carry and how much space
+ it occupies in containers.
+
+ CAPACITY: For containers, this property specifies the total size
+ or weight of objects it can hold.
+
+ VALUE: In games with scoring systems, this property defines the
+ points awarded for taking or interacting with the object.
+
+ LDESC: This property provides a long description of the object,
+ displayed when the player examines it or enters a room in verbose
+ mode.
+
+ FDESC: This property defines a "first" description used before
+ the object is touched or interacted with for the first time.
+
+ TEXT: This property contains text displayed when the player tries
+ to READ the object.
+
+These are just some of the commonly used properties. ZIL allows for
+creating custom properties to suit your game's specific needs.
+
+## Manipulating Properties
+
+Object properties can be dynamically accessed and modified during
+gameplay using the GETP and PUTP instructions:
+
+ GETP: Retrieves the value of a specific property for a given
+ object. For example, <GETP ,HERE ,P?LDESC> retrieves the long
+ description of the current room.
+
+ PUTP: Changes the value of a property for a given object. For
+ example, <PUTP ,SWORD ,P?SIZE 10> sets the size of the SWORD
+ object to 10.
+
+Note that some properties, like exits, cannot be manipulated directly
+with GETP and PUTP. They require using GETPT and PUTPT to access and
+modify their underlying table structures.
+
+## Edge Cases and Considerations
+
+ Multiple adjectives: When a player uses multiple adjectives to
+ describe an object, the parser typically uses the first one for
+ matching. However, you can implement custom logic to handle
+ specific combinations or prioritize certain adjectives.
+
+ Synonyms and ambiguity: If multiple objects share the same
+ synonym, the parser might ask the player for clarification. You
+ can use the GENERIC property to define a routine that helps
+ resolve such ambiguities.
+
+ Property limitations: ZIL has limitations on the number of
+ properties an object can have and the size of property values. Be
+ mindful of these limitations when designing your game and consider
+ alternative approaches if necessary.
+
+By understanding the intricacies of object creation, properties, and
+manipulation techniques, you can build a rich and interactive game
+world within your ZIL-based interactive fiction.
+
+# Chapter 5: Rooms and Exits: Building the Spatial Fabric of Your Game
+
+Rooms are the fundamental building blocks of your interactive fiction
+world, defining the spaces players can explore and interact with. This
+chapter will guide you through the process of creating rooms in ZIL,
+focusing on the various types of exits that connect them and the
+action routines that bring them to life. We'll explore detailed
+examples and edge cases, equipping you with the knowledge to craft a
+compelling and immersive game environment.
+
+## Defining a Room in ZIL
+
+Rooms are created using the ROOM subroutine, which takes several
+properties to define its characteristics:
+
+ <ROOM room-name
+ (IN ROOMS)
+ (DESC "short description")
+ (FLAGS flag-1 ... flag-n)
+ (property value)
+ ...
+ (property value)
+ >
+
+Let's break down each element:
+
+ room-name: This is the unique identifier for your room,
+ represented as a global ATOM.
+
+ (IN ROOMS): This indicates that the room belongs to the special
+ ROOMS object, which acts as a container for all rooms in your
+ game.
+
+ (DESC "short description"): This defines the short description
+ displayed when the player enters the room and on the status line.
+
+ (FLAGS flag-1 ... flag-n): Here, you specify flags that determine
+ the room's initial state, such as RLANDBIT (indicating the room is
+ on land) and ONBIT (meaning the room is lit).
+
+ (property value): This section defines additional properties of
+ the room, including exits, long descriptions (LDESC), and action
+ routines (ACTION).
+
+## Exits: Connecting Your Rooms
+
+Exits are crucial for allowing players to navigate your game world.
+ZIL offers several types of exits, each with unique behaviors and
+implementation methods:
+
+1. Unconditional Exits (UEXIT)
+
+These are the simplest exits, allowing players to move in a specific
+direction without any restrictions. They are defined as follows:
+
+ (direction TO room-name)
+
+For example, (NORTH TO FOYER) creates an exit leading north to the
+FOYER room.
+
+2. Unconditional Non-Exits (NEXIT)
+
+These define directions players cannot go in, but instead of the
+default "You can't go that way" message, you can provide a custom
+response:
+
+ (direction "reason-why-not")
+
+For example, (WEST "A sheer cliff drops off to the west.") explains
+why the player cannot go west.
+
+3. Conditional Exits (CEXIT)
+
+These exits allow movement only if a specific condition is met,
+typically based on the value of a global variable:
+
+ (direction TO room-name IF global-atom-name)
+
+For example, (EAST TO HIDDEN-CHAMBER IF SECRET-DOOR-OPEN) allows
+passage east only if the SECRET-DOOR-OPEN global is true.
+
+You can also provide an alternative message if the condition isn't
+met:
+
+ (direction TO room-name IF global-atom-name ELSE "reason-why-not")
+
+4. Door Exits (DEXIT)
+
+These exits are specifically for doors, allowing movement only if the
+door object is open:
+
+ (direction TO room-name IF door-name IS OPEN)
+
+For example, (SOUTH TO GARDEN IF OAK-DOOR IS OPEN) allows passage
+south only if the OAK-DOOR object has its OPENBIT flag set.
+
+5. Flexible Exits (FEXIT)
+
+These offer the most flexibility, calling a custom routine to handle
+the movement logic:
+
+ (direction PER routine-name)
+
+The routine can perform checks, modify the game state, and determine
+the outcome of the movement attempt.
+
+Examples:
+
+Here are some examples of how these exits might be used in your game:
+
+ UEXIT: (NORTH TO LIBRARY) - A simple exit leading north to the
+ library.
+
+ NEXIT: (UP "The ceiling is too low to climb up here.") - Explains
+ why the player cannot go up.
+
+ CEXIT: (WEST TO TREASURE-ROOM IF KEY-FOUND) - Allows access to
+ the treasure room only after finding the key.
+
+ DEXIT: (EAST TO BALCONY IF FRENCH-DOORS IS OPEN) - Requires the
+ French doors to be open to access the balcony.
+
+ FEXIT: (DOWN PER TRAPDOOR-EXIT) - Calls a custom routine to handle
+ the complexities of using the trapdoor.
+
+Things to Remember:
+
+ Case sensitivity: Direction names, tokens (TO, PER, IF, IS, OPEN,
+ ELSE), and room/routine names must be capitalized in ZIL.
+
+ Standard directions: The substrate assumes standard directions
+ (north, south, east, west, etc.). If you need custom directions,
+ consult the relevant documentation or seek assistance.
+
+## Room Action Routines: Adding Dynamic Behavior
+
+While exits define the connections between rooms, action routines
+breathe life into them. These routines are associated with the ACTION
+property of a room and are called in different contexts, identified by
+specific arguments:
+
+ M-BEG: Called at the beginning of each turn when the player is in
+ the room. This allows for dynamic changes or events to occur.
+
+ M-END: Called at the end of each turn, after the player's action
+ has been handled. This can be used for cleanup or setting up
+ future events.
+
+ M-ENTER: Called when the player enters the room, providing an
+ opportunity for special actions or descriptions.
+
+ M-LOOK: Called by the describers when they need to generate the
+ room's long description. This allows for dynamic descriptions that
+ change based on the game state.
+
+Example:
+
+Here's an example of a room action routine that handles different
+contexts:
+
+ <ROUTINE KITCHEN-F (RARG)
+ <COND
+ ((EQUAL? .RARG ,M-BEG)
+ ; Check if the oven is on and handle potential fire hazards.
+ )
+ ((EQUAL? .RARG ,M-END)
+ ; Update the state of objects in the kitchen based on time
+ ; passing.
+ )
+ ((EQUAL? .RARG ,M-ENTER)
+ ; Play a sound effect of sizzling bacon when the player enters.
+ )
+ ((EQUAL? .RARG ,M-LOOK)
+ ; Describe the kitchen dynamically based on the state of objects
+ ; and flags.
+ )
+ >
+ >
+
+This routine demonstrates how you can use different contexts to create
+dynamic and responsive environments within your game.
+
+## LDESC: Providing a Static Description
+
+The LDESC property allows you to define a static long description for
+a room. This is useful for rooms that don't change significantly
+throughout the game:
+
+ (LDESC "You are in a cozy kitchen. The aroma of freshly baked cookies
+ fills the air.")
+
+However, if your room's description needs to change dynamically based
+on the game state, you should use the M-LOOK clause in the room's
+action routine instead.
+
+## Conclusion
+
+By understanding how to define rooms, implement various types of
+exits, and leverage action routines, you can build a rich and
+immersive game world for your interactive fiction. Remember to
+consider the player's experience and use the different tools at your
+disposal to create engaging and dynamic environments that enhance your
+narrative.
+
+# Chapter 6: The Containment System and Accessibility
+
+The containment system is a fundamental aspect of ZIL programming,
+governing how objects are located and interact within the game world.
+This chapter will provide a comprehensive exploration of this system,
+delving into the hierarchy of object locations and the rules that
+determine object accessibility for player interaction. We'll also
+examine the distinctions between local, global, and local-global
+objects, equipping you with the knowledge to expertly manage object
+placement and interaction in your ZIL games.
+
+## Understanding the Containment Hierarchy
+
+In ZIL, every object has a location, defined by its LOC property. This
+property specifies the object's container, creating a hierarchical
+structure that dictates where objects reside within the game world.
+Rooms, for instance, are contained within a special object called
+ROOMS, while items can be located within rooms or inside other
+containers.
+
+Here's an example illustrating the containment hierarchy:
+
+ ROOMS: This special object acts as the top-level container for
+ all rooms in the game.
+
+ Living Room: This room object is contained within ROOMS.
+
+ Treasure Chest: This object is located within the Living Room.
+
+ Golden Key: This object is contained within the Treasure Chest.
+
+This hierarchical structure allows for complex object relationships
+and interactions. For example, opening the Treasure Chest would make
+the Golden Key accessible to the player, while the key itself might be
+used to unlock a door in another room.
+
+## Rules of Accessibility and the Parser
+
+The parser, responsible for interpreting player input, relies heavily
+on the containment system to determine which objects are accessible to
+the player at any given moment. An object is considered accessible if
+it meets the following criteria:
+
+ Present: The object must exist within the game world and have a
+ valid LOC property.
+
+ Visible: The object must be visible to the player, meaning it's
+ not hidden or inside a closed container.
+
+ Referenceable: The object must be referenceable by the player,
+ meaning it has appropriate synonyms and adjectives defined.
+
+When the player attempts to interact with an object, the parser
+analyzes the input and searches for a matching object based on the
+provided noun phrase. The search prioritizes objects in the following
+order:
+
+ Local Objects: The parser first looks for matching objects within
+ the current room or carried by the player.
+
+ Local-Global Objects: If no local object is found, the parser
+ searches for local-global objects accessible in the current room.
+
+ Global Objects: Finally, the parser considers global objects,
+ which are accessible from any location in the game.
+
+This search order prioritizes efficiency, as searching through local
+objects is faster than examining all objects in the game. However, it
+can lead to unexpected behavior if multiple objects share the same
+name. For example, if a local object and a local-global object are
+both named "button," the parser will prioritize the local object even
+if the player intended to interact with the local-global one. To avoid
+such ambiguity, ensure unique names or provide additional context in
+object descriptions.
+
+## Distinctions between Local, Global, and Local-Global Objects
+
+ZIL categorizes objects into three types based on their accessibility:
+
+ Local Objects: These objects can only exist in one location at a
+ time. Most takeable objects fall into this category, as they are
+ either in a specific room or carried by the player.
+
+ Global Objects: These objects are accessible from any location in
+ the game. They typically represent abstract concepts, characters
+ not physically present, or omnipresent elements like the sky or
+ ground.
+
+ Local-Global Objects: These objects can be referenced in multiple
+ specific locations, but not everywhere. Doors are a classic
+ example, as they exist in the two rooms they connect. Other
+ examples include geographical features like rivers or mountains.
+
+Defining local-global objects requires specifying the rooms where they
+are accessible using the GLOBAL property within each relevant room
+definition. This allows for efficient parsing and prevents players
+from referencing objects that wouldn't make sense in their current
+context.
+
+## Edge Cases and Considerations
+
+While the containment system and accessibility rules generally
+function seamlessly, some edge cases require careful consideration:
+
+ Nested Containers: When dealing with nested containers, the
+ parser's search depth is limited by default. To ensure objects
+ within multiple layers of containers are accessible, use the
+ SEARCHBIT flag on the relevant containers.
+
+ Ambiguity and Disambiguation: If multiple objects share the same
+ name, the parser might require disambiguation from the player.
+ Provide clear descriptions and distinct synonyms to minimize
+ ambiguity.
+
+ Dynamic Changes: If an object's location or accessibility changes
+ during gameplay, ensure that the relevant properties and flags are
+ updated accordingly.
+
+By understanding these edge cases and applying the principles outlined
+in this chapter, you can expertly manage object placement and
+interaction within your ZIL games, creating a seamless and immersive
+experience for your players.
+
+This chapter has provided a thorough exploration of the containment
+system and accessibility rules in ZIL. By mastering these concepts,
+you'll be able to craft intricate and believable game worlds where
+players can interact with objects in a logical and intuitive manner.
+
+# Chapter 7: Events and Interrupts
+
+In interactive fiction, not all actions and responses happen solely
+due to player input. Events can occur independently, adding dynamism
+and enriching the game world. ZIL provides powerful mechanisms for
+implementing such events through interrupts and room M-END clauses.
+This chapter will delve into these features, offering a comprehensive
+exploration of event handling in ZIL. We'll cover queuing and
+dequeuing interrupts, designing effective event routines, and
+addressing potential edge cases to ensure your events seamlessly
+integrate into your interactive narrative.
+
+## Understanding Interrupts
+
+Interrupts are routines triggered by specific conditions or after a
+set number of moves, regardless of player input. They allow you to
+create dynamic events like a sudden storm, a character entering a
+room, or an alarm going off.
+
+Here's how interrupts work:
+
+ Defining the Interrupt Routine:
+
+ Create a routine with a name typically prefixed with "I-"
+ (e.g., I-THUNDERSTORM).
+
+ Within the routine, define the actions and responses that
+ occur when the interrupt is triggered.
+
+ Ensure the routine returns true if it outputs text using TELL
+ and false otherwise. This is crucial for proper interaction
+ with the WAIT verb.
+
+ Queuing the Interrupt:
+
+ Use the QUEUE instruction to schedule the interrupt.
+
+ Provide the interrupt routine's name and the number of moves
+ after which it should be triggered.
+
+ For example, <QUEUE I-THUNDERSTORM 10> will trigger the
+ I-THUNDERSTORM routine after 10 moves.
+
+ Interrupt Execution:
+
+ After each turn where time passes (excluding parser failures
+ and specific commands like SCRIPT), the CLOCKER routine runs.
+
+ CLOCKER checks queued interrupts and calls those whose time
+ has come.
+
+ Once an interrupt runs, it's removed from the queue unless
+ queued with -1, which makes it run every turn until explicitly
+ dequeued.
+
+ Dequeuing Interrupts:
+
+ Use the DEQUEUE instruction to remove a queued interrupt
+ before it triggers.
+
+ This is useful for situations where the event is no longer
+ relevant due to player actions or other changes in the game
+ state.
+
+# Designing Effective Interrupt Routines
+
+Here are some key considerations for crafting well-structured and
+efficient interrupt routines:
+
+ Check Player Location: Before outputting text or performing
+ actions, ensure the player is in a relevant location to experience
+ the event. This avoids nonsensical situations like a character
+ appearing in a room the player isn't currently in.
+
+ Manage Interrupt Duration: If an interrupt involves multiple
+ actions or messages, use a counter or flag system to track its
+ progress and ensure it deactivates itself when finished. This
+ prevents the interrupt from continuously triggering and causing
+ unintended repetition.
+
+ Consider Player Actions: Account for how player actions might
+ affect the interrupt. For example, if an interrupt involves a
+ character approaching the player, consider what happens if the
+ player moves away or interacts with the character before the
+ interrupt fully plays out.
+
+## Room M-END Clauses: Events within Rooms
+
+An alternative way to handle events is through M-END clauses within a
+room's action routine. These clauses execute at the end of every turn
+spent in that room, offering a way to create location-specific events
+without relying on the global interrupt queue.
+
+Here's how to use M-END clauses:
+
+ Define the M-END Clause:
+
+ Within the room's action routine, include a COND clause
+ checking for the M-END argument.
+
+ Inside this clause, define the actions and responses that
+ occur at the end of each turn in that room.
+
+ Event Execution:
+
+ At the end of every turn (before CLOCKER runs), the current
+ room's action routine is called with the M-END argument.
+
+ If the M-END clause exists, it executes the defined actions
+ and responses.
+
+M-END clauses are ideal for events inherently tied to a specific
+location, such as a dripping faucet, a flickering light, or a
+recurring sound. Edge Cases and Considerations
+
+While interrupts and M-END clauses offer powerful tools for event
+handling, be mindful of potential edge cases:
+
+ Interrupt Conflicts: If multiple interrupts are queued to trigger
+ simultaneously, their execution order might not be guaranteed.
+ Design your interrupts to be independent or implement mechanisms
+ to manage potential conflicts.
+
+ Player Death and Interrupts: When the player dies, ensure any
+ ongoing interrupts are appropriately handled. This might involve
+ dequeuing them or modifying their behavior to fit the new game
+ state.
+
+ Save and Restore: Consider how events and interrupts interact with
+ save and restore functionality. Ensure that queued interrupts and
+ ongoing events are properly saved and restored to maintain game
+ consistency.
+
+By carefully considering these edge cases and designing your events
+with foresight, you can ensure your ZIL game delivers a dynamic and
+engaging experience for players.
+
+This chapter has provided a detailed exploration of event handling in
+ZIL. By understanding interrupts, M-END clauses, and the nuances of
+event design, you can now create a vibrant and responsive game world
+that reacts to both player actions and the passage of time.
+
+# Chapter 8: Actors and Interaction
+
+Interactive fiction thrives on engaging characters that populate the
+game world and interact with the player. ZIL refers to these
+characters as actors. This chapter will provide a detailed guide to
+creating and managing actors in your ZIL games. We'll explore how to
+define actors, handle dialog and interaction, and address potential
+challenges to ensure your characters feel believable and contribute to
+an immersive narrative experience.
+
+## Defining Actors
+
+Actors are essentially objects with the PERSONBIT flag set, indicating
+they are characters capable of independent actions and communication.
+When creating an actor, consider the following:
+
+ Basic Object Properties:
+
+ Provide a descriptive DESC for the actor.
+
+ Include relevant SYNONYMs and ADJECTIVEs for player reference.
+
+ Set appropriate flags like OPENBIT, CONTBIT, and SEARCHBIT if
+ the actor carries items.
+
+ Action Routine:
+
+ Define an ACTION routine for the actor, similar to other
+ objects.
+
+ Remember that this routine handles both player interaction
+ with the actor as an object (e.g., "examine actor") and
+ actions performed by the actor themself.
+
+ dialog and Interaction:
+
+ Implement logic within the action routine to handle dialog
+ and interaction with the player.
+
+ Use the WINNER variable to determine if the player is
+ currently addressing the actor.
+
+ Provide appropriate responses based on the player's input and
+ the game context.
+
+## Managing dialog and Interaction
+
+The WINNER variable plays a crucial role in managing dialog.
+Typically, WINNER is set to the PLAYER object. However, when the
+player addresses an actor using the TELL verb, the WINNER temporarily
+becomes that actor. This allows the actor's action routine to handle
+the subsequent player input as dialog directed specifically at them.
+
+Here's how to handle dialog in an actor's action routine:
+
+ Check for M-WINNER:
+
+ Use a COND clause to check if the RARG is equal to M-WINNER.
+
+ If true, it indicates the player is speaking to the actor.
+
+ Handle Player Input:
+
+ Within the M-WINNER clause, implement logic to interpret and
+ respond to the player's input.
+
+ Use VERB? and other predicates to identify the player's
+ intent.
+
+ Provide appropriate responses using TELL, taking into account
+ the game context and the actor's personality.
+
+ Default Response:
+
+ Include a catch-all clause to handle unrecognized or
+ irrelevant input.
+
+ This ensures the player receives feedback even if their
+ command doesn't have a specific response.
+
+Remember to switch WINNER back to the PLAYER object once the dialog
+ends.
+
+## Challenges and Edge Cases
+
+While implementing actors, be mindful of potential challenges:
+
+ Ambiguity: If multiple actors are present, ensure the parser
+ correctly identifies the intended recipient of the player's
+ speech. Use specific noun phrases or implement disambiguation
+ mechanisms.
+
+ Confusing Responses: Ensure the actor's responses are consistent
+ with their personality and the game context. Avoid generic or
+ nonsensical replies.
+
+ Unintended Actions: Prevent situations where the player can
+ manipulate the actor in unintended ways. For example, avoid
+ allowing the player to "take" or "drop" an actor.
+
+By carefully considering these challenges and implementing robust
+logic in your action routines, you can create engaging and believable
+actors that enhance the player's experience in your interactive
+fiction game.
+
+# Chapter 9: The Parser and Syntaxes: Mastering Player Input
+
+The parser is responsible for interpreting the player's input. This
+chapter will delve deep into the parser's role and its intricate
+relationship with syntaxes, the rules that govern how players can
+express their intentions. We'll explore how to define legal input
+structures, utilize verb synonyms, and employ syntax tokens to guide
+the parser effectively. Additionally, we'll unravel the mysteries of
+GWIMming and the FIND feature, allowing you to create a truly
+responsive and intuitive experience for your players.
+
+## Demystifying the Parser
+
+Imagine the parser as a dedicated language expert who meticulously
+analyzes each sentence the player types. Its primary goal is to
+identify three key elements:
+
+ Verb (PRSA): The action the player wants to perform (e.g., TAKE,
+ OPEN, EXAMINE).
+
+ Direct Object (PRSO): The primary object the action is directed
+ towards (e.g., BOOK, DOOR, KEY).
+
+ Indirect Object (PRSI): An optional secondary object involved in
+ the action (e.g., "PUT BOOK ON TABLE").
+
+The parser accomplishes this by comparing the player's input to a set
+of predefined rules called syntaxes.
+
+## Syntaxes: Defining the Rules of Interaction
+
+Syntaxes are the building blocks of player interaction, dictating the
+allowed sentence structures and their corresponding actions. Each
+syntax specifies a particular combination of verbs, prepositions, and
+noun phrases that the parser can recognize.
+
+Defining a syntax involves using the SYNTAX subroutine, where you
+outline the sentence structure with OBJECT tokens representing noun
+phrases and actual prepositions in their respective positions. For
+example:
+
+ <SYNTAX TAKE OBJECT = V-TAKE PRE-TAKE>
+
+This syntax tells the parser that any sentence in the form "TAKE
+noun-phrase" is valid. The V-TAKE and PRE-TAKE indicate the default
+action routine and pre-action routine, respectively, associated with
+this syntax.
+
+Here are some additional examples of common syntax definitions:
+
+ <SYNTAX LOOK = V-LOOK>
+ <SYNTAX OPEN OBJECT = V-OPEN>
+ <SYNTAX PUT OBJECT IN OBJECT = V-PUT PRE-PUT>
+ <SYNTAX EXAMINE OBJECT = V-EXAMINE>
+
+Notice how syntaxes can accommodate various sentence structures,
+including those with indirect objects and prepositions.
+
+## Edge Cases and Preposition Handling
+
+It's important to remember that the parser ignores the second
+preposition when two consecutive prepositions appear. For instance,
+both "SIT DOWN CHAIR" and "SIT DOWN ON CHAIR" would be recognized by
+the following syntax:
+
+ <SYNTAX SIT DOWN OBJECT = V-SIT>
+
+This behavior simplifies syntax definitions and accommodates natural
+language variations in player input.
+
+## Guiding the Parser with Syntax Tokens
+
+While basic syntax definitions are essential, you can further refine
+how the parser interprets player input by employing special tokens
+within the syntax definition. These tokens provide additional context
+and instructions to the parser, ensuring accurate and efficient
+interpretation of player intentions.
+
+Here are some of the most commonly used syntax tokens:
+
+ TAKE: Instructs the parser to implicitly take the object if it's
+ not already in the player's inventory. This is often used for
+ actions like READ or those requiring tools.
+
+ HAVE: Requires the object to be in the player's possession for the
+ syntax to be valid. If not, the parser will generate a message
+ like "You don't have the X."
+
+ MANY: Allows multiple objects to be specified in the noun phrase.
+ This is useful for actions like TAKE or PUT where players might
+ want to interact with several objects at once.
+
+Additionally, several tokens guide the parser in where to look for
+objects:
+
+ HELD: Look for objects held directly by the player (not inside
+ other containers).
+
+ CARRIED: Look for objects held by the player, including those
+ inside containers they are carrying.
+
+ ON-GROUND: Look for objects located directly on the ground in the
+ current room.
+
+ IN-ROOM: Look for objects within containers that are on the ground
+ in the current room.
+
+By strategically using these tokens, you can significantly enhance the
+parser's accuracy and create a more intuitive experience for your players.
+
+For example, the following syntax definition for TAKE ensures that
+players can only take objects that are on the ground and allows them
+to take multiple objects at once:
+
+ <SYNTAX TAKE OBJECT (MANY ON-GROUND) = V-TAKE PRE-TAKE>
+
+## GWIMming and the FIND Feature: Filling in the Blanks
+
+One of the parser's capabilities is its ability to "get what I mean"
+(GWIM). This feature allows players to omit certain information in
+their input, and the parser will attempt to fill in the blanks based
+on context and available objects.
+
+The FIND token, combined with a specific flag, enables GWIMming within
+a syntax. For instance:
+
+ <SYNTAX OPEN OBJECT (FIND DOORBIT) = V-OPEN>
+
+If the player simply types "OPEN" without specifying an object, the
+parser will search for an accessible object with the DOORBIT flag set.
+If only one such object exists, the parser will assume that's the
+object the player intends to open.
+
+This feature significantly enhances the game's intuitiveness and
+allows for more natural language interaction. However, it's crucial to
+use FIND judiciously to avoid ambiguity. If multiple objects with the
+specified flag are present, the parser will prompt the player for
+clarification, preventing unintended actions.
+
+## Mastering the Parser: Tips and Best Practices
+
+Here are some valuable tips for working effectively with the parser
+and syntaxes:
+
+ Start with simple syntaxes: Begin by defining basic syntaxes for
+ essential actions like TAKE, LOOK, and GO. Gradually add more
+ complex structures as needed.
+
+ Use verb synonyms: Expand player vocabulary and allow for natural
+ language variations by defining verb synonyms with the SYNONYM
+ subroutine.
+
+ Choose meaningful names: Use clear and descriptive names for your
+ action routines and pre-action routines to improve code
+ readability and maintainability.
+
+ Test extensively: Thoroughly test your syntaxes and parser
+ interactions to ensure they function as intended and handle edge
+ cases gracefully.
+
+ Consider player perspective: When designing syntaxes, think about
+ how players might naturally express their intentions and try to
+ accommodate various phrasings.
+
+By following these guidelines and carefully crafting your syntaxes,
+you can create a robust and user-friendly parser that allows players
+to interact with your game world seamlessly and intuitively.
+
+Mastering the parser and syntaxes is crucial for building engaging and
+immersive interactive fiction experiences. This chapter has provided a
+comprehensive exploration of these topics, equipping you with the
+knowledge and tools to create a truly responsive and enjoyable game
+for your players.
+
+# Chapter 10: Describers and Object Presentation
+
+In interactive fiction, painting a vivid picture of the game world is
+crucial for immersing players in the narrative. This chapter delves
+into the describers, a set of routines in ZIL responsible for
+presenting rooms and objects to the player. We'll explore various
+description methods, including NDESCBIT, LDESC, FDESC, and DESCFCN,
+and learn how to handle darkness and light conditions effectively. By
+mastering the describers, you'll be able to craft evocative and
+detailed descriptions that bring your game world to life.
+
+## The Role of Describers
+
+The describers are called upon whenever the game needs to present a
+room description to the player. This typically occurs when:
+
+ The player enters a new room.
+
+ The player types the "LOOK" command.
+
+ Other verbs like "INVENTORY" or "LOOK INSIDE" require a
+ description of the surroundings.
+
+The describers handle both the room name and its descriptive text,
+taking into account the game's verbosity level (verbose, brief,
+superbrief) and whether the room has been visited before.
+
+## Describing Rooms
+
+There are two main components to a room description:
+
+ Room Name: This is the DESC property of the room object and is
+ displayed every time the player enters the room. Some games
+ enhance the presentation by using bold type or adding an addendum
+ if the player is in a vehicle (e.g., "Living Room, on the couch").
+
+ Descriptive Text: This provides a detailed description of the
+ room's appearance and contents. It is displayed based on the
+ verbosity level and whether the room has been visited before.
+
+The describers first determine if the room is lit or dark. If dark,
+they display a message like "It's too dark to see" and return.
+Otherwise, they proceed to describe the room:
+
+ Check for LDESC: If the room has an LDESC property (a static long
+ description), it is displayed.
+
+ Call Room Action Routine: If no LDESC exists, the room's action
+ routine is called with the argument M-LOOK. The action routine
+ then handles the description dynamically, allowing for changes
+ based on game events.
+
+## Edge Case: M-FLASH
+
+There exists an additional context code, M-FLASH, which can be used in
+a room's action routine to force a description regardless of verbosity
+or previous descriptions. This is rarely used but can be helpful in
+specific situations.
+
+## Describing Objects
+
+Object descriptions are handled by the DESCRIBE-OBJECTS routine, which
+is called after DESCRIBE-ROOM unless the room is dark. This routine
+offers several ways to describe objects:
+
+ Default Description: If no special description is defined, the
+ object's DESC is used in a default sentence like "You can see a
+ [object name] here."
+
+ LDESC: If the object has an LDESC property, it is used to describe
+ the object when it is on the ground in the player's room.
+
+ FDESC: An FDESC property provides a special initial description
+ for the object before it is first moved. Once the object's
+ TOUCHBIT is set (by taking or putting it), the FDESC is no longer
+ used.
+
+ DESCFCN: This property specifies a dedicated routine for
+ describing the object dynamically based on various conditions.
+ This offers the most flexibility and complexity.
+
+DESCRIBE-OBJECTS makes three passes through the objects in a room:
+
+ Objects with DESCFCNs and FDESCs are described.
+
+ Objects with LDESCs are described.
+
+ Remaining objects are described using their default descriptions.
+
+Note: The contents of containers are described immediately after the
+container itself.
+
+## DESCFCNs: Dynamic Descriptions
+
+A DESCFCN is a powerful tool for crafting context-aware descriptions
+for objects. It involves creating a dedicated routine that handles the
+description based on various conditions. Here's how it works:
+
+ Define DESCFCN Property: Assign the DESCFCN property to the
+ object, specifying the name of the describing routine.
+
+ Write the DESCFCN Routine: This routine takes one argument (ARG)
+ and checks if it is called with M-OBJDESC?. If so, it returns
+ RTRUE to indicate it will handle the description. Otherwise, it
+ proceeds to describe the object based on relevant conditions using
+ TELL statements.
+
+Example:
+
+ (DESCFCN HORN-DESC-F)
+
+ <ROUTINE HORN-DESC-F (ARG)
+ <COND (<EQUAL? .RARG ,M-OBJDESC?>
+ <RTRUE>)
+ (,HORN-MOUNTED
+ <TELL "A brass bike horn is mounted on the bicycle handlebars.">
+ <COND (<EQUAL? ,HERE ,MAGIC-BIKEPATH>
+ <TELL "The horn is glowing with a gentle yellow light.">)>)
+ <CRLF>)
+ (T
+ <TELL "A brass bicycle horn is lying here. You can almost
+ hear it saying, \"Mount me on a pair of handlebars!\""
+ CR>)>>
+
+This DESCFCN describes the horn differently depending on whether it is
+mounted on the handlebars and whether the player is on the Magic Bikepath.
+
+## NDESCBIT: Suppressing Descriptions
+
+The NDESCBIT flag tells the describers to skip an object's
+description. This is useful when:
+
+ The object is already described in the room description.
+
+ The object is initially described in the room but becomes takeable
+ later.
+
+Caution: When using NDESCBIT for takeable objects, ensure the room
+description stops mentioning the object once taken and that the
+NDESCBIT is cleared when the object is moved.
+
+By mastering the describers and their various options, you can create
+rich and immersive descriptions that enhance the player's experience
+and bring your interactive fiction game to life.
+
+# Chapter 11: Vehicles and Movement
+
+In interactive fiction, players typically navigate the world by moving
+between rooms. However, ZIL offers an additional layer of complexity
+with vehicles - objects that players can enter and move around in.
+This chapter explores the implementation of vehicles, including
+defining vehicle types, movement restrictions, and handling object
+interaction within vehicles. By understanding these concepts, you can
+add depth and variety to player movement in your game.
+
+## What are Vehicles?
+
+Vehicles are non-room objects that can become the player's location.
+Vehicles must have the VEHBIT flag set and typically also have the
+CONTBIT and OPENBIT flags, as they can contain objects and need to be
+"open" for the player to enter.
+
+## Defining Vehicle Types and Movement
+
+Movement between rooms and vehicles is governed by the "medium" of
+travel. Rooms have flags like RLANDBIT (for walking), RWATERBIT (for
+boats), and RAIRBIT (for flying vehicles). The WALK handler checks
+these flags to determine if movement is possible. For example, moving
+from a land room to a water room requires a water-based vehicle.
+
+Vehicles themselves have a VTYPE property that defines their type and
+capabilities. This property is set up in a specific way, and
+consulting experienced ZIL programmers is recommended when
+implementing vehicles.
+
+## Movement Restrictions within Vehicles
+
+The Location routine (the ACTION property of the vehicle object) can
+be used to restrict movement within vehicles. For example, you could
+prevent the player from walking or taking objects while seated. It
+also handles specific actions like getting up, taking into account
+conditions like whether the seat belt is fastened.
+
+## Object Interaction in Vehicles
+
+When the player is inside a vehicle, object interaction can be handled
+in several ways:
+
+ Location Routine: The vehicle's action routine can handle
+ interactions with objects inside or outside the vehicle.
+
+ UNTOUCHABLE? Predicate: This predicate can be used to determine
+ if an object is out of reach because the player is inside a
+ vehicle.
+
+ DESCFCNs: Dynamic object descriptions can be used to reflect the
+ player's perspective from within the vehicle.
+
+## Edge Cases and Considerations
+
+ Nested Vehicles: While ZIL allows for vehicles within vehicles,
+ this can quickly become complex and confusing for players. Use
+ this sparingly and with caution.
+
+ Movement Verbs: Consider how verbs like "CLIMB" or "ENTER"
+ interact with vehicles. You might need to define specific syntaxes
+ and handlers for these cases.
+
+ Object Visibility: Objects inside a closed vehicle might not be
+ visible to the player unless the vehicle is transparent or has the
+ SEARCHBIT flag set.
+
+By carefully considering these aspects, you can create engaging and
+intuitive gameplay experiences involving vehicles and movement in your
+ZIL game.
+
+# Chapter 12: Organizing Your ZIL Code
+
+As your interactive fiction game grows in complexity, maintaining a
+well-organized codebase becomes essential. This chapter delves into
+best practices for structuring and dividing your ZIL code into
+multiple files. We'll explore the concept of the substrate, common
+game files, and strategies for organizing code based on geography,
+scenes, or specific game elements. By following these guidelines,
+you'll ensure your code remains manageable, readable, and easy to
+maintain.
+
+## The Importance of Organization
+
+Organizing your ZIL code offers several benefits:
+
+ Maintainability: A well-structured codebase is easier to
+ understand and modify, making it simpler to fix bugs and implement
+ new features.
+
+ Readability: Clear organization helps both you and other
+ programmers quickly locate specific code sections and understand
+ their purpose.
+
+## Organizing Your Game Files
+
+While you have flexibility in organizing your game-specific code, here
+are some common approaches:
+
+ Geographical Organization: Divide the code based on the game's
+ geography, with separate files for different areas or locations.
+
+ Mystery-Based Organization: Structure the code around the game's
+ mysteries, with files dedicated to People (actors), Places
+ (rooms), and Things (objects). This is often used in detective or
+ puzzle-focused games.
+
+ Scene-Based Organization: If your game is divided into distinct
+ scenes, you can organize the code accordingly. This can be helpful
+ for managing complex narratives with branching paths.
+
+ Element-Based Organization: Dedicate separate files to specific
+ game elements with significant code.
+
+Ultimately, the best approach depends on your game's specific
+structure and complexity. As your project evolves, you might need to
+adjust your organization strategy to maintain clarity and efficiency.
+
+## Edge Cases and Considerations
+
+ File Size: Avoid creating excessively large files, as they can
+ become difficult to manage. Split large files into smaller, more
+ focused ones.
+
+ File Naming: Use descriptive and consistent naming conventions for
+ your ZIL files to improve readability and navigation.
+
+ Dependencies: Be mindful of dependencies between files and ensure
+ they are loaded in the correct order.
+
+By carefully organizing your ZIL code, you'll create a solid
+foundation for developing and maintaining a complex and engaging
+interactive fiction game.
+
+# Chapter 13: Compiling and Debugging
+
+Bringing your ZIL code to life requires transforming it into a
+playable game. This chapter explores the compilation process, guiding
+you through the use of the compiler and assembler. We'll also delve
+into debugging techniques, helping you identify and resolve common
+errors in your ZIL code.
+
+## Compilation: From ZIL to Z-code
+
+Compiling your ZIL game involves two main steps:
+
+ The compiler translates your ZIL source code into Z-assembly
+ language. This intermediate language is specific to the
+ Z-machine, the virtual machine that executes ZIL games.
+
+ The assembler takes the Z-assembly code generated by the compiler
+ and converts it into Z-code, a machine-independent bytecode
+ format.
+
+This Z-code is what the Z-machine interpreter ultimately executes to
+run your game.
+
+To compile your game, you typically use a command-line interface or a
+dedicated development environment that integrates the compiler and
+assmebler. The specific commands might vary depending on your setup.
+
+## Debugging: Finding and Fixing Errors
+
+Debugging is an essential part of game development, and ZIL offers
+various tools and techniques to help you identify and resolve errors
+in your code:
+
+ Error Messages: Both the compiler and assembler generate error
+ messages when encountering problems in your code. These messages
+ provide valuable clues about the nature and location of the error.
+
+ Commenting Out Code: Temporarily commenting out sections of code
+ can help isolate problematic areas and narrow down the source of
+ errors.
+
+## Common Errors and Troubleshooting
+
+Here are some common errors you might encounter when working with ZIL:
+
+ Syntax Errors: These occur when your code violates ZIL's syntax
+ rules, such as unbalanced angle brackets or incorrect use of
+ operators.
+
+ Runtime Errors: These errors happen during game execution, often
+ caused by issues like accessing undefined variables or attempting
+ illegal operations.
+
+ Logic Errors: These are the trickiest to find, as the code might
+ be syntactically correct but produce unintended results due to
+ flaws in the game logic.
+
+When debugging, it's important to approach the problem systematically:
+
+ Identify the Error: Carefully read error messages and observe the
+ game's behavior to understand the nature of the problem.
+
+ Isolate the Cause: Use techniques like tracing and commenting out
+ code to narrow down the source of the error.
+
+ Fix the Problem: Once you've identified the cause, make the
+ necessary changes to your code.
+
+ Test and Verify: Recompile and test your game to ensure the error
+ has been resolved and no new issues have been introduced.
+
+## Edge Cases and Considerations
+
+ Compiler Quirks: Be aware of potential quirks or limitations in
+ the compiler and adjust your code accordingly.
+
+ Testing Thoroughly: Test your game extensively to catch edge cases
+ and unexpected scenarios that might trigger errors.
+
+By mastering the art of debugging and utilizing the available tools
+effectively, you'll be able to ensure your ZIL code runs smoothly and
+delivers a polished and enjoyable interactive fiction experience.
+
+# Chapter 14: Graphics and Sound
+
+While ZIL is primarily focused on text-based interaction, it also
+provides capabilities for incorporating graphics and sound effects
+into your interactive fiction games. This chapter explores how to
+integrate these elements using the DISPLAY and SOUND instructions, as
+well as considerations for managing picture files and ensuring
+cross-platform compatibility.
+
+## Integrating Graphics
+
+To display graphics in your ZIL game, you use the DISPLAY instruction.
+It takes three arguments:
+
+ Picture Number: This identifies the specific graphic to be
+ displayed from the picture file.
+
+ Y-Coordinate: The vertical position (in pixels) where the top-left
+ corner of the picture should be placed.
+
+ X-Coordinate: The horizontal position (in pixels) where the
+ top-left corner of the picture should be placed.
+
+Example:
+
+ <DISPLAY ,P-TITLE 1 1>
+
+This displays the picture identified by P-TITLE at the top-left corner
+of the screen (coordinates 1, 1).
+
+## Implementing Sound Effects
+
+The SOUND instruction allows you to play sound effects in your game.
+It takes four arguments:
+
+ Sound Number: Identifies the specific sound effect to be played
+ from the sound file.
+
+ Operation: Determines the action to be performed: initialize (1),
+ start (2, default), stop (3), or clean up (4).
+
+ Volume: (Optional) Sets the volume level for the sound effect.
+
+ Repeat Count: (Optional) Specifies how many times the sound should
+ be repeated.
+
+Example:
+
+ <SOUND ,CAR-BACKFIRE 2 5 2>
+
+This plays the sound effect CAR-BACKFIRE at volume level 5 and repeats
+it twice.
+
+## Managing Picture and Sound Files
+
+Graphics and sound effects are typically stored in separate files from
+the main game code. These files need to be organized and referenced
+correctly for your game to function properly.
+
+ Picture File: This file contains the actual graphics data and
+ invisible pictures used for positioning. It needs to be tailored
+ to each target platform to ensure compatibility.
+
+ Sound File: This file contains the sound effects data in a format
+ compatible with the target platform.
+
+## Accessibility
+
+ Consider players who might not be able to experience graphics or
+ sound due to disabilities. Provide alternative ways to access the
+ information conveyed by these elements.
+
+By carefully integrating graphics and sound effects into your ZIL
+game, you can create a richer and more immersive experience for your
+players.
+
+# Chapter 15: Advanced Techniques and Optimizations
+
+As you gain proficiency in ZIL programming, you can explore advanced
+techniques and optimizations to enhance your interactive fiction games
+and push the boundaries of what's possible. This chapter delves into
+powerful ZIL features like tables, generics, and advanced property
+manipulation. We'll also discuss strategies for optimizing code for
+efficiency and memory usage, as well as techniques for handling
+complex game mechanics and interactions.
+
+## Tables: Storing and Managing Data
+
+Tables in ZIL are similar to arrays in other languages, allowing you
+to store and manage collections of data efficiently. They can hold
+various types of data, including numbers, strings, object names, and
+even routines.
+
+Creating Tables:
+
+You create tables at the top level of your ZIL code using the TABLE or
+LTABLE instructions:
+
+ <TABLE element1 element2 element3 ...>
+ <LTABLE element1 element2 element3 ...>
+
+LTABLE creates a special type of table where the first element
+automatically stores the number of elements in the table. This is
+useful when you need to know the table's length dynamically.
+
+## Accessing and Modifying Table Elements:
+
+Use the GET and PUT instructions to retrieve and modify elements
+within a table:
+
+ <GET table element-number>
+ <PUT table element-number value>
+
+Example:
+
+ <CONSTANT maze-exits <TABLE 12 18 24 0 0 0>>
+
+ <SET current-room 2>
+ <SET next-room <GET ,maze-exits .current-room>>
+
+In this example, maze-exits is a table storing exit information for
+different rooms. The code retrieves the exit for the current room
+(stored in the current-room variable) and assigns it to the next-room
+variable.
+
+## Generics: Handling Ambiguity
+
+Generics provide a mechanism for resolving ambiguity when the parser
+cannot determine which object the player is referring to. By defining
+a GENERIC property for an object, you can specify a routine that
+handles these ambiguous cases.
+
+Example:
+
+ <OBJECT book
+ (DESC "book")
+ (SYNONYM BOOK NOVEL)
+ (GENERIC BOOK-GENERIC)
+ ...
+ >
+
+ <ROUTINE book-generic ()
+ ...
+ >
+
+Here, the BOOK-GENERIC routine is called when the player uses a noun
+phrase like "book" and the parser finds multiple matching objects. The
+routine can then ask the player for clarification or use other
+strategies to resolve the ambiguity.
+
+## Advanced Property Manipulation
+
+While GETP and PUTP allow you to access and modify object properties,
+ZIL offers more advanced techniques for handling complex property
+manipulation:
+
+ GETPT and PUTPT: These instructions operate on "property tables,"
+ which can represent properties with values larger than 16 bits.
+ This is useful for properties like exits, which require multiple
+ bytes to store their information.
+
+ GETB and PUTB: These instructions access and modify individual
+ bytes within tables, providing finer-grained control over property
+ manipulation.
+
+These advanced techniques are typically used for specific scenarios
+and require a deeper understanding of ZIL's internal workings. Consult
+the ZIL documentation and seek guidance from experienced programmers
+when working with these instructions.
+
+## Optimizations: Efficiency and Memory Usage
+
+Optimizing your ZIL code can improve game performance and reduce
+memory consumption. Here are some strategies to consider:
+
+ Use efficient data structures: Choose appropriate data types and
+ structures to minimize memory usage. For example, use LTABLE only
+ when you need to know the table's length dynamically.
+
+ Minimize routine calls: Avoid unnecessary routine calls, as they
+ can impact performance. Consider inlining small routines or using
+ macros when appropriate.
+
+ Optimize conditional expressions: Structure your COND statements
+ to check the most likely conditions first. This can reduce the
+ number of comparisons performed.
+
+ Use comments and formatting: Clear comments and formatting improve
+ code readability and maintainability, making it easier to identify
+ areas for optimization.
+
+## Handling Complex Mechanics
+
+ZIL provides various tools and techniques for implementing complex
+game mechanics and interactions:
+
+ Events and Interrupts: Use queued actions and interrupts to create
+ time-based events and dynamic responses to player actions.
+
+ Actors and dialog: Define actors (characters) and handle
+ dialog interactions through the WINNER variable and specific
+ routines.
+
+ Custom Syntaxes: Extend the parser's capabilities by defining
+ custom syntaxes for unique actions and interactions.
+
+ Advanced Property Manipulation: Utilize advanced property
+ manipulation techniques to implement complex object behaviors and
+ game mechanics.
+
+By combining these techniques and optimizing your code, you can create
+sophisticated and engaging interactive fiction experiences that push
+the boundaries of the genre.
+
+Remember that optimization is often a trade-off between performance,
+memory usage, and code readability. Choose the strategies that best
+suit your game's needs and prioritize clarity and maintainability to
+ensure your code remains manageable and enjoyable to work with.
+
+# Chapter 16: Using ZIL for Other Game Genres
+
+While ZIL was originally designed for creating text-based interactive
+fiction, its flexibility and powerful features allow it to be adapted
+for other game genres. This chapter explores the possibilities of
+using ZIL to create different types of interactive experiences,
+pushing the boundaries of traditional IF and venturing into new gaming
+territories.
+
+## Beyond Text Adventures
+
+ZIL's core strengths lie in its ability to manage complex narratives,
+track object states, and handle intricate player interactions. These
+capabilities can be applied to various game genres beyond traditional
+text adventures, including:
+
+ Puzzle Games: ZIL can be used to create intricate puzzle
+ mechanics, manage object interactions, and track player progress
+ through challenging scenarios.
+
+ Role-Playing Games: While ZIL might not be ideal for real-time
+ combat, it can handle turn-based RPG systems, character stats,
+ inventory management, and dialog interactions effectively.
+
+ Simulation Games: ZIL's ability to track object states and
+ simulate complex systems makes it suitable for creating engaging
+ simulations, from managing a city to running a spaceship.
+
+ Interactive Stories: ZIL can be used to craft interactive
+ narratives with branching paths and choices that impact the
+ story's outcome, offering a more engaging experience than linear
+ storytelling.
+
+## Adapting ZIL for Different Mechanics
+
+When using ZIL for non-standard game formats, you might need to adapt
+certain aspects of the language and develop creative solutions to
+implement specific mechanics. Here are some considerations:
+
+ Input and Output: While text-based input remains ZIL's primary
+ interaction method, you can integrate other input methods like
+ mouse clicks or keyboard shortcuts for specific actions. Output
+ can also be enhanced with graphical elements or sound effects.
+
+ Game Loops and Timing: ZIL's turn-based structure might need
+ adjustments for real-time or time-sensitive mechanics. You can use
+ interrupts and queued actions to manage timing and create the
+ illusion of continuous action.
+
+ Object Interactions: ZIL's object-oriented structure is
+ well-suited for managing interactions in various game genres. You
+ can define custom properties and action routines to implement
+ specific game mechanics.
+
+## Examples and Edge Cases
+
+ Graphical ZIL Games: Some developers have experimented with adding
+ graphical elements to ZIL games, creating hybrid experiences that
+ combine text descriptions with visual representations.
+
+ Multiplayer ZIL Games: While ZIL is inherently single-player,
+ creative approaches can enable multiplayer interactions, such as
+ hot-seat gameplay or shared world experiences.
+
+ Non-Narrative Games: ZIL can be used to create purely mechanical
+ games without a strong narrative focus, such as logic puzzles or
+ abstract strategy games.
+
+By thinking outside the box and leveraging ZIL's core strengths, you
+can explore new possibilities for interactive game design and create
+innovative experiences that go beyond the traditional text adventure
+format.
+
+Remember that adapting ZIL for different genres might require
+overcoming certain limitations and developing creative solutions.
+However, the language's flexibility and power offer a unique
+opportunity to explore uncharted territory in interactive game design.
\ No newline at end of file