Skip to content

Commit a31643f

Browse files
authored
Create showscript3.md
1 parent d756d48 commit a31643f

File tree

1 file changed

+358
-0
lines changed

1 file changed

+358
-0
lines changed

docs/showscript3.md

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
## Introduction
2+
ShowScript 3 is a programming language that allows you to schedule commands and other actions to be executed at specified timecodes. Here's what it looks like:
3+
4+
5+
```groovy
6+
ticks(0) {
7+
cmd {
8+
"broadcast Hello World!"
9+
}
10+
}
11+
12+
seconds(2) {
13+
cmd {
14+
"broadcast This will run 2 seconds after the show starts"
15+
}
16+
}
17+
18+
```
19+
20+
## Basic Concepts
21+
22+
At its core, a ShowScript is a text file (ending in the `.groovy` extension) that defines what actions should happen and when. The file is broken up into blocks of "Timecodes" with one or more blocks of "Actions" inside of them to be executed at that timecode.
23+
24+
### Timecodes
25+
26+
A Timecode block may be specified multiple ways:
27+
28+
#### Ticks `(ticks)`
29+
The fundamental time unit of the Minecraft server. 20 ticks is equal to 1 second.
30+
```groovy
31+
ticks(20) {
32+
...
33+
}
34+
```
35+
36+
#### Seconds (`seconds`)
37+
For you convenience, you can also use seconds as a unit for your timecode block:
38+
```groovy
39+
seconds(1) {
40+
...
41+
}
42+
```
43+
Fractional seconds are also supported:
44+
45+
```groovy
46+
seconds(1.5) {
47+
...
48+
}
49+
```
50+
51+
If you provide a fractional second that does not line up evenly on a tick, it will be rounded down to the nearest tick.
52+
53+
> Multiple actions in one tick will not always be run in the same order as they are written in the show file.
54+
{.is-warning}
55+
56+
### Actions
57+
Inside of your Timecode blocks, you can set any number of Actions to be executed at that timecode. ShowScript 3 supports a few different types of actions:
58+
59+
#### Command (`cmd`)
60+
Run a command in the console of your server. Any command from any plugin that can be run from console can be used! On MCParks, we primarily use commands from in-house custom plugins.
61+
```groovy
62+
cmd {
63+
"any command you can run in console"
64+
}
65+
```
66+
67+
#### Text (`text`)
68+
Display a piece of `text` to all players within `range` blocks of `x`/`y`/`z` in world `world`
69+
```groovy
70+
text {
71+
world = "world"
72+
x = 0
73+
y = 0
74+
z = 0
75+
text = "your text here"
76+
range = 10
77+
}
78+
```
79+
80+
### Show (`show`)
81+
82+
Start another show (either ShowScript 2 or 3)!
83+
84+
```groovy
85+
show {
86+
name = "showName"
87+
<argumentName> = <argValue> // arguments are only required if the show requires arguments. See the "Show arguments" section for more information
88+
// arguments are parsed as Strings right now; proper support for arbitrary scripts is coming soon
89+
}
90+
91+
```
92+
93+
### Comments
94+
95+
It's important to write comments in your code so other people know what's going on!
96+
97+
ShowScript 3 supports single line comments:
98+
```groovy
99+
// this is a comment
100+
```
101+
102+
and multi-line comments:
103+
```groovy
104+
/* this
105+
is
106+
a
107+
comment
108+
that spans
109+
multiple
110+
lines!
111+
*/
112+
```
113+
114+
### Show arguments
115+
116+
Sometimes, you may want to write a ShowScript that is reusable under different circumstances.
117+
118+
Say you want to write a show that sets the time of day using `/time set <timeOfDay>`, and you know you'll need one that runs `/time set day` and `/time set night`. You *could* write this as two separate shows:
119+
120+
121+
```groovy
122+
// setDay.groovy
123+
ticks(0) {
124+
cmd {
125+
"time set day"
126+
}
127+
}
128+
```
129+
130+
131+
```groovy
132+
// setNight.groovy
133+
ticks(0) {
134+
cmd {
135+
"time set night"
136+
}
137+
}
138+
```
139+
140+
But, ShowScript 3 lets you turn this show into a "function" that can be called with any input you want, like this:
141+
142+
```groovy
143+
// setTime.groovy
144+
show { timeOfDay ->
145+
ticks(0) {
146+
cmd {
147+
"time set ${timeOfDay}"
148+
}
149+
}
150+
}
151+
```
152+
153+
You can then use the `--args` flag when starting your show to specify the argument to pass: `/show start setTime --args "day"`, for example (yes, you need to wrap the string `"day"` in quotes. If you're interested in why, check out the . And since the `/time set <timeOfDay>` command can take *any* time of day,
154+
155+
156+
Your show can have more than one argument, too:
157+
```groovy
158+
// adder.groovy
159+
show { num1, num2 ->
160+
ticks(0) {
161+
cmd {
162+
"broadcast ${num1 + num2}"
163+
}
164+
}
165+
}
166+
```
167+
You would start this show with `/show start adder --args 1, 2` if you want `/broadcast 3` to be executed. Multiple arguments are separated with commas (`,`).
168+
## Advanced Concepts
169+
170+
### Variables
171+
172+
Sometimes there will be a string, number, or some other piece of data that repeats _constantly_ in your shows (coordinates, an armorstand's name, preamble to an `imagemap animate` command, etc). It's bad style to repeat this code over and over again, so you can use variables to avoid repetition.
173+
174+
#### Variable definition and assignment
175+
176+
Variables can be defined using the `def` keyword followed by a variable name:
177+
```groovy
178+
def myCoolVariable
179+
180+
```
181+
182+
You can assign variables for later use:
183+
```groovy
184+
myCoolVariable = 5
185+
```
186+
187+
You can also definite and assign a variable in one step, like this:
188+
```groovy
189+
def myCoolVariable = 5
190+
191+
def approximatelyPi = 3.1415
192+
193+
def isRyanCool = true
194+
```
195+
196+
Variable definition and assignment can happen outside of a timecode block and can be used anywhere in your show (it will be initialized when `/show start` is initially called)
197+
```groovy
198+
def imagemapAnimate = "imagemap animate 163 55 703 https://mcparks.us/images/WDW/MK/Tomorrowland/Space/Preshow1"
199+
200+
ticks(0) {
201+
cmd {
202+
"${imagemapAnimate}/001.png"
203+
}
204+
}
205+
206+
ticks(10) {
207+
cmd {
208+
"${imagemapAnimate}/002.png"
209+
}
210+
}
211+
```
212+
213+
Variable definition and assignment can happen in a timecode block, too, but the variable can only be used in that block (it will be initialized when the timecode block runs)
214+
```groovy
215+
ticks(0) {
216+
def location = "105 65 222"
217+
cmd {
218+
"asa animate ${location} ..."
219+
}
220+
221+
cmd {
222+
"imagemap animate ${location} ..."
223+
}
224+
}
225+
226+
ticks(10) {
227+
// this will produce an error
228+
cmd {
229+
"broadcast location is ${location}"
230+
}
231+
}
232+
233+
```
234+
235+
You can also define a variable outside a timecode block, but change its value in different timecode blocks:
236+
237+
```groovy
238+
def theNumber = 0
239+
ticks(1) {
240+
theNumber = theNumber + 1
241+
}
242+
243+
ticks(2) {
244+
theNumber = theNumber + 1
245+
}
246+
247+
ticks(3) {
248+
cmd {
249+
"broadcast theNumber is ${theNumber}" // will broadcast "theNumber is 2"
250+
}
251+
}
252+
253+
```
254+
255+
256+
257+
258+
### Programming
259+
260+
A lot of the power of ShowScript 3 comes from the fact that it's powered by the Groovy programming language. All [semantics](https://groovy-lang.org/semantics.html) of the Groovy programming language, including `if` statements/conditionals, `for`/`while` loops, and more.
261+
262+
> It's important that any code you run is PERFORMANT! If you think the code you're running might be resource intensive (looping over a lot of entities, running intense math every single tick, etc), ask in #technicians for guidance on how to accomplish your goal as performantly as possible!
263+
{.is-warning}
264+
265+
Here are examples of this power:
266+
267+
```groovy
268+
def imagemapAnimate = "imagemap animate 163 55 703 https://mcparks.us/images/WDW/MK/Tomorrowland/Space/Preshow1" // preamble for an imagemap animate command in the Space Mountain preshow monitor
269+
270+
for (int i=1; i<=42; i++) { // there are 42 frames in this video, named `001.png` to `042.png`
271+
def formattedNumber = String.format("%03d", i) // use Java's String formatting (which Groovy inherits) to format the number to 3 digits
272+
ticks(i*10) { // create a timecode block for every 10 ticks
273+
cmd {
274+
"${imagemapAnimate}/${formattedNumber}.png" // the commmand is the preamble we defined on line 1, followed by a '/', followed by the number of the frame, followed by .png
275+
}
276+
}
277+
}
278+
```
279+
280+
281+
282+
### Accessing server info
283+
284+
ShowScript 3 has some convenience methods for accessing information from the Minecraft server that you can use in programming to make certain decisions.
285+
> Be careful when accessing server information, especially when running methods on objects on `World`s, `Player`s, etc -- these methods have the power to change literally _anything_ on the server!
286+
{.is-warning}
287+
288+
289+
290+
291+
#### `world(String worldName)` (returns: [World](https://helpch.at/docs/1.12.2/org/bukkit/World.html))
292+
293+
Example usage:
294+
295+
```groovy
296+
ticks(0) {
297+
def time = world("world").getTime()
298+
if (time > 12000) {
299+
cmd {
300+
"broadcast it is night time"
301+
}
302+
} else {
303+
cmd {
304+
"broadcast it is day time"
305+
}
306+
}
307+
}
308+
```
309+
310+
#### `player(String playerName)` (returns: [Player](https://helpch.at/docs/1.12.2/org/bukkit/entity/Player.html))
311+
312+
Example usage:
313+
```groovy
314+
ticks(0) {
315+
def ryanLocation = player("RyanHecht_").getLocation()
316+
317+
cmd {
318+
"broadcast Ryan is at ${ryanLocation.getX()}, ${ryanLocation.getY()}, ${ryanLocation.getZ()}"
319+
}
320+
}
321+
```
322+
#### `location(String worldName, double x, double y, double z)` (returns: [Location](https://helpch.at/docs/1.12.2/org/bukkit/Location.html))
323+
324+
#### `location(World world, double x, double y, double z)`
325+
#### `location(double x, double y, double z)` (creates a location in the world called "world")
326+
327+
#### `onlinePlayers()` (returns List\<Player\>)
328+
Get a list of all the players on the server
329+
330+
#### `runningShows()` (returns List\<ShowScheduler\>)
331+
Get a list of all running shows
332+
333+
`ShowScheduler` has these methods:
334+
```java
335+
public String getName();
336+
337+
public int getSyntaxVersion();
338+
339+
public Integer getShowTaskId();
340+
341+
public void stopShow();
342+
343+
public int getTimecode();
344+
```
345+
346+
#### `isShowRunning(String showName)` returns `boolean`
347+
Returns `true` if a show of that name is running, otherwise `false`
348+
349+
### Other convenience methods
350+
351+
#### `sin(double angle)` (returns double)
352+
Get the mathematical sine of an angle
353+
354+
#### `cos(double angle)` (returns double)
355+
Get the mathematical cosine of an angle
356+
357+
#### `tan(double angle)` (returns double)
358+
Get the mathematical tangent of an angle

0 commit comments

Comments
 (0)