1Me and My Shadow Script API Reference
2=====================================
3
4(draft)
5
6The script language is Lua 5.2 (later we may bump it to 5.3).
7
8Always check `ScriptAPI.cpp` for the newest API changed unmentioned in this document.
9
10How to edit script
11==================
12
13To edit the script of a block, right click the block and select "Scripting".
14
15To edit the script of the level, right click the empty space of the level and select "Scripting".
16
17Currently the scenery block doesn't support scripting.
18
19Available event types of block:
20
21Event type            | Description
22----------------------|--------------
23"playerWalkOn"        | Fired once when the player walks on. (For example this is used in fragile block.)
24"playerIsOn"          | Fired every frame when the player is on.
25"playerLeave"         | Fired once when the player leaves.
26"onCreate"            | Fired when object creates.
27"onEnterFrame"        | Fired every frame.
28"onPlayerInteraction" | Fired when the player press DOWN key. Currently this event only fires when the block type is TYPE_SWITCH.
29"onToggle"            | Fired when the block receives "toggle" from a switch/button. NOTE: The switch/button itself will also receive this event. This is used in an old example found on my old computer.
30"onSwitchOn"          | Fired when the block receives "switch on" from a switch/button. NOTE: The switch/button itself will also receive this event. This is used in an old example found on my old computer.
31"onSwitchOff"         | Fired when the block receives "switch off" from a switch/button. NOTE: The switch/button itself will also receive this event. This is used in an old example found on my old computer.
32
33NOTE: During the event execution the global variable `this` temporarily points to current block. (Ad-hoc workaround!)
34When the event execution ends the global variable `this` is reset to its previous value.
35
36The block event may return an integer value (default is 0) to alter the game logic:
37
38Return value | Description
39-------------|--------------
400            | Skip the default game logic for this event.
411            | Do the default game logic for this event.
42
43Available event types of level:
44
45Event type | Description
46-----------|--------------
47"onCreate" | Fired when the level is created or the game is reset. This happens after all the blocks are created and their `onCreate` is called.
48"onSave"   | Fired when the game is saved.
49"onLoad"   | Fired when the game is loaded.
50
51For the newest lists of event types, see `init()` function in `Functions.cpp`.
52
53NOTE: the following methods to specify scripts can be used:
54
55* Specify scripts for each events in the block script editing dialog.
56* Only specify `onCreate` script in the block script editing dialog,
57  and use `setEventHandler()` function in script to specify scripts for other events dynamically.
58* Only specify `onCreate` script in the level script editing dialog,
59  and use `setEventHandler()` function in script to specify scripts for other events for level/blocks dynamically.
60
61Script API reference
62====================
63
64The "block" library
65-------------------
66
67### Static functions:
68
69* getBlockById(id)
70
71Returns the first block with specified id. If not found, returns `nil`.
72
73Example:
74
75~~~lua
76local b=block.getBlockById("1")
77local x,y=b:getLocation()
78print(x..","..y)
79~~~
80
81* getBlocksById(id)
82
83Returns the list of all blocks with specified id.
84
85Example:
86
87~~~lua
88local l=block.getBlocksById("1")
89for i,b in ipairs(l) do
90  local x,y=b:getLocation()
91  print(x..","..y)
92end
93~~~
94
95### Member functions:
96
97* isValid() -- check the object is valid (i.e. not deleted, etc.)
98
99* moveTo(x,y)
100
101Move the block to the new position, update the velocity of block according to the position changed.
102
103Example:
104
105~~~lua
106local b=block.getBlockById("1")
107local x,y=b:getLocation()
108b:moveTo(x+1,y)
109~~~
110
111* getLocation()
112
113Returns the position of the block.
114
115Example: see the example for moveTo().
116
117* getBaseLocation()
118
119Returns the base position of the block. Mainly used for moving blocks.
120
121* setLocation(x,y)
122
123Move the block to the new position without updating the velocity of block.
124
125Example: omitted since it's almost the same as moveTo().
126
127* growTo(w,h)
128
129Resize the block, update the velocity of block according to the size changed.
130
131NOTE: I don't think the velocity need to be updated when resizing block, so don't use this function.
132
133Example: omitted since it's almost the same as setSize().
134
135* getSize()
136
137Returns the size of the block.
138
139Example:
140
141~~~lua
142local b=block.getBlockById("1")
143local w,h=b:getSize()
144print(w..","..h)
145~~~
146
147* getBaseSize()
148
149Returns the base size of the block. Mainly used for moving blocks.
150
151* setSize(w,h)
152
153Resize the block without updating the velocity of block.
154
155Example:
156
157~~~lua
158local b=block.getBlockById("1")
159local w,h=b:getSize()
160b:setSize(w+1,h)
161~~~
162
163* getType()
164
165Returns the type of the block (which is a string).
166
167Example:
168
169~~~lua
170local b=block.getBlockById("1")
171local s=b:getType()
172print(s)
173~~~
174
175* changeThemeState(new_state)
176
177Change the state of the block to new_state (which is a string).
178
179Example:
180
181~~~lua
182local b=block.getBlockById("1")
183b:changeThemeState("activated")
184~~~
185
186* setVisible(b)
187
188Set the visibility the block.
189
190NOTE: The default value is `true`. If set to `false` the block is hidden completely,
191the animation is stopped, can't receive any event, can't execute any scripts (except for `onCreate`),
192can't be used as a portal destination,
193doesn't participate in collision check and game logic, etc...
194
195NOTE: This is a newly added feature.
196If you find any bugs (e.g. if an invisible block still affects the game logic)
197please report the bugs to GitHub issue tracker.
198
199Example:
200
201~~~lua
202local b=block.getBlockById("1")
203if b:isVisible() then
204  b:setVisible(false)
205else
206  b:setVisible(true)
207end
208~~~
209
210* isVisible()
211
212Returns whether the block is visible.
213
214Example: see the example for setVisible().
215
216* getEventHandler(event_type)
217
218Returns the event handler of event_type (which is a string).
219
220Example:
221
222~~~lua
223local b=block.getBlockById("1")
224local f=b:getEventHandler("onSwitchOn")
225b:setEventHandler("onSwitchOff",f)
226~~~
227
228* setEventHandler(event_type,handler)
229
230Set the handler of event_type (which is a string). The handler should be a function or `nil`.
231Returns the previous event handler.
232
233Example:
234
235~~~lua
236local b=block.getBlockById("1")
237b:setEventHandler("onSwitchOff",function()
238  print("I am switched off.")
239end)
240~~~
241
242* onEvent(eventType)
243
244Fire an event to specified block.
245
246NOTE: The event will be processed immediately.
247
248Example:
249
250~~~lua
251local b=block.getBlockById("1")
252b:onEvent("onToggle")
253~~~
254
255NOTE: Be careful not to write infinite recursive code! Bad example:
256
257~~~lua
258-- onToggle event of a moving block
259this:onEvent("onToggle")
260~~~
261
262* isActivated() / setActivated(bool) -- get/set a boolean indicates if the block is activated
263  -- the block should be one of TYPE_MOVING_BLOCK, TYPE_MOVING_SHADOW_BLOCK, TYPE_MOVING_SPIKES,
264  TYPE_CONVEYOR_BELT, TYPE_SHADOW_CONVEYOR_BELT.
265
266* isAutomatic() / setAutomatic(bool) -- get/set a boolean indicates if the portal is automatic
267  -- the block should be TYPE_PORTAL
268
269* getBehavior() / setBehavior(str) -- get/set a string (must be "on", "off" or "toggle")
270  representing the behavior of the block -- the block should be TYPE_BUTTON, TYPE_SWITCH
271
272* getState() / setState(num) -- get/set a number (must be 0,1,2 or 3)
273  representing the state of a fragile block -- the block should be TYPE_FRAGILE
274
275* isPlayerOn() -- get a boolean indicates if the player is on -- only works for TYPE_BUTTON
276
277* getPathMaxTime() -- get the total time of the path of a moving block
278
279* getPathTime() / setPathTime(num) -- get/set the current time of the path of a moving block
280
281* isLooping() / setLooping(bool) -- get/set the looping property of a moving block
282
283* getSpeed() / setSpeed(num) -- get/set the speed of a conveyor belt. NOTE: 1 Speed = 0.08 block/s = 0.1 pixel/frame
284
285The "playershadow" library
286--------------------------
287
288### Global constants:
289
290* player
291
292The player object.
293
294* shadow
295
296The shadow object.
297
298### Member functions:
299
300* getLocation()
301
302Returns the location of player/shadow.
303
304Example:
305
306~~~lua
307local x,y=player:getLocation()
308print("player: "..x..","..y)
309x,y=shadow:getLocation()
310print("shadow: "..x..","..y)
311~~~
312
313* setLocation(x,y)
314
315Set the location of player/shadow.
316
317Example:
318
319~~~lua
320local x,y=player:getLocation()
321player:setLocation(x+1,y)
322~~~
323
324* jump([strength=13])
325
326Let the player/shadow jump if it's allowed.
327
328strength: Jump strength.
329
330Example:
331
332~~~lua
333player:jump(20)
334~~~
335
336* isShadow()
337
338Returns whether the current object is shadow.
339
340Example:
341
342~~~lua
343print(player:isShadow())
344print(shadow:isShadow())
345~~~
346
347* getCurrentStand()
348
349Returns the block on which the player/shadow is standing on. Can be `nil`.
350
351Example:
352
353~~~lua
354local b=player:getCurrentStand()
355if b then
356  print(b:getType())
357else
358  print("The player is not standing on any blocks")
359end
360~~~
361
362* isInAir() -- returns a boolean indicating if the player is in air
363
364* canMove() -- returns a boolean indicating if the player can move (i.e. not standing on shadow)
365
366* isDead() -- returns a boolean indicating if the player is dead
367
368* isHoldingOther() -- returns a boolean indicating if the player is holding other
369
370The "level" library
371-------------------
372
373### Static functions:
374
375* getSize() -- get the level size
376
377* getWidth() -- get the level width
378
379* getHeight() -- get the level height
380
381* getName() -- get the level name
382
383* getEventHandler(event_type) -- get the event handler
384
385* setEventHandler(event_type,handler) -- set the event handler, return the old handler
386
387* win() -- win the game
388
389* getTime() -- get the game time (in frames)
390
391* getRecordings() -- get the game recordings
392
393* broadcastObjectEvent(eventType,[objectType=nil],[id=nil],[target=nil])
394
395Broadcast the event to blocks satisfying the specified condition.
396
397NOTE: The event will be processed in next frame.
398
399Argument name | Description
400--------------|-------------
401eventType     | string.
402objectType    | string or nil. If this is set then the event is only received by the block with specified type.
403id            | string or nil. If this is set then the event is only received by the block with specified id.
404target        | block or nil. If this is set then the event is only received by the specified block.
405
406Example:
407
408~~~lua
409level.broadcastObjectEvent("onToggle",nil,"1")
410~~~
411
412The "delayExecution" library
413----------------------------
414
415### Static functions:
416
417* schedule(func,time,[repeatCount=1],[repeatInterval],[enabled=true],[arguments...])
418
419Schedule a delay execution of a given function after the given time.
420
421Argument name  | Description
422---------------|-------------
423func           | A function to be executed.
424time           | Time, given in frames (NOTE: 40 frames = 1 second). NOTE: If <=0 it is the same as =1.
425repeatCount    | The number of times the function will be executed. After such number of times executed, the delay execution will be removed from the list and get deleted. If =0 the delay execution object will be deleted soon. If <0 the function will be executed indefinitely.
426repeatInterval | The repeat interval. If it is `nil` then the `time` argument will be used instead. NOTE: If <=0 the repeat execution will be disabled at all and the repeatCount will be set to 1.
427enabled        | Enabled.
428arguments      | Optional arguments passed to the function.
429
430Return value: the delayExecution object.
431
432NOTE: If you want to update time/repeatCount during the function execution,
433notice that the time/repeatCount is updated BEFORE the function execution.
434
435NOTE: During the execution the global variable `this`
436temporarily points to current delay execution object. (Ad-hoc workaround!)
437When the execution ends the global variable `this` is reset to its previous value.
438
439Example:
440
441~~~lua
442local f=function()
443  local a
444  a=0
445  return(function(b)
446    shadow:jump()
447    print('obj1 '..this:getExecutionTime()..' '..a..' '..tostring(b))
448    a=a+2
449  end)
450end
451
452local obj1=delayExecution.schedule(f(),40*2,5,nil,nil,100)
453
454local obj2=delayExecution.schedule(
455function(o)
456  print('obj2 '..tostring(o:isValid()))
457  if not o:isValid() then
458    this:setFunc(f())
459  end
460end,40*1,-1,nil,nil,obj1)
461
462local obj3=delayExecution.schedule(
463function(o)
464  o:cancel()
465end,40*30,1,nil,nil,obj2)
466~~~
467
468### Member functions:
469
470* isValid() -- Check if it's valid, i.e. not removed from list.
471
472* cancel() -- Cancels a delay execution. The canceled delay execution will be removed from the list and can not be restored.
473
474* isEnabled()/setEnabled(bool) -- get/set enabled of a delay execution. A disabled one will not count down its timer.
475
476* getTime()/setTime(integer) -- get/set the remaining time until the next execution. NOTE: If <=0 it is the same as =1.
477
478* getRepeatCount()/setRepeatCount(integer) -- get/set the remaining repeat count. If =0 the object will get deleted soon. If <0 the function will be executed indefinitely.
479
480* getRepeatInterval()/setRepeatInterval(integer) -- get/set the repeat interval. NOTE: If <=0 then nothing happens.
481
482* getFunc()/setFunc(func) -- get/set the function to be executed. NOTE: The setFunc will return the original function.
483
484* getArguments()/setArguments(args...) -- get/set the arguments
485
486* getExecutionTime()/setExecutionTime(integer) -- get/set the number of times the function being executed. NOTE: this execution time doesn't affect the default logic.
487
488The "camera" library
489--------------------
490
491### Static functions:
492
493* setMode(mode) -- set the camera mode, which is "player" or "shadow"
494
495* lookAt(x,y) -- set the camera mode to "custom" and set the new center of camera
496
497The "audio" library
498-------------------
499
500NOTE: the following functions are not going to work if the sound/music volume is 0.
501
502### Static functions:
503
504* playSound(name[,concurrent=-1[,force=false[,fade=-1]]])
505
506Play a sound effect.
507
508Argument name | Description
509--------------|-------------
510name          | The name of the sound effect. Currently available: "jump", "hit", "checkpoint", "swap", "toggle", "error", "collect", "achievement".
511concurrent    | The number of times the same sfx can be played at once, -1 is unlimited. NOTE: there are 64 channels.
512force         | If the sound must be played even if all channels are used. In this case the sound effect in the first channel will be stopped.
513fade          | A factor to temporarily turn the music volume down (0-128). -1 means don't use this feature.
514
515Return value: The channel of the sfx. -1 means failed (channel is full, invalid sfx name, sfx volume is 0, etc.)
516
517* playMusic(name[,fade=true])
518
519Play a music.
520
521Argument name | Description
522--------------|-------------
523name          | The name of the song, e.g. "default/neverending" or "menu".
524fade          | Boolean if it should fade the current one out or not.
525
526* pickMusic() - pick a song from the current music list.
527
528* getMusicList()/setMusicList(name_of_the_music_list) - get/set the music list. Example: "default".
529
530* currentMusic() - get the current music.
531