A lot of projects ported from the old metanohi site.
This commit is contained in:
BIN
site/projects/zita/img/zita-logo.png
Executable file
BIN
site/projects/zita/img/zita-logo.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
199
site/projects/zita/img/zita-logo.svg
Executable file
199
site/projects/zita/img/zita-logo.svg
Executable file
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="300"
|
||||
height="150"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docname="zita-logo.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.0">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient3250">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3252" />
|
||||
<stop
|
||||
style="stop-color:#434343;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3254" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3217">
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3219" />
|
||||
<stop
|
||||
style="stop-color:#c9c9c9;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3221" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3213"
|
||||
x="-0.061428573"
|
||||
width="1.1228571"
|
||||
y="-0.13279411"
|
||||
height="1.2655882">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="7.057955"
|
||||
id="feGaussianBlur3215" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3217"
|
||||
id="radialGradient3223"
|
||||
cx="207.28346"
|
||||
cy="125.68319"
|
||||
fx="207.28346"
|
||||
fy="125.68319"
|
||||
r="137.87633"
|
||||
gradientTransform="matrix(1,0,0,0.4625851,-56.540598,18.32786)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3250"
|
||||
id="radialGradient3256"
|
||||
cx="205.24016"
|
||||
cy="126.79092"
|
||||
fx="205.24016"
|
||||
fy="126.79092"
|
||||
r="124.16836"
|
||||
gradientTransform="matrix(1,0,0,0.4009525,0,75.953779)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3250"
|
||||
id="radialGradient3258"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,0.4009525,0,75.953779)"
|
||||
cx="205.24016"
|
||||
cy="126.79092"
|
||||
fx="205.24016"
|
||||
fy="126.79092"
|
||||
r="124.16836" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3250"
|
||||
id="radialGradient3260"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,0.4009525,0,75.953779)"
|
||||
cx="205.24016"
|
||||
cy="126.79092"
|
||||
fx="205.24016"
|
||||
fy="126.79092"
|
||||
r="124.16836" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3250"
|
||||
id="radialGradient3262"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,0.4009525,0,75.953779)"
|
||||
cx="205.24016"
|
||||
cy="126.79092"
|
||||
fx="205.24016"
|
||||
fy="126.79092"
|
||||
r="124.16836" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.9466667"
|
||||
inkscape:cx="204.63801"
|
||||
inkscape:cy="75"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="744"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:url(#radialGradient3223);fill-opacity:1;stroke:none;stroke-width:2.0999999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3213)"
|
||||
id="rect2413"
|
||||
width="275.75266"
|
||||
height="127.55906"
|
||||
x="12.866536"
|
||||
y="12.687495"
|
||||
transform="matrix(0.9547721,0,0,0.9547721,5.2482151,4.3068607)" />
|
||||
<g
|
||||
id="g3243"
|
||||
style="fill:url(#radialGradient3256);fill-opacity:1"
|
||||
transform="matrix(0.9547721,0,0,0.9547721,-48.735168,-42.683356)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text2383"
|
||||
y="176.57654"
|
||||
x="74.936134"
|
||||
style="font-size:136.58532715px;font-style:normal;font-weight:normal;line-height:125%;fill:url(#radialGradient3258);fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:136.58532715px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#radialGradient3258);fill-opacity:1;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
y="176.57654"
|
||||
x="74.936134"
|
||||
id="tspan2385"
|
||||
sodipodi:role="line">Z</tspan></text>
|
||||
<text
|
||||
id="text2387"
|
||||
y="156.1474"
|
||||
x="158.49486"
|
||||
style="font-size:106.78322601px;font-style:normal;font-weight:normal;fill:url(#radialGradient3260);fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="156.1474"
|
||||
x="158.49486"
|
||||
id="tspan2389"
|
||||
sodipodi:role="line"
|
||||
style="fill:url(#radialGradient3260);fill-opacity:1">ITA</tspan></text>
|
||||
<rect
|
||||
ry="0"
|
||||
y="165.29819"
|
||||
x="160.99013"
|
||||
height="11.263652"
|
||||
width="168.4184"
|
||||
id="rect2411"
|
||||
style="fill:url(#radialGradient3262);fill-opacity:1;stroke:none;stroke-width:2.0999999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.7 KiB |
511
site/projects/zita/index.org
Normal file
511
site/projects/zita/index.org
Normal file
@@ -0,0 +1,511 @@
|
||||
#+title: Zita
|
||||
#&summary
|
||||
A simple but cumbersome text adventure game
|
||||
#&
|
||||
#+license: bysa, page
|
||||
#+license: gpl 3+, program
|
||||
#+license: cc0, Zeqy
|
||||
#&toc
|
||||
|
||||
#&img;url=img/zita-logo.png, center, alt='Logo of Zita'
|
||||
|
||||
* Zita
|
||||
Zita is a text adventure engine written in Python. Text adventures, also known
|
||||
as [[http://en.wikipedia.org/wiki/Interactive_fiction][interactive fiction]] in some cases, challenge the minds of people, using no
|
||||
graphics at all. With Zita, it is now possible to write a text adventure in
|
||||
normal Python syntax.
|
||||
|
||||
|
||||
** Installation
|
||||
To run Zita, Python must be installed. No other depencies are needed.
|
||||
|
||||
[[zita.tar.gz][Download Zita]].
|
||||
|
||||
To run Zita, run zita.py. If a game directory is specified, Zita will attempt
|
||||
to execute the game files in that directory. If no game directory is specified,
|
||||
Zita will attempt to run the game Zeqy. Besides zita.py, there is also a file
|
||||
named defs.py. This file is executed by zita.py on startup and should not be
|
||||
used on its own. It contains functions crucial to Zita.
|
||||
|
||||
*** Hacking
|
||||
|
||||
Zita is released under the GPLv3+. Feel free to improve it.
|
||||
|
||||
|
||||
** Zeqy
|
||||
|
||||
Zeqy is a very short text adventure developed for Zita and is shipped together
|
||||
with the engine. It features a short "story" and proves Zita's simplicity. Zeqy
|
||||
is released under the [[http://creativecommons.org/publicdomain/zero/1.0/][Creative Commons Zero 1.0 Universal]] license. This means
|
||||
that you're free to do whatever you want to do with Zeqy. There is no owner of
|
||||
Zeqy.
|
||||
|
||||
** Loading data
|
||||
Games to be run in Zita's engine are saved in text files in a directory. In the
|
||||
case of Zeqy, several files reside in the 'zeqy' directory. The files of a game
|
||||
directory are loaded when Zita runs. In this section, Zeqy will be used as an
|
||||
example of how Zita works.
|
||||
|
||||
A look at the 'zeqy' directory reveals the following files:
|
||||
#&pre
|
||||
commands.zt functions.zt LICENSE rooms.zt
|
||||
defaults.zt items.zt main.zt vars.zt
|
||||
#&
|
||||
|
||||
When Zita starts, it first looks for a file named 'prerun' inside the game
|
||||
directory. If a file named that is found, Zita will execute any Python code
|
||||
inside the file. This allows programmers to change various default
|
||||
values. After looking for 'prerun', Zita attempts to find a main file. By
|
||||
default, the main file must be named something that starts with 'main', though
|
||||
this can be changed in the 'prerun' file. If several files that have names
|
||||
starting with 'main' exist, only one of them will be used. If, for example, a
|
||||
directory has both a file named 'main', a file named 'main.py' and a file named
|
||||
'main.zt', the latter will be loaded (except if the 'prerun' file states
|
||||
otherwise). This is because the '.zt' ending is the default suffix.
|
||||
|
||||
Looking at the file list earlier, it is now possible to deduct that the file
|
||||
'main.zt' must be the main file for Zeqy. Here it is:
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
# Print welcome message
|
||||
p('Welcome to Zeqy, a simple (and short) text adventure demonstrating the \
|
||||
possibilities of Zita, an even simpler Python text adventure engine. If you\'re \
|
||||
completely lost, try asking the engine for help.\n')
|
||||
|
||||
# Include files
|
||||
include(['functions', 'rooms', 'items', 'vars', 'commands', 'defaults'])
|
||||
|
||||
# Starting position
|
||||
goto('grass1')
|
||||
#+END_SRC
|
||||
|
||||
Python code in the main file is executed before Zita starts a game. This means
|
||||
that the main file is suitable to use to print a welcome message, though this
|
||||
is of course also possible to do in the 'prerun' file.<br /> What should be
|
||||
done in the main file and not in the 'prerun' file is including files. The
|
||||
<span class='code'>include</span> function loads and executes both files and
|
||||
files in subdirectories. In the above example, only files are imported, as no
|
||||
subdirectories exist. If, however, such directories did exist, the include
|
||||
command would look for those too.
|
||||
|
||||
*** An example
|
||||
We have a game directory with a file named 'stuff' and a directory named
|
||||
'stuff' that holds several files. In the main file we write this:
|
||||
|
||||
#++python2
|
||||
: include(['stuff'])
|
||||
|
||||
This makes Zita load and execute both the 'stuff' file and the files in the
|
||||
'stuff' folder.
|
||||
|
||||
It is possible to make the <span class='code'>include</span> function accept
|
||||
only either one file, all files or files in subdirectories. Refer to the
|
||||
=include= and =getfilenames= functions found in defs.py.
|
||||
|
||||
When Zita has succesfully loaded all data that it needs to run a game
|
||||
succesfully, it is important to use the =goto= function to create a starting
|
||||
position. A starting position can also be defined in another way, but using
|
||||
=goto= ensures that a message describing the current location is shown.
|
||||
|
||||
|
||||
** Data structures
|
||||
|
||||
When the main file has been loaded and executed, an infinite loop is
|
||||
started. It runs until the variable =COMPLETELY_DONE= is true. When that
|
||||
happens, Zita exits.
|
||||
|
||||
The code inside the loop asks the user for input, which it the processes. Input
|
||||
is split with spaces, and the first word is always the command. A command
|
||||
cannot exist of more than one word. All characters that come after the command
|
||||
are considered part of an object. After the user has pressed Enter, Zita
|
||||
searches through several global variables to see if what the user has typed
|
||||
matches a stored command and/or an object.
|
||||
|
||||
The 6 important global variables in Zita are:
|
||||
|
||||
+ =room=
|
||||
+ =item=
|
||||
+ =var=
|
||||
+ =command=
|
||||
+ =default=
|
||||
+ =extra=
|
||||
|
||||
All except =extra= are dictionaries. The =extra= variable is a string that can
|
||||
contain Python code.
|
||||
|
||||
*** =>room=
|
||||
This variable keeps track of the "rooms" in a game. Rooms are the locations in
|
||||
which a player can be. Rooms can hold items and point to other rooms. See the
|
||||
commented example below containing the room (taken from Zeqy's 'rooms.zt'):
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
room = {
|
||||
'grass1': { # We start defining a room with the grass1 id
|
||||
'name': 'grassy field', # Its name (names are currently not used by Zita)
|
||||
'desc': 'You are standing on a grassy field covered with flowers. The wind \
|
||||
almost blows you away.', # This is the description. The description of this
|
||||
# room is shown when the user enters it.
|
||||
|
||||
# Items are included in a list containing dictionaries. The 'id' property
|
||||
# should point to the id of an item, while the 'desc' property is optional
|
||||
# and can be used to describe the relationship between an item and the room
|
||||
# it is in.
|
||||
'items': [{
|
||||
'id': 'redflower',
|
||||
'desc': "'To the right is a ' + item[citem]['name'] + '.'"
|
||||
}, {
|
||||
'id': 'multic_flower',
|
||||
'desc': "'To the left is a ' + item[citem]['name'] + '.'"
|
||||
}],
|
||||
|
||||
# Rooms includes directions in the 'dir' part. From the code below Zita
|
||||
# understands that walking north will take the user to the room with an
|
||||
# id of 'grass2', walking west will take the user to a swamp, going up
|
||||
# will result in a message telling the user going up is impossible, and
|
||||
# trying everything else will result in Zita giving the user a message.
|
||||
'dir': {
|
||||
'n': 'grass2',
|
||||
'w': 'swamp',
|
||||
'u': "!p('You can\\'t fly yet!')",
|
||||
'&rest': "!p('Going north or west should be possible.')"
|
||||
}
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Note that in the above code, the variable =citem= pops up. This is a special
|
||||
variable holding the current item id. In the items list above, in the case of
|
||||
'redflower', =citem= would be short for 'redflower', and in the case of
|
||||
'multic_flower', =citem= would be short for 'multic_flower'. This may seem
|
||||
useless, but in some cases it's handy. Read on.
|
||||
|
||||
|
||||
*** =>item=
|
||||
This variable keeps information about items. Items can be carried around in an
|
||||
inventory. An item has a name and a series of commands associated with it. An
|
||||
item can have two states. Either it's /in/ or it's /out/, i.e. it's either in
|
||||
the inventory or in the current room. See below for a commented example (taken
|
||||
from Zeqy's 'items.zt'):
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
item = {
|
||||
'redflower': { # This is the id. Rooms use ids like this.
|
||||
'name': 'red flower', # The name
|
||||
|
||||
# Commands associated with the item and the code to execute on activation.
|
||||
# Apart from 'cmd', which reacts to an item no matter what state it is in,
|
||||
# there is also 'in' and 'out'. These are simply not needed in this case.
|
||||
|
||||
# ┏━┓┏┓╻ ┏━╸╻ ╻┏━┓┏┳┓┏━┓╻ ┏━╸
|
||||
# ┣━┫┃┗┫ ┣╸ ┏╋┛┣━┫┃┃┃┣━┛┃ ┣╸ ╹
|
||||
# ╹ ╹╹ ╹ ┗━╸╹ ╹╹ ╹╹ ╹╹ ┗━╸┗━╸╹
|
||||
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# A user types:
|
||||
# > eat red flower
|
||||
# Zita finds this item and executes the value of the 'eat' property in the
|
||||
# 'cmd' property. If there were no 'cmd' commands that matched the command,
|
||||
# Zita would move on to see if any 'in' or 'out' commands, depending on the
|
||||
# state of the item, matching the command existed.
|
||||
|
||||
'cmd': {
|
||||
'eat': "p('It doesn\\'t seem edible.')",
|
||||
'look': "p('It\\'s pretty.')",
|
||||
'get': "p('The flower is stuck.')"
|
||||
}
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
The above example presents only a simple item. It is possible to create much
|
||||
more complex ones. A slightly more complex item can be seen below (this one is
|
||||
also taken from 'items.zt'):
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
item = {
|
||||
'multic_flower': {
|
||||
'name': 'yellow flower',
|
||||
'cmd': {
|
||||
'smell':
|
||||
# Using Python's multiline indicator (three quotes), one can write code that
|
||||
# takes up more than one line. The code below prints a message and changes the
|
||||
# color (in the name) of the current item. This happens when the flower is
|
||||
# smelled to.
|
||||
"""
|
||||
flcolor = randelm(var['colors']) # Gets a random color. The 'var' variable is
|
||||
# explained later on.
|
||||
p('You breathe in the fumes of the ' + item[citem]['name'] + '. In a matter of
|
||||
picoseconds the flower changes its color to ' + flcolor + '.')
|
||||
item[citem]['name'] = flcolor + ' flower'
|
||||
""",
|
||||
'look': "p('It\\'s like the sun.')"
|
||||
}
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Last, but not least, Zita understands the 'pref' (prefix) property:
|
||||
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
item = {
|
||||
'wood': {
|
||||
'name': 'dry wood',
|
||||
'pref': 'some'
|
||||
# If 'some' wasn't specified as a prefix in this case, opening one's
|
||||
# inventory would read this:
|
||||
|
||||
# You currently have:
|
||||
# A dry wood
|
||||
|
||||
# In this case, however, 'a wood' is not what we want to write. 'some wood'
|
||||
# is better. Setting 'pref' to 'some' solves this problem. Now it reads:
|
||||
|
||||
# You currently have:
|
||||
# Some dry wood
|
||||
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
If Zita detects more than one item matching the user's input, the user is
|
||||
prompted to choose between the available items. This would be the case if a
|
||||
room had to books, a red one and a green one, and the user merely states the
|
||||
lust to read /a/ book.
|
||||
|
||||
*Tip:* If you get tired of typing long item names, you can choose to only type
|
||||
the last part of an item. Instead of typing 'capture magenta-coloured space
|
||||
creep', you can choose to simply type 'capture creep' or even 'capture p' (as
|
||||
the last letter in 'capture magenta-coloured space creep' is a p).
|
||||
|
||||
|
||||
*** =>var=
|
||||
This variable merely holds variables and their respective values. =var=
|
||||
variables can be used to store data. Looking at 'vars.zt' from Zeqy, we see,
|
||||
among other stuff, this (commented version):
|
||||
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
var = {
|
||||
# 'imposs' does not have to exist, though Zeqy needs it in the <span class='code'>default</span>
|
||||
# variable.
|
||||
'imposs': ['That\'s not an option.', 'I am unable to accomplish that \
|
||||
particular feat.', 'That seems out of the question.', 'Are you stupid?', 'I \
|
||||
could try, but I don\'t want to.', 'I\'m not doing that!', 'No way.'],
|
||||
|
||||
# 'listoptions' MUST exist. If Zita prompts a user to choose between
|
||||
# several items, a list is created using characters from 'listoptions'.
|
||||
'listoptions': 'abcdefghijklmnopqrstuvwxyz',
|
||||
# Using these list letters would result in multiple-choice scenarios
|
||||
# looking like this:
|
||||
|
||||
# > eat python
|
||||
# Which python?
|
||||
# <span class='b'>a</span>. dangerous python
|
||||
# <span class='b'>b</span>. Monty Python
|
||||
|
||||
# 'which' MUST exist. It holds what to output when multiple items are
|
||||
# available. The variable <span class='code'>what</span> holds the current
|
||||
# object specified by the user. In the above example, <span class='code'>what</span> would be python.
|
||||
'which': "'Which ' + what + '?'",
|
||||
|
||||
# 'invalidwhich' MUST exist. The value of this variable is output when
|
||||
# multiple items are available and the user attempts to get an item that
|
||||
# doesn't exist.
|
||||
'invalidwhich': "'Not a valid ' + what + '. Try again.'",
|
||||
#An example:
|
||||
|
||||
# > c
|
||||
# Not a valid python. Try again.
|
||||
|
||||
# 'steps' does not have to exist. It is self-explanatory.
|
||||
'steps': 0,
|
||||
|
||||
# 'inventory' MUST exist. Normally it should be an empty list, but it is of
|
||||
# course also possible to have the user start with one or more items.
|
||||
'inventory': [],
|
||||
|
||||
# 'location' MUST exist, though it isn't completely necessary to have it
|
||||
# defined here. Mostly, writing a <span class='code'>goto</span> function in the main file is better
|
||||
# than defining the room here. Defining the room here means that the user
|
||||
# will not see a startup message describing the current location.
|
||||
'location': None,
|
||||
|
||||
# 'points' does not necessarily have to exist. Zita doesn't depend on it.
|
||||
'points': 0
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Variables are useful.
|
||||
|
||||
|
||||
*** =>command=
|
||||
If Zita is unable to match a user-typed command with a user-typed object, it
|
||||
checks if a command independent of items matches. A command can be short ones
|
||||
such as:
|
||||
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
command = {
|
||||
'steps': "p('You have taken ' + str(var['steps']) + ' steps.')"
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
..Though it can also include more complex commands, such as:
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
command = {
|
||||
'go': # It's the common 'go' command!
|
||||
"""
|
||||
if len(cmd) == 1: # cmd is a list containing user input split with spaces.
|
||||
p('You can\\'t go nowhere.')
|
||||
else:
|
||||
ltd = long2dir(cmd[1]) # Converts 'north' to 'n', etc.
|
||||
if not 'dir' in room[var['location']]:
|
||||
p('You are trapped!')
|
||||
elif cmd[1] != '&rest' and ltd in room[var['location']]['dir']:
|
||||
rname = room[var['location']]['dir'][ltd]
|
||||
if rname[0] == '!':
|
||||
exec(rname[1:]) # Only execute what's after the exclamation mark.
|
||||
else:
|
||||
goto(rname) # Use the <span class='code'>goto</span> function
|
||||
elif '&rest' in room[var['location']]['dir']: # Default action
|
||||
rname = room[var['location']]['dir']['&rest']
|
||||
if rname[0] == '!':
|
||||
exec(rname[1:])
|
||||
else:
|
||||
goto(rname)
|
||||
else: # Converts 'w' to 'west', etc.
|
||||
p('It is not possible to go ' + short2dir(txt[len(cmd[0])+1:]) + '.')
|
||||
"""
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
If no available item has a command named 'go', the above code will be executed
|
||||
in the case of a 'go' request. Typing 'go s', 'go west' and other variations
|
||||
can, however, end up being annoying (if you're lazy), so adding 's', 'west' and
|
||||
similar shortcut commands would easen playing a game. This can be done in the
|
||||
following way:
|
||||
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
command = {
|
||||
'n': # 'go n' shortcut
|
||||
"""
|
||||
txt = 'go ' + cmd[0] # Not really needed
|
||||
cmd = ['go', cmd[0]] # Fools the 'go' command
|
||||
exec(command['go']) # Acts as if the program was the user
|
||||
""",
|
||||
# Applying more shortcuts are even easier:
|
||||
'ne': "exec(command['n'])"
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Item-independent commands can also be used to make people laugh.
|
||||
|
||||
*** =>default=
|
||||
|
||||
The =default= variable contains info on what to do when commands don't seem to
|
||||
exist. For example, it's tiresome to insert a 'get' commands in ever item we
|
||||
create. By using the default variable, we can create an item definition which
|
||||
acts as a shortcut. See below:
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
default = {
|
||||
'item': { # Default values for items
|
||||
'cmd': { # Either 'a', 'an', 'some', etc.
|
||||
'look': "p('It\\'s ' + getprefix(citem) + ' ' + item[citem]['name'] +
|
||||
'.')", # The <span class='code'>exec_proper_command</span> function will find the correct place to look
|
||||
# for a command. A hierachy is defined in Zeqy's defs.py.
|
||||
'lookat': "exec_proper_command('look', i, i_or_o, citem)",
|
||||
|
||||
# The rest is simple shortcut-shortcuts.
|
||||
'examine': "exec(default['item']['cmd']['lookat'])",
|
||||
'e': "exec(default['item']['cmd']['lookat'])",
|
||||
'l': "exec(default['item']['cmd']['lookat'])"
|
||||
},
|
||||
'out': {
|
||||
'get': # All items should be gettable by default.
|
||||
"""
|
||||
p('You take the ' + item[citem]['name'] + '.')
|
||||
inv(citem) # Adds item to inventory
|
||||
""",
|
||||
'take': "exec_proper_command('get', i, i_or_o, citem)",
|
||||
'g': "exec(default['item']['out']['take'])",
|
||||
't': "exec(default['item']['out']['take'])"
|
||||
}
|
||||
},
|
||||
|
||||
# 'item-substitutes' MUST exist. It is used as a reference to a previous item.
|
||||
# This specific property could just as well have been placed in the <span class='code'>var</span>
|
||||
# variable, but for now it must be in <span class='code'>default</span>.
|
||||
'item-substitutes': ['it'],
|
||||
|
||||
# Zita will print a random messages of the list when there is no command match.
|
||||
'command': "p(randelm(var['imposs']))",
|
||||
|
||||
# Code to execute when a load has been succesfully completed. Not strictly
|
||||
# necessary, but quite useful.
|
||||
'loaded': "p('Data succesfully loaded.\\n\\n')",
|
||||
|
||||
'room': { # Rooms can have default values too.
|
||||
# Will be shown if no room description exists.
|
||||
'desc': "'You have reached a ' + croom + '.'",
|
||||
|
||||
# Will be shown if no item description exists.
|
||||
'item': "'You see ' + getprefix(citem) + ' ' + item[citem]['name'] + '.'"
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Using defaults thereby make programming text adventures in Zita much easier.
|
||||
|
||||
|
||||
*** =>extra=
|
||||
Let's have another look at the zeqy directory:
|
||||
|
||||
#&pre
|
||||
commands.zt&del functions.zt LICENSE rooms.zt&del
|
||||
defaults.zt&del items.zt&del main.zt&del vars.zt&del
|
||||
#&
|
||||
|
||||
The only file we haven't had a look in is the 'functions.zt' file (LICENSE does
|
||||
not include Python code). The functions file contains.. functions. And global
|
||||
ones at that.
|
||||
|
||||
|
||||
#+BEGIN_SRC python2
|
||||
def point(p):
|
||||
# Adds points
|
||||
global var
|
||||
var['points'] += p
|
||||
#+END_SRC</pre>
|
||||
|
||||
There is no 'extra' file. The job of the =extra= variable is to hold
|
||||
information on dynamically created global content. Using the =extra_add=
|
||||
function, one can save and execute e.g. a function at the same time. While it
|
||||
would be easier to simply define a global function directly, problems would
|
||||
arise when saving and loading the progress in a game, as eventual global
|
||||
functions would not be saved/loaded. By storing them in the =extra= variable,
|
||||
this obstacle is overcome. The problem is that it gets a little messy in that a
|
||||
lot of backslashes may be needed to escape quote characters.</p>
|
||||
|
||||
But because functions in 'functions.zt' are defined when Zita loads a game and
|
||||
not dynamically, those functions do not have to reside inside =extra=.
|
||||
|
||||
|
||||
** Saving and loading progress
|
||||
Using the built-in =save and =code= functions, it's quite easy to create a command that
|
||||
keeps track of a player's progress. Saving and loading take place with the
|
||||
Python =pickle= module.
|
||||
|
||||
|
||||
** Footnote
|
||||
This short manual might not have covered everything there is to say about
|
||||
Zita. The best way to get an impression of Zita is to try it out. It's
|
||||
recommended to use a pre-existing Zita adventure (like Zeqy) as a base.
|
||||
|
||||
** Prominent languages/engines
|
||||
While I haven't actually used it, the [[http://adl.sourceforge.net/][Adventure Definition Language]] (ADL) seems
|
||||
to be pretty good. At least it's extensively documented. Other engines
|
||||
naturally exist too.
|
||||
BIN
site/projects/zita/zita.tar.gz
Executable file
BIN
site/projects/zita/zita.tar.gz
Executable file
Binary file not shown.
Reference in New Issue
Block a user