Project

Profile

Help

SharpScript » History » Sprint/Milestone 1

Vincent Le Goff, 01/25/2020 05:38 PM

1 1 Vincent Le Goff
h1. Scripting in project:cocomud-client
2
3
4
5
project:cocomud-client offers a simple yet easily-extendable scripting language.  This language can be used to describe macros, aliases or triggers, or more complex features in the MUD.
6
7
8
9
This document describes the syntax of SharpScript, gives examples and provides frequent questions at the bottom of each section.  If you want the answer to one of these questions, just click on the question, the answer will appear on the next line.
10
11
12
13
{{toc}}
14
15
16
17
h2. The SharpScript logic
18
19
20
21
The logic of the SharpScript can be summarized in two main ideas:
22
23
24
25
* Have a very easy-to-write language to perform simple functions ;
26
27
* Allow to include Python code in this language to perform more complex tasks.
28
29
30
31
As you will see, the syntax of the SharpScript is pretty light, but it already allows interesting features.  Should you need more, Python is here, and it's not exactly a limited alternative.
32
33
34
35
h2. Basic syntax
36
37
38
39
The SharpScript finds its name in its syntax.  As most MUD clients, a SharpScript command begins with a sharp symbol (@#@).  It can already feel like a constraint of some type, but maintaining the difference between commands to the server and to the clients is important.  Unlike most MUD clients, project:cocomud-client tries to not force symbol in user input.  If you want to send a message beginning with the sharp symbol, you can do so, unless you configure your client to interpret SharpScript as input.
40
41
42
43
h2. Commands
44
45
46
47
SharpScript features are kept in commands (or functions).  Both terms refer to the same thing in this documentation.  These commands can ask to create a [[Macro|macro]], an [[Alias|alias]], a [[Trigger|trigger]], send some message to the server, display some message to the client, prompt the client with a question, store some information about a character and so on.
48
49
50
51
Here's a single example:
52
53
54
55
<pre>
56
57
#say Hello!
58
59
</pre>
60
61
62
63
If you try this piece of SharpScript in an input that accepts SharpScript syntax, the client should display "Hello!" at the bottom of your screen.  The text should also be sent to the screen reader, spoken by it and displayed on a Braille display, if supported.
64
65
66
67
The @#say@ command that we have used is very simple:  It expects one argument, one information, which is the message to be displayed.
68
69
70
71
Frequent questions:
72
73
74
75
{{collapse(How to send a command with a sharp symbol (#) in it?)
76
77
By default, project:cocomud-client doesn't interfere with your playing.  When you are in the input field on the client, you cannot enter SharpScript unless you enable that setting.  So you can type about every symbol you want, none of them will be interpreted by the client.
78
79
80
81
However, at times, you really want to send sharp signs to the client while having SharpScript interpret part of your commands.  To do so, you must precede the sharp sign (#) with another one.  This syntax is only necessary at the beginning of a command or an argument:
82
83
84
85
<pre>
86
87
#say {{##I'm saying something with a #.}
88
89
</pre>
90
91
92
93
This will display: @#I'm saying something with a #.@
94
95
96
97
Notice that only the first sharp symbol had to be kept twice (at the beginning of the argument).  The other (at the end) didn't need to be escaped.
98
99
100
101
<pre>
102
103
##forward
104
105
</pre>
106
107
108
109
This will send @#forward@ to the client.
110
111
}}
112
113
114
115
h2. Arguments with spaces
116
117
118
119
If you try to display a message with spaces, it will not work:
120
121
122
123
<pre>
124
125
#say This character isn't feeling so well.
126
127
</pre>
128
129
130
131
Some commands take more than one argument, and to separate them, they use the space (we will see examples a little below).  Therefore, if you want to have spaces in your argument, you should surround it by braces ({}) :
132
133
134
135
<pre>
136
137
#say {This character isn't feeling so well.}
138
139
</pre>
140
141
142
143
Surrounding arguments by braces is only necessary if this argument contains spaces.  Consider the following example, to create a [[Macro|macro]]:
144
145
146
147
<pre>
148
149
#macro F1 north
150
151
</pre>
152
153
154
155
This time, the @#macro@ command expects two arguments:
156
157
158
159
* The shortcut to which this macro should react.
160
161
* The action to be performed.
162
163
164
165
Here, when we press F1, the client will send "north" to the server.
166
167
168
169
Remember to enclose the arguments containing spaces, however:
170
171
172
173
<pre>
174
175
#macro {Ctrl + F1} north
176
177
</pre>
178
179
180
181
This time, the shortcut is Ctrl + F1. Because there are spaces in this argument, we enclose it in braces.
182
183
184
185
<pre>
186
187
#macro F8 {say Greetings!}
188
189
</pre>
190
191
192
193
When we press F8, the client will send "say greetings!" to the server.
194
195
196
197
<pre>
198
199
#macro {Ctrl + Shift + K} {look into backpack}
200
201
</pre>
202
203
204
205
Since both arguments contain spaces, we enclose them both.
206
207
208
209
Notice that if you have a doubt, use braces.  It will work regardless:
210
211
212
213
<pre>
214
215
#macro {F1} {north}
216
217
</pre>
218
219
220
221
h2. Multi-line scripts
222
223
224
225
By default, SharpScript expects every command to be on a different line.  This is not always a good thing for readability's sake, and sometimes it can get really complicated.
226
227
228
229
Let's say we want to create the [[Alias|alias]] as follows:  When we enter "victory", the client plays a sound and sends a few commands to the server:
230
231
232
233
<pre>
234
235
#alias victory {
236
237
    #play victory.wav
238
239
    say I've done it!
240
241
    north
242
243
    #wait 3
244
245
    sheathe sword
246
247
}
248
249
</pre>
250
251
252
253
The second argument is split on several lines, because it's much more readable.  Notice here that the argument contains SharpScript commands (beginning with a sharp symbol) and commands to be sent to the server.  The lines not beginning with a sharp symbol (#) are sent as it to the server.  This is the case for the line 3 (say I've done it!) for instance.
254
255
256
257
For readability, the second argument is indented a little on the right:  Each command in this second argument stands 4 space on the right.  This is not mandatory, it just makes things easier to understand.  Since Python relies on indentation however, it might be a good thing to get used to it, regardless of its being necessary or not.
258
259
260
261
Frequent questions:
262
263
264
265
{{collapse(Can I put several instructions on a single line?)
266
267
You can, although it might not be very readable.  The syntax to do so is to use semi-colons to separate commands on a single line.  The previous example could be written on a single line like this:
268
269
270
271
<pre>
272
273
#alias victory {#play victory.wav;say I've done it!;north;#wait 3;sheathe sword}
274
275
</pre>
276
277
278
279
As you can see, it's not as readable, but this syntax may sometimes be useful.
280
281
282
283
If you want o write a semi-colon in your SharpScript command, just put two semi-colons instead of one:
284
285
286
287
<pre>
288
289
#say {I would like to display something;; but I'm not sure what.}
290
291
</pre>
292
293
}}
294
295
296
297
h2. Flags
298
299
300
301
Some commands support flags:  Flags are here to influence the behavior of a function in some way.  The best example available at this time is the @#say@ command we have seen.  By default, it displays the provided text, sends it to the screen reader to be spoken, and to the Braille display to be displayed.  There are three flags that control that:
302
303
304
305
* "screen":  Should the text be displayed on the screen (as if it were coming from the server)?  If you don't change it, it's on by default.
306
307
* "speech":  Should the text be sent to the screen reader to be spoken aloud?  Once again, if not changed, it's on.
308
309
* "braille":  Should the text be sent to the Braille display?  Again, this flag is on by default.
310
311
312
313
You can change flags given to a command at the end of the SharpScript line (or instruction).  To set a flag on, write its name after a plus sign (+).  If you want to set this flag off, write its name after a minus sign (-).
314
315
316
317
<pre>
318
319
#say {I don't want it to be displayed.} -screen
320
321
#say {And that shouldn't be spoken nor displayed in Braille.} -speech -braille
322
323
#say {This may be displayed on screen and on the Braille display.} +screen -speech +braille
324
325
</pre>
326
327
328
329
Notice that the flags "screen" and "braille" are not necessary in the last example:  Both are on by default.  This example is here to illustrate the syntax.
330
331
332
333
h2. Embedding Python into SharpScript
334
335
336
337
Sometimes, what we want to do is a bit too complex in SharpScript.  It's possible to extend its syntax and bring new commands into it, but it's better to keep it simple and to learn to do more complex things with Python, which is a highly-readable language without few limitations.  It's still a good thing to keep your script readable, not only for you (although it might be handy, should you modify it), but to potential users.
338
339
340
341
To add Python code, use the syntax for long arguments (with braces), but after the left brace, add a plus sign (+).  This tells the client that what follows between the braces isn't SharpScript, but Python code.
342
343
344
345
If we want to write a script that plays different sounds depending on the XP we receive, we might do it that way:
346
347
348
349
<pre>
350
351
#trigger {You received {xp} XP.} {+
352
353
    # The 'xp' variable contains the received XP
354
355
    # It might be a number, but we have to convert it
356
357
    if xp.isdigit():
358
359
        if xp > 200:
360
361
            play("victory.wav")
362
363
        elif xp > 100:
364
365
            play("notbad.wav")
366
367
        elif xp > 10:
368
369
            play("notalot.wav")
370
371
}
372
373
</pre>
374
375
376
377
This trigger will wait for the line @"You received *** XP."@ and will put whatever XP in the 'xp' variable, before passing it to the Python script.  The Python script will convert the XP (if it's a number) and will play a different sound:
378
379
380
381
* If the received XP is over 200, it will play "victory.wav".
382
383
* If it's between 100 and 200, it will play "notbad.wav".
384
385
* If it's between 10 and 100, it will play "notalot.wav".
386
387
388
389
Notice that nothing happens if you receive less than 10 XP in this example.
390
391
392
393
It's very useful to embed Python code into SharpScript that way.  It makes for clear and readable scripts that are almost limitless.  Keep the indentation in this example, as it will be used by Python to determine blocks.
394
395
396
397
Frequent questions:
398
399
400
401
{{collapse(Which functions are available in embedded Python?)
402
403
All SharpScript commands are available as functions.  That's why you can use the @#play@ or @#say@ command.  Inside of Python, the commands are not preceded by a sharp sign and are just respect the function syntax:
404
405
406
407
<pre>
408
409
say("Could you display that?")
410
411
say("After all, just speak that.", screen=False)
412
413
play("sound/file.ogg")
414
415
</pre>
416
417
}}
418
419
{{collapse(What variables are available in embedded Python?)
420
421
Python scripts share their variable across the entire game setting.  This can sometimes be confusing, but it also prevents from bad headaches if you remember that no variable defined in a script will magically disappear unless you close the program.  Therefore, if you have a script like this:
422
423
424
425
<pre>
426
427
#alias todo {+
428
429
    health = 38
430
431
}
432
433
</pre>
434
435
436
437
The variable 'health' will be available in all other Python scripts.
438
439
440
441
In some cases, other variables are defined by the client.  For instance, the @#trigger@ command creates variables depending on the trigger.  For more information, read [[Trigger|the section about triggers]].
442
443
}}