# Celestia/Celx Scripting/CELX Lua Methods

This summary describes the support for Lua/CELX-scripting in Celestia and consists mostly of the CELX API. This documents as well as the CELX-support in Celestia probably contain a number of errors or bugs. Please report any problems you find.

## Introduction
### About this document

It was started to document the available functionality during development celestia v1.3.1pre11, and was then extended as new functionality was contributed.
CELX uses the Lua Programming Language, so you are writing real programs. This is completely different than older CEL Celestia scripts, which are just sequences of fixed commands. So you probably should have a little experience in programming, otherwise this document won't help you much.
It's also a good idea to read at least the first sections of the Lua-Documentation, available here:
* http://www.lua.org/manual/5.0/
* http://www.lua.org/manual/5.1/ (Celestia version 1.5.0 and later)

### How CELX works in Celestia

Celestia works roughly(!) by repeating this:
* Check user input, change rendering settings accordingly (e.g. enable rendering of orbits, change observer position/orientation)
* Update the simulation time
* Update the observer's position if goto is active
* Render all objects using the current settings (renderflags, time. positions)
If a CELX script has been started, it is executed just before rendering begins. Then Celestia gives control to the Lua interpreter, which continues to execute the script where it stopped the last time. When a CELX method is called in a script, e.g. celestia:print, the Lua interpreter invokes a small C++ function which converts the arguments from Lua types to C++ types, calls the right Celestia-methods to perform the action, and, if necessary, converts the C++ return value back to a Lua value. Note that the Lua interpreter called this C++ function, so when the function returns, the script continues: there is never a chance to return control back to the Celestia loop. To do this, the script has to call the wait function, which makes the Lua interpreter return control.
Forgetting to call wait in Celestia 1.3.1 meant that Celestia never gained control again, and thus couldn't handle the command to stop or quit the script - it was completely blocked. Starting with version 1.3.2, Celestia periodically checks if the script has exceeded the maximum allowed time to execute (5 seconds), and if it has, it terminates the script.
It should be apparent that most actions don't really change anything immediately. Instead, scripts change a setting which is used later on during rendering, which from the point of view of the script happens while calling wait. So if the position of the observer is changed ten times without calling wait in between, this will have no effect - only the last position will actually be used in rendering.

### Syntax

For a complete description of the syntax of Lua, please read http://www.lua.org/manual/5.0/ Celestia version 1.5.0 uses Lua version 5.1, which differs slightly from version 5.0 of Lua, used in earlier Celestia releases. The Lua 5.1 manual can be found at http://www.lua.org/manual/5.1/ For details about what changed between Lua versions 5.0 and 5.1, see http://www.lua.org/manual/5.1/manual.html#7
Some quick starting notes:
* Lua commands can be terminated either by a textual line terminator or by a semicolon. To include several Lua commands on a single line of text, separate them by semi-colons (;), but if there is only a single Lua command on a line of text, no semi-colon is needed.
* Write your CELX script by using a line editor like "Notepad", "Notepad++" or "Wordpad", without text formatting;
* Short (singleline) comments start with two hyphens "--";
* Long (multiline) comments use "--[[ comment ]]".
* When you use the comment "-- Title: string:text" in the first line of the CELX script, the string:text title will be displayed in the Celestia/File/Scripts drop down menu instead of the filename.
Example:

#### Variables & Types

Lua variables don't have to be declared and don't have a type, but the content has a type.
There are eight basic types in Lua:
* nil
** Nil is the type of the value nil, whose main property is to be different from any other value; it usually represents the absence of a useful value.
* boolean
** Boolean is the type of the values false and true. Both nil and false make a condition false; any other value makes it true.
* number
** Number represents real (double-precision floating-point) numbers.
* string
** String represents arrays of any 8-bit characters.
* table
** Tables can be used as arrays that can be indexed not only with numbers, but with any value (except nil). Tables also can contain values of all types (except nil).
* userdata
** The objects to control Celestia are of this special type userdata.
* function
** The function type is an executable expression, compiled from a block of Lua and CELX code.
* thread
** Not further explained here.
Example: The same variable "a" can have content of different type.
Example: A table can be used like this.
To operate on userdata, you can call methods for the objects. To use Lua for Celestia, you mostly need to know only about the available objects, the methods defined on them and how to call them - everybody who already knows Object-Oriented-Programming should feel right at home.
At the beginning of a script, the celestia object is automatically defined, holding a reference to the core-functionality of Celestia! To operate on this celestia object you can call methods which are defined on it by using the "celestia:" prefix, as shown in section celestia methods.
Example:
A function is an executable expression, compiled from a block of Lua and CELX code, whose value has type function.
A function can have arguments for input values and a function can also return zero, one or more values (see the Lua-documentation for details).
One or more functions can be defined at the beginning of your CELX script and they can be called once or several times from the main body of your CELX script.
Example:
The function "wait(number:n)" is predefined in Celestia and waits number:n seconds. It is special because it returns control to Celestia, which you have to do to avoid blocking Celestia.
Many more functions are defined in Lua (see Lua-docs), such as mathematical functions or string operations.
Notes:
* Not all Lua-libraries are loaded, you don't have access to io and debug-functions (which greatly reduces the danger of security problems from "evil" scripts). See the method celestia:requestsystemaccess for more information.

#### Control Structures

Lua has the typical control structures, like for, while, repeat and if.
Examples:

## Objects and Methods (The CELX API)

This section documents the userdata classes (object types) available in CELX Lua scripting.
Besides the predefined celestia object, there are also other celestia related objects to control Celestia. You can't create an object (i.e. userdata) yourself, you must call some method to create one. As you only have the celestia object (ignoring methods which are not Celestia related) available when the script is starting, you must use it to create other objects.
The following celestia related objects can be used within a CELX script:
* Observer object: An observer object is used to access properties specific to a view, such as viewer position, viewer orientation, frame of reference, and tracking status. To operate on an observer objects, you can call observer methods which are defined on them, as shown in section observer methods.
* Object objects: An "object" object in CELX refers to a celestial object like a planet or a star. To operate on "object" objects, you can call "object" methods which are defined on them, as shown in section object methods.
* Position objects: A position object contains the exact coordinates of a point in space. To operate on position objects, you can call position methods which are defined on them, as shown in section position methods.
* Vector objects: A vector object is a geometric object that has both a length and direction [X,Y,Z] in a 3-dimensional Coordinate System. To operate on vector objects, you can call vector methods which are defined on them, as shown in section vector methods.
* Rotation objects: A rotation object is internally a Quaternion, which is one possibility to mathematically describe a rotation in 3 dimensions (i.e. it can be converted to a rotation matrix). A rotation can also be used to describe the orientation of objects or the observer (i.e. where the observer is looking to, and where "up" is). To operate on rotation objects, you can call rotation methods which are defined on them, as shown in section rotation methods.
* Frame objects: The frame object describes the celestia coordinate cystem and tells how the X, Y, and Z, axes of each 3-dimensional coordinate system are aligned. Coordinate systems are well documented in the available Celestia .Cel Scripting Guide v1-0g by Don Goyette, in the chapter: "Coordinate Systems". To operate on frame objects, you can call frame methods which are defined on them, as shown in section frame methods.
* Phase objects: The timeline of an object can be subdivided into one or more phases. Each phase object has its own trajectory, rotation model, orbit frame, and body frame. To operate on phase objects, you can call phase methods which are defined on them, as shown in section phase methods.
* CELscript objects: A CELscript object contains a string with a valid CEL script, which can be imbedded in a CELX script by using the "celestia:createcelscript" method. To operate on CELscript objects, you can call CELscript methods which are defined on them, as shown in section CELscript methods.
Example: To call the method getposition of observer, you have to get an observer-instance from celestia first and then call getposition on it:
Notes:
* While using names for the various classes in this documentation, these names have no real meaning in a script. Even "celestia" is just a variable, holding an object of type celestia and is not really special.
In the following section, each method is listed with its signature:
return_value_type object:methodname(type:parameter, type:parameter [, type:optional parameter])
This is followed by:
* A short description of what the method does;
* A list of the arguments/parameters and what they are for;
* Possibly some notes about how to use this method, what it does exactly, some concerns etc..
* Finally an example about the usage of the method is given.

## Object and method index
### celestia

* 2.1.1. print
* 2.1.2. flash
* 2.1.3. show
* 2.1.4. hide
* 2.1.5. getrenderflags
* 2.1.6. setrenderflags
* 2.1.7. showlabel
* 2.1.8. hidelabel
* 2.1.9. getlabelflags
* 2.1.10. setlabelflags
* 2.1.11. getorbitflags
* 2.1.12. setorbitflags
* 2.1.13. getambient
* 2.1.14. setambient
* 2.1.15. getfaintestvisible
* 2.1.16. setfaintestvisible
* 2.1.17. getminorbitsize
* 2.1.18. setminorbitsize
* 2.1.19. getstardistancelimit
* 2.1.20. setstardistancelimit
* 2.1.21. getminfeaturesize
* 2.1.22. setminfeaturesize
* 2.1.23. getstarstyle
* 2.1.24. setstarstyle
* 2.1.25. find
* 2.1.26. getselection
* 2.1.27. select
* 2.1.28. mark
* 2.1.29. unmark
* 2.1.30. unmarkall
* 2.1.31. gettime
* 2.1.32. settime
* 2.1.33. gettimescale
* 2.1.34. settimescale
* 2.1.35. getscripttime
* 2.1.36. getobserver
* 2.1.37. getobservers
* 2.1.38. tojulianday
* 2.1.39. fromjulianday
* 2.1.40. getscreendimension
* 2.1.41. newvector
* 2.1.42. newposition
* 2.1.43. newposition (base64)
* 2.1.44. newrotation (axis-angle)
* 2.1.45. newrotation
* 2.1.46. newframe
* 2.1.47. requestkeyboard
* 2.1.48. requestsystemaccess
* 2.1.49. getscriptpath
* 2.1.50. takescreenshot
* 2.1.51. createcelscript
* 2.1.52. getstarcount
* 2.1.53. getstar
* 2.1.54. 1.5.0 getdsocount
* 2.1.55. 1.5.0 getdso
* 2.1.56. 1.5.0 utctotdb
* 2.1.57. 1.5.0 tdbtoutc
* 2.1.58. 1.5.0 stars
* 2.1.59. 1.5.0 dsos
* 2.1.60. 1.5.0 gettextwidth
* 2.1.61. 1.5.0 getaltazimuthmode
* 2.1.62. 1.5.0 setaltazimuthmode
* 2.1.63. 1.5.0 getoverlayelements
* 2.1.64. 1.5.0 setoverlayelements
* 2.1.65. 1.5.0 getgalaxylightgain
* 2.1.66. 1.5.0 setgalaxylightgain
* 2.1.67. 1.5.0 log
* 2.1.68. 1.5.0 registereventhandler
* 2.1.69. 1.5.0 geteventhandler
* 2.1.70. 1.5.0 setlabelcolor
* 2.1.71. 1.5.0 setlinecolor
* 2.1.72. 1.6.0 getlabelcolor
* 2.1.73. 1.6.0 getlinecolor
* 2.1.74. 1.6.0 getsystemtime
* 2.1.75. 1.6.0 showconstellations
* 2.1.76. 1.6.0 hideconstellations
* 2.1.77. 1.6.0 setconstellationcolor
* 2.1.78. 1.6.0 ispaused
* 2.1.79. 1.6.0 gettextureresolution
* 2.1.80. 1.6.0 settextureresolution
* 2.1.81. 1.6.0 windowbordersvisible
* 2.1.82. 1.6.0 setwindowbordersvisible
* 2.1.83. 1.6.1 synchronizetime
* 2.1.84. 1.6.1 istimesynchronized
* 2.1.85. 1.6.1 seturl
* 2.1.86. 1.6.1 geturl
* 2.1.87. 1.6.1 settextcolor
* 2.1.88. 1.6.1 gettextcolor
* 2.1.89. 1.6.1 runscript

### observer

* 2.2.1. goto
* 2.2.2. goto (table)
* 2.2.3. gotolonglat
* 2.2.4. gotolocation
* 2.2.5. gotodistance
* 2.2.6. gotosurface
* 2.2.7. center
* 2.2.8. centerorbit
* 2.2.9. travelling
* 2.2.10. cancelgoto
* 2.2.11. follow
* 2.2.12. synchronous
* 2.2.13. chase
* 2.2.14. lock
* 2.2.15. track
* 2.2.16. setposition
* 2.2.17. getposition
* 2.2.18. getorientation
* 2.2.19. setorientation
* 2.2.20. rotate
* 2.2.21. lookat
* 2.2.22. gettime
* 2.2.23. getspeed
* 2.2.24. setspeed
* 2.2.25. getsurface
* 2.2.26. setsurface
* 2.2.27. getlocationflags
* 2.2.28. setlocationflags
* 2.2.29. getfov
* 2.2.30. setfov
* 2.2.31. getframe
* 2.2.32. setframe
* 2.2.33. splitview
* 2.2.34. deleteview
* 2.2.35. singleview
* 2.2.36. isvalid
* 2.2.37. 1.5.0 gettrackedobject
* 2.2.38. 1.6.0 makeactiveview
* 2.2.39. 1.6.1 orbit

### object

* 2.3.1. radius
* 2.3.2. type
* 2.3.3. spectraltype
* 2.3.4. absmag
* 2.3.5. name
* 2.3.6. getinfo
* 2.3.7. mark
* 2.3.8. unmark
* 2.3.9. getposition
* 2.3.10. getchildren
* 2.3.11. preloadtexture
* 2.3.12. 1.5.0 setradius
* 2.3.13. 1.5.0 localname
* 2.3.14. 1.6.0 visible
* 2.3.15. 1.6.0 setvisible
* 2.3.16. 1.6.0 setorbitcolor
* 2.3.17. 1.6.0 orbitcoloroverridden
* 2.3.18. 1.6.0 setorbitcoloroverridden
* 2.3.19. 1.6.0 orbitvisibility
* 2.3.20. 1.6.0 setorbitvisibility
* 2.3.21. 1.6.0 addreferencemark
* 2.3.22. 1.6.0 removereferencemark
* 2.3.23. 1.6.0 catalognumber
* 2.3.24. 1.6.0 locations
* 2.3.25. 1.6.0 bodyfixedframe
* 2.3.26. 1.6.0 equatorialframe
* 2.3.27. 1.6.0 orbitframe
* 2.3.28. 1.6.0 bodyframe
* 2.3.29. 1.6.0 getphase
* 2.3.30. 1.6.0 phases

### position

* 2.4.1. addvector
* 2.4.2. vectorto
* 2.4.3. distanceto
* 2.4.4. orientationto
* 2.4.5. getx
* 2.4.6. gety
* 2.4.7. getz

### vector

* 2.5.1. getx
* 2.5.2. gety
* 2.5.3. getz
* 2.5.4. normalize
* 2.5.5. length

### rotation

* 2.6.1. imag
* 2.6.2. real
* 2.6.3. transform
* 2.6.4. setaxisangle
* 2.6.5. slerp

### frame

* 2.7.1. to
* 2.7.2. to (rotation)
* 2.7.3. from
* 2.7.4. from (rotation)
* 2.7.5. getcoordinatesystem
* 2.7.6. getrefobject
* 2.7.7. gettargetobject

### phase

1.6.0 Phases available only in Celestia 1.6.0 and later
* 2.8.1. 1.6.0 timespan
* 2.8.2. 1.6.0 orbitframe
* 2.8.3. 1.6.0 bodyframe
* 2.8.4. 1.6.0 getposition
* 2.8.5. 1.6.0 getorientation

### celscript

* 2.9.1. tick

## Object and method index (alphabetical)
### celestia

* createcelscript
* dsos 1.5.0
* find
* flash
* fromjulianday
* getaltazimuthmode 1.5.0
* getambient
* getdso 1.5.0
* getdsocount 1.5.0
* geteventhandler 1.5.0
* getfaintestvisible
* getgalaxylightgain 1.5.0
* getlabelcolor 1.6.0
* getlabelflags
* getlinecolor 1.6.0
* getminfeaturesize
* getminorbitsize
* getobserver
* getobservers
* getorbitflags
* getoverlayelements 1.5.0
* getrenderflags
* getscreendimension
* getscriptpath
* getscripttime
* getselection
* getstar
* getstarcount
* getstardistancelimit
* getstarstyle
* getsystemtime 1.6.0
* gettextcolor 1.6.1
* gettextureresolution 1.6.0
* gettextwidth 1.5.0
* gettime
* gettimescale
* geturl 1.6.1
* hide
* hideconstellations 1.6.0
* hidelabel
* ispaused 1.6.0
* istimesynchronized 1.6.1
* log 1.5.0
* mark
* newframe
* newposition
* newposition (base64)
* newrotation
* newrotation (axis-angle)
* newvector
* print
* registereventhandler 1.5.0
* requestkeyboard
* requestsystemaccess
* runscript 1.6.1
* select
* setaltazimuthmode 1.5.0
* setambient
* setconstellationcolor 1.6.0
* setfaintestvisible
* setgalaxylightgain 1.5.0
* setlabelcolor 1.5.0
* setlabelflags
* setlinecolor 1.5.0
* setminfeaturesize
* setminorbitsize
* setorbitflags
* setoverlayelements 1.5.0
* setrenderflags
* setstardistancelimit
* setstarstyle
* settextcolor 1.6.1
* settextureresolution 1.6.0
* settime
* settimescale
* seturl 1.6.1
* setwindowbordersvisible 1.6.0
* show
* showconstellations 1.6.0
* showlabel
* stars 1.5.0
* synchronizetime 1.6.1
* takescreenshot
* tdbtoutc 1.5.0
* tojulianday
* unmark
* unmarkall
* utctotdb 1.5.0
* windowbordersvisible 1.6.0

### celscript

* tick

### frame

* from
* from (rotation)
* getcoordinatesystem
* getrefobject
* gettargetobject
* to
* to (rotation)

### object

* absmag
* addreferencemark 1.6.0
* bodyfixedframe 1.6.0
* bodyframe 1.6.0
* catalognumber 1.6.0
* equatorialframe 1.6.0
* getchildren
* getinfo
* getphase 1.6.0
* getposition
* localname 1.5.0
* locations 1.6.0
* mark
* name
* orbitcoloroverridden 1.6.0
* orbitframe 1.6.0
* orbitvisibility 1.6.0
* phases 1.6.0
* preloadtexture
* radius
* removereferencemark 1.6.0
* setorbitcolor 1.6.0
* setorbitcoloroverridden 1.6.0
* setorbitvisibility 1.6.0
* setradius 1.5.0
* setvisible 1.6.0
* spectraltype
* type
* unmark
* visible 1.6.0

### observer

* cancelgoto
* center
* centerorbit
* chase
* deleteview
* follow
* getfov
* getframe
* getlocationflags
* getorientation
* getposition
* getspeed
* getsurface
* gettime
* gettrackedobject 1.5.0
* goto (table)
* goto
* gotodistance
* gotolocation
* gotolonglat
* gotosurface
* isvalid
* lock
* lookat
* makeactiveview 1.6.0
* orbit 1.6.1
* rotate
* setfov
* setframe
* setlocationflags
* setorientation
* setposition
* setspeed
* setsurface
* singleview
* splitview
* synchronous
* track
* travelling

### phase

1.6.0 Phases available only in Celestia 1.6.0 and later
* bodyframe 1.6.0
* getorientation 1.6.0
* getposition 1.6.0
* orbitframe 1.6.0
* timespan 1.6.0

### position

* addvector
* distanceto
* getx
* gety
* getz
* orientationto
* vectorto

### rotation

* imag
* real
* setaxisangle
* slerp
* transform

### vector

* getx
* gety
* getz
* length
* normalize

## Callbacks

Callbacks are functions which are executed as a result of external events.
Right now there are two callbacks available in Celestia:
* Keyboard callback.
* Cleanup callback.
Note: Callbacks are limited in what you can do:
* The callback must complete within 1 second, or it will be terminated;
* You CANNOT use the wait function in a callback !

## CEL to CELX migration

The following section contains an index of the available CEL commands. By clicking on a specific command, you will be routed to the explanation on its functionality and how that CEL command can be migrated to equivalent CELX objects and methods.

### CEL command index

The CEL commands below are organized following the sequence and explanation of CEL script commands in Celestia .Cel Scripting Guide v1-0g by Don Goyette. The explanations also contain many of Don's examples and syntax descriptions to aid in the migration from CEL to CELX.
Within this section, parameter values for CEL commands and CELX methods are printed like <type> or <name>. These parameter values need to be replaced when actually using these commands or methods.
Example:
Since Celestia version 1.6.0 and 1.6.1 the original listing of only 35 Cel commands has been expanded to 52 Cel commands. The additional commands are indicated with 1.6.0 and 1.6.1.
* cancel
* 1.6.0 capture
* center
* changedistance
* chase
* cls
* 1.6.0 constellationcolor
* 1.6.0 constellations
* 1.6.0 deleteview
* 1.6.0 exit
* follow
* goto
* gotoloc
* gotolonglat
* labels
* lock
* lookback
* mark
* move
* orbit
* 1.6.0 orbitflags
* preloadtex
* print
* renderflags
* 1.6.0 renderpath
* rotate
* select
* set
* 1.6.0 setactiveview
* 1.6.0 setambientlight
* setfaintestautomag45deg
* setframe
* 1.6.0 setgalaxylightgain
* 1.6.0 setlabelcolor
* 1.6.0 setlinecolor
* setorientation
* setposition
* 1.6.0 setradius
* setsurface
* 1.6.1 settextcolor
* 1.6.0 settextureresolution
* seturl
* setvisibilitylimit
* 1.6.0 singleview
* 1.6.0 splitview
* synchronous
* time
* timerate
* track
* unmark
* unmarkall
* wait

## Notes
### Typical Problems

* Lua scripts are executed between Celestia's rendering phases. So if you do some lengthy calculation (or an endless loop), Celestia won't be able to update the screen or even check for key presses (i.e. you can't stop the script by pressing [Esc] key). From the script's point of view, rendering and UI-handling only happen during calls to wait. If the script doesn't return control to Celestia for more than 5 seconds, then the script is terminated.
* If you want to move the observer smoothly, do this by setting its position and then call wait. But watch out: if "track" is activated on a body this can override any observer:setorientation in the script. A high time rate will change the position of planets significantly before they are rendered, which can result in a jerky movement. If necessary, check and reset time and timerate in your script.
* On Windows wait can return very quickly without doing any rendering, while on Linux it reliably enforces a rendering pass.
* The user can change settings while a script is running, including which body is selected, position, orientation, speed, timerate, renderflags etc. Don't rely on these to stay constant, if necessary you have to continuously reset them.
* Reference frames can be difficult to master at first. If you are trying to set the observer to a position within the Solar System, but get distances to the Sun of about 206 au instead, you probably got your reference-frame wrong. Before version 1.5.0, 206 AU is the distance between the point of origin [0,0,0] in universal coordinates and the position of the Sun. Starting with version 1.5.0, Celestia places the Solar System's barycenter at [0,0,0].
* If your script turns your screen completely black or other weird effects occur, check for any usage of observer:setorientation or observer:lookat. You probably have your orientation set to an "invalid" quaternion (for example all zero), possibly by using observer:lookat with your up-vector parallel to the direction of view. If this happens, you should get Celestia usable again by running a script which sets the orientation to some sensible value (or simply by restarting Celestia).