-
Notifications
You must be signed in to change notification settings - Fork 0
/
textgame.txt
359 lines (288 loc) · 21.6 KB
/
textgame.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
Things that a text adventure world needs:
TABLES (and their columns)
users: username, password, salt, obj, email
objects: id, name, type, flags, desc, link, parent, owner
deleted: id
inventory: parent, child
locks: obj, lock
acl: obj, player, flags
messages: obj, succ, fail, osucc, ofail
objdata: obj, props, script
INITIAL OBJECTS
When the database is created, it is populated with two initial objects, as follows:
- The Universe (Room #0)
This is the root of the database; without it, there would be no place for any other objects to exist in.
- The parent of Room #0 is itself.
- Room #0 is owned by God (#1).
- God (Player #1)
This is the superuser account, allowing the server admin to log in and begin creating more objects.
- God's parent is initially #0, (there is nowhere else for it to be).
- Like all players, #1 is owned by itself.
Because of the importance of these two objects, the system will not allow them to be deleted, and certain flags will be enforced.
For example, player #1 will not be able to remove the Admin flag, and if it is found to be missing at server startup, it will be re-added.
TABLE DETAILS
users table:
Stores information about user accounts.
This is basically just a username and password pair that then links to the id of the player's object.
objects table:
Stores basic data about an object. This is the most important table in the database.
- id: The database ID of the object. This is a unique, non-null unsigned integer.
- name: A name for this object (String).
- Names do not need to be unique, with one exception: no object may be given the same name as a Player, to prevent impersonation.
- type: A type value (Player, Room, Action, Item, Script). This is set at creation and cannot be modified.
- flags: A set of boolean flags that modify the object (long integer).
- Flags have varying meaning depending on object type. Flags are listed elsewhere.
- desc: A description (String).
- Describes the object, and is seen when a player looks at the object.
- link: The ID of an object that this object links to. May be null.
- Setting the link of a Player, Item or Script to a valid container sets the object's home. These cannot be unlinked.
- Setting the link of an Action determines either a script to execute or a room to transport the player to.
- Setting the link of a Room currently has no effect.
- parent: The ID of the object that contains this object, i.e. the location of the object. Cannot be null.
- Cannot be explicitly set, but is set implicitly by moving the object.
- owner: An owner (ID), must be a Player's ID. Players always own themselves.
deleted table:
Contains a list of IDs whose objects have been marked as deleted.
When a user requests deletion of an object, it is flagged as deleted, and its ID is added to this table. This gives users a chance to undo.
When a new object is created, the first ID in this table (if any) is removed and claimed as the ID of the new object.
The details of the deleted object with that ID are then overwritten with those of the new object, and the old object is lost forever.
This system allows IDs to be reused and doesn't leave "holes" in the database.
inventory table: TODO: Inventory table nuked because an index on the objects table is just as fast, if not faster.
Stores which objects contain which other objects. This is a many-to-one relationship table.
This is basically just a fast lookup table to quickly get a list of objects contained by another.
The "parent" field of the objects table is authorative, and if needed, the inventory table can be entirely rebuilt from the objects table.
Every object must have a parent, and cannot have multiple parents, but can contain multiple child objects.
All objects must be able to trace their "ancestry" back to ID 0, forming a tree structure rooted at Room #0, whose "parent" is itself.
The ancestry constraint sensibly prevents an object from ever containing itself, its parent, or one of its ancestors.
Certain types of object are limited in what they can contain:
- Rooms: May contain any type, including other Rooms.
- A room's purpose is to contain other objects.
- Players: May contain Items, Scripts, Actions and even other Players, but not Rooms.
- A player may contain another in order to allow a player to "ride" or "carry" another.
- Items: May contain other Items, Scripts, and Actions, but not Rooms or Players.
- Scripts: Identical to Items.
- See SCRIPTS for explanation.
- Actions: Cannot contain anything.
- Actions exist almost as "labels" to be activated, and don't really have contents.
Fields:
- parent: The ID of the containing object.
- child: The ID of an object contained by parent.
messages table: TODO: Messages table nuked in favor of storing messages in properties (via props table).
Contains the values for the various messages that an object may have.
This will generally only contain rows for Actions and Items.
All values are varchars, and all may be null, in which case no message is displayed.
Fields:
- succ: A success message.
- For Actions, a player will see this message when they successfully invoke the Action.
- For Items, a player will see this message when they pick up the item.
- fail: A failure message.
- For Actions, a player will see this message when they fail the Action's lock, or the script invoked by the Action returns failure.
- For Items, a player will see this message when they fail to pick up an item.
- osucc: An external success message, which others nearby will see.
- The message will be automatically prepended by the player's name.
- For Actions, players in the same room will see this message when a player successfully uses the Action.
- For Actions linked to a room (Exits), replaces the standard "X has left" message when a player uses the exit.
- For Items, players in the same room will see this message when a player successfully picks up the item.
- ofail: An external failure message, which others nearby will see.
- The message will be automatically prepended by the player's name.
- For actions, this message is seen by others in the same room when a player fails the action's lock, or a linked script fails.
- For Items, this message is seen seen by other players in the room when a player fails to pick up the item.
- drop: Similar to success value.
- The message will be automatically prepended by the player's name.
- For Exits, this message is broadcast to all players in the destination room, replacing the standard "X has arrived" message.
- For Items, this message is seen by other players in the room where a player drops this item.
- There is no "drop fail" message.
locks table:
This is a many-to-many relationship table, holding the individual values from an object's basic lock list.
acl table:
This is a many-to-many relationship table, holding the individual values from an object's access control list.
Each entry has associated flags that specify what level of access that player has to this object.
- acl: An access list, basically a list of player IDs with permission to modify this object. Access lists are inherited from the parent.
- props: Properties, which is an arbitrary dictionary of string key/value pairs, whose values may themselves be a dictionary.
TODO: Should this say flags instead of properties?
TODO: Messages replaced by properties. The properties are:
@desc: _/desc
@succ: _/succ
@osucc: _/osucc
@fail: _/fail
@ofail: _/ofail
@drop: _/drop
@odrop: _/odrop
FLAGS
G: God
- Script: allows it to use all functions without restriction. Warning! This basically lets a script run "as root".
- Player: makes that Player a God (Superadmin). This lets them stop the server, so be careful!
A: admin
- Script: allows it to use admin functions. Warning! This lets the script do powerful things.
- Player: makes that Player an admin.
M: moderator
H: helper
a: ACCESSLIST
- Activates ACLs on the object. See ACCESS LISTS for details. (Is this flag needed?)
e: ENVIRONMENT
- Only applicable to Rooms.
- Room: Marks this room as an Environment room. It becomes the default parent for any new Rooms created by a player standing in it or any non-Environment child rooms.
p: PUBLIC
- Room: Any user may now use this Room as a parent room (i.e. create child rooms in this room).
By default, only the owner of a room can use it as a parent for other rooms.
- Action: If this Action is in a user's inventory, then anyone in the same room can use the Action (safe?).
Note that actions made Public in this way will not override existing ones; they are used only if no other exists.
These type of Actions can only run scripts, they cannot transport the invoking player anywhere. (Why not?)
- Script: The script may be executed by anyone. By default, scripts may only be executed by their owner.
- ??Item/Player: Any user may access the contents of this thing. (Needed/desirable?)
l: LINKABLE (public)
- Room: allows any player to set their home here, overriding the lock.
- Script: allows actions to be publically linked to the script, overriding the lock.
By default, the lock is checked.
i: INVISIBLE
- Item, Script, Action or Player: hides the item from the respective list (item's owner can still see it).
- Room: makes that room "dark", meaning that a Player cannot see any other Players or Items in the room (but can still hear them, unless Silent is also set).
s: SILENT
- A player may not set this flag on themselves.
- Item, Player: will cause messages to be suppressed when it enters or leaves a room, allowing movement without being noticed.
- Action: Suppresses the default messages that an action would produce in the absence of user-defined messages.
- On a Room, will cause silence within the room by preventing players from speaking and performing actions.
x: XLOCK
When checking the lock list, ALL of the locks must be passed instead of just one.
k: LOCKED
Marks the item as locked.
By default the lock list is checked anyway
The result of checking the lock list is inverted, so that players will pass the lock UNLESS they match it.
t: TRANSPARENT
- Room: causes messages from the parent room to be shown in this room, while messages in this room are broadcast into the parent room.
w: WARPABLE
- Room: Players and objects may warp (teleport) into this room.
- Item: Players and objects may warp to the same room as this item, only if the room is also warpable (?)
LOCKS
The general purpose of a lock is to control who can access or activate an object.
Modify access to an object is dealt with mainly through ACLs.
Locks are checked for different reasons depending on object type:
- Action: The lock list is checked when the user tries to trigger (use) the action.
- Script: The lock list is checked when a user tries to link an action to this script.
- Room: The lock list is checked when a user tries to drop an item in this room.
- Player: The lock list is checked when another player tries to pick up and carry this player.
- Item: The lock list is checked when a player tries to pick up this item.??
The owner of an object automatically passes the lock on that object no matter what the lock is set to.
The lock list is made up of a list of IDs. When the lock is checked, each ID in the list is first resolved to a boolean value as follows:
- Player ID: true only if it matches the ID of the player who triggered the lock check.
The most basic of locks, essentially just a simple list of allowed players.
- Item ID: true if the inventory of the triggering player contains an object with this ID.
This type of lock essentially requires a player to be carrying the correct "key".
This can be used e.g. to implement quest scenarios where a player must locate and obtain
some particular item in order to activate a device or open an exit.
- Script ID: Under the right conditions, the script is executed, and gives true if the script returns success, or false on failure.
This allows complex lock conditions to be built as a script.
- The script must either have the same owner as the locked object, or be set p:PUBLIC, otherwise it will resolve to false.
- Room and Action IDs are invalid, and will always resolve to false.
The resulting list of boolean values is then treated as follows:
- An empty list always results in false.
- If the list is not empty, the result is true if any one value is true (Logical OR).
- If the XLOCK flag is set, then all values must be true in order to give a true result (Logical AND).
- If LOCKED is set, then the triggering player will fail the lock if the result is false.
- Otherwise, the result is inverted, and the triggering player will fail the lock if the result is true.
The default for a new object is an empty list and no LOCKED flag, which means all lock checks will pass.
Setting the LOCKED flag will cause everyone to fail the lock. Subsequently adding a player's ID to the lock list will allow only them to use the object. This is fairly intuitive.
However adding a player's ID to the list WITHOUT setting the LOCKED flag will allow everyone EXCEPT the user in the list to use the object, that is, it locks that player out.
Note: The object's owner does not automatically pass if the object is locked - they must be explicitly allowed in the list.
NEW ITEMS
Newly-created items are treated as follows:
New Players:
Obviously only created upon a new user registering. The Player object will be created in the server's configured room for newbies.
By default, players are locked to themselves (to prevent accidents).
New Items, Scripts and Actions:
Will be created in the inventory of the creating player.
New Rooms:
The room containing the player is checked for the Environment (+e) flag. If it lacks this flag, then the room's parent is checked, and so on, until a room with the Environment flag is found (room #0 always has this flag). The new room will then be created as a parent of this room.
SCRIPTS
- A script is executed by making it the destination of an action. The script is run when the action is triggered.
- Like Items, the Destination field of a script sets its home.
- Scripts may not be directly executed - they must be run by an Action.
- Scripts can contain Actions, which if linked to the Script, makes them usable as a standalone item.
- By default an Action with a Script destination will succeed. However, Scripts may explicitly return failure, which causes the Action that called it to fail. The Action will also fail if a script contains errors.
- The success value holds the executable text of the script itself.
- The failure value and external values are unused at the current time.
- A script may access its own properties as a kind of persistant global storage. Generally though, such storage would be done on the Action that calls it. (Why?)
- The lock value controls who may link an Action to the script. Anyone may link to an unlocked script.
ACTIONS
- Actions can be invoked by a player and usually have some affect on the object referred to by the action's destination field.
- A Room destination will transport a player to that room, a Script destination will execute that script.
- An action cannot be linked to an Object, Player or Item.
- An action
- The action's Lock field determines who can successfully use/run the action.
- Actions cannot contain anything, they do not have an inventory.
- Visibility rules:
- When contained by a Room, or an Item/Script in a Room the action is usable by any Player in that room.
- When contained by a Player, or an Item/Script carried by a Player, only that Player can use the action.
ROOMS
A note on contents:
Players INTERACT. Rooms CONTAIN. Actions TRANSPORT. Items EXIST. Scripts MODIFY.
Players can be connected to, can perform actions, and can move between rooms.
Commands
There are two distinct types of commands.
At-commands (@commands) are prefixed by the @ symbol and are entered as "@create", "@quit", etc.
These commands generally modify or examine objects and are not generally useful during roleplay.
These commands CANNOT be overridden by Actions - the @ prefix designates it as a system command.
Natural commands are words like "look", "go", "inventory", or "help" and are invoked simply by typing the command's name.
These commands may be overridden by an Action with the same name, allowing their behaviour to be modified. They exist to facilitate roleplay through the use of natural language.
Some at-commands may have natural commands as an alias, to assist players who are used to other MU* systems. Like any natural command these aliases can be overridden, although the at-command itself cannot.
ADDENDUM:
The software provides a minimal set of @-commands (system commands) that provide basic functions: creating objects and rooms, recycling objects, modifying or viewing object flags and properties, see where you are and what objects/exits are here, teleport around, and give a basic inventory listing. Everything else is expected to be provided via scripts, as most admins will want to customize the behaviour of many commands anyhow. Since the @-commands cannot be overridden, this provides a failsafe should the worst happen.
BUILTIN COMMANDS
Default syntax:
@cmd target=value
@inv : lists what you're carrying, or what something contains
@look : prints name of room you're in, its description, and contents (excluding other rooms).
@build,@dig : creates a room.
@create : creates an item.
@action,@exit : creates an action.
@script : creates a script.
@recycle : marks an object as recycled, effectively deleting it.
@password : Changes your password (god can change anyone's password).
@name : Changes the name of an object.
@flag : Sets flags on an object.
@set : Sets properties on an object.
@examine,@ex : Dumps info about an object.
@props : Lists properties on an object.
@get : Gets a specific property value for an object.
@link,@home : Link an object to another
@teleport,@tel : Teleports you or an object to a location
@sweep : Sends an object home (default: all objects in this room)
@pay : Pay currency to a player or object
@quit : Disconnects you
@kick : Lets admins disconnect other players
INTERSCRIPT
Interscript is a simple substitution-based text processing language designed to be used within existing text strings. Here is an example string containing Interscript:
Hello, {[name:<me>]}! You're currently in {[name:[loc:<me>]]}. This text uses [name:<me>].
This might resolve to the following string:
Hello, God! You're currently in The Universe. This text uses [name:<me>].
Interscript is only parsed between curly braces. Specifically, the delimiters {[ ... ]} begin and end an Interscript block, but the square brackets form part of the script within.
Interscript consists almost solely of nested functions that perform string processing. Function calls are made using the following syntax:
[function_name:arg1,arg2,arg3]
This will call function_name with the arguments "arg1", "arg2" and "arg3".
If a function takes no arguments, the colon delimiter is omitted. Consider the following:
[noargs] - calls the noargs function with no arguments.
[onearg:] - calls the onearg function with the argument "" (empty string).
In Interscript, all data is represented as strings. However, some functions operate on certain kinds of data, such as numbers, booleans, or database IDs.
Integers: Strings are converted to integers the usual way. Examples: "123", "-7"
Floats: Floating point numbers are not currently supported.
Database IDs: A hash followed by a number, e.g. "#12345". An asterisk followed by a character name (e.g. "*God") will resolve to the database ID of that player object
Booleans: The values "0" and "" (empty string) will evaluate as False, all other values are True. Functions that return booleans will return "1" for True and "0" for False.
The following functions are currently defined. Function names are case-insensitive.
<me>
Contains the dbref of the player executing the Interscript.
<this>
Contains the dbref of the object that contains this Interscript.
<cmd>
Contains the name of the Action that triggered this Interscript to be parsed.
<arg>
Contains any text that follows the Action that triggered this Interscript.
[name:dbref]
Takes a dbref as argument. Returns the name of the object referred to.
[loc:dbref]
Takes a dbref as argument. Returns the dbref of the object's parent.
[null:str]
Takes any string. Returns the empty string. Used to suppress output.
[eval:str]
Takes any string. Evaluates any Interscript contained within the string and returns the result.
[owner:dbref]
Takes a dbref. Returns the dbref of the object that owns the provided object.