singe/zbstudio/packages/singe/api-de.lua

7967 lines
452 KiB
Lua

-- Singe's API for ZeroBrane Studio's autocompletion and tooltips (de).
-- Generated by util/zbstudioApi.py from the Reference and Singe's own globals; do not edit.
return {
BILLBOARD_ALL = {
type = "value",
description = "Wie ein Knoten sich der Kamera zuwendet, für nodeSetBillboard.\n= 1",
},
BILLBOARD_NONE = {
type = "value",
description = "Wie ein Knoten sich der Kamera zuwendet, für nodeSetBillboard.\n= 0",
},
BILLBOARD_Y = {
type = "value",
description = "Wie ein Knoten sich der Kamera zuwendet, für nodeSetBillboard.\n= 2",
},
BODY_DYNAMIC = {
type = "value",
description = "Körpertypen für bodyNew.\n= 1",
},
BODY_KINEMATIC = {
type = "value",
description = "Körpertypen für bodyNew.\n= 2",
},
BODY_STATIC = {
type = "value",
description = "Körpertypen für bodyNew.\n= 0",
},
COLLIDE_FLOOR = {
type = "value",
description = "Wovon Partikel abprallen, für emitterSetCollide.\n= 1",
},
COLLIDE_NONE = {
type = "value",
description = "Wovon Partikel abprallen, für emitterSetCollide.\n= 0",
},
COLLIDE_SCENE = {
type = "value",
description = "Wovon Partikel abprallen, für emitterSetCollide.\n= 2",
},
Colourb = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ alpha, blue, green, red, rgba }",
},
__setters = {
type = "value",
description = "{ alpha, blue, green, red, rgba }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
Colourf = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ alpha, blue, green, red, rgba }",
},
__setters = {
type = "value",
description = "{ alpha, blue, green, red, rgba }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
Context = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
CloseDataModel = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
CreateDocument = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsMouseInteracting = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
LoadDocument = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
OpenDataModel = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessKeyDown = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessKeyUp = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessMouseButtonDown = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessMouseButtonUp = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessMouseLeave = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessMouseMove = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessMouseWheel = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ProcessTextInput = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Render = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
UnloadAllDocuments = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
UnloadDocument = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Update = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ dimensions, documents, dp_ratio, focus_element, hover_element, name, root_element }",
},
__setters = {
type = "value",
description = "{ dimensions, dp_ratio }",
},
},
},
ContextDocumentsProxy = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
DEBUG_ALL = {
type = "value",
description = "Was physicsSetDebug zeichnet; addiere sie.\n= 15",
},
DEBUG_CONSTRAINTS = {
type = "value",
description = "Was physicsSetDebug zeichnet; addiere sie.\n= 2",
},
DEBUG_CONTACTS = {
type = "value",
description = "Was physicsSetDebug zeichnet; addiere sie.\n= 4",
},
DEBUG_NONE = {
type = "value",
description = "Was physicsSetDebug zeichnet; addiere sie.\n= 0",
},
DEBUG_SHAPES = {
type = "value",
description = "Was physicsSetDebug zeichnet; addiere sie.\n= 1",
},
DEBUG_STATIC = {
type = "value",
description = "Was physicsSetDebug zeichnet; addiere sie.\n= 16",
},
DEBUG_VELOCITIES = {
type = "value",
description = "Was physicsSetDebug zeichnet; addiere sie.\n= 8",
},
DIR = {
type = "value",
description = "Pfade in einem Skript sind relativ zu dem Ordner, aus dem Singe gestartet wurde, nicht zum Skript. Verwende die globale Variable DIR, die Framework.singe auf den eigenen Ordner des Skripts setzt, damit ein Spiel funktioniert, egal wo es installiert ist:",
},
DISC_EJECTED = {
type = "value",
description = "Rückgabewerte von discGetState.\n= 5",
},
DISC_PAUSED = {
type = "value",
description = "Rückgabewerte von discGetState.\n= 4",
},
DISC_PLAYING = {
type = "value",
description = "Rückgabewerte von discGetState.\n= 3",
},
DISC_STOPPED = {
type = "value",
description = "Rückgabewerte von discGetState.\n= 2",
},
Document = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Close = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
CreateElement = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
CreateTextNode = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Hide = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
PullToFront = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
PushToBack = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Show = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, context, first_child, id, inner_rml, last_child, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, style, tag_name, title }",
},
__setters = {
type = "value",
description = "{ class_name, id, inner_rml, scroll_left, scroll_top, title }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
DocumentFocus = {
type = "lib",
description = "",
childs = {
Auto = {
type = "value",
description = "= 3",
},
Document = {
type = "value",
description = "= 1",
},
Keep = {
type = "value",
description = "= 2",
},
None = {
type = "value",
description = "= 0",
},
},
},
DocumentModal = {
type = "lib",
description = "",
childs = {
Keep = {
type = "value",
description = "= 2",
},
Modal = {
type = "value",
description = "= 1",
},
None = {
type = "value",
description = "= 0",
},
},
},
EASE_BACK_IN = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 13",
},
EASE_BACK_IN_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 15",
},
EASE_BACK_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 14",
},
EASE_BOUNCE_IN = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 19",
},
EASE_BOUNCE_IN_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 21",
},
EASE_BOUNCE_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 20",
},
EASE_CUBIC_IN = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 4",
},
EASE_CUBIC_IN_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 6",
},
EASE_CUBIC_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 5",
},
EASE_ELASTIC_IN = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 16",
},
EASE_ELASTIC_IN_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 18",
},
EASE_ELASTIC_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 17",
},
EASE_EXPO_IN = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 10",
},
EASE_EXPO_IN_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 12",
},
EASE_EXPO_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 11",
},
EASE_LINEAR = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 0",
},
EASE_QUAD_IN = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 1",
},
EASE_QUAD_IN_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 3",
},
EASE_QUAD_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 2",
},
EASE_SINE_IN = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 7",
},
EASE_SINE_IN_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 9",
},
EASE_SINE_OUT = {
type = "value",
description = "Die Easing-Kurven sind die üblichen. EASE_LINEAR ist gar keine Kurve; EASE_QUAD_*, EASE_CUBIC_*, EASE_SINE_* und EASE_EXPO_* reichen von sanft bis scharf; EASE_BACK_* schießt über das Ziel hinaus und kommt zurück; EASE_ELASTIC_* federt; EASE_BOUNCE_* fällt und springt auf. Jede gibt es als _IN (langsam am Anfang), _OUT (langsam am Ende) und _IN_OUT (beides).\n= 8",
},
Element = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ Document, ElementForm, ElementFormControl, ElementFormControlInput, ElementFormControlSelect, ElementFormControlTextArea, ElementTabSet, ElementText }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, first_child, id, inner_rml, last_child, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, style, tag_name }",
},
__setters = {
type = "value",
description = "{ class_name, id, inner_rml, scroll_left, scroll_top }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementAttributesProxy = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
ElementChildNodesProxy = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
ElementForm = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Submit = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, first_child, id, inner_rml, last_child, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, style, tag_name }",
},
__setters = {
type = "value",
description = "{ class_name, id, inner_rml, scroll_left, scroll_top }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementFormControl = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, disabled, first_child, id, inner_rml, last_child, name, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, style, tag_name, value }",
},
__setters = {
type = "value",
description = "{ class_name, disabled, id, inner_rml, name, scroll_left, scroll_top, value }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementFormControlInput = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetSelection = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Select = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetSelection = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, checked, child_nodes, class_name, client_height, client_left, client_top, client_width, disabled, first_child, id, inner_rml, last_child, max, maxlength, min, name, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, size, step, style, tag_name, value }",
},
__setters = {
type = "value",
description = "{ checked, class_name, disabled, id, inner_rml, max, maxlength, min, name, scroll_left, scroll_top, size, step, value }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementFormControlSelect = {
type = "lib",
description = "",
childs = {
Add = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Remove = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, disabled, first_child, id, inner_rml, last_child, name, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, options, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, selection, style, tag_name, value }",
},
__setters = {
type = "value",
description = "{ class_name, disabled, id, inner_rml, name, scroll_left, scroll_top, selection, value }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementFormControlTextArea = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetSelection = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Select = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetSelection = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, cols, disabled, first_child, id, inner_rml, last_child, maxlength, name, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, rows, scroll_height, scroll_left, scroll_top, scroll_width, style, tag_name, value, wordwrap }",
},
__setters = {
type = "value",
description = "{ class_name, cols, disabled, id, inner_rml, maxlength, name, rows, scroll_left, scroll_top, value, wordwrap }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementInstancer = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ InstanceElement }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementPtr = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
ElementStyleProxy = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
ElementTabSet = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetPanel = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetTab = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ active_tab, attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, first_child, id, inner_rml, last_child, next_sibling, num_tabs, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, style, tag_name }",
},
__setters = {
type = "value",
description = "{ active_tab, class_name, id, inner_rml, scroll_left, scroll_top }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ElementText = {
type = "lib",
description = "",
childs = {
AddEventListener = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
AppendChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
As = {
type = "value",
description = "{ }",
},
Blur = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Click = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
DispatchEvent = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Focus = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementById = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
GetElementsByTagName = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
HasChildNodes = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
InsertBefore = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
IsClassSet = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Matches = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelector = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
QuerySelectorAll = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RemoveChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ReplaceChild = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
ScrollIntoView = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetAttribute = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
SetClass = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ attributes, child_nodes, class_name, client_height, client_left, client_top, client_width, first_child, id, inner_rml, last_child, next_sibling, offset_height, offset_left, offset_parent, offset_top, offset_width, owner_document, parent_node, previous_sibling, scroll_height, scroll_left, scroll_top, scroll_width, style, tag_name, text }",
},
__setters = {
type = "value",
description = "{ class_name, id, inner_rml, scroll_left, scroll_top, text }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
Event = {
type = "lib",
description = "",
childs = {
StopImmediatePropagation = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
StopPropagation = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ current_element, parameters, target_element, type }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
EventParametersProxy = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
FILTER_LINEAR = {
type = "value",
description = "Texturabtastung für materialSetFilter.\n= 0",
},
FILTER_NEAREST = {
type = "value",
description = "Texturabtastung für materialSetFilter.\n= 1",
},
FONT_QUALITY_BLENDED = {
type = "value",
description = "Argumente für fontQuality.\n= 3",
},
FONT_QUALITY_SHADED = {
type = "value",
description = "Argumente für fontQuality.\n= 2",
},
FONT_QUALITY_SOLID = {
type = "value",
description = "Argumente für fontQuality.\n= 1",
},
GAMEPAD_0 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
AXIS_LEFT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER\", value = 512 }",
},
AXIS_LEFT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_N\", value = 513 }",
},
AXIS_LEFT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_P\", value = 514 }",
},
AXIS_LEFT_X = {
type = "value",
description = "{ name = \"AXIS_LEFT_X\", value = 500 }",
},
AXIS_LEFT_X_L = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_L\", value = 501 }",
},
AXIS_LEFT_X_R = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_R\", value = 502 }",
},
AXIS_LEFT_Y = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y\", value = 503 }",
},
AXIS_LEFT_Y_D = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_D\", value = 505 }",
},
AXIS_LEFT_Y_U = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_U\", value = 504 }",
},
AXIS_RIGHT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER\", value = 515 }",
},
AXIS_RIGHT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_N\", value = 516 }",
},
AXIS_RIGHT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_P\", value = 517 }",
},
AXIS_RIGHT_X = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X\", value = 506 }",
},
AXIS_RIGHT_X_L = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_L\", value = 507 }",
},
AXIS_RIGHT_X_R = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_R\", value = 508 }",
},
AXIS_RIGHT_Y = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y\", value = 509 }",
},
AXIS_RIGHT_Y_D = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_D\", value = 511 }",
},
AXIS_RIGHT_Y_U = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_U\", value = 510 }",
},
BUTTON_A = {
type = "value",
description = "{ name = \"BUTTON_A\", value = 518 }",
},
BUTTON_B = {
type = "value",
description = "{ name = \"BUTTON_B\", value = 519 }",
},
BUTTON_BACK = {
type = "value",
description = "{ name = \"BUTTON_BACK\", value = 522 }",
},
BUTTON_GUIDE = {
type = "value",
description = "{ name = \"BUTTON_GUIDE\", value = 523 }",
},
BUTTON_LEFT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_LEFT_BUMPER\", value = 527 }",
},
BUTTON_LEFT_STICK = {
type = "value",
description = "{ name = \"BUTTON_LEFT_STICK\", value = 525 }",
},
BUTTON_RIGHT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_BUMPER\", value = 528 }",
},
BUTTON_RIGHT_STICK = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_STICK\", value = 526 }",
},
BUTTON_START = {
type = "value",
description = "{ name = \"BUTTON_START\", value = 524 }",
},
BUTTON_X = {
type = "value",
description = "{ name = \"BUTTON_X\", value = 520 }",
},
BUTTON_Y = {
type = "value",
description = "{ name = \"BUTTON_Y\", value = 521 }",
},
DPAD_DOWN = {
type = "value",
description = "{ name = \"DPAD_DOWN\", value = 530 }",
},
DPAD_LEFT = {
type = "value",
description = "{ name = \"DPAD_LEFT\", value = 531 }",
},
DPAD_RIGHT = {
type = "value",
description = "{ name = \"DPAD_RIGHT\", value = 532 }",
},
DPAD_UP = {
type = "value",
description = "{ name = \"DPAD_UP\", value = 529 }",
},
},
},
GAMEPAD_1 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
AXIS_LEFT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER\", value = 612 }",
},
AXIS_LEFT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_N\", value = 613 }",
},
AXIS_LEFT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_P\", value = 614 }",
},
AXIS_LEFT_X = {
type = "value",
description = "{ name = \"AXIS_LEFT_X\", value = 600 }",
},
AXIS_LEFT_X_L = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_L\", value = 601 }",
},
AXIS_LEFT_X_R = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_R\", value = 602 }",
},
AXIS_LEFT_Y = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y\", value = 603 }",
},
AXIS_LEFT_Y_D = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_D\", value = 605 }",
},
AXIS_LEFT_Y_U = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_U\", value = 604 }",
},
AXIS_RIGHT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER\", value = 615 }",
},
AXIS_RIGHT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_N\", value = 616 }",
},
AXIS_RIGHT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_P\", value = 617 }",
},
AXIS_RIGHT_X = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X\", value = 606 }",
},
AXIS_RIGHT_X_L = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_L\", value = 607 }",
},
AXIS_RIGHT_X_R = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_R\", value = 608 }",
},
AXIS_RIGHT_Y = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y\", value = 609 }",
},
AXIS_RIGHT_Y_D = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_D\", value = 611 }",
},
AXIS_RIGHT_Y_U = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_U\", value = 610 }",
},
BUTTON_A = {
type = "value",
description = "{ name = \"BUTTON_A\", value = 618 }",
},
BUTTON_B = {
type = "value",
description = "{ name = \"BUTTON_B\", value = 619 }",
},
BUTTON_BACK = {
type = "value",
description = "{ name = \"BUTTON_BACK\", value = 622 }",
},
BUTTON_GUIDE = {
type = "value",
description = "{ name = \"BUTTON_GUIDE\", value = 623 }",
},
BUTTON_LEFT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_LEFT_BUMPER\", value = 627 }",
},
BUTTON_LEFT_STICK = {
type = "value",
description = "{ name = \"BUTTON_LEFT_STICK\", value = 625 }",
},
BUTTON_RIGHT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_BUMPER\", value = 628 }",
},
BUTTON_RIGHT_STICK = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_STICK\", value = 626 }",
},
BUTTON_START = {
type = "value",
description = "{ name = \"BUTTON_START\", value = 624 }",
},
BUTTON_X = {
type = "value",
description = "{ name = \"BUTTON_X\", value = 620 }",
},
BUTTON_Y = {
type = "value",
description = "{ name = \"BUTTON_Y\", value = 621 }",
},
DPAD_DOWN = {
type = "value",
description = "{ name = \"DPAD_DOWN\", value = 630 }",
},
DPAD_LEFT = {
type = "value",
description = "{ name = \"DPAD_LEFT\", value = 631 }",
},
DPAD_RIGHT = {
type = "value",
description = "{ name = \"DPAD_RIGHT\", value = 632 }",
},
DPAD_UP = {
type = "value",
description = "{ name = \"DPAD_UP\", value = 629 }",
},
},
},
GAMEPAD_2 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
AXIS_LEFT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER\", value = 712 }",
},
AXIS_LEFT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_N\", value = 713 }",
},
AXIS_LEFT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_P\", value = 714 }",
},
AXIS_LEFT_X = {
type = "value",
description = "{ name = \"AXIS_LEFT_X\", value = 700 }",
},
AXIS_LEFT_X_L = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_L\", value = 701 }",
},
AXIS_LEFT_X_R = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_R\", value = 702 }",
},
AXIS_LEFT_Y = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y\", value = 703 }",
},
AXIS_LEFT_Y_D = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_D\", value = 705 }",
},
AXIS_LEFT_Y_U = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_U\", value = 704 }",
},
AXIS_RIGHT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER\", value = 715 }",
},
AXIS_RIGHT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_N\", value = 716 }",
},
AXIS_RIGHT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_P\", value = 717 }",
},
AXIS_RIGHT_X = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X\", value = 706 }",
},
AXIS_RIGHT_X_L = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_L\", value = 707 }",
},
AXIS_RIGHT_X_R = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_R\", value = 708 }",
},
AXIS_RIGHT_Y = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y\", value = 709 }",
},
AXIS_RIGHT_Y_D = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_D\", value = 711 }",
},
AXIS_RIGHT_Y_U = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_U\", value = 710 }",
},
BUTTON_A = {
type = "value",
description = "{ name = \"BUTTON_A\", value = 718 }",
},
BUTTON_B = {
type = "value",
description = "{ name = \"BUTTON_B\", value = 719 }",
},
BUTTON_BACK = {
type = "value",
description = "{ name = \"BUTTON_BACK\", value = 722 }",
},
BUTTON_GUIDE = {
type = "value",
description = "{ name = \"BUTTON_GUIDE\", value = 723 }",
},
BUTTON_LEFT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_LEFT_BUMPER\", value = 727 }",
},
BUTTON_LEFT_STICK = {
type = "value",
description = "{ name = \"BUTTON_LEFT_STICK\", value = 725 }",
},
BUTTON_RIGHT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_BUMPER\", value = 728 }",
},
BUTTON_RIGHT_STICK = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_STICK\", value = 726 }",
},
BUTTON_START = {
type = "value",
description = "{ name = \"BUTTON_START\", value = 724 }",
},
BUTTON_X = {
type = "value",
description = "{ name = \"BUTTON_X\", value = 720 }",
},
BUTTON_Y = {
type = "value",
description = "{ name = \"BUTTON_Y\", value = 721 }",
},
DPAD_DOWN = {
type = "value",
description = "{ name = \"DPAD_DOWN\", value = 730 }",
},
DPAD_LEFT = {
type = "value",
description = "{ name = \"DPAD_LEFT\", value = 731 }",
},
DPAD_RIGHT = {
type = "value",
description = "{ name = \"DPAD_RIGHT\", value = 732 }",
},
DPAD_UP = {
type = "value",
description = "{ name = \"DPAD_UP\", value = 729 }",
},
},
},
GAMEPAD_3 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
AXIS_LEFT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER\", value = 812 }",
},
AXIS_LEFT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_N\", value = 813 }",
},
AXIS_LEFT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_LEFT_TRIGGER_P\", value = 814 }",
},
AXIS_LEFT_X = {
type = "value",
description = "{ name = \"AXIS_LEFT_X\", value = 800 }",
},
AXIS_LEFT_X_L = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_L\", value = 801 }",
},
AXIS_LEFT_X_R = {
type = "value",
description = "{ name = \"AXIS_LEFT_X_R\", value = 802 }",
},
AXIS_LEFT_Y = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y\", value = 803 }",
},
AXIS_LEFT_Y_D = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_D\", value = 805 }",
},
AXIS_LEFT_Y_U = {
type = "value",
description = "{ name = \"AXIS_LEFT_Y_U\", value = 804 }",
},
AXIS_RIGHT_TRIGGER = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER\", value = 815 }",
},
AXIS_RIGHT_TRIGGER_N = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_N\", value = 816 }",
},
AXIS_RIGHT_TRIGGER_P = {
type = "value",
description = "{ name = \"AXIS_RIGHT_TRIGGER_P\", value = 817 }",
},
AXIS_RIGHT_X = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X\", value = 806 }",
},
AXIS_RIGHT_X_L = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_L\", value = 807 }",
},
AXIS_RIGHT_X_R = {
type = "value",
description = "{ name = \"AXIS_RIGHT_X_R\", value = 808 }",
},
AXIS_RIGHT_Y = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y\", value = 809 }",
},
AXIS_RIGHT_Y_D = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_D\", value = 811 }",
},
AXIS_RIGHT_Y_U = {
type = "value",
description = "{ name = \"AXIS_RIGHT_Y_U\", value = 810 }",
},
BUTTON_A = {
type = "value",
description = "{ name = \"BUTTON_A\", value = 818 }",
},
BUTTON_B = {
type = "value",
description = "{ name = \"BUTTON_B\", value = 819 }",
},
BUTTON_BACK = {
type = "value",
description = "{ name = \"BUTTON_BACK\", value = 822 }",
},
BUTTON_GUIDE = {
type = "value",
description = "{ name = \"BUTTON_GUIDE\", value = 823 }",
},
BUTTON_LEFT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_LEFT_BUMPER\", value = 827 }",
},
BUTTON_LEFT_STICK = {
type = "value",
description = "{ name = \"BUTTON_LEFT_STICK\", value = 825 }",
},
BUTTON_RIGHT_BUMPER = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_BUMPER\", value = 828 }",
},
BUTTON_RIGHT_STICK = {
type = "value",
description = "{ name = \"BUTTON_RIGHT_STICK\", value = 826 }",
},
BUTTON_START = {
type = "value",
description = "{ name = \"BUTTON_START\", value = 824 }",
},
BUTTON_X = {
type = "value",
description = "{ name = \"BUTTON_X\", value = 820 }",
},
BUTTON_Y = {
type = "value",
description = "{ name = \"BUTTON_Y\", value = 821 }",
},
DPAD_DOWN = {
type = "value",
description = "{ name = \"DPAD_DOWN\", value = 830 }",
},
DPAD_LEFT = {
type = "value",
description = "{ name = \"DPAD_LEFT\", value = 831 }",
},
DPAD_RIGHT = {
type = "value",
description = "{ name = \"DPAD_RIGHT\", value = 832 }",
},
DPAD_UP = {
type = "value",
description = "{ name = \"DPAD_UP\", value = 829 }",
},
},
},
GAMEPAD_AXIS_LEFT_TRIGGER = {
type = "value",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.\n= 4",
},
GAMEPAD_AXIS_LEFT_X = {
type = "value",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.\n= 0",
},
GAMEPAD_AXIS_LEFT_Y = {
type = "value",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.\n= 1",
},
GAMEPAD_AXIS_RIGHT_TRIGGER = {
type = "value",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.\n= 5",
},
GAMEPAD_AXIS_RIGHT_X = {
type = "value",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.\n= 2",
},
GAMEPAD_AXIS_RIGHT_Y = {
type = "value",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.\n= 3",
},
JOINT_BALL = {
type = "value",
description = "Gelenktypen (die joint*-Aufrufe nennen sie direkt).\n= 1",
},
JOINT_HINGE = {
type = "value",
description = "Gelenktypen (die joint*-Aufrufe nennen sie direkt).\n= 0",
},
JOINT_SLIDER = {
type = "value",
description = "Gelenktypen (die joint*-Aufrufe nennen sie direkt).\n= 2",
},
LAYER_FRONT = {
type = "value",
description = "Ob ein Knoten unter dem Overlay oder davor gezeichnet wird, für nodeSetLayer.\n= 1",
},
LAYER_SCENE = {
type = "value",
description = "Ob ein Knoten unter dem Overlay oder davor gezeichnet wird, für nodeSetLayer.\n= 0",
},
LIGHT_DIRECTIONAL = {
type = "value",
description = "Argumente für lightNew.\n= 0",
},
LIGHT_POINT = {
type = "value",
description = "Argumente für lightNew.\n= 1",
},
LIGHT_SPOT = {
type = "value",
description = "Argumente für lightNew.\n= 2",
},
Log = {
type = "lib",
description = "",
childs = {
Message = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
logtype = {
type = "value",
description = "{ always = 0, debug = 5, error = 1, info = 4, warning = 3 }",
},
},
},
LuaRmlUi = {
type = "lib",
description = "",
childs = {
CreateContext = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
LoadFontFace = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
RegisterTag = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ contexts, key_identifier, key_modifier }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
MANY_MOUSE = {
type = "value",
description = "Argumente für mouseSetMode.\n= 200",
},
MODE_FULL = {
type = "value",
description = "Argumente für keyboardSetMode.\n= 1",
},
MODE_NORMAL = {
type = "value",
description = "Argumente für keyboardSetMode.\n= 0",
},
MODIFIER = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
ALT = {
type = "value",
description = "{ name = \"ALT\", value = 768 }",
},
CAPS = {
type = "value",
description = "{ name = \"CAPS\", value = 8192 }",
},
CTRL = {
type = "value",
description = "{ name = \"CTRL\", value = 192 }",
},
GUI = {
type = "value",
description = "{ name = \"GUI\", value = 3072 }",
},
LALT = {
type = "value",
description = "{ name = \"LALT\", value = 256 }",
},
LCTRL = {
type = "value",
description = "{ name = \"LCTRL\", value = 64 }",
},
LGUI = {
type = "value",
description = "{ name = \"LGUI\", value = 1024 }",
},
LSHIFT = {
type = "value",
description = "{ name = \"LSHIFT\", value = 1 }",
},
MODE = {
type = "value",
description = "{ name = \"MODE\", value = 16384 }",
},
NONE = {
type = "value",
description = "{ name = \"NONE\", value = 0 }",
},
NUM = {
type = "value",
description = "{ name = \"NUM\", value = 4096 }",
},
RALT = {
type = "value",
description = "{ name = \"RALT\", value = 512 }",
},
RCTRL = {
type = "value",
description = "{ name = \"RCTRL\", value = 128 }",
},
RGUI = {
type = "value",
description = "{ name = \"RGUI\", value = 2048 }",
},
RSHIFT = {
type = "value",
description = "{ name = \"RSHIFT\", value = 2 }",
},
SCROLL = {
type = "value",
description = "{ name = \"SCROLL\", value = 32768 }",
},
SHIFT = {
type = "value",
description = "{ name = \"SHIFT\", value = 3 }",
},
},
},
MOUSE_0 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
BUTTON_LEFT = {
type = "value",
description = "{ name = \"BUTTON_LEFT\", value = 1000 }",
},
BUTTON_MIDDLE = {
type = "value",
description = "{ name = \"BUTTON_MIDDLE\", value = 1002 }",
},
BUTTON_RIGHT = {
type = "value",
description = "{ name = \"BUTTON_RIGHT\", value = 1001 }",
},
BUTTON_X1 = {
type = "value",
description = "{ name = \"BUTTON_X1\", value = 1003 }",
},
BUTTON_X2 = {
type = "value",
description = "{ name = \"BUTTON_X2\", value = 1004 }",
},
WHEEL_DOWN = {
type = "value",
description = "{ name = \"WHEEL_DOWN\", value = 1006 }",
},
WHEEL_UP = {
type = "value",
description = "{ name = \"WHEEL_UP\", value = 1005 }",
},
},
},
MOUSE_1 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
BUTTON_LEFT = {
type = "value",
description = "{ name = \"BUTTON_LEFT\", value = 1100 }",
},
BUTTON_MIDDLE = {
type = "value",
description = "{ name = \"BUTTON_MIDDLE\", value = 1102 }",
},
BUTTON_RIGHT = {
type = "value",
description = "{ name = \"BUTTON_RIGHT\", value = 1101 }",
},
BUTTON_X1 = {
type = "value",
description = "{ name = \"BUTTON_X1\", value = 1103 }",
},
BUTTON_X2 = {
type = "value",
description = "{ name = \"BUTTON_X2\", value = 1104 }",
},
WHEEL_DOWN = {
type = "value",
description = "{ name = \"WHEEL_DOWN\", value = 1106 }",
},
WHEEL_UP = {
type = "value",
description = "{ name = \"WHEEL_UP\", value = 1105 }",
},
},
},
MOUSE_2 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
BUTTON_LEFT = {
type = "value",
description = "{ name = \"BUTTON_LEFT\", value = 1200 }",
},
BUTTON_MIDDLE = {
type = "value",
description = "{ name = \"BUTTON_MIDDLE\", value = 1202 }",
},
BUTTON_RIGHT = {
type = "value",
description = "{ name = \"BUTTON_RIGHT\", value = 1201 }",
},
BUTTON_X1 = {
type = "value",
description = "{ name = \"BUTTON_X1\", value = 1203 }",
},
BUTTON_X2 = {
type = "value",
description = "{ name = \"BUTTON_X2\", value = 1204 }",
},
WHEEL_DOWN = {
type = "value",
description = "{ name = \"WHEEL_DOWN\", value = 1206 }",
},
WHEEL_UP = {
type = "value",
description = "{ name = \"WHEEL_UP\", value = 1205 }",
},
},
},
MOUSE_3 = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
BUTTON_LEFT = {
type = "value",
description = "{ name = \"BUTTON_LEFT\", value = 1300 }",
},
BUTTON_MIDDLE = {
type = "value",
description = "{ name = \"BUTTON_MIDDLE\", value = 1302 }",
},
BUTTON_RIGHT = {
type = "value",
description = "{ name = \"BUTTON_RIGHT\", value = 1301 }",
},
BUTTON_X1 = {
type = "value",
description = "{ name = \"BUTTON_X1\", value = 1303 }",
},
BUTTON_X2 = {
type = "value",
description = "{ name = \"BUTTON_X2\", value = 1304 }",
},
WHEEL_DOWN = {
type = "value",
description = "{ name = \"WHEEL_DOWN\", value = 1306 }",
},
WHEEL_UP = {
type = "value",
description = "{ name = \"WHEEL_UP\", value = 1305 }",
},
},
},
MOUSE_MANY = {
type = "value",
description = "Argumente für mouseSetMode.\n= 200",
},
MOUSE_SINGLE = {
type = "value",
description = "Argumente für mouseSetMode.\n= 100",
},
OVERLAY_NOT_UPDATED = {
type = "value",
description = "Rückgabewerte für onOverlayUpdate.\n= 0",
},
OVERLAY_UPDATED = {
type = "value",
description = "Rückgabewerte für onOverlayUpdate.\n= 1",
},
PARTICLE_ADD = {
type = "value",
description = "Blending für emitterSetBlend.\n= 1",
},
PARTICLE_ALPHA = {
type = "value",
description = "Blending für emitterSetBlend.\n= 0",
},
PARTICLE_OVER = {
type = "value",
description = "Wo 2D-Partikel gezeichnet werden, für emitterSetLayer.\n= 0",
},
PARTICLE_UNDER = {
type = "value",
description = "Wo 2D-Partikel gezeichnet werden, für emitterSetLayer.\n= 1",
},
RENDER_PIXELATED = {
type = "value",
description = "Argumente für spriteQuality / videoQuality.\n= 0",
},
RENDER_SMOOTH = {
type = "value",
description = "Argumente für spriteQuality / videoQuality.\n= 1",
},
RmlUiContextsProxy = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
SCANCODE = {
type = "lib",
description = "Framework.singe fügt die Tabellen SCANCODE und MODIFIER hinzu (die Tasten- und Modifikatorwerte von SDL), GAMEPAD_0 bis GAMEPAD_3, MOUSE_0 bis MOUSE_3, die Indizes GAMEPAD_AXIS_* für controllerGetAxis und DIR.",
childs = {
A = {
type = "value",
description = "{ name = \"A\", value = 4 }",
},
AC_BACK = {
type = "value",
description = "{ name = \"AC_BACK\", value = 270 }",
},
AC_BOOKMARKS = {
type = "value",
description = "{ name = \"AC_BOOKMARKS\", value = 274 }",
},
AC_FORWARD = {
type = "value",
description = "{ name = \"AC_FORWARD\", value = 271 }",
},
AC_HOME = {
type = "value",
description = "{ name = \"AC_HOME\", value = 269 }",
},
AC_REFRESH = {
type = "value",
description = "{ name = \"AC_REFRESH\", value = 273 }",
},
AC_SEARCH = {
type = "value",
description = "{ name = \"AC_SEARCH\", value = 268 }",
},
AC_STOP = {
type = "value",
description = "{ name = \"AC_STOP\", value = 272 }",
},
AGAIN = {
type = "value",
description = "{ name = \"AGAIN\", value = 121 }",
},
ALTERASE = {
type = "value",
description = "{ name = \"ALTERASE\", value = 153 }",
},
APOSTROPHE = {
type = "value",
description = "{ name = \"APOSTROPHE\", value = 52 }",
},
APP1 = {
type = "value",
description = "{ name = \"APP1\", value = 283 }",
},
APP2 = {
type = "value",
description = "{ name = \"APP2\", value = 284 }",
},
APPLICATION = {
type = "value",
description = "{ name = \"APPLICATION\", value = 101 }",
},
AUDIOFASTFORWARD = {
type = "value",
description = "{ name = \"AUDIOFASTFORWARD\", value = 286 }",
},
AUDIOMUTE = {
type = "value",
description = "{ name = \"AUDIOMUTE\", value = 262 }",
},
AUDIONEXT = {
type = "value",
description = "{ name = \"AUDIONEXT\", value = 258 }",
},
AUDIOPLAY = {
type = "value",
description = "{ name = \"AUDIOPLAY\", value = 261 }",
},
AUDIOPREV = {
type = "value",
description = "{ name = \"AUDIOPREV\", value = 259 }",
},
AUDIOREWIND = {
type = "value",
description = "{ name = \"AUDIOREWIND\", value = 285 }",
},
AUDIOSTOP = {
type = "value",
description = "{ name = \"AUDIOSTOP\", value = 260 }",
},
B = {
type = "value",
description = "{ name = \"B\", value = 5 }",
},
BACKSLASH = {
type = "value",
description = "{ name = \"BACKSLASH\", value = 49 }",
},
BACKSPACE = {
type = "value",
description = "{ name = \"BACKSPACE\", value = 42 }",
},
BRIGHTNESSDOWN = {
type = "value",
description = "{ name = \"BRIGHTNESSDOWN\", value = 275 }",
},
BRIGHTNESSUP = {
type = "value",
description = "{ name = \"BRIGHTNESSUP\", value = 276 }",
},
C = {
type = "value",
description = "{ name = \"C\", value = 6 }",
},
CALCULATOR = {
type = "value",
description = "{ name = \"CALCULATOR\", value = 266 }",
},
CANCEL = {
type = "value",
description = "{ name = \"CANCEL\", value = 155 }",
},
CAPSLOCK = {
type = "value",
description = "{ name = \"CAPSLOCK\", value = 57 }",
},
CLEAR = {
type = "value",
description = "{ name = \"CLEAR\", value = 156 }",
},
CLEARAGAIN = {
type = "value",
description = "{ name = \"CLEARAGAIN\", value = 162 }",
},
COMMA = {
type = "value",
description = "{ name = \"COMMA\", value = 54 }",
},
COMPUTER = {
type = "value",
description = "{ name = \"COMPUTER\", value = 267 }",
},
COPY = {
type = "value",
description = "{ name = \"COPY\", value = 124 }",
},
CRSEL = {
type = "value",
description = "{ name = \"CRSEL\", value = 163 }",
},
CURRENCYSUBUNIT = {
type = "value",
description = "{ name = \"CURRENCYSUBUNIT\", value = 181 }",
},
CURRENCYUNIT = {
type = "value",
description = "{ name = \"CURRENCYUNIT\", value = 180 }",
},
CUT = {
type = "value",
description = "{ name = \"CUT\", value = 123 }",
},
D = {
type = "value",
description = "{ name = \"D\", value = 7 }",
},
DECIMALSEPARATOR = {
type = "value",
description = "{ name = \"DECIMALSEPARATOR\", value = 179 }",
},
DELETE = {
type = "value",
description = "{ name = \"DELETE\", value = 76 }",
},
DISPLAYSWITCH = {
type = "value",
description = "{ name = \"DISPLAYSWITCH\", value = 277 }",
},
DOWN = {
type = "value",
description = "{ name = \"DOWN\", value = 81 }",
},
E = {
type = "value",
description = "{ name = \"E\", value = 8 }",
},
EJECT = {
type = "value",
description = "{ name = \"EJECT\", value = 281 }",
},
END = {
type = "value",
description = "{ name = \"END\", value = 77 }",
},
EQUALS = {
type = "value",
description = "{ name = \"EQUALS\", value = 46 }",
},
ESCAPE = {
type = "value",
description = "{ name = \"ESCAPE\", value = 41 }",
},
EXECUTE = {
type = "value",
description = "{ name = \"EXECUTE\", value = 116 }",
},
EXSEL = {
type = "value",
description = "{ name = \"EXSEL\", value = 164 }",
},
F = {
type = "value",
description = "{ name = \"F\", value = 9 }",
},
F1 = {
type = "value",
description = "{ name = \"F1\", value = 58 }",
},
F10 = {
type = "value",
description = "{ name = \"F10\", value = 67 }",
},
F11 = {
type = "value",
description = "{ name = \"F11\", value = 68 }",
},
F12 = {
type = "value",
description = "{ name = \"F12\", value = 69 }",
},
F13 = {
type = "value",
description = "{ name = \"F13\", value = 104 }",
},
F14 = {
type = "value",
description = "{ name = \"F14\", value = 105 }",
},
F15 = {
type = "value",
description = "{ name = \"F15\", value = 106 }",
},
F16 = {
type = "value",
description = "{ name = \"F16\", value = 107 }",
},
F17 = {
type = "value",
description = "{ name = \"F17\", value = 108 }",
},
F18 = {
type = "value",
description = "{ name = \"F18\", value = 109 }",
},
F19 = {
type = "value",
description = "{ name = \"F19\", value = 110 }",
},
F2 = {
type = "value",
description = "{ name = \"F2\", value = 59 }",
},
F20 = {
type = "value",
description = "{ name = \"F20\", value = 111 }",
},
F21 = {
type = "value",
description = "{ name = \"F21\", value = 112 }",
},
F22 = {
type = "value",
description = "{ name = \"F22\", value = 113 }",
},
F23 = {
type = "value",
description = "{ name = \"F23\", value = 114 }",
},
F24 = {
type = "value",
description = "{ name = \"F24\", value = 115 }",
},
F3 = {
type = "value",
description = "{ name = \"F3\", value = 60 }",
},
F4 = {
type = "value",
description = "{ name = \"F4\", value = 61 }",
},
F5 = {
type = "value",
description = "{ name = \"F5\", value = 62 }",
},
F6 = {
type = "value",
description = "{ name = \"F6\", value = 63 }",
},
F7 = {
type = "value",
description = "{ name = \"F7\", value = 64 }",
},
F8 = {
type = "value",
description = "{ name = \"F8\", value = 65 }",
},
F9 = {
type = "value",
description = "{ name = \"F9\", value = 66 }",
},
FIND = {
type = "value",
description = "{ name = \"FIND\", value = 126 }",
},
G = {
type = "value",
description = "{ name = \"G\", value = 10 }",
},
GRAVE = {
type = "value",
description = "{ name = \"GRAVE\", value = 53 }",
},
H = {
type = "value",
description = "{ name = \"H\", value = 11 }",
},
HELP = {
type = "value",
description = "{ name = \"HELP\", value = 117 }",
},
HOME = {
type = "value",
description = "{ name = \"HOME\", value = 74 }",
},
I = {
type = "value",
description = "{ name = \"I\", value = 12 }",
},
INSERT = {
type = "value",
description = "{ name = \"INSERT\", value = 73 }",
},
INTERNATIONAL1 = {
type = "value",
description = "{ name = \"INTERNATIONAL1\", value = 135 }",
},
INTERNATIONAL2 = {
type = "value",
description = "{ name = \"INTERNATIONAL2\", value = 136 }",
},
INTERNATIONAL3 = {
type = "value",
description = "{ name = \"INTERNATIONAL3\", value = 137 }",
},
INTERNATIONAL4 = {
type = "value",
description = "{ name = \"INTERNATIONAL4\", value = 138 }",
},
INTERNATIONAL5 = {
type = "value",
description = "{ name = \"INTERNATIONAL5\", value = 139 }",
},
INTERNATIONAL6 = {
type = "value",
description = "{ name = \"INTERNATIONAL6\", value = 140 }",
},
INTERNATIONAL7 = {
type = "value",
description = "{ name = \"INTERNATIONAL7\", value = 141 }",
},
INTERNATIONAL8 = {
type = "value",
description = "{ name = \"INTERNATIONAL8\", value = 142 }",
},
INTERNATIONAL9 = {
type = "value",
description = "{ name = \"INTERNATIONAL9\", value = 143 }",
},
J = {
type = "value",
description = "{ name = \"J\", value = 13 }",
},
K = {
type = "value",
description = "{ name = \"K\", value = 14 }",
},
KBDILLUMDOWN = {
type = "value",
description = "{ name = \"KBDILLUMDOWN\", value = 279 }",
},
KBDILLUMTOGGLE = {
type = "value",
description = "{ name = \"KBDILLUMTOGGLE\", value = 278 }",
},
KBDILLUMUP = {
type = "value",
description = "{ name = \"KBDILLUMUP\", value = 280 }",
},
KP_0 = {
type = "value",
description = "{ name = \"KP_0\", value = 98 }",
},
KP_00 = {
type = "value",
description = "{ name = \"KP_00\", value = 176 }",
},
KP_000 = {
type = "value",
description = "{ name = \"KP_000\", value = 177 }",
},
KP_1 = {
type = "value",
description = "{ name = \"KP_1\", value = 89 }",
},
KP_2 = {
type = "value",
description = "{ name = \"KP_2\", value = 90 }",
},
KP_3 = {
type = "value",
description = "{ name = \"KP_3\", value = 91 }",
},
KP_4 = {
type = "value",
description = "{ name = \"KP_4\", value = 92 }",
},
KP_5 = {
type = "value",
description = "{ name = \"KP_5\", value = 93 }",
},
KP_6 = {
type = "value",
description = "{ name = \"KP_6\", value = 94 }",
},
KP_7 = {
type = "value",
description = "{ name = \"KP_7\", value = 95 }",
},
KP_8 = {
type = "value",
description = "{ name = \"KP_8\", value = 96 }",
},
KP_9 = {
type = "value",
description = "{ name = \"KP_9\", value = 97 }",
},
KP_A = {
type = "value",
description = "{ name = \"KP_A\", value = 188 }",
},
KP_AMPERSAND = {
type = "value",
description = "{ name = \"KP_AMPERSAND\", value = 199 }",
},
KP_AT = {
type = "value",
description = "{ name = \"KP_AT\", value = 206 }",
},
KP_B = {
type = "value",
description = "{ name = \"KP_B\", value = 189 }",
},
KP_BACKSPACE = {
type = "value",
description = "{ name = \"KP_BACKSPACE\", value = 187 }",
},
KP_BINARY = {
type = "value",
description = "{ name = \"KP_BINARY\", value = 218 }",
},
KP_C = {
type = "value",
description = "{ name = \"KP_C\", value = 190 }",
},
KP_CLEAR = {
type = "value",
description = "{ name = \"KP_CLEAR\", value = 216 }",
},
KP_CLEARENTRY = {
type = "value",
description = "{ name = \"KP_CLEARENTRY\", value = 217 }",
},
KP_COLON = {
type = "value",
description = "{ name = \"KP_COLON\", value = 203 }",
},
KP_COMMA = {
type = "value",
description = "{ name = \"KP_COMMA\", value = 133 }",
},
KP_D = {
type = "value",
description = "{ name = \"KP_D\", value = 191 }",
},
KP_DBLAMPERSAND = {
type = "value",
description = "{ name = \"KP_DBLAMPERSAND\", value = 200 }",
},
KP_DBLVERTICALBAR = {
type = "value",
description = "{ name = \"KP_DBLVERTICALBAR\", value = 202 }",
},
KP_DECIMAL = {
type = "value",
description = "{ name = \"KP_DECIMAL\", value = 220 }",
},
KP_DIVIDE = {
type = "value",
description = "{ name = \"KP_DIVIDE\", value = 84 }",
},
KP_E = {
type = "value",
description = "{ name = \"KP_E\", value = 192 }",
},
KP_ENTER = {
type = "value",
description = "{ name = \"KP_ENTER\", value = 88 }",
},
KP_EQUALS = {
type = "value",
description = "{ name = \"KP_EQUALS\", value = 103 }",
},
KP_EQUALSAS400 = {
type = "value",
description = "{ name = \"KP_EQUALSAS400\", value = 134 }",
},
KP_EXCLAM = {
type = "value",
description = "{ name = \"KP_EXCLAM\", value = 207 }",
},
KP_F = {
type = "value",
description = "{ name = \"KP_F\", value = 193 }",
},
KP_GREATER = {
type = "value",
description = "{ name = \"KP_GREATER\", value = 198 }",
},
KP_HASH = {
type = "value",
description = "{ name = \"KP_HASH\", value = 204 }",
},
KP_HEXADECIMAL = {
type = "value",
description = "{ name = \"KP_HEXADECIMAL\", value = 221 }",
},
KP_LEFTBRACE = {
type = "value",
description = "{ name = \"KP_LEFTBRACE\", value = 184 }",
},
KP_LEFTPAREN = {
type = "value",
description = "{ name = \"KP_LEFTPAREN\", value = 182 }",
},
KP_LESS = {
type = "value",
description = "{ name = \"KP_LESS\", value = 197 }",
},
KP_MEMADD = {
type = "value",
description = "{ name = \"KP_MEMADD\", value = 211 }",
},
KP_MEMCLEAR = {
type = "value",
description = "{ name = \"KP_MEMCLEAR\", value = 210 }",
},
KP_MEMDIVIDE = {
type = "value",
description = "{ name = \"KP_MEMDIVIDE\", value = 214 }",
},
KP_MEMMULTIPLY = {
type = "value",
description = "{ name = \"KP_MEMMULTIPLY\", value = 213 }",
},
KP_MEMRECALL = {
type = "value",
description = "{ name = \"KP_MEMRECALL\", value = 209 }",
},
KP_MEMSTORE = {
type = "value",
description = "{ name = \"KP_MEMSTORE\", value = 208 }",
},
KP_MEMSUBTRACT = {
type = "value",
description = "{ name = \"KP_MEMSUBTRACT\", value = 212 }",
},
KP_MINUS = {
type = "value",
description = "{ name = \"KP_MINUS\", value = 86 }",
},
KP_MULTIPLY = {
type = "value",
description = "{ name = \"KP_MULTIPLY\", value = 85 }",
},
KP_OCTAL = {
type = "value",
description = "{ name = \"KP_OCTAL\", value = 219 }",
},
KP_PERCENT = {
type = "value",
description = "{ name = \"KP_PERCENT\", value = 196 }",
},
KP_PERIOD = {
type = "value",
description = "{ name = \"KP_PERIOD\", value = 99 }",
},
KP_PLUS = {
type = "value",
description = "{ name = \"KP_PLUS\", value = 87 }",
},
KP_PLUSMINUS = {
type = "value",
description = "{ name = \"KP_PLUSMINUS\", value = 215 }",
},
KP_POWER = {
type = "value",
description = "{ name = \"KP_POWER\", value = 195 }",
},
KP_RIGHTBRACE = {
type = "value",
description = "{ name = \"KP_RIGHTBRACE\", value = 185 }",
},
KP_RIGHTPAREN = {
type = "value",
description = "{ name = \"KP_RIGHTPAREN\", value = 183 }",
},
KP_SPACE = {
type = "value",
description = "{ name = \"KP_SPACE\", value = 205 }",
},
KP_TAB = {
type = "value",
description = "{ name = \"KP_TAB\", value = 186 }",
},
KP_VERTICALBAR = {
type = "value",
description = "{ name = \"KP_VERTICALBAR\", value = 201 }",
},
KP_XOR = {
type = "value",
description = "{ name = \"KP_XOR\", value = 194 }",
},
L = {
type = "value",
description = "{ name = \"L\", value = 15 }",
},
LALT = {
type = "value",
description = "{ name = \"LALT\", value = 226 }",
},
LANG1 = {
type = "value",
description = "{ name = \"LANG1\", value = 144 }",
},
LANG2 = {
type = "value",
description = "{ name = \"LANG2\", value = 145 }",
},
LANG3 = {
type = "value",
description = "{ name = \"LANG3\", value = 146 }",
},
LANG4 = {
type = "value",
description = "{ name = \"LANG4\", value = 147 }",
},
LANG5 = {
type = "value",
description = "{ name = \"LANG5\", value = 148 }",
},
LANG6 = {
type = "value",
description = "{ name = \"LANG6\", value = 149 }",
},
LANG7 = {
type = "value",
description = "{ name = \"LANG7\", value = 150 }",
},
LANG8 = {
type = "value",
description = "{ name = \"LANG8\", value = 151 }",
},
LANG9 = {
type = "value",
description = "{ name = \"LANG9\", value = 152 }",
},
LCTRL = {
type = "value",
description = "{ name = \"LCTRL\", value = 224 }",
},
LEFT = {
type = "value",
description = "{ name = \"LEFT\", value = 80 }",
},
LEFTBRACKET = {
type = "value",
description = "{ name = \"LEFTBRACKET\", value = 47 }",
},
LGUI = {
type = "value",
description = "{ name = \"LGUI\", value = 227 }",
},
LSHIFT = {
type = "value",
description = "{ name = \"LSHIFT\", value = 225 }",
},
M = {
type = "value",
description = "{ name = \"M\", value = 16 }",
},
MAIL = {
type = "value",
description = "{ name = \"MAIL\", value = 265 }",
},
MAIN_0 = {
type = "value",
description = "{ name = \"MAIN_0\", value = 39 }",
},
MAIN_1 = {
type = "value",
description = "{ name = \"MAIN_1\", value = 30 }",
},
MAIN_2 = {
type = "value",
description = "{ name = \"MAIN_2\", value = 31 }",
},
MAIN_3 = {
type = "value",
description = "{ name = \"MAIN_3\", value = 32 }",
},
MAIN_4 = {
type = "value",
description = "{ name = \"MAIN_4\", value = 33 }",
},
MAIN_5 = {
type = "value",
description = "{ name = \"MAIN_5\", value = 34 }",
},
MAIN_6 = {
type = "value",
description = "{ name = \"MAIN_6\", value = 35 }",
},
MAIN_7 = {
type = "value",
description = "{ name = \"MAIN_7\", value = 36 }",
},
MAIN_8 = {
type = "value",
description = "{ name = \"MAIN_8\", value = 37 }",
},
MAIN_9 = {
type = "value",
description = "{ name = \"MAIN_9\", value = 38 }",
},
MEDIASELECT = {
type = "value",
description = "{ name = \"MEDIASELECT\", value = 263 }",
},
MENU = {
type = "value",
description = "{ name = \"MENU\", value = 118 }",
},
MINUS = {
type = "value",
description = "{ name = \"MINUS\", value = 45 }",
},
MODE = {
type = "value",
description = "{ name = \"MODE\", value = 257 }",
},
MUTE = {
type = "value",
description = "{ name = \"MUTE\", value = 127 }",
},
N = {
type = "value",
description = "{ name = \"N\", value = 17 }",
},
NONUSBACKSLASH = {
type = "value",
description = "{ name = \"NONUSBACKSLASH\", value = 100 }",
},
NONUSHASH = {
type = "value",
description = "{ name = \"NONUSHASH\", value = 50 }",
},
NUMLOCKCLEAR = {
type = "value",
description = "{ name = \"NUMLOCKCLEAR\", value = 83 }",
},
O = {
type = "value",
description = "{ name = \"O\", value = 18 }",
},
OPER = {
type = "value",
description = "{ name = \"OPER\", value = 161 }",
},
OUT = {
type = "value",
description = "{ name = \"OUT\", value = 160 }",
},
P = {
type = "value",
description = "{ name = \"P\", value = 19 }",
},
PAGEDOWN = {
type = "value",
description = "{ name = \"PAGEDOWN\", value = 78 }",
},
PAGEUP = {
type = "value",
description = "{ name = \"PAGEUP\", value = 75 }",
},
PASTE = {
type = "value",
description = "{ name = \"PASTE\", value = 125 }",
},
PAUSE = {
type = "value",
description = "{ name = \"PAUSE\", value = 72 }",
},
PERIOD = {
type = "value",
description = "{ name = \"PERIOD\", value = 55 }",
},
POWER = {
type = "value",
description = "{ name = \"POWER\", value = 102 }",
},
PRINTSCREEN = {
type = "value",
description = "{ name = \"PRINTSCREEN\", value = 70 }",
},
PRIOR = {
type = "value",
description = "{ name = \"PRIOR\", value = 157 }",
},
Q = {
type = "value",
description = "{ name = \"Q\", value = 20 }",
},
R = {
type = "value",
description = "{ name = \"R\", value = 21 }",
},
RALT = {
type = "value",
description = "{ name = \"RALT\", value = 230 }",
},
RCTRL = {
type = "value",
description = "{ name = \"RCTRL\", value = 228 }",
},
RETURN = {
type = "value",
description = "{ name = \"RETURN\", value = 40 }",
},
RETURN2 = {
type = "value",
description = "{ name = \"RETURN2\", value = 158 }",
},
RGUI = {
type = "value",
description = "{ name = \"RGUI\", value = 231 }",
},
RIGHT = {
type = "value",
description = "{ name = \"RIGHT\", value = 79 }",
},
RIGHTBRACKET = {
type = "value",
description = "{ name = \"RIGHTBRACKET\", value = 48 }",
},
RSHIFT = {
type = "value",
description = "{ name = \"RSHIFT\", value = 229 }",
},
S = {
type = "value",
description = "{ name = \"S\", value = 22 }",
},
SCROLLLOCK = {
type = "value",
description = "{ name = \"SCROLLLOCK\", value = 71 }",
},
SELECT = {
type = "value",
description = "{ name = \"SELECT\", value = 119 }",
},
SEMICOLON = {
type = "value",
description = "{ name = \"SEMICOLON\", value = 51 }",
},
SEPARATOR = {
type = "value",
description = "{ name = \"SEPARATOR\", value = 159 }",
},
SLASH = {
type = "value",
description = "{ name = \"SLASH\", value = 56 }",
},
SLEEP = {
type = "value",
description = "{ name = \"SLEEP\", value = 282 }",
},
SPACE = {
type = "value",
description = "{ name = \"SPACE\", value = 44 }",
},
STOP = {
type = "value",
description = "{ name = \"STOP\", value = 120 }",
},
SYSREQ = {
type = "value",
description = "{ name = \"SYSREQ\", value = 154 }",
},
T = {
type = "value",
description = "{ name = \"T\", value = 23 }",
},
TAB = {
type = "value",
description = "{ name = \"TAB\", value = 43 }",
},
THOUSANDSSEPARATOR = {
type = "value",
description = "{ name = \"THOUSANDSSEPARATOR\", value = 178 }",
},
U = {
type = "value",
description = "{ name = \"U\", value = 24 }",
},
UNDO = {
type = "value",
description = "{ name = \"UNDO\", value = 122 }",
},
UP = {
type = "value",
description = "{ name = \"UP\", value = 82 }",
},
V = {
type = "value",
description = "{ name = \"V\", value = 25 }",
},
VOLUMEDOWN = {
type = "value",
description = "{ name = \"VOLUMEDOWN\", value = 129 }",
},
VOLUMEUP = {
type = "value",
description = "{ name = \"VOLUMEUP\", value = 128 }",
},
W = {
type = "value",
description = "{ name = \"W\", value = 26 }",
},
WWW = {
type = "value",
description = "{ name = \"WWW\", value = 264 }",
},
X = {
type = "value",
description = "{ name = \"X\", value = 27 }",
},
Y = {
type = "value",
description = "{ name = \"Y\", value = 28 }",
},
Z = {
type = "value",
description = "{ name = \"Z\", value = 29 }",
},
},
},
SHAPE_BOX = {
type = "value",
description = "Kollisionsformen für bodyNew.\n= 0",
},
SHAPE_CAPSULE = {
type = "value",
description = "Kollisionsformen für bodyNew.\n= 2",
},
SHAPE_CYLINDER = {
type = "value",
description = "Kollisionsformen für bodyNew.\n= 3",
},
SHAPE_HULL = {
type = "value",
description = "Kollisionsformen für bodyNew.\n= 4",
},
SHAPE_MESH = {
type = "value",
description = "Kollisionsformen für bodyNew.\n= 5",
},
SHAPE_SPHERE = {
type = "value",
description = "Kollisionsformen für bodyNew.\n= 1",
},
SINGE_AXIS_STRIDE = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 3",
},
SINGE_CONTROLLER_AXES = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 6",
},
SINGE_CONTROLLER_BUTTONS = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 15",
},
SINGE_DEAD_ZONE = {
type = "value",
description = "Die DEAD_ZONE aus controls.cfg, in rohen Achseneinheiten.",
},
SINGE_DISC = {
type = "value",
description = "Wahr, wenn das Spiel eine Laserdisc hat; falsch, wenn die Zeichenfläche die Welt ist.",
},
SINGE_FRAMEWORK_VERSION = {
type = "value",
description = "Die Engine-Version, als Ganzzahlen, als String (\"v3.00\") und als die Zahl, die singeVersion() zurückgibt.\n= 3.0",
},
SINGE_GAMEPAD_BASE = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 500",
},
SINGE_GAMEPAD_BUTTON_OFFSET = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 18",
},
SINGE_GAMEPAD_STRIDE = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 100",
},
SINGE_LEGACY_SPRITE_ARGS = {
type = "value",
description = "Wahr, wenn das Spiel die Sprite-Argumentreihenfolge von 2.10 verlangt hat.",
},
SINGE_MAX_CONTROLLERS = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 4",
},
SINGE_MAX_MICE = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 4",
},
SINGE_MOUSE_BASE = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 1000",
},
SINGE_MOUSE_STRIDE = {
type = "value",
description = "Aufbau der Eingabecodes für Controller und Maus und wie viele Achsen und Knöpfe ein Pad hat; Framework.singe baut daraus die Tabellen GAMEPAD_N und MOUSE_N, und ein Servicebildschirm geht damit ein Pad durch.\n= 100",
},
SINGE_ROTATE_STEP = {
type = "value",
description = "Was vldpSetScale, vldpSetShift und vldpSetRotate annehmen. Begrenze auf diese Werte statt auf eigene Kopien: Eine Verschiebung außerhalb des Bereichs beendet das Skript.\n= 90",
},
SINGE_SCALE_MAX = {
type = "value",
description = "Was vldpSetScale, vldpSetShift und vldpSetRotate annehmen. Begrenze auf diese Werte statt auf eigene Kopien: Eine Verschiebung außerhalb des Bereichs beendet das Skript.\n= 100",
},
SINGE_SCALE_MIN = {
type = "value",
description = "Was vldpSetScale, vldpSetShift und vldpSetRotate annehmen. Begrenze auf diese Werte statt auf eigene Kopien: Eine Verschiebung außerhalb des Bereichs beendet das Skript.\n= 25",
},
SINGE_SHIFT_MAX = {
type = "value",
description = "Was vldpSetScale, vldpSetShift und vldpSetRotate annehmen. Begrenze auf diese Werte statt auf eigene Kopien: Eine Verschiebung außerhalb des Bereichs beendet das Skript.\n= 100",
},
SINGE_SHIFT_MIN = {
type = "value",
description = "Was vldpSetScale, vldpSetShift und vldpSetRotate annehmen. Begrenze auf diese Werte statt auf eigene Kopien: Eine Verschiebung außerhalb des Bereichs beendet das Skript.\n= -100",
},
SINGE_TRIGGER_THRESHOLD = {
type = "value",
description = "Die Schwelle der analogen Trigger in denselben rohen Einheiten; 0, wenn die Trigger auf SINGE_DEAD_ZONE liegen, was der Standard ist.",
},
SINGE_UPDATE_CHECK = {
type = "value",
description = "= true",
},
SINGE_VERSION_MAJOR = {
type = "value",
description = "Die Engine-Version, als Ganzzahlen, als String (\"v3.00\") und als die Zahl, die singeVersion() zurückgibt.\n= 3",
},
SINGE_VERSION_MINOR = {
type = "value",
description = "Die Engine-Version, als Ganzzahlen, als String (\"v3.00\") und als die Zahl, die singeVersion() zurückgibt.\n= 0",
},
SINGE_VERSION_STRING = {
type = "value",
description = "Die Engine-Version, als Ganzzahlen, als String (\"v3.00\") und als die Zahl, die singeVersion() zurückgibt.\n= \"v3.00b1\"",
},
SINGLE_MOUSE = {
type = "value",
description = "Argumente für mouseSetMode.\n= 100",
},
SOFT_BODY = {
type = "value",
description = "Arten von Soft Bodies für softNew.\n= 1",
},
SOFT_CLOTH = {
type = "value",
description = "Arten von Soft Bodies für softNew.\n= 0",
},
SOFT_ROPE = {
type = "value",
description = "Arten von Soft Bodies für softNew.\n= 2",
},
SOUND_ERROR_INVALID = {
type = "value",
description = "-1, was soundPlay zurückgibt, wenn kein Kanal frei ist.\n= -1",
},
SOUND_REMOVE_HANDLE = {
type = "value",
description = "-1, was soundPlay zurückgibt, wenn kein Kanal frei ist.\n= -1",
},
SPRITE_ADD = {
type = "value",
description = "Blending für spriteSetBlend.\n= 1",
},
SPRITE_ALPHA = {
type = "value",
description = "Blending für spriteSetBlend.\n= 0",
},
SPRITE_MULTIPLY = {
type = "value",
description = "Blending für spriteSetBlend.\n= 2",
},
SWITCH_BUTTON1 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 6",
},
SWITCH_BUTTON2 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 7",
},
SWITCH_BUTTON3 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 8",
},
SWITCH_BUTTON4 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 21",
},
SWITCH_COIN1 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 9",
},
SWITCH_COIN2 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 10",
},
SWITCH_CONSOLE = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 20",
},
SWITCH_DOWN = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 2",
},
SWITCH_GRAB = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 23",
},
SWITCH_LEFT = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 1",
},
SWITCH_MOUSE_DISCONNECT = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 24",
},
SWITCH_PAUSE = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 19",
},
SWITCH_QUIT = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 18",
},
SWITCH_RECORD = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 25",
},
SWITCH_RESET = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 16",
},
SWITCH_RIGHT = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 3",
},
SWITCH_SCREENSHOT = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 17",
},
SWITCH_SERVICE = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 14",
},
SWITCH_SKILL1 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 11",
},
SWITCH_SKILL2 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 12",
},
SWITCH_SKILL3 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 13",
},
SWITCH_START1 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 4",
},
SWITCH_START2 = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 5",
},
SWITCH_TEST = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 15",
},
SWITCH_TILT = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 22",
},
SWITCH_UP = {
type = "value",
description = "Werte, die in MODE_NORMAL an onInputPressed / onInputReleased übergeben werden. SWITCH_MOUSE_DISCONNECT löst die Engine selbst aus, wenn eine Maus oder Lightgun abgezogen wird, einmal als Drücken und einmal als Loslassen; keine Taste und kein Knopf erzeugt ihn. SWITCH_RECORD ist der Aufnahmeschalter, auf den die Engine selbst reagiert, wie auf den Screenshot-Schalter.\n= 0",
},
SelectOptionsProxy = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ }",
},
__setters = {
type = "value",
description = "{ }",
},
},
},
TONEMAP_ACES = {
type = "value",
description = "Tonkurven für sceneSetTonemap.\n= 2",
},
TONEMAP_NEUTRAL = {
type = "value",
description = "Tonkurven für sceneSetTonemap.\n= 1",
},
TONEMAP_NONE = {
type = "value",
description = "Tonkurven für sceneSetTonemap.\n= 0",
},
VEHICLE_BOAT = {
type = "value",
description = "Fahrzeugarten für vehicleNew.\n= 3",
},
VEHICLE_CAR = {
type = "value",
description = "Fahrzeugarten für vehicleNew.\n= 0",
},
VEHICLE_MOTORCYCLE = {
type = "value",
description = "Fahrzeugarten für vehicleNew.\n= 1",
},
VEHICLE_TANK = {
type = "value",
description = "Fahrzeugarten für vehicleNew.\n= 2",
},
Vector2f = {
type = "lib",
description = "",
childs = {
DotProduct = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Normalise = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
Rotate = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
__getters = {
type = "value",
description = "{ magnitude, x, y }",
},
__setters = {
type = "value",
description = "{ x, y }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
Vector2i = {
type = "lib",
description = "",
childs = {
__getters = {
type = "value",
description = "{ magnitude, x, y }",
},
__setters = {
type = "value",
description = "{ x, y }",
},
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
allowSocketCall = {
type = "function",
description = "Hypseus-Erweiterung, in Singe immer false. Hypseus antwortet damit, ob der Benutzer ihm erlaubt hat, Daten an einen Statistikserver zu senden, was dort -noserversend abschaltet; das Senden selbst ist dort auskommentiert. Singe sendet nirgendwohin etwas, also ist nichts erlaubt, und die Antwort ändert sich nie. Die Funktion gibt es, damit ein Spiel, das fragt, nicht an einer fehlenden Funktion stehen bleibt.\nRückgabe: ein Boolean, immer false.\nSeit: 3.00",
args = "()",
returns = "(allowed)",
},
animationGetTime = {
type = "function",
description = "Die aktuelle Zeit im Clip der Basisebene, ob er spielt oder pausiert, in den eigenen Sekunden des Clips (ein speed von 2 bewegt sie doppelt so schnell). Ein Clip in Schleife springt an seinem Ende auf 0 zurück; einer ohne Schleife bleibt bei seiner Länge stehen. Wurde noch nichts gespielt, ergibt das 0. Clips auf den oberen Ebenen werden nicht gemeldet. Ein Knoten, der keine Instanzwurzel ist, beendet das Skript.\nRückgabe: Sekunden als Zahl.\nSeit: 3.00.",
args = "(node)",
returns = "(seconds)",
},
animationIsPlaying = {
type = "function",
description = "Ob der Clip der Basisebene auf dieser Instanz weiterläuft. Ein Clip ohne Schleife hört auf zu spielen, wenn er sein Ende erreicht, und animationPause und animationStop machen dies beide false; ein Clip in Schleife bleibt true, bis er gestoppt wird. Anders als bei den übrigen Aufrufen hier beendet ein Knoten, der keine Instanzwurzel ist, nicht das Skript, sondern bekommt false als Antwort.\nRückgabe: Boolean.\nSeit: 3.00.",
args = "(node)",
returns = "(boolean)",
},
animationPause = {
type = "function",
description = "Friert den Clip der Basisebene bei seiner aktuellen Zeit ein; die Knoten halten diese Pose, bis animationResume ihn fortsetzt oder ein anderer Clip gespielt wird. Clips auf den oberen Ebenen laufen weiter. Eine Instanz zu pausieren, auf der nichts spielt, ist harmlos. Ein Knoten, der keine Instanzwurzel ist, beendet das Skript.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
animationPlay = {
type = "function",
description = "Startet einen der Clips des Modells von seinem Anfang an auf der Basisebene dieser Instanz und ersetzt, was dort gespielt hat; die Pose wird sofort aktualisiert. Mit einem fade läuft der alte Clip weiter, während er über so viele Sekunden ausgeblendet wird, und wenn nichts gespielt hat, beginnt die Überblendung bei der Pose, in der die Knoten gerade sind (eine eben abgeschaltete Ragdoll, eine per Skript gesetzte Pose), wobei Knoten, die der neue Clip nicht animiert, sanft in die Ruhepose des Modells zurückgleiten. Ein Knoten, der keine Instanzwurzel ist, ein Name, den das Modell nicht hat, oder eine Zahl außerhalb von 1 bis zur Anzahl der Clips beendet das Skript.\nSeit: 3.00.",
args = "(node, nameOrIndex [, loop: boolean, speed, fade])",
returns = "()",
},
animationPlayLayer = {
type = "function",
description = "Spielt einen Clip auf einer der vier Ebenen über der Basis, über alles darunter geblendet nach dem Gewicht der Ebene (animationSetLayerWeight, Standard 1) und auf einen Teil des Skeletts beschränkt, wenn eine Maske gesetzt ist (animationSetLayerMask). Höhere Ebenen werden über niedrigere geblendet; jede Ebene führt ihren eigenen Clip, ihre eigene Zeit und Schleife unabhängig von der Basis. nameOrIndex, loop, speed und fade bedeuten dasselbe wie bei animationPlay, mit einem Unterschied: Ein fade auf einer Ebene, die leer war, fährt das Gewicht der Ebene von 0 hoch, statt von einer Pose überzublenden. Eine Ebene außerhalb von 1 bis 4, ein Knoten, der keine Instanzwurzel ist, oder ein Clip, den das Modell nicht hat, beendet das Skript.\nSeit: 3.00.",
args = "(node, layer, nameOrIndex [, loop, speed, fade])",
returns = "()",
},
animationResume = {
type = "function",
description = "Setzt den Clip der Basisebene dort fort, wo animationPause ihn eingefroren hat, oder dort, wohin animationSetTime ihn inzwischen bewegt hat. Einen Clip fortzusetzen, der bereits spielt, ändert nichts. Eine Instanz ohne Clip auf ihrer Basisebene (nie gespielt oder gestoppt) beendet das Skript, ebenso ein Knoten, der keine Instanzwurzel ist.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
animationSetLayerMask = {
type = "function",
description = "Beschränkt eine Ebene auf maskNode und alles darunter, sodass der Clip auf dieser Ebene nur diesen Teil des Modells bewegt und der Rest weiter den Ebenen darunter folgt. maskNode muss einer der eigenen Knoten der Instanz sein, gefunden mit nodeFind(name, node); die Instanzwurzel selbst zählt nicht. maskNode wegzulassen oder nil zu übergeben hebt die Beschränkung auf. Die Maske bleibt über spätere Aufrufe von animationPlayLayer hinweg auf der Ebene. Eine Ebene außerhalb von 1 bis 4 beendet das Skript, ebenso ein Knoten, der keine Instanzwurzel ist, oder ein maskNode, der nicht zu dieser Instanz gehört.\nSeit: 3.00.",
args = "(node, layer [, maskNode])",
returns = "()",
},
animationSetLayerWeight = {
type = "function",
description = "Wie stark der Clip einer Ebene über dem durchscheint, was darunter liegt, 0 (gar nicht) bis 1 (voll, der Standard); Werte außerhalb dieses Bereichs werden begrenzt. Das Gewicht gehört zur Ebene, nicht zum Clip, also übersteht es animationPlayLayer und animationStop auf dieser Ebene. Ändere es jeden Frame ein wenig, um eine Ebene von Hand ein- oder auszublenden, oder lass einen fade bei animationPlayLayer das einmal erledigen. Eine Ebene außerhalb von 1 bis 4 oder ein Knoten, der keine Instanzwurzel ist, beendet das Skript.\nSeit: 3.00.",
args = "(node, layer, weight)",
returns = "()",
},
animationSetTime = {
type = "function",
description = "Lässt den Clip der Basisebene zu einer Zeit in seinen eigenen Sekunden springen; negative Werte werden zu 0. Die Pose wird sofort aktualisiert, ob der Clip spielt oder nicht, sodass eine pausierte Instanz auf einen genauen Frame gespult werden kann und eine spielende von der neuen Zeit aus weiterläuft. Eine laufende Überblendung auf der Basisebene wird abgebrochen. Eine Instanz ohne Clip auf ihrer Basisebene beendet das Skript, ebenso ein Knoten, der keine Instanzwurzel ist.\nSeit: 3.00.",
args = "(node, seconds)",
returns = "()",
},
animationStop = {
type = "function",
description = "Stoppt und vergisst jeden Clip auf der Instanz oder nur den Clip auf einer Ebene über der Basis (1 bis 4); die Basisebene allein lässt sich nicht ohne die Ebenen darüber stoppen. Die Knoten behalten ihre letzte Pose, aus der ein folgendes animationPlay mit einem fade sanft herausführt. Nachdem alles gestoppt wurde, beenden animationResume und animationSetTime das Skript, bis wieder etwas gespielt wird. Gewichte und Masken der Ebenen bleiben erhalten. Eine Ebene außerhalb von 1 bis 4 oder ein Knoten, der keine Instanzwurzel ist, beendet das Skript.\nSeit: 3.00.",
args = "(node [, layer])",
returns = "()",
},
bodyApplyForce = {
type = "function",
description = "Übt auf einen dynamischen Körper eine Kraft in Newton aus, nur für die Schritte dieses Frames; ruf es jeden Frame auf, um weiter zu schieben. Ohne Punkt wirkt die Kraft durch den Schwerpunkt und bewegt den Körper nur; mit einem Weltpunkt (px, py, pz) dreht sie den Körper außerdem um seinen Mittelpunkt. Eine Kraft beschleunigt um Kraft geteilt durch Masse, also bemiss sie nach bodySetMass. Statische und kinematische Körper ignorieren sie.\nSeit: 3.00.",
args = "(node, fx, fy, fz [, px, py, pz])",
returns = "()",
},
bodyApplyImpulse = {
type = "function",
description = "Ändert den Impuls eines dynamischen Körpers auf einen Schlag: Ein Impuls von Masse mal Geschwindigkeit fügt diese Geschwindigkeit hinzu. Ohne Punkt wirkt er durch den Schwerpunkt; mit einem Weltpunkt (px, py, pz) dreht er den Körper außerdem, sodass ein Treffer nahe der Oberkante einer Kiste sie umkippt. Das ist der Aufruf für einen Treffer, einen Tritt, eine Explosion oder einen Abschuss, während bodyApplyForce für ein Schieben ist, das anhält. Statische und kinematische Körper ignorieren ihn.\nSeit: 3.00.",
args = "(node, ix, iy, iz [, px, py, pz])",
returns = "()",
},
bodyDelete = {
type = "function",
description = "Entfernt den Körper aus der Welt; der Knoten und sein Mesh bleiben, wo sie sind. Jedes Gelenk, das am Körper hängt, und jedes darauf gebaute Fahrzeug verschwindet mit ihm. Den Knoten zu löschen entfernt auch seinen Körper, also wird dies nur gebraucht, um einen Knoten ohne seinen Körper zu behalten. Beendet das Skript, wenn der Knoten keinen Körper hat.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
bodyGetAngularVelocity = {
type = "function",
description = "Wie schnell sich der Körper um jede Weltachse dreht, in Radiant pro Sekunde, beim letzten Schritt. Ein statischer Körper meldet null. Nützlich für die Tonhöhe eines Rads oder einen Drehzähler.\nRückgabe: Drei Zahlen, Radiant pro Sekunde um X, Y und Z.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z)",
},
bodyGetVelocity = {
type = "function",
description = "Wie schnell sich der Körper entlang jeder Weltachse bewegt, in Welteinheiten pro Sekunde, beim letzten Schritt. Ein statischer Körper meldet null; ein kinematischer Körper meldet die Geschwindigkeit, die sich aus der Bewegung seines Knotens ergab.\nRückgabe: Drei Zahlen, Einheiten pro Sekunde entlang X, Y und Z.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z)",
},
bodyIsResting = {
type = "function",
description = "Ob die Simulation den Körper schlafen gelegt hat, weil er sich nicht mehr bewegt. Statische Körper und mit bodySetEnabled aus der Welt genommene Körper gelten als ruhend. Ein ruhender Körper wacht von selbst auf, wenn ihn etwas berührt oder wenn eine Geschwindigkeit, eine Kraft oder ein Impuls angewendet wird.\nRückgabe: Boolean.\nSeit: 3.00.",
args = "(node)",
returns = "(boolean)",
},
bodyNew = {
type = "function",
description = "Gibt dem Knoten einen Körper des angegebenen Typs, dort platziert, wo der Knoten gerade in der Welt ist (seine Eltern eingeschlossen), mit einer Kollisionsform, die durch a, b und c in Welteinheiten bemessen und mit der Weltskalierung des Knotens skaliert wird. Ein zweiter Aufruf auf demselben Knoten ersetzt den ersten, und ein Knoten, der eine Spielfigur hatte, verliert sie. Die Masse eines dynamischen Körpers ergibt sich aus dem Volumen seiner Form bei der Dichte von Wasser, also setze bodySetMass bei allem, was sich leicht anfühlen soll. Die Skalierung des Knotens später zu ändern, ändert die Größe des Körpers nicht. Beendet das Skript bei einem unbekannten Typ oder einer unbekannten Form, wenn auf diesem Rechner keine Physik verfügbar ist, wenn die Welt bereits 4096 Körper enthält oder wenn die Form nicht gebaut werden kann (ein dynamisches SHAPE_MESH oder eine Hülle ohne Mesh unter dem Knoten).\nSeit: 3.00.",
args = "(node, type, shape [, a, b, c])",
returns = "()",
},
bodySetAngularVelocity = {
type = "function",
description = "Setzt die Drehung um jede Weltachse, in Radiant pro Sekunde, und weckt den Körper. Statische Körper ignorieren es. Die Drehung eines kinematischen Körpers wird beim nächsten Schritt von seinem Knoten überschrieben, also wirkt der Aufruf nur bei dynamischen Körpern fort.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
bodySetBounce = {
type = "function",
description = "Setzt die Restitution des Körpers, von 0 (bleibt sofort liegen) bis 1 (prallt mit allem zurück, womit er ankam); Werte außerhalb dieses Bereichs werden begrenzt. Der Standard ist 0.1. Die Werte der beiden sich berührenden Körper werden kombiniert, sodass ein lebhafter Ball auf einem dämpfenden Boden trotzdem springt.\nSeit: 3.00.",
args = "(node, bounce)",
returns = "()",
},
bodySetBuoyancy = {
type = "function",
description = "Wie der Körper schwimmt, wenn er in einem Wasservolumen ist: 1 ist neutral, mehr schwimmt höher, weniger sinkt, und 0 ist ein Stein. Der Standard ist 1.2, das sanft schwimmt. Der Faktor multipliziert die eigene Dichte des Wassers aus bodySetWater, und negative Werte werden auf 0 begrenzt. Nur dynamische Körper werden von Wasser bewegt, aber der Wert kann auf jedem Körper gesetzt werden.\nSeit: 3.00.",
args = "(node, factor)",
returns = "()",
},
bodySetCurrent = {
type = "function",
description = "Setzt die Strömung in einem Wasservolumen, in Welteinheiten pro Sekunde entlang jeder Weltachse; dynamische Körper, die darin schwimmen, treiben mit der Strömung, und eine schwimmende Spielfigur wird von ihr mitgetragen. Der Standard ist keine Strömung. Setze sie auf dem Knoten, auf dem bodySetWater aufgerufen wurde; auf jedem anderen Körper wird sie gespeichert und bewirkt nichts.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
bodySetEnabled = {
type = "function",
description = "Nimmt den Körper mit false aus der Welt: Er kollidiert nicht mehr, bewegt sich nicht mehr, treibt seinen Knoten weder an noch folgt er ihm, und er gilt als ruhend. true setzt ihn dort wieder ein, wo er ist, und weckt ihn. Der Körper behält Form, Masse und Einstellungen, also ist das billiger, als ihn für etwas, das kommt und geht, zu löschen und neu zu erzeugen.\nSeit: 3.00.",
args = "(node, enabled)",
returns = "()",
},
bodySetFriction = {
type = "function",
description = "Setzt die Oberflächenreibung: 0 ist Eis, 0.5 (der Standard) ist gewöhnlich, höhere Werte greifen stärker. Negative Werte werden auf 0 begrenzt. Die Werte der beiden sich berührenden Körper werden kombiniert, sodass ein rutschiger Boden einen niedrigen Wert auf dem Boden braucht, nicht auf allem, was darauf läuft.\nSeit: 3.00.",
args = "(node, friction)",
returns = "()",
},
bodySetMass = {
type = "function",
description = "Skaliert die Masse eines dynamischen Körpers und mit ihr seine Trägheit neu. Tu das bei allem, was sich leicht oder schwer anfühlen soll: Der Standard ist das Volumen der Form bei der Dichte von Wasser, sodass ein türgroßer Quader etwa 140 Kilogramm wiegt und ein Stups ihn nicht bewegt. Kräfte und Impulse skalieren mit der Masse, also setze die Masse, bevor du sie abstimmst. Beendet das Skript, wenn der Körper nicht dynamisch oder die Masse nicht positiv ist.\nSeit: 3.00.",
args = "(node, kilograms)",
returns = "()",
},
bodySetTrigger = {
type = "function",
description = "Macht den Körper mit true zum Trigger: Er schiebt nichts und hält nichts auf, aber onTrigger meldet jeden Körper und jede Spielfigur, die ihn betreten und verlassen. false macht ihn wieder fest: Was in ihm war, wird ohne Meldung des Verlassens vergessen, während ein Trigger, in dem der Körper selbst steht, ihn weiter meldet. Ein Trigger ist meist ein statischer Quader oder eine statische Kugel über einer Tür, einer Ziellinie oder einer Gefahrenzone. Strahlen aus physicsRaycast treffen Trigger wie jeden anderen Körper.\nSeit: 3.00.",
args = "(node, trigger)",
returns = "()",
},
bodySetVelocity = {
type = "function",
description = "Setzt die Geschwindigkeit des Körpers entlang jeder Weltachse, in Welteinheiten pro Sekunde, und weckt ihn. Das ersetzt jede Geschwindigkeit, die der Körper hatte, während bodyApplyImpulse etwas hinzufügt. Statische Körper ignorieren es, und die Geschwindigkeit eines kinematischen Körpers wird beim nächsten Schritt aus der Bewegung seines Knotens überschrieben.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
bodySetWater = {
type = "function",
description = "Füllt einen statischen Körper mit Wasser und macht ihn zum Trigger: Die Oberseite seiner Form ist die Oberfläche, und jeder dynamische Körper darin schwimmt, sinkt oder rollt durch den Auftrieb gegen diese Oberfläche (der eingetauchte Teil der Form zählt, sodass eine schräge Kiste sich aufrichtet), gebremst durch die Widerstände. Eine Spielfigur, deren Mitte unter der Oberfläche liegt, schwimmt. Weil das Volumen ein Trigger ist, feuert onTrigger beim Hinein- und Hinausgehen. Das Wasser wird nicht gezeichnet: Gib dem Knoten ein Material mit Blending oder keines. Beendet das Skript, wenn der Körper nicht statisch ist.\nSeit: 3.00.",
args = "(node, density [, linearDrag, angularDrag])",
returns = "()",
},
cameraSet = {
type = "function",
description = "cameraSet(node)\ncameraSet(-1)\nMacht einen Knoten zur Kamera: Die Szene wird von seiner Weltposition aus mit Blick entlang seiner eigenen -Z-Richtung gezeichnet, sodass Bewegung und Drehung seiner Eltern zählen. Jeder Knoten geht, auch einer, der zugleich ein Mesh oder ein Licht trägt, und die Kamera zu wechseln ist ein einziger Aufruf. -1 stellt die Standardansicht von (0, 0, 5) mit Blick auf den Ursprung wieder her. Wird der Kameraknoten gelöscht, fällt die Ansicht ebenfalls auf die Standardansicht zurück. Beendet das Skript bei einem ungültigen Knoten-Handle.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
cameraSetOrthographic = {
type = "function",
description = "Schaltet auf eine Parallelprojektion um, die height Welteinheiten von oben bis unten zeigt, wobei die Breite dem Seitenverhältnis der Ebene folgt, von near bis far vor der Kamera. Entfernung lässt Dinge nicht schrumpfen, was zu Diagrammen, isometrischen und seitlichen Ansichten und HUD-artigen Szenen passt. Die Einstellung gilt für den aktuellen und jeden späteren Kameraknoten, bis cameraSetPerspective aufgerufen wird. Der Schatten eines gerichteten Lichts benutzt unter einer orthografischen Kamera eine einzige Shadow Map, egal, was sceneSetShadowCascades sagt.\nSeit: 3.00.",
args = "(height, near, far)",
returns = "()",
},
cameraSetPerspective = {
type = "function",
description = "Schaltet auf die übliche perspektivische Projektion um, den Standard. fov ist das vertikale Sichtfeld in Grad (Standard 60); near und far (Standards 0.1 und 1000) begrenzen, was gezeichnet wird, in Welteinheiten vor der Kamera. Die Tiefengenauigkeit verteilt sich zwischen beiden, also halte near so groß, wie die Szene es erlaubt, und far nicht größer als nötig: 0.05 bis 100 für einen Raum, 0.1 bis 400 für eine Landschaft. Die Einstellung gilt für den aktuellen und jeden späteren Kameraknoten und für gerenderte Ansichten.\nSeit: 3.00.",
args = "(fov, near, far)",
returns = "()",
},
collideCircles = {
type = "function",
description = "Ob sich zwei Kreise überschneiden. Billiger, als es aussieht: Für eine Ja-oder-Nein-Frage wird keine Quadratwurzel gezogen.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(x1, y1, radius1, x2, y2, radius2)",
returns = "(touching)",
},
collidePointCircle = {
type = "function",
description = "Ob ein Punkt innerhalb eines Kreises liegt. Der Rand zählt als innen.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(pointX, pointY, x, y, radius)",
returns = "(inside)",
},
collidePointPolygon = {
type = "function",
description = "Ob ein Punkt innerhalb eines Polygons beliebiger Form liegt, konkave eingeschlossen. Die Tabelle ist eine flache Liste aus x, y, x, y -- die Form, die eine Hitbox in den meisten Spielen ohnehin hat -- und der Umlaufsinn spielt keine Rolle. Weniger als drei Ecken enthalten nichts. Höchstens 256 Ecken.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(pointX, pointY, points: table)",
returns = "(inside)",
},
collidePointRect = {
type = "function",
description = "Ob ein Punkt innerhalb eines Rechtecks liegt. Der Rand zählt als innen.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(pointX, pointY, x, y, width, height)",
returns = "(inside)",
},
collideRectCircle = {
type = "function",
description = "Ob sich ein Rechteck und ein Kreis überschneiden; dazu wird der Punkt des Rechtecks gesucht, der dem Mittelpunkt des Kreises am nächsten liegt.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(x, y, width, height, circleX, circleY, radius)",
returns = "(touching)",
},
collideRects = {
type = "function",
description = "Ob sich zwei Rechtecke überschneiden. Die Funktion, zu der du am häufigsten greifen wirst.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(x1, y1, width1, height1, x2, y2, width2, height2)",
returns = "(touching)",
},
collideSegments = {
type = "function",
description = "Ob sich zwei Strecken kreuzen: ein Schuss entlang einer Bahn gegen eine Wand oder der Schritt, den ein bewegtes Objekt machen will, gegen die Kante, die es nicht überschreiten darf. Strecken, die aufeinander liegen, ergeben false, weil „wo kreuzen sie sich“ dann keine eindeutige Antwort hat.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2)",
returns = "(crossing)",
},
colorBackground = {
type = "function",
description = "Setzt die Hintergrundfarbe: womit overlayClear das Overlay füllt und was Text in FONT_QUALITY_SHADED aus fontPrint und fontToSprite hinter seine Glyphen malt. Beim Start ist sie transparentes Schwarz, und Alpha ist ohne Angabe 0, sodass colorBackground(0, 0, 0) gefolgt von overlayClear() das Overlay wieder unsichtbar macht. Ein teilweises Alpha über Schwarz dunkelt das Video ab; 255 verdeckt es. Kanalwerte außerhalb des Bereichs werden begrenzt statt abgewiesen.\nSeit: 1.x",
args = "(r, g, b [, a])",
returns = "()",
},
colorForeground = {
type = "function",
description = "Setzt die Vordergrundfarbe, die overlayBox, overlayCircle, overlayEllipse, overlayLine und overlayPlot verwenden, und die Textfarbe für fontPrint und fontToSprite. Beim Start ist sie deckendes Weiß, und Alpha ist ohne Angabe 255, das Gegenteil von colorBackground. Sprites und overlayPrint werden mit ihren eigenen Pixeln gezeichnet und nicht eingefärbt. Kanalwerte außerhalb des Bereichs werden begrenzt statt abgewiesen.\nSeit: 1.x",
args = "(r, g, b [, a])",
returns = "()",
},
controllerDoRumble = {
type = "function",
description = "controllerDoRumble(strength, duration)\ncontrollerDoRumble(controller, strength, duration)\nHypseus-Erweiterung. Lässt einen Controller mit beiden Motoren in einer von vier Stärken für eine von vier Dauern vibrieren. Die Form mit zwei Argumenten spricht Controller 0 an. Ein Slot ohne Controller tut nichts (Hypseus bricht dort ab, deshalb sichern sich seine Spiele mit controllerIsValid ab); eine Stärke oder Dauer außerhalb von 1 bis 4 oder ein Index außerhalb von 0 bis 3 bricht das Skript ab. Ein Controller ohne Vibrationsunterstützung ignoriert den Aufruf.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(strength, duration)",
returns = "()",
},
controllerGetAxis = {
type = "function",
description = "Gibt die Stellung einer analogen Achse zurück, wie die Engine sie zuletzt gesehen hat. Der Wert wird bei jedem Achsenereignis aktualisiert, auch bei Bewegung innerhalb der Totzone, und ist 0 für einen Controller, der nicht verbunden ist, oder eine Achse, die sich nie bewegt hat. Sticks reichen von -32768 bis 32767; Trigger ruhen bei 0 und erreichen voll gedrückt 32767. Ein Index außerhalb von 0 bis 3 oder eine Achse außerhalb von 0 bis 5 bricht das Skript ab.\nRückgabe: Ganzzahl, -32768 bis 32767.\nSeit: 2.00",
args = "(controller, axis)",
returns = "(integer)",
},
controllerGetButton = {
type = "function",
description = "Gibt zurück, ob eine Taste gerade gehalten wird, direkt vom Controller gelesen statt aus der Ereigniswarteschlange. Verwende es zum Aufladen durch Gedrückthalten und für ähnliche Fälle, in denen onInputPressed und onInputReleased umständlich sind. Ein Slot ohne Controller ergibt false. Der Tastencode muss aus der Tabelle GAMEPAD_N desselben Controller-Index stammen; ein Code aus der Tabelle eines anderen Controllers oder ein Achsencode fällt aus dem Tastenbereich und bricht das Skript ab, ebenso ein Index außerhalb von 0 bis 3.\nRückgabe: Boolean.\nSeit: 2.10",
args = "(controller, button)",
returns = "(boolean)",
},
controllerGetName = {
type = "function",
description = "Der Name des Geräts in einem Controller-Slot, wie SDL ihn meldet, oder nil, wenn der Slot leer ist. Ein Gerät, das SDL nicht erkannt hat, meldet seinen eigenen Namen über das Mapping, das Singe dafür geschrieben hat, sodass ein Service-Bildschirm einen Arcade-Encoder ebenso leicht mit Namen auflisten kann wie ein Markenpad. Ein Index außerhalb von 0 bis 3 bricht das Skript ab.\nRückgabe: String oder nil.\nSeit: 3.00",
args = "(controller)",
returns = "(string)",
},
controllerGetPadding = {
type = "function",
description = "Hypseus-Erweiterung, in Singe immer 0. Hypseus addiert diesen Offset zu einem Schaltercode, der von einem Gamepad kam, damit ein Spiel erkennen kann, welches Gerät was gedrückt hat, und den Schalter trotzdem durch Abziehen zurückgewinnt. Singe liefert Gamepad-Eingaben als gewöhnliche belegte Schalter ohne eine solche Markierung, deshalb antwortet es mit 0: ein Spiel, das auf den verschobenen Bereich prüft, nimmt seinen anderen Zweig und liest den Schalter so, wie er ist.\nRückgabe: eine Ganzzahl, immer 0.\nSeit: 3.00",
args = "()",
returns = "(padding)",
},
controllerHowMany = {
type = "function",
description = "Hypseus-Erweiterung. Wie viele Gamepads geöffnet sind, von den vier Slots, die Singe hat. Da jeder Joystick, den Singe öffnen kann, zum Gamepad wird (siehe Jedes Gerät ist ein Gamepad), werden hier auch ein Arcade-Encoder oder ein Spinner mitgezählt.\nRückgabe: Zahl, 0 bis 4.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "(number)",
},
controllerIsValid = {
type = "function",
description = "Hypseus-Erweiterung. Gibt zurück, ob gerade ein Controller im Slot geöffnet ist; Controller kommen und gehen beim Ein- und Ausstecken im laufenden Betrieb, frag also vor jedem controllerDoRumble. Ein Index außerhalb von 0 bis 3 bricht das Skript ab.\nRückgabe: Boolean.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(controller)",
returns = "(boolean)",
},
controllerSetPadding = {
type = "function",
description = "Hypseus-Erweiterung, angenommen und ignoriert. Warum es den Offset, den sie verlangt, in Singe nicht gibt, steht bei controllerGetPadding. Ihn einzuschalten, ohne die Ereignisse zu markieren, wäre schlimmer, als ihn ausgeschaltet zu lassen, weil das Spiel dann einen Offset von Schaltercodes abziehen würde, die nie einen trugen.\nRückgabe: nichts.\nSeit: 3.00",
args = "(boolean)",
returns = "()",
},
daphneGetHeight = {
type = "function",
description = "Aliase in Framework.singe Bevorzuge die singe*-Entsprechungen.",
args = "()",
returns = "()",
anchor = "unimplementedandlegacy",
},
daphneGetWidth = {
type = "function",
description = "Aliase in Framework.singe Bevorzuge die singe*-Entsprechungen.",
args = "()",
returns = "()",
anchor = "unimplementedandlegacy",
},
daphneScreenshot = {
type = "function",
description = "Aliase in Framework.singe Bevorzuge die singe*-Entsprechungen.",
args = "()",
returns = "()",
anchor = "unimplementedandlegacy",
},
debugPrint = {
type = "function",
description = "Gibt eine Zeile auf der Konsole (Standardausgabe) aus. Wurde Singe mit --noconsole gestartet, wird nichts ausgegeben; mit --trace landen der Aufruf und seine Nachricht außerdem in trace.txt. Das Argument muss ein String oder eine Zahl sein; alles andere bricht das Skript ab, verpacke Werte also in tostring oder verwende string.format. Der Aufruf ist billig genug, um im ausgelieferten Code zu bleiben, wird aber nicht gedrosselt, eine Ausgabe in onOverlayUpdate läuft also in jedem Frame.\nSeit: 1.x",
args = "(message)",
returns = "()",
},
discAudio = {
type = "function",
description = "Schaltet einen Kanal der Tonspur der Disc ein oder aus. Der Kanal wird auf die eingestellte Laserdisc-Lautstärke (--volume_vldp, Standard 100) gesetzt, wenn enabled true ist, und auf 0, wenn es false ist; der andere Kanal bleibt, wie er ist. Viele Originaltitel hatten Erzählung oder eine Datenspur nur auf einem Kanal, und mit diesem Aufruf bringst du sie zum Schweigen. Ein anderer Kanal als 1 oder 2 beendet das Skript. Ohne Disc tut der Aufruf nichts.\nSeit: 1.x",
args = "(channel, enabled)",
returns = "()",
},
discAudioSuffix = {
type = "function",
description = "Hypseus-Erweiterung. Schaltet die Disc auf eine eigene Audiodatei neben ihrem Video um: <base><suffix>.ogg, wobei die Basis der Name der Videodatei ohne Endung ist, sodass movie.m2v mit \"-es\" die Datei movie-es.ogg abspielt. Die Datei wird beim aktuellen Frame geöffnet, und die Wiedergabe richtet sich neu aus, wie bei discSetAudioTrack; Lautstärke, Wiedergabezustand und Spurindex bleiben erhalten, sofern die neue Datei so viele Spuren hat. Mit einer Frame-Datei schaltet jedes Segment um. Ein leeres Suffix stellt das Standardaudio wieder her: die .ogg neben einer .m2v oder den Ton in jedem anderen Container. Gibt true zurück, wenn die Datei geöffnet wurde; fehlt sie, läuft das bisherige Audio weiter, nichts wird gemerkt, und false kommt zurück (Hypseus hinterlässt in diesem Fall Stille). Das Suffix wird vergessen, wenn das Skript neu geladen wird. Ohne Disc gibt der Aufruf false zurück. Verwende ihn für ein Sprachmenü, dessen Spuren als eigene Dateien mitgeliefert werden; Spuren innerhalb einer Datei sind Aufgabe von discSetAudioTrack.\nRückgabe: Boolean.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(suffix: string)",
returns = "(boolean)",
},
discChangeSpeed = {
type = "function",
description = "Tut nichts. Echte Laserdisc-Player konnten mit einer anderen Geschwindigkeit als 1x laufen; der Software-Player von Singe kann das nicht, deshalb nimmt der Aufruf beliebige Argumente an, schreibt eine Trace-Zeile und kehrt zurück. Er bleibt erhalten, damit Skripte von vor 2.00 ohne Änderungen laden.\nSeit: 1.x",
args = "(...)",
returns = "()",
},
discGetAudioTrack = {
type = "function",
description = "Gibt den nullbasierten Index der Tonspur zurück, die die Disc gerade abspielt. Beim Start wählt die Engine die durch --audio oder den Eintrag AUDIO_TRACK in games.dat genannte Spur (Standard 0), sofern die Disc so viele Spuren hat. Gibt ohne Disc 0 zurück.\nRückgabe: ganzzahliger Spurindex.\nSeit: 2.10",
args = "()",
returns = "(integer)",
},
discGetAudioTracks = {
type = "function",
description = "Gibt zurück, wie viele Audiostreams die Videodatei der Disc enthält. Mehrere Streams sind typischerweise alternative Synchronfassungen. Ein stummes Video meldet 0, ebenso ein Spiel ohne Disc, sichere Schleifen und Modulo-Rechnungen also gegen null ab.\nRückgabe: ganzzahlige Anzahl, 0 oder mehr.\nSeit: 2.10",
args = "()",
returns = "(integer)",
},
discGetFrame = {
type = "function",
description = "Gibt den Frame zurück, den die Disc gerade zeigt. Mit einer Frame-Datei ist die Nummer die Position in der zusammengesetzten Folge, Segmentgrenzen sind für das Skript also unsichtbar. Gibt 0 zurück, solange die Disc gestoppt ist, und ohne Disc. Frag ihn in onOverlayUpdate ab, um darauf zu reagieren, dass das Video einen Entscheidungspunkt erreicht.\nRückgabe: ganzzahlige Frame-Nummer.\nSeit: 1.x",
args = "()",
returns = "(integer)",
},
discGetFrameCount = {
type = "function",
description = "Die Anzahl der Frames auf der Disc, also eins mehr als der höchste Frame, den discSearch findet. Eine Frame-Datei antwortet für die ganze Disc statt für das laufende Segment, die Anzahl ändert sich also nicht, wenn Segmente kommen und gehen. Ohne Disc antwortet sie mit 0.\nRückgabe: ganzzahlige Anzahl der Frames, 0 ohne Disc.\nSeit: 3.00.",
args = "()",
returns = "(integer)",
},
discGetHeight = {
type = "function",
description = "Gibt die Höhe des Disc-Videos in Pixeln zurück. Ohne Disc gibt es die Höhe der Zeichenfläche zurück (CANVAS_Y in games.dat oder --canvas, Standard 480), es ist also immer die Größe des Hintergrunds, über den das Overlay gestreckt wird. Kombiniere es mit discGetWidth, um dem Overlay dieselbe Auflösung wie dem Video zu geben.\nRückgabe: ganzzahlige Höhe in Pixeln.\nSeit: 2.00",
args = "()",
returns = "(integer)",
},
discGetLanguage = {
type = "function",
description = "Gibt das in der Videodatei gespeicherte Sprach-Tag für eine der Tonspuren der Disc zurück. Das Tag ist ein dreibuchstabiger ISO-639-Code wie \"eng\" oder \"jpn\". Spuren ohne dreibuchstabiges Tag ergeben \"unk\", ebenso jede Spur, wenn es keine Disc gibt. Mit Disc beendet eine Spur außerhalb von 0 bis discGetAudioTracks() - 1 das Skript.\nRückgabe: String mit dem Sprachcode.\nSeit: 2.10",
args = "(track)",
returns = "(string)",
},
discGetLanguageDescription = {
type = "function",
description = "= videoGetLanguageDescription\nSchlägt den englischen Namen eines Sprachcodes nach. Anders als die übrigen video*-Funktionen nimmt sie kein Handle; sie ist ein reines Nachschlagen in einer Tabelle, das zweibuchstabige Codes nach ISO 639-1 und dreibuchstabige Codes nach ISO 639-2 (sowohl die T- als auch die B-Form) annimmt, verglichen ohne Rücksicht auf Groß- und Kleinschreibung. Unbekannte Codes, auch das \"unk\", das für Spuren ohne Tag zurückkommt, ergeben \"Unknown\". Framework.singe stellt sie zur Symmetrie mit der Disc-API auch als discGetLanguageDescription bereit.\nRückgabe: String mit dem Namen der Sprache oder \"Unknown\".\nSeit: 2.10",
args = "(code)",
returns = "(string)",
anchor = "videogetlanguagedescription",
},
discGetState = {
type = "function",
description = "Gibt den Transportzustand der Disc als eine der Konstanten DISC_* zurück. Ein Spiel ohne Disc meldet DISC_EJECTED; nach discStop meldet die Disc DISC_STOPPED bis zum nächsten discPlay, discSearch oder discSkipToFrame; ansonsten ist der Zustand DISC_PLAYING, solange das Video vorrückt, und DISC_PAUSED, wenn nicht. Einen eigenen Suchzustand gibt es nicht; eine Disc, die gerade springt, meldet DISC_PAUSED oder DISC_PLAYING, je nachdem, was angefordert wurde.\nRückgabe: eine der folgenden Konstanten, die die Engine definiert und die jedem Skript zur Verfügung stehen.\nSeit: 1.x (RDG)",
args = "()",
returns = "(state)",
},
discGetSubtitleLanguage = {
type = "function",
description = "Die Sprache, mit der eine Untertitelspur im eigenen Container der Disc gekennzeichnet ist, als der ISO-639-Code, den die Datei trägt (eng, fra, spa). Eine Spur, die die Datei mit nichts kennzeichnet, ergibt einen leeren String, und das ist kein Fehler -- viele Dateien kennzeichnen gar nichts.\nRückgabe: ein String.\nSeit: 3.00.",
args = "(track: number)",
returns = "(language)",
},
discGetSubtitleTracks = {
type = "function",
description = "Wie viele Untertitelspuren der eigene Container der Disc enthält. 0 ohne Disc und 0 für eine Disc, deren Untertitel als eigene .srt mitgeliefert werden -- was die übliche Anordnung ist und wofür srtLoad da ist.\nRückgabe: eine Zahl.\nSeit: 3.00.",
args = "()",
returns = "(count)",
},
discGetWidth = {
type = "function",
description = "Gibt die Breite des Disc-Videos in Pixeln zurück. Ohne Disc gibt es die Breite der Zeichenfläche zurück (CANVAS_X in games.dat oder --canvas, Standard 720). Zusammen mit discGetHeight ist das die Größe, auf die das Overlay skaliert wird, weshalb das mitgelieferte Menü beide an overlaySetResolution übergibt.\nRückgabe: ganzzahlige Breite in Pixeln.\nSeit: 2.00",
args = "()",
returns = "(integer)",
},
discPause = {
type = "function",
description = "Hält die Wiedergabe beim aktuellen Frame an, der auf dem Bildschirm bleibt. Der Ton der Disc pausiert mit. Der Aufruf wird ignoriert, solange die Disc gestoppt ist, und tut ohne Disc nichts. Fortsetzen mit discPlay.\nSeit: 1.x",
args = "()",
returns = "()",
},
discPauseAtFrame = {
type = "function",
description = "Springt zu frame, zeigt ihn und pausiert. Das ist dieselbe Bindung wie discSearch unter einem zweiten Namen; die beiden sind in jeder Hinsicht austauschbar, einschließlich der dort beschriebenen Regeln für die Begrenzung. Bevorzuge discSearch in neuem Code und behalte discPauseAtFrame nur beim Portieren alter Skripte.\nSeit: 1.18",
args = "(frame)",
returns = "()",
},
discPlay = {
type = "function",
description = "Startet die Wiedergabe beim aktuellen Frame oder setzt sie fort und hebt den von discStop gesetzten Stoppzustand auf. Der Ton läuft mit dem Video weiter, und die Wiedergabeuhr startet beim aktuellen Frame neu, damit eine lange Pause keinen Sprung verursacht. Tut ohne Disc nichts, außer das Stopp-Flag zu löschen.\nSeit: 1.x",
args = "()",
returns = "()",
},
discSearch = {
type = "function",
description = "Springt mit der Disc zu frame, zeigt diesen Frame und pausiert darauf; war die Disc gestoppt, wird der Stoppzustand aufgehoben. Die Disc hält den Frame bis zu discPlay, discSkipToFrame oder einem anderen Transportaufruf. Ein negativer Frame wird auf den ersten Frame begrenzt und einer hinter dem Ende auf den letzten; mit einer Frame-Datei wird das Segment gewählt, das den Frame enthält, und die Position innerhalb davon begrenzt. Tut ohne Disc nichts.\nSeit: 1.x",
args = "(frame)",
returns = "()",
},
discSearchBlanking = {
type = "function",
description = "Tut nichts. Auf Laserdisc-Hardware wählte das, ob der Bildschirm dunkel wurde, während der Player einen Frame suchte; der Software-Player von Singe springt, ohne dunkel zu werden, deshalb nimmt der Aufruf beliebige Argumente an, schreibt eine Trace-Zeile und kehrt zurück.\nSeit: 1.x",
args = "(...)",
returns = "()",
},
discSetAudioTrack = {
type = "function",
description = "Schaltet die Disc auf eine andere Tonspur um. Bereits eingereihtes Audio der alten Spur wird verworfen, und die Wiedergabe richtet sich neu aus, die Änderung ist also fast sofort zu hören. Mit Disc beendet eine Spur außerhalb von 0 bis discGetAudioTracks() - 1 das Skript; ohne Disc tut der Aufruf nichts. Verwende ihn, um ein Sprachmenü umzusetzen oder eine zwischen Sitzungen gespeicherte Vorliebe zu beachten.\nSeit: 2.10",
args = "(track)",
returns = "()",
},
discSetFPS = {
type = "function",
description = "Tut nichts. Die Bildrate stammt aus der Videodatei, deshalb nimmt der Aufruf beliebige Argumente an, schreibt eine Trace-Zeile und kehrt zurück. Nichts im mitgelieferten Framework.singe ruft ihn auf; das tun nur Skripte von vor 2.00.\nSeit: 1.x",
args = "(...)",
returns = "()",
},
discSkipBackward = {
type = "function",
description = "Springt um frames vom aktuellen Frame zurück, ohne den Wiedergabe- oder Pausenzustand zu ändern: eine laufende Disc spielt von der neuen Position aus weiter, eine pausierte bleibt dort pausiert. Der Aufruf wird ignoriert, solange die Disc gestoppt ist, und ohne Disc. Die Differenz wird nicht geprüft; ein negativer Wert springt vorwärts, und eine Differenz, die größer als der aktuelle Frame ist, wird bei Frame 0 begrenzt. Mit einer Frame-Datei gilt die Differenz für die Frame-Nummer, die discGetFrame meldet, ein Sprung kann also in ein früheres Segment hinüberreichen.\nSeit: 1.x",
args = "(frames: number)",
returns = "()",
},
discSkipBlanking = {
type = "function",
description = "Tut nichts. Früher wählte es auf Laserdisc-Hardware, ob der Bildschirm bei einem Sprung dunkel wurde; der Software-Player von Singe wird nie dunkel, deshalb nimmt der Aufruf beliebige Argumente an, schreibt eine Trace-Zeile und kehrt zurück.\nSeit: 1.x",
args = "(...)",
returns = "()",
},
discSkipForward = {
type = "function",
description = "Springt um frames vom aktuellen Frame vorwärts, ohne den Wiedergabe- oder Pausenzustand zu ändern. Das Spiegelbild von discSkipBackward: ignoriert, solange gestoppt, und ohne Disc, die Differenz wird nicht geprüft, und ein Ziel hinter dem letzten Frame wird beim letzten Frame begrenzt. Mit einer Frame-Datei gilt die Differenz für die Frame-Nummer, die discGetFrame meldet, ein Sprung kann also in ein späteres Segment hinüberreichen.\nSeit: 1.x",
args = "(frames: number)",
returns = "()",
},
discSkipToFrame = {
type = "function",
description = "Springt zu frame und spielt von dort ab, egal in welchem Zustand die Disc ist; wenn nötig, wird der Stoppzustand aufgehoben. Im Gegensatz dazu springt discSearch und pausiert. Ein Frame vor dem Anfang oder hinter dem Ende wird auf den ersten oder letzten Frame begrenzt; mit einer Frame-Datei wird das Segment gewählt, das den Frame enthält, und die Position innerhalb davon begrenzt. Tut ohne Disc nichts, außer das Stopp-Flag zu löschen.\nSeit: 1.x",
args = "(frame)",
returns = "()",
},
discStepBackward = {
type = "function",
description = "Bewegt die Disc genau einen Frame zurück und pausiert darauf, egal in welchem Wiedergabezustand sie vorher war. Ein Schritt bei Frame 0 bleibt auf Frame 0. Wird wie discSkipBackward ignoriert, solange die Disc gestoppt ist. Gedacht für framegenaues Debugging und Service-Bildschirme. Tut ohne Disc nichts.\nSeit: 1.x",
args = "()",
returns = "()",
},
discStepForward = {
type = "function",
description = "Bewegt die Disc genau einen Frame vorwärts und pausiert darauf, egal in welchem Wiedergabezustand sie vorher war. Ein Schritt auf dem letzten Frame bleibt auf dem letzten Frame. Wie discStepBackward wird der Aufruf ignoriert, solange die Disc gestoppt ist. Tut ohne Disc nichts.\nSeit: 1.x",
args = "()",
returns = "()",
},
discStop = {
type = "function",
description = "Stoppt die Disc. Die Wiedergabe hält an, das Video wird durch den klassischen blauen Bildschirm ersetzt, discGetState meldet DISC_STOPPED, und discGetFrame gibt 0 zurück, bis die Disc wieder gestartet wird. Während sie gestoppt ist, werden discPause, discSkipForward, discSkipBackward, discStepForward und discStepBackward ignoriert. Jeder der Aufrufe discPlay, discSearch oder discSkipToFrame hebt den Stoppzustand auf. Ein zweites discStop wird ignoriert.\nSeit: 1.x",
args = "()",
returns = "()",
},
drawTransparent = {
type = "function",
description = "Hypseus-Erweiterung. Entscheidet, ob Farbe 0 auf den danach geladenen Sprites und dem danach gerenderten Text transparent gezeichnet wird. false, der Standard, stanzt Farbe 0 aus, wie Hypseus es tut: Palettenindex 0 oder reines Schwarz, und das schließt deckendes Schwarz in einem Bild mit Alphakanal ein, sodass schwarze Schrift oder ein schwarzer Umriss verschwindet. true zeichnet sie allein nach ihrem Alphakanal, sodass deckendes Schwarz schwarz bleibt. Bereits geladene Sprites behalten die Einstellung, mit der sie geladen wurden, und jedes Skript beginnt bei false.\nRückgabe: nichts.\nSeit: 3.00",
args = "(boolean)",
returns = "()",
},
emitterBurst = {
type = "function",
description = "Erzeugt count Partikel auf einmal nach dem aktuellen Rezept, mit oder ohne Strom: eine Explosion, ein Spritzer, ein Wölkchen. Es werden nur so viele erzeugt, wie im Pool Platz haben; emitterSetMax legt den Platz fest. Ein 2D-Emitter stößt sie an seinem Punkt von emitterSetPosition aus, ein 3D-Emitter an seinem Knoten, verteilt über emitterSetRadius.\nSeit: 3.00.",
args = "(emitter, count)",
returns = "()",
},
emitterClear = {
type = "function",
description = "Tötet jetzt jedes lebende Partikel und vergisst jeden noch geschuldeten Bruchteil eines Partikels. Der Strom wird nicht gestoppt: ein gestarteter Emitter erzeugt im nächsten Frame weiter neue Partikel, ruf also auch emitterStop auf, um ihn endgültig zu leeren. Verwende es, wenn eine Szene wechselt und die alten Funken nicht nachglimmen dürfen.\nSeit: 3.00.",
args = "(emitter)",
returns = "()",
},
emitterDelete = {
type = "function",
description = "Entfernt den Emitter, seine lebenden Partikel und seine Kopie der Textur sofort; nichts blendet aus. Verwende stattdessen emitterStop, um die letzten Partikel zu Ende leben zu lassen. Ein 3D-Emitter wird auch von selbst entfernt, wenn sein Knoten gelöscht wird. Ein Handle, das kein lebender Emitter ist, beendet das Skript, leere die Variable also danach.\nSeit: 3.00.",
args = "(emitter)",
returns = "()",
},
emitterDraw = {
type = "function",
description = "Nur 2D, aus onOverlayUpdate: stellt die Partikel des Emitters in die Warteschlange, damit sie in diesem Frame gezeichnet werden, über oder unter dem Overlay je nach emitterSetLayer, in Overlay-Koordinaten, die auf das Fenster abgebildet werden. Emitter auf derselben Ebene zeichnen in der Reihenfolge, in der sie eingereiht wurden. Die Warteschlange leert sich in jedem Frame, der Aufruf gehört also in jeden Frame, in dem die Partikel zu sehen sein sollen; einen Emitter nicht zu zeichnen, hält ihn nicht an. Bis zu 64 Emitter pro Ebene werden in einem Frame gezeichnet. Ein 3D-Emitter zeichnet sich selbst in der Szene und beendet hier das Skript.\nSeit: 3.00.",
args = "(emitter)",
returns = "()",
},
emitterGetCount = {
type = "function",
description = "Wie viele Partikel des Emitters in diesem Frame leben, 0 bis zur Größe des Pools. Nützlich, um einen Pool abzustimmen, für ein Budget auf dem Bildschirm oder um zu wissen, wann ein Stoß verklungen ist.\nRückgabe: Die Anzahl der lebenden Partikel, eine Ganzzahl.\nSeit: 3.00.",
args = "(emitter)",
returns = "(count)",
},
emitterIsActive = {
type = "function",
description = "Ob der Emitter strömt oder noch lebende Partikel hat: true ab emitterStart oder emitterBurst, bis der Strom gestoppt und das letzte Partikel gestorben ist, false, sobald die Explosion vorbei ist. Ein strömender Emitter, dessen Pool gerade leer ist, ist trotzdem aktiv.\nRückgabe: Boolean.\nSeit: 3.00.",
args = "(emitter)",
returns = "(boolean)",
},
emitterNew = {
type = "function",
description = "Erzeugt einen Emitter. Ohne Argument ist es ein 2D-Emitter an der Overlay-Position (0, 0), der mit emitterSetPosition bewegt wird; mit einem Knoten ist es ein 3D-Emitter, dessen Partikel an der Weltposition dieses Knotens geboren werden, und er braucht die 3D-Szene, sodass der Aufruf auf einem Rechner ohne sie das Skript beendet (2D-Emitter funktionieren überall). Ein neuer Emitter strömt noch nicht; ruf emitterStart oder emitterBurst auf. Wird der Knoten gelöscht, werden seine Emitter mitgelöscht. Standardwerte: 50 Partikel pro Sekunde, die ein bis zwei Sekunden leben, 30 Grad Streuung, Weiß, das zu transparent verblasst, normales Blending, keine Schwerkraft, keine Dämpfung, keine Drehung, kein Radius, keine Textur, kein Schweif und keine Kollision, ein Pool von 1000; ein 2D-Emitter schickt sie mit 50 bis 100 Overlay-Einheiten pro Sekunde den Bildschirm hinauf und lässt sie von 16 auf 4 schrumpfen, ein 3D-Emitter mit 1 bis 2 Welteinheiten pro Sekunde die Y-Achse hinauf, schrumpfend von 0,2 auf 0,05.\nRückgabe: Das Handle des Emitters.\nSeit: 3.00.",
args = "([node])",
returns = "(emitter)",
},
emitterSetBlend = {
type = "function",
description = "Wie sich Partikel mit dem verbinden, was hinter ihnen liegt. PARTICLE_ALPHA (Standard) blendet normal, für Rauch, Staub, Regen und Trümmer; PARTICLE_ADD addiert Licht, für Feuer, Funken, Leuchten und Magie, und dunkelt nie ab. Wirkt sofort auf die lebenden Partikel. Alles andere als diese beiden Konstanten beendet das Skript.\nSeit: 3.00.",
args = "(emitter, mode)",
returns = "()",
},
emitterSetCollide = {
type = "function",
description = "Wovon Partikel abprallen. COLLIDE_NONE (Standard) ist nichts; COLLIDE_FLOOR ist eine waagerechte Ebene in der Höhe floor, unterhalb derer (größeres Y in 2D, kleineres Y in 3D) ein Partikel auf die Ebene zurückgesetzt und reflektiert wird; COLLIDE_SCENE ist die Physikwelt, nur für 3D-Emitter, mit einem Raycast pro Partikel entlang seiner Bewegung in jedem Frame, begrenzt auf 200 Raycasts pro Emitter und Frame und dort fortgesetzt, wo sie aufgehört haben, sodass ein großer Emitter die Kosten über ein paar Frames verteilt. Bei einem 2D-Emitter wird COLLIDE_SCENE angenommen und tut nichts. Ein anderer Modus als diese drei beendet das Skript.\nSeit: 3.00.",
args = "(emitter, mode [, bounce, friction, floor])",
returns = "()",
},
emitterSetColor = {
type = "function",
description = "Farbe und Deckkraft bei der Geburt (r, g, b, a) und beim Tod (r2, g2, b2, a2), jeweils 0 bis 255, gleichmäßig über die Lebensdauer des Partikels wechselnd; Werte außerhalb des Bereichs werden begrenzt. Standard: von Weiß und deckend zu Weiß und transparent. Die Tönung multipliziert die Textur oder die eingebaute Scheibe, ein weißes Bild nimmt die Farbe also genau an. Ein Ein- und Ausblenden braucht zwei Emitter oder eine Textur, in der die Form steckt; ein Rezept fährt eine einzige gerade Rampe.\nSeit: 3.00.",
args = "(emitter, r, g, b, a, r2, g2, b2, a2)",
returns = "()",
},
emitterSetDirection = {
type = "function",
description = "Die mittlere Richtung, in die neue Partikel aufbrechen; nur die Richtung zählt, nicht die Länge. 2D-Standard (0, -1), den Bildschirm hinauf, da Y im Overlay nach unten wächst; 3D-Standard (0, 1, 0), die Y-Achse der Welt hinauf. Ein 2D-Emitter ignoriert z; ein 3D-Emitter, der zwei Werte bekommt, erhält z = 0. Ein Nullvektor wird als (0, -1, 0) behandelt. Bei einem 3D-Emitter ist die Richtung in Weltachsen angegeben, nicht in denen des Knotens, dreh sie also selbst, wenn sich der Knoten dreht.\nSeit: 3.00.",
args = "(emitter, x, y [, z])",
returns = "()",
},
emitterSetDrag = {
type = "function",
description = "Wie schnell Partikel ihre Geschwindigkeit verlieren: in jedem Frame wird die Geschwindigkeit mit 1 - perSecond * dt multipliziert, nie unter 0, sodass 1 den größten Teil der Geschwindigkeit innerhalb einer Sekunde nimmt und 0 (der Standard) sie für immer behält. Negative Werte werden zu 0. Rauch, Glut und Feuerwerk werden langsamer; Funken und Regen nicht. Wirkt ab dem nächsten Frame auf die lebenden Partikel.\nSeit: 3.00.",
args = "(emitter, perSecond)",
returns = "()",
},
emitterSetFrames = {
type = "function",
description = "Mit einem animierten Sprite als Textur nimmt jedes neue Partikel einen zufälligen Frame von first bis last und behält ihn sein Leben lang; Frames zählen ab 0. Die Werte werden auf die Frames begrenzt, die die Textur hat, und last wird auf first angehoben, wenn es kleiner ist. Standard: nur Frame 0, auf den auch emitterSetTexture zurücksetzt. Mit der eingebauten Scheibe oder einem Sprite aus einem einzigen Frame hat der Bereich keine Wirkung.\nSeit: 3.00.",
args = "(emitter, first, last)",
returns = "()",
},
emitterSetGravity = {
type = "function",
description = "Eine konstante Beschleunigung auf jedes Partikel, in Overlay-Einheiten (2D) oder Welteinheiten (3D) pro Sekunde zum Quadrat: (0, 500) zieht 2D-Funken den Bildschirm hinunter, (0, -20) lässt 2D-Rauch aufsteigen, (0, -9.8, 0) ist die Erde in der Szene. Standard keine. Sie wirkt ab dem nächsten Frame auf die lebenden Partikel. Partikel sind keine Physikkörper; gib ihnen emitterSetCollide, damit sie von einem Boden oder der Szene abprallen.\nSeit: 3.00.",
args = "(emitter, x, y [, z])",
returns = "()",
},
emitterSetLayer = {
type = "function",
description = "Nur 2D: wohin emitterDraw die Partikel setzt. PARTICLE_OVER (Standard) zeichnet über allem auf dem Overlay; PARTICLE_UNDER zeichnet unter dem Overlay und über dem Video und der 3D-Szene, für Rauch hinter dem Punktestand. Bei einem 3D-Emitter wird die Einstellung angenommen und ignoriert. Alles andere als diese beiden Konstanten beendet das Skript.\nSeit: 3.00.",
args = "(emitter, layer)",
returns = "()",
},
emitterSetLife = {
type = "function",
description = "Wie lange jedes neue Partikel lebt, zufällig zwischen den beiden gezogen; Standard 1 bis 2. Seine Größe und Farbe laufen über diese Zeit von ihrem Anfang zu ihrem Ende, die Lebensdauer bestimmt also das Tempo jedes Ausblendens. Das Minimum wird bei 0.001 oder darüber gehalten, und das Maximum wird auf das Minimum angehoben, wenn es kleiner ist. Lebende Partikel behalten die Lebensdauer, mit der sie geboren wurden.\nSeit: 3.00.",
args = "(emitter, minSeconds, maxSeconds)",
returns = "()",
},
emitterSetLit = {
type = "function",
description = "Nur 3D: schattiert jedes Partikel nach den Lichtern und dem Himmel der Szene, als wäre es eine kleine Kugel, die zur Kamera zeigt, sodass Rauch die Farbe einer Feuerschale annimmt und Staub in der Sonne glitzert. Standardmäßig aus; Schatten werden nicht berücksichtigt. Mit PARTICLE_ADD wird die Beleuchtung trotzdem auf die Tönung angewendet, bevor sie addiert wird. Ein 2D-Emitter speichert den Wert und ignoriert ihn.\nSeit: 3.00.",
args = "(emitter, lit)",
returns = "()",
},
emitterSetLocal = {
type = "function",
description = "Ob lebende Partikel dem Emitter folgen. false (Standard) lässt jedes dort, wo es geboren wurde, sodass eine durch einen Raum getragene Fackel Rauch hinter sich lässt; true hält die ganze Wolke relativ zum Ursprung des Emitters, sodass sich der Abgasstrahl einer Schubdüse mit dem Schiff bewegt. Das Umschalten überführt die lebenden Partikel ohne Sprung von einem Bezugssystem ins andere. Bei einem 3D-Emitter ist der Ursprung die Weltposition des Knotens; bei einem 2D-Emitter ist es der Punkt von emitterSetPosition, eine lokale 2D-Wolke gleitet also ebenfalls mit. Schweife folgen derselben Regel.\nSeit: 3.00.",
args = "(emitter, local)",
returns = "()",
},
emitterSetMax = {
type = "function",
description = "Der Pool: wie viele Partikel gleichzeitig leben dürfen, Standard 1000. Ein voller Pool erzeugt keine weiteren, weder aus dem Strom noch aus einem Stoß, bis einige sterben. Eine Änderung der Anzahl baut den Pool neu und tötet jedes lebende Partikel, setz sie also vor dem Start. Bemiss den Pool als Rate mal längste Lebensdauer plus den größten Stoß. Eine Anzahl unter 1 beendet das Skript.\nSeit: 3.00.",
args = "(emitter, count)",
returns = "()",
},
emitterSetPosition = {
type = "function",
description = "Nur 2D: wo neue Partikel geboren werden, in Overlay-Koordinaten; Standard (0, 0). Setze die Position in jedem Frame, um einem Sprite oder einem 2D-Physikkörper zu folgen. Lebende Partikel bleiben, wo sie sind, außer emitterSetLocal ist eingeschaltet. Ein 3D-Emitter folgt seinem Knoten und beendet hier das Skript; bewege stattdessen den Knoten.\nSeit: 3.00.",
args = "(emitter, x, y)",
returns = "()",
},
emitterSetRadius = {
type = "function",
description = "Neue Partikel werden irgendwo innerhalb dieses Abstands vom Ursprung des Emitters geboren, gleichmäßig über eine Scheibe (2D) oder eine Kugel (3D), in Overlay- oder Welteinheiten. Standard 0, ein Punkt; negative Werte werden zu 0. Ein Radius füllt ein Volumen, einen Fackelkopf oder ein Stück Staub in der Luft, wo ein Punkt eine Nadel ergäbe.\nSeit: 3.00.",
args = "(emitter, radius)",
returns = "()",
},
emitterSetRate = {
type = "function",
description = "Wie viele Partikel pro Sekunde ein gestarteter Emitter erzeugt; Standard 50, negative Werte werden zu 0. Bruchteile summieren sich, sodass 0.5 alle zwei Sekunden eines erzeugt. Ändere den Wert während des Stroms, um eine Flamme oder eine Schubdüse zu drosseln. Ein voller Pool (emitterSetMax) erzeugt keine weiteren, bis einige sterben, egal bei welcher Rate.\nSeit: 3.00.",
args = "(emitter, perSecond)",
returns = "()",
},
emitterSetSize = {
type = "function",
description = "Größe bei der Geburt und beim Tod, in Overlay-Einheiten (2D) oder Welteinheiten (3D), gleichmäßig über die Lebensdauer des Partikels wechselnd; Standard 16 bis 4 in 2D und 0.2 bis 0.05 in 3D. variation (0 bis 1, Standard 0) skaliert beide Größen jedes neuen Partikels mit einem einzigen Zufallsfaktor zwischen 1 - variation und 1 + variation, sodass ein Wölkchen sein ganzes Leben lang etwas größer oder kleiner ist. Negative Größen werden zu 0, und variation wird begrenzt. Ein texturiertes Partikel wird als Quadrat dieser Größe gezeichnet; ein breiteres Bild wird gestaucht.\nSeit: 3.00.",
args = "(emitter, start, finish [, variation])",
returns = "()",
},
emitterSetSoftness = {
type = "function",
description = "Nur 3D: blendet ein Partikel über distance Welteinheiten aus, wo es auf Geometrie dahinter trifft, sodass ein Rauchwölkchen keine harte Linie zeichnet, wo es eine Wand kreuzt, und ein Springbrunnen in sein Becken eintaucht, statt es zu zerschneiden. 0 (der Standard) schaltet es aus; negative Werte werden zu 0. Solange irgendein Emitter es verwendet, wird die Tiefe der Szene pro Frame einmal mehr gerendert, ein Raspberry Pi sollte es also sparsam einsetzen. Ein 2D-Emitter speichert den Wert und ignoriert ihn.\nSeit: 3.00.",
args = "(emitter, distance)",
returns = "()",
},
emitterSetSpeed = {
type = "function",
description = "Anfangsgeschwindigkeit jedes neuen Partikels, zufällig zwischen den beiden gezogen, in Overlay-Einheiten pro Sekunde (2D) oder Welteinheiten pro Sekunde (3D); Standard 50 bis 100 in 2D und 1 bis 2 in 3D. Das Maximum wird auf das Minimum angehoben, wenn es kleiner ist. Die Geschwindigkeit bestimmt, wie weit ein Partikel kommt, bevor Dämpfung, Schwerkraft und seine Lebensdauer übernehmen.\nSeit: 3.00.",
args = "(emitter, min, max)",
returns = "()",
},
emitterSetSpin = {
type = "function",
description = "Drehgeschwindigkeit jedes neuen Partikels in Grad pro Sekunde, zufällig zwischen den beiden gezogen; negative Werte drehen andersherum, und ein Bereich, der 0 überspannt, ergibt beides. Jedes Partikel beginnt mit einem zufälligen Winkel, ob es sich dreht oder nicht. Standard keine. Das Maximum wird auf das Minimum angehoben, wenn es kleiner ist. Die Drehung sieht man an einem texturierten Partikel oder einem Schweif; die eingebaute Scheibe ist rund und sieht in jedem Winkel gleich aus.\nSeit: 3.00.",
args = "(emitter, min, max)",
returns = "()",
},
emitterSetSpread = {
type = "function",
description = "Der halbe Winkel des Kegels (3D) oder Fächers (2D) um die Richtung, in den neue Partikel geworfen werden, 0 bis 180; 0 ist eine gerade Linie, 180 jede Richtung. Standard 30; Werte außerhalb des Bereichs werden begrenzt. In 3D werden die Richtungen gleichmäßig über die Kappe des Kegels verteilt, sodass sich ein weiter Kegel nicht zu seiner Achse hin ballt.\nSeit: 3.00.",
args = "(emitter, degrees)",
returns = "()",
},
emitterSetTexture = {
type = "function",
description = "Das Bild, das jedes Partikel trägt: ein geladenes Sprite oder keines (ein Argument oder nil) für die eingebaute weiche Scheibe. Der Emitter behält seine eigene Kopie der Pixel des Sprites, jeden Frame eines animierten Sprites eingeschlossen, das Sprite kann danach also entladen werden. Das Setzen der Textur setzt den Frame-Bereich auf Frame 0 zurück und setzt jedes lebende Partikel auf Frame 0, ruf emitterSetFrames also danach auf, nicht davor. Blending und Tönung wirken auf das Bild wie auf die Scheibe.\nSeit: 3.00.",
args = "(emitter [, sprite])",
returns = "()",
},
emitterSetTrail = {
type = "function",
description = "Ein Band hinter jedem Partikel durch seine letzten length Positionen, eine pro Frame aufgezeichnet (2 bis 16; 0 oder 1 für keines, der Standard), width breit in Welt- oder Overlay-Einheiten, in 2D wie in 3D. Das Band trägt die aktuelle Tönung des Partikels, verblasst zu seinem Ende hin zu transparent und wird mit der mittleren Spalte des Partikelbilds texturiert, sodass der weiche Rand der Scheibe zum Rand des Bands wird. Die Werte werden auf den Bereich begrenzt. Eine Änderung der Länge baut den Speicher der Schweife neu, lebende Partikel beginnen ihre Bänder also von vorn. Funken, Glut, Leuchtspurgeschosse, Kometen.\nSeit: 3.00.",
args = "(emitter, length, width)",
returns = "()",
},
emitterStart = {
type = "function",
description = "Beginnt den stetigen Strom mit der eingestellten Rate; von da an erzeugt der Emitter in jedem Frame Partikel bis emitterStop. Einen Emitter zu starten, der bereits strömt, ändert nichts. Der Strom braucht keinen Zeichenaufruf, um zu laufen; ein 2D-Emitter, der strömt, aber nicht gezeichnet wird, verbraucht trotzdem seinen Pool.\nSeit: 3.00.",
args = "(emitter)",
returns = "()",
},
emitterStop = {
type = "function",
description = "Beendet den Strom; die lebenden Partikel leben ihr Leben zu Ende, und jeder noch geschuldete Bruchteil eines Partikels wird verworfen. emitterBurst funktioniert auch bei einem gestoppten Emitter, und emitterIsActive bleibt true, bis das letzte Partikel stirbt. Verwende emitterClear, um die Partikel außerdem sofort zu entfernen.\nSeit: 3.00.",
args = "(emitter)",
returns = "()",
},
fontLoad = {
type = "function",
description = "Öffnet eine TrueType-Schriftart in einer Punktgröße und macht sie zur ausgewählten Schriftart. Die Größe ist für die Lebensdauer des Handles fest, lade dieselbe Datei also einmal pro benötigter Größe. Der Name geht wie jedes andere Asset durch das virtuelle Dateisystem; stelle DIR voran für Dateien, die mit deinem Spiel mitgeliefert werden, oder verwende Singe/FreeSansBold.ttf für den mitgelieferten Schriftschnitt. Eine Datei, die sich nicht öffnen lässt, beendet das Skript mit Unable to open und dem Namen.\nRückgabe: ganzzahliges Schriftart-Handle.\nSeit: 1.x",
args = "(filename, pointSize: integer)",
returns = "(integer)",
},
fontPrint = {
type = "function",
description = "Rendert einen String mit der ausgewählten Schriftart, der aktuellen Qualität und der aktuellen Vordergrundfarbe (bei FONT_QUALITY_SHADED zusätzlich der Hintergrundfarbe) und blittet ihn dann mit seiner oberen linken Ecke bei (x, y) auf das Overlay. Ruf es aus onOverlayUpdate auf, wenn nötig in jedem Frame: die Engine behält jeden String, den sie rendert, mit Schriftart, Qualität, Farben und Text als Schlüssel, und ein späterer Aufruf, der denselben verlangt, blittet ihn nur noch. Strings, die etwa eine Sekunde lang nicht ausgegeben wurden, werden vergessen, und die Strings einer Schriftart verschwinden, wenn sie entladen wird, sodass Text, der sich ändert, nicht mehr kostet als schon immer, und Text, der sich nicht ändert, fast nichts. Eine ganze Seite Highscores in jedem Frame neu auszugeben ist in Ordnung. Ohne ausgewählte Schriftart endet das Skript mit einem Fehler.\nSeit: 1.x",
args = "(x, y, text)",
returns = "()",
},
fontQuality = {
type = "function",
description = "Wählt, wie fontPrint und fontToSprite Text von nun an rastern. Die Einstellung ist global, nicht pro Schriftart, und beginnt bei FONT_QUALITY_SOLID. Sprites, die fontToSprite schon erzeugt hat, behalten die Qualität, mit der sie gerendert wurden. Ein Wert außerhalb der drei Konstanten beendet das Skript mit einem Fehler.\nSeit: 1.x",
args = "(mode)",
returns = "()",
},
fontSelect = {
type = "function",
description = "Macht eine geladene Schriftart zu der, die fontPrint und fontToSprite verwenden. Die Auswahl bleibt bis zum nächsten fontSelect oder fontLoad bestehen, da auch das Laden auswählt. Sie kann so oft wie nötig geändert werden, auch mehrmals innerhalb eines onOverlayUpdate. Ein unbekanntes oder entladenes Handle (oder gar keine Zahl) lässt die aktuelle Schriftart ausgewählt und gibt eine Warnung aus, so wie Hypseus Singe es durchgehen lässt.\nSeit: 1.x",
args = "(id)",
returns = "()",
},
fontToSprite = {
type = "function",
description = "Rendert einen String mit der ausgewählten Schriftart, Qualität und den Farben in ein neues Sprite und gibt dessen Handle zurück. Das Sprite ist von da an unabhängig von der Schriftart, übersteht also fontUnload, und es funktioniert mit jedem sprite*-Aufruf: zeichne es, miss es, skaliere oder drehe es und gib es mit spriteUnload frei. Für einen String, der sich ändert, rendere ein neues Sprite und entlade das alte. Ohne ausgewählte Schriftart endet das Skript mit einem Fehler.\nRückgabe: ganzzahliges Sprite-Handle.\nSeit: 1.x",
args = "(text)",
returns = "(integer)",
},
fontUnload = {
type = "function",
description = "Schließt eine Schriftart und macht ihr Handle ungültig. Sprites, die mit fontToSprite daraus gemacht wurden, sind nicht betroffen. War die entladene Schriftart die ausgewählte, ist danach keine Schriftart ausgewählt, und das nächste fontPrint oder fontToSprite beendet das Skript mit einem Fehler, bis fontSelect oder fontLoad eine andere wählt.\nSeit: 2.00",
args = "(id)",
returns = "()",
},
getFValue = {
type = "function",
description = "Hypseus-Erweiterung. Gibt die als --fvalue angegebene Zahl zurück oder 0, wenn die Option nicht verwendet wurde. Sie ist ein Kanal für eine einzige Zahl von demjenigen, der Singe gestartet hat, zum Spiel, gedacht für einen Wert, den ein Frontend von Start zu Start ändern will -- einen Schwierigkeitsgrad, eine Anzahl Start-Credits, einen Menüindex. Die Engine reicht ihn nur durch.\nRückgabe: Zahl.\nSeit: 3.00 (Hypseus)",
args = "()",
returns = "(number)",
},
getUserString = {
type = "function",
description = "Hypseus-Erweiterung, immer ein leerer String. Trotz des Namens ist es kein String, den der Benutzer gesetzt hat: Hypseus antwortet mit der Installations-ID des Rechners, die es mit Netzwerkstatistiken sendet, genommen aus der MachineGuid von Windows oder der Machine-ID von Linux. Singe sendet nirgendwohin etwas und gibt einem Spiel keinen Fingerabdruck des Rechners, auf dem es läuft.\nRückgabe: ein String, immer leer.\nSeit: 3.00",
args = "()",
returns = "(id)",
},
guiClose = {
type = "function",
description = "Entlädt das Dokument aus der GUI und verwirft seine Elemente, seine Handler und seine Skripte. Das Dokument-Handle ist danach ungültig. Ein Dokument, das sein eigenes Skript über die API von RmlUi schließt (document:Close()), wird auf dieselbe Weise entladen. Löst bei einem ungültigen Handle No document N in GUI G aus.\nSeit: 3.00.",
args = "(gui, document)",
returns = "()",
},
guiDelete = {
type = "function",
description = "Gibt die GUI, jedes Dokument darin und ihre Textur frei und beendet das Aktualisieren und Rendern in jedem Frame, das sie kostete. Materialien, die sie über materialSetGui zeigen, kehren zu ihrer eigenen Textur zurück. Das Handle ist danach ungültig und beendet das Skript, wenn es noch einmal verwendet wird; da eine GUI weiter rendert, ob sie gezeichnet wird oder nicht, lösche die, mit denen ein Spiel fertig ist, statt sie zu verstecken.\nSeit: 3.00.",
args = "(gui)",
returns = "()",
},
guiDraw = {
type = "function",
description = "Legt die Textur der GUI für diesen Frame über das Overlay, in Overlay-Koordinaten, sodass sie wie alles andere auf dem Overlay dem Sinden-Rahmen und der Overscan-Skalierung folgt: mit einem Argument über das ganze Overlay, in ihrer eigenen Größe mit einer Ecke bei x, y oder skaliert in das Rechteck width mal height. Die Stelle des Aufrufs im Zeichnen des Skripts entscheidet, was unter der GUI liegt und was darüber: alles, was vorher auf das Overlay gezeichnet wurde, bleibt darunter, und alles, was danach gezeichnet wird -- bis zum nächsten guiDraw oder bis das Skript das nächste Mal an der Reihe ist -- kommt auf eine eigene Ebene, die über diese GUI gelegt wird. Ein Zeiger, der nach dem HUD gezeichnet wird, liegt über dem HUD; ein danach gezeichnetes zweites Dokument liegt über dem Zeiger, mit seiner eigenen Ebene darüber. Bis zu sechzehn solcher Ebenen pro Frame; ein Aufruf darüber hinaus zeichnet seine GUI ohne etwas darüber. overlayClear leert die Ebene, auf die gerade gezeichnet wird, und overlaySetMonochrome macht nur das Basis-Overlay grau. Der Aufruf gilt einen Frame; mach ihn aus onOverlayUpdate (oder singeMain) in jedem Frame, in dem die GUI sichtbar sein soll. GUIs zeichnen über dem Overlay in der Reihenfolge der Aufrufe (die letzte oben), unter Partikeln in PARTICLE_OVER und der Pausenanzeige, und die GUI, die zuletzt unter dem Zeiger gezeichnet wurde, ist die, die die Maus bekommt. Bis zu sechzehn Aufrufe pro Frame werden beachtet; weitere werden ignoriert. Jede andere Anzahl von Argumenten löst Expected 1, 3 or 5 arguments aus.\nSeit: 3.00.",
args = "(gui [, x, y, width, height])",
returns = "()",
},
guiDrawScreen = {
type = "function",
description = "Dasselbe wie guiDraw, nur dass das Rechteck über das ganze Fenster gemessen wird statt über das Bild. Die Koordinaten sind weiterhin Overlay-Koordinaten -- 0, 0 ist oben links im Fenster und overlayGetWidth(), overlayGetHeight() unten rechts -- sodass eine GUI auf der Bezel-Grafik neben dem Bild, darüber oder darunter sitzen kann. Ohne Bezel und ohne --scalefactor, --shiftx oder --shifty ist das Bild das ganze Fenster, und dies ist genau guiDraw.\nSeit: 3.00.",
args = "(gui [, x, y, width, height])",
returns = "()",
},
guiGetHeight = {
type = "function",
description = "Die Höhe der GUI in ihren eigenen Pixeln, wie an guiNew übergeben. Beendet das Skript bei einem ungültigen Handle.\nRückgabe: Eine Ganzzahl.\nSeit: 3.00.",
args = "(gui)",
returns = "(height)",
},
guiGetStats = {
type = "function",
description = "Was das Rendern aller GUIs im letzten abgeschlossenen Frame gekostet hat, zum Abstimmen von Dokumenten, die Filter, Masken und Schatten verwenden (die alle über eine Ebene in der Größe der GUI zeichnen). Die Zähler gelten für alle GUIs zusammen. In einem Frame, in dem sich das Bild keiner GUI geändert hat, sind sie alle null, da nichts neu gezeichnet wurde (siehe guiRefresh).\nRückgabe: Eine Tabelle mit den Feldern drawCalls (indizierte Zeichenaufrufe, einschließlich Maskenschreibvorgängen, Kompositionen und Filterdurchgängen), layerPushes (betretene Ebenen für Filter, Maskenbilder und Box-Schatten), filterPasses (Durchgänge in voller Größe und Blits innerhalb von Filterketten; eine Unschärfe kostet mehrere), maskWrites (Zeichenaufrufe in die Stencil-Clipmaske), layerBytes (Bytes der derzeit belegten Ebenentexturen; jede hat die Größe ihrer GUI bei vier Bytes pro Pixel) und passes (begonnene Render-Durchgänge; jeder Ebenenwechsel beginnt einen).\nSeit: 3.00.",
args = "()",
returns = "(stats)",
},
guiGetValue = {
type = "function",
description = "Der Wert des Elements mit dieser id im Dokument, als String: der Wert eines Formularelements (der Text eines Textfelds, der value einer Option eines select, ein Schieberegler in der eigenen Formatierung von RmlUi wie \"85.000000\", das Attribut value eines Kontrollkästchens oder Optionsfelds, \"on\", wenn es keines hat, ob es angekreuzt ist oder nicht; sein Zustand ist sein Attribut checked, das über die API von RmlUi gelesen wird) oder bei jedem anderen Element sein inneres RML. Gibt nil zurück, wenn kein Element diese id hat, sodass eine Seite abgefragt werden kann, ohne das Skript zu beenden; ein falsches GUI- oder Dokument-Handle beendet es. Werte, die länger als 4095 Zeichen sind, werden abgeschnitten.\nRückgabe: Ein String oder nil.\nSeit: 3.00.",
args = "(gui, document, id)",
returns = "(value)",
},
guiGetWidth = {
type = "function",
description = "Die Breite der GUI in ihren eigenen Pixeln, wie an guiNew übergeben. Beendet das Skript bei einem ungültigen Handle.\nRückgabe: Eine Ganzzahl.\nSeit: 3.00.",
args = "(gui)",
returns = "(width)",
},
guiHide = {
type = "function",
description = "Versteckt das Dokument: es wird nicht gezeichnet und nimmt keine Eingaben an, behält aber seine Elemente und Werte, und guiShow bringt es so zurück, wie es war. Löst bei einem ungültigen Handle No document N in GUI G aus.\nSeit: 3.00.",
args = "(gui, document)",
returns = "()",
},
guiLoad = {
type = "function",
description = "Lädt ein RML-Dokument in die GUI, zeigt es an und gibt ein ganzzahliges Dokument-Handle für die anderen Aufrufe zurück. Der Name geht wie der eines Sprites durch das virtuelle Dateisystem und wird relativ zu dem Ordner aufgelöst, in dem Singe gestartet wurde, stelle also DIR voran für Dateien, die mit deinem Spiel mitgeliefert werden; Stylesheets, Bilder und Schriftarten, die im Dokument genannt werden, werden relativ zu der Datei aufgelöst, die sie nennt, und dann über dieselbe Suche, sodass ein gepacktes Spiel sie findet. Die <script>-Blöcke und on*-Attribute des Dokuments laufen im Lua-Zustand des Spiels, und es ist als rmlui.contexts[\"guiN\"].documents[\"<body id>\"] erreichbar. Ein Dokument, das sich nicht laden lässt, beendet das Skript mit dem Namen und dem Grund von RmlUi (eine fehlende Datei, ein Parse-Fehler); die eigenen Warnungen von RmlUi zu Markup und Stil gehen an die Konsole. Jede GUI fasst bis zu zweiunddreißig Dokumente.\nRückgabe: Das Dokument-Handle, eine Ganzzahl.\nSeit: 3.00.",
args = "(gui, filename)",
returns = "(document)",
},
guiLoadFont = {
type = "function",
description = "Lädt einen TrueType- oder OpenType-Schriftschnitt für jede GUI, sodass Dokumente ihn in font-family über den Familiennamen in der Datei nennen können (wobei font-weight und font-style unter den Schnitten einer Familie wählen). Mit fallback true bedient der Schnitt auch jede Glyphe, die kein anderer Schnitt hat, was bis dahin der engine-eigene Singe/FreeSansBold.ttf tut (Familie FreeSans, Gewicht fett, der Schnitt, den das mitgelieferte Theme verwendet). Lade Schriftarten vor den Dokumenten, die sie verwenden. Jeder Schnitt kostet einen Glyphenatlas pro Größe, in der er verwendet wird. Eine Datei, die sich nicht öffnen lässt, beendet das Skript mit Unable to load und dem Namen.\nSeit: 3.00.",
args = "(filename [, fallback])",
returns = "()",
},
guiNew = {
type = "function",
description = "Erzeugt eine GUI von width mal height Pixeln, die in jedem Frame in ihre eigene Textur gerendert wird, ob sie gezeichnet wird oder nicht, und gibt ihr Handle zurück. Die Größe ist der Koordinatenraum des Dokuments: 100% des Body ist die ganze Textur, und ein dp ist eines ihrer Pixel. Eine GUI in der Größe des Overlays passt zu einer Seite im Vollbild; ein HUD-Element oder ein Monitor in der Szene will eine kleinere, und ein Raspberry Pi will alles bescheiden. Eine neue GUI zeigt nur an, bis guiSetInput Eingaben einschaltet. Löst bei einer Größe von null oder kleiner The size must be positive aus und No GUI available, wenn schon sechzehn in Gebrauch sind oder der Rechner kein GPU-Gerät hat (eine GUI braucht dasselbe Gerät wie die 3D-Szene).\nRückgabe: Das GUI-Handle, eine Ganzzahl.\nSeit: 3.00.",
args = "(width, height)",
returns = "(gui)",
},
guiRefresh = {
type = "function",
description = "Zeichnet die GUI im nächsten Frame erneut, auch wenn sich scheinbar nichts an ihr geändert hat. Eine GUI wird nur neu gezeichnet, wenn sich ihr Bild ändert: wenn das Dokument eines Frames genau das zeichnet, was der letzte Frame gezeichnet hat, und dazwischen nichts Neues erzeugt wurde, enthält die Textur dieses Bild schon und wird behalten, was der GPU den größten Teil der Kosten einer GUI in den Frames erspart, in denen ein HUD oder ein Menü stillsteht. Änderungen über RML, RCSS, die Lua-Schnittstelle von RmlUi oder die gui*-Aufrufe werden alle bemerkt. Dieser Aufruf ist der Ausweg, falls doch einmal eine übersehen wird -- eine GUI, die aufhört, sich zu aktualisieren, wenn sie es sollte -- und ein Spiel sollte ihn nicht brauchen; wenn doch, ist das eine Meldung wert. Eine GUI, die es nicht gibt, beendet das Skript.\nSeit: 3.00.",
args = "(gui)",
returns = "()",
},
guiSetHandler = {
type = "function",
description = "guiSetHandler(gui, document, id, event, function)\nguiSetHandler(gui, document, id, event, nil)\nRuft function(gui, document, id, event, value) auf, wann immer das Element mit dieser id das genannte Ereignis auslöst: \"click\" für Schaltflächen und Zeilen, \"change\" für Formularelemente, \"submit\" für ein Formular oder jeden anderen Ereignisnamen von RmlUi (\"focus\", \"mouseover\", \"keydown\", ...). value ist der Wert des Elements in diesem Moment als String, so wie guiGetValue ihn zurückgeben würde (ein Schieberegler kommt so, wie RmlUi ihn formatiert, \"85.000000\", gib ihn also durch tonumber). Pro Element und Ereignis wird eine Funktion behalten; eine andere zu setzen ersetzt sie, und nil entfernt sie. Der Handler gehört zur id, nicht zu einem Element: setze ihn nach dem Neuaufbau erneut, wenn das Element ersetzt wird -- eine über inner_rml neu aufgebaute Liste erzeugt neue Elemente -- und er hängt sich an das Element, das die id jetzt trägt. Handler laufen, während die Ereignisse geschehen, zwischen den eigenen Callbacks des Spiels, und ein Fehler in einem beendet das Spiel wie ein Fehler in jedem Callback. Ids sind höchstens 63 Zeichen lang. Löst No element \"id\" in document N of GUI G aus, wenn das Element nicht existiert, und Argument 5 must be a function or nil bei allem anderen an dieser Stelle.\nSeit: 3.00.",
args = "(gui, document, id, event, function)",
returns = "()",
},
guiSetInput = {
type = "function",
description = "Ob Maus und Lightgun, Tasten, getippter Text und die Schalter des Frameworks von einem Pad oder einer Maus die GUI erreichen. Eine neue GUI zeigt nur an, was zu einem HUD oder einem Schild passt; schalte Eingaben für ein Menü oder ein Formular ein. Solange sie eingeschaltet sind, erreicht der Zeiger die GUI, wo auch immer sie flach gezeichnet (die zuletzt gezeichnete oben) oder auf einer Fläche in der Szene gezeigt wird, jede Taste geht an sie außer Tab, das die GUI nur bekommt, während in ein Textfeld getippt wird (RmlUi verwendet es, um den Fokus zu bewegen, und gibt es nie zurück, und ein Spiel, dessen Tasten Tab einschließen, würde es sonst verlieren), ein Textfeld mit Fokus schaltet die Texteingabe von SDL ein, und die Richtungen des Pads kommen als Pfeiltasten an, mit ACTION_1 als Eingabetaste und ACTION_2 als Esc. Was ein Element verwendet, erreicht nie onInputPressed, onKeyPressed oder die Maus-Callbacks; was nichts verwendet hat, fällt wie üblich zu ihnen durch. Beendet das Skript bei einem ungültigen Handle.\nSeit: 3.00.",
args = "(gui, enabled)",
returns = "()",
},
guiSetValue = {
type = "function",
description = "Setzt den Wert des Elements mit dieser id: den Wert eines Formularelements (den Text eines Textfelds, die Zahl eines Schiebereglers, den value einer Option eines select; der Zustand checked eines Kontrollkästchens ist ein Attribut und wird über die API von RmlUi gesetzt) oder bei jedem anderen Element sein inneres RML, sodass ein Absatz oder ein div mit schlichtem Text oder mit Markup neu geschrieben werden kann. Das Dokument berechnet sein Layout im nächsten Frame neu. Löst No element \"id\" in document N of GUI G aus, wenn das Element nicht existiert.\nSeit: 3.00.",
args = "(gui, document, id, value)",
returns = "()",
},
guiShow = {
type = "function",
description = "Zeigt ein von guiHide verstecktes Dokument an (ein Dokument wird angezeigt, wenn guiLoad zurückkehrt, der Aufruf ist dann also nicht nötig). Ein angezeigtes Dokument wird überall gezeichnet, wo seine GUI gezeichnet wird, und nimmt Eingaben an, wenn seine GUI es tut. Löst bei einem ungültigen Handle No document N in GUI G aus.\nSeit: 3.00.",
args = "(gui, document)",
returns = "()",
},
hypseusGetHeight = {
type = "function",
description = "Ein Alias von singeGetHeight.",
args = "()",
returns = "()",
anchor = "_hypseus_compatibility",
},
hypseusGetWidth = {
type = "function",
description = "Ein Alias von singeGetWidth.",
args = "()",
returns = "()",
anchor = "_hypseus_compatibility",
},
jitterGet = {
type = "function",
description = "Das Paket, das jetzt abgespielt werden soll, und der Buffer rückt um einen Schritt weiter. Ruf es einmal je Frame-Dauer auf, egal, was angekommen ist.\nRückgabe: das Paket oder nil und ein Status: \"ok\", \"missing\" (nichts ist fällig: gib nil an opusDecode, um die Lücke zu füllen) oder \"insertion\" (der Buffer wächst, um verspätete Pakete aufzufangen: spiel ein wenig Stille ab).\nSeit: 3.00.",
args = "(jitter [, span])",
returns = "(packet, status)",
},
jitterNew = {
type = "function",
description = "Ein Jitter-Buffer: Pakete gehen nach ihrem Zeitstempel hinein, wenn sie ankommen, und kommen der Reihe nach heraus, einen Schritt nach dem anderen, ein wenig verzögert, damit ein verspätetes es noch schafft.\nRückgabe: das Handle des Jitter-Buffers.\nSeit: 3.00.",
args = "([step])",
returns = "(jitter)",
},
jitterPut = {
type = "function",
description = "Ein Paket, das angekommen ist. Der Buffer behält seine eigene Kopie.\nSeit: 3.00.",
args = "(jitter, packet: string, timestamp [, span])",
returns = "()",
},
jointBall = {
type = "function",
description = "Erzeugt ein Kugelgelenk am Weltpunkt (ax, ay, az): Die Körper können sich beliebig darum drehen, sich aber nicht voneinander lösen. Ein Pendel, ein Kettenglied, ein hängendes Schild, eine Ragdoll-Schulter. Beide Knoten müssen einen Körper tragen, oder nodeB darf -1 sein, um nodeA an einem festen Punkt in der Welt aufzuhängen. Ein Kugelgelenk hat keine Grenzen, deshalb lehnt jointSetLimits es ab. Beendet das Skript, wenn ein Knoten keinen Körper hat oder das Gelenk nicht erzeugt werden kann.\nRückgabe: Das Gelenk-Handle.\nSeit: 3.00.",
args = "(nodeA, nodeB, ax, ay, az)",
returns = "(joint)",
},
jointDelete = {
type = "function",
description = "Entfernt das Gelenk; die Körper sind wieder frei voneinander und behalten die Geschwindigkeit, die sie gerade hatten. Gelenke verschwinden auch mit einem ihrer Körper, deshalb wird dies nur gebraucht, um zwei Körper voneinander zu lösen, die beide bleiben. Beendet das Skript bei einem Handle, das nicht existiert oder bereits gelöscht wurde.\nSeit: 3.00.",
args = "(joint)",
returns = "()",
},
jointHinge = {
type = "function",
description = "Erzeugt ein Scharnier zwischen den beiden Körpern durch den Weltpunkt (ax, ay, az) entlang der Achse (dx, dy, dz): eine Tür, ein Rad, ein Hebel, eine Wippe. Die Körper teilen sich diesen Punkt und diese Achse und können sich nur um sie drehen. Die Achse wird normalisiert, ihre Länge spielt also keine Rolle; eine Nullachse wird zu (0, 1, 0). Beide Knoten müssen einen Körper tragen, oder nodeB darf -1 sein, um nodeA per Scharnier an der Welt zu befestigen. Beendet das Skript, wenn ein Knoten keinen Körper hat oder das Gelenk nicht erzeugt werden kann.\nRückgabe: Das Gelenk-Handle.\nSeit: 3.00.",
args = "(nodeA, nodeB, ax, ay, az, dx, dy, dz)",
returns = "(joint)",
},
jointSetLimits = {
type = "function",
description = "Begrenzt den Winkel eines Scharniers in Grad oder den Weg eines Schiebegelenks in Welteinheiten, nach beiden Seiten von der Stellung aus, in der das Gelenk begann. Ein positiver Scharnierwinkel ist eine Drehung von nodeA um die Achse nach der Rechte-Hand-Regel; ein positiver Schiebeweg liegt in Achsrichtung. low wird auf höchstens 0 begrenzt und high auf mindestens 0, sodass die Ausgangsstellung immer im Bereich liegt. Ruf es erneut auf, um den Bereich jederzeit zu ändern. Beendet das Skript bei einem Kugelgelenk oder einem Handle, das nicht mehr existiert.\nSeit: 3.00.",
args = "(joint, low, high)",
returns = "()",
},
jointSlider = {
type = "function",
description = "Lässt die Körper relativ zueinander nur entlang der Achse (dx, dy, dz) durch den Anker (ax, ay, az) gleiten, wobei ihre Ausrichtung erhalten bleibt: eine Schublade, ein Kolben, ein Aufzug, eine Schiebetür. Die Achse wird normalisiert, ihre Länge spielt also keine Rolle; eine Nullachse wird zu (0, 1, 0). Beide Knoten müssen einen Körper tragen, oder nodeB darf -1 sein, damit nodeA auf einer fest in der Welt verankerten Schiene läuft. Beendet das Skript, wenn ein Knoten keinen Körper hat oder das Gelenk nicht erzeugt werden kann.\nRückgabe: Das Gelenk-Handle.\nSeit: 3.00.",
args = "(nodeA, nodeB, ax, ay, az, dx, dy, dz)",
returns = "(joint)",
},
joyMouseEnable = {
type = "function",
description = "Hypseus-Erweiterung. Schaltet Joystick-als-Maus ein oder aus, während das Spiel läuft. Ist es eingeschaltet, steuert der linke Stick des Gamepad-Slots 0 den Zeiger, den das Spiel sieht, über dasselbe onMouseMoved, das auch eine echte Maus erreicht, und bleibt dabei innerhalb des Bildes; --js_range ist die Geschwindigkeit, und die Achse folgt ihrer eigenen Totzone. Das macht ein Lightgun-Spiel an einem Automaten mit Stick und ohne Maus spielbar.\nRückgabe: nichts.\nSeit: 3.00 (Hypseus)",
args = "(enabled)",
returns = "()",
},
joyMouseIsEnabled = {
type = "function",
description = "Ob der Stick gerade den Mauscursor steuert, gleich ob das durch --joymouse oder durch joyMouseEnable entschieden wurde.\nRückgabe: Boolean.\nSeit: 3.00",
args = "()",
returns = "(boolean)",
},
keyboardCatchQuit = {
type = "function",
description = "Hypseus-Erweiterung. Übergibt den Beenden-Schalter an das Skript, genau wie singeSetQuitKeyEnabled(not catch): keyboardCatchQuit(true) verhindert, dass die Engine bei INPUT_QUIT beendet wird, und false stellt das wieder her. Es ist eine in Framework.singe definierte Funktion, die erhalten bleibt, damit für Hypseus Singe geschriebene Spiele unverändert laufen.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(catch)",
returns = "()",
},
keyboardGetLastDown = {
type = "function",
description = "Gibt den Scancode der Taste zurück, die im aktuellen Frame zuletzt gedrückt wurde, oder 0, wenn seit dem letzten Frame nichts gedrückt wurde. Der Wert wird nach jedem Aufruf von onOverlayUpdate gelöscht, was ihn zu einer einmaligen Abfrage „wurde gerade eine Taste gedrückt“ für das Thread-Modell macht. Controller- und Maustasten werden hier ebenfalls festgehalten, als ihre Codes GAMEPAD_N und MOUSE_N, da die Engine sie über denselben Weg leitet wie Tasten. Der Wert wird unabhängig vom Tastaturmodus und von den Belegungen in controls.cfg festgehalten.\nRückgabe: ganzzahliger Scancode oder 0.\nSeit: 2.10",
args = "()",
returns = "(integer)",
},
keyboardGetLastUp = {
type = "function",
description = "Gibt den Scancode der Taste zurück, die im aktuellen Frame zuletzt losgelassen wurde, oder 0, wenn seit dem letzten Frame nichts losgelassen wurde. Er wird wie bei keyboardGetLastDown nach jedem Aufruf von onOverlayUpdate gelöscht und hält Controller- und Maustastencodes auf dieselbe Weise fest.\nRückgabe: ganzzahliger Scancode oder 0.\nSeit: 2.10",
args = "()",
returns = "(integer)",
},
keyboardGetMode = {
type = "function",
description = "Gibt den geltenden Tastaturmodus zurück: MODE_NORMAL (0) oder MODE_FULL (1). Jedes Skript beginnt im MODE_NORMAL, auch nach einem Neuladen.\nRückgabe: ganzzahliger Modus.\nSeit: 1.x (RDG)",
args = "()",
returns = "(integer)",
},
keyboardGetModifiers = {
type = "function",
description = "Gibt die gerade gehaltenen Modifikatortasten als Bitmaske aus SDL-KMOD_*-Bits zurück. Prüfe sie mit einem bitweisen Und gegen die Werte in der Tabelle MODIFIER: die Einträge für einzelne Tasten wie MODIFIER.LSHIFT und die zusammengefassten MODIFIER.SHIFT, MODIFIER.CTRL, MODIFIER.ALT und MODIFIER.GUI, die beide Seiten abdecken. Es liest den aktuellen Zustand, funktioniert also in jedem Tastaturmodus und aus jedem Callback.\nRückgabe: ganzzahlige Bitmaske.\nSeit: 2.10",
args = "()",
returns = "(integer)",
},
keyboardIsDown = {
type = "function",
description = "Prüft, ob eine Taste gerade physisch gehalten wird, anhand des Zustands, den die Engine für jedes Tastenereignis führt, das sie sieht. Es hängt weder vom Tastaturmodus noch von controls.cfg ab und funktioniert aus jedem Callback, eignet sich also für Bewegung, die weitergehen soll, solange eine Taste gehalten wird. Scancodes außerhalb des Bereichs, den SDL definiert, ergeben false, statt abzubrechen.\nRückgabe: Boolean.\nSeit: 2.10",
args = "(scancode)",
returns = "(boolean)",
},
keyboardSetMode = {
type = "function",
description = "Wechselt zwischen den beiden Tastaturmodellen. Im MODE_NORMAL erreichen nur in controls.cfg belegte Tasten das Skript, als SWITCH_*-Werte, die Tastenwiederholung wird verworfen, sodass jeder Druck einmal ankommt, und die Engine reagiert auf ihre eigenen Schalter (Pause, Beenden, Screenshot, Maus einfangen). Im MODE_FULL erreicht jede Taste onInputPressed und onInputReleased als ihr Keysym und onKeyPressed und onKeyReleased als Keysym und Scancode, der Text, den ein Tastendruck erzeugt, erreicht onTextInput, die Tastenwiederholung wird für die Texteingabe geliefert, und Tastaturbelegungen der engineeigenen Schalter werden ignoriert, damit das Spiel jede Taste behält; Belegungen von Controller- und Maustasten wirken weiterhin, und diese Tasten erreichen das Skript weiterhin als ihre SWITCH_*-Werte, da sie nicht getippt werden können. Die meisten Spiele setzen den Modus einmal beim Start; ein Spiel mit Texteingabe wechselt für deren Dauer zu MODE_FULL und wieder zurück. Jeder andere Wert bricht das Skript ab. Im MODE_FULL sind die Keysyms von vier Tasten zugleich Schalternummern -- Rücktaste ist 8 (SWITCH_BUTTON3), Tab 9 (SWITCH_COIN1), Eingabetaste 13 und Esc 27 -- und ein Skript, das onInputPressed für einen Pad- oder Mausschalter liest und zugleich diese Tasten erwartet, sollte deshalb mit keyboardIsDown nach der Taste sehen, bevor es den Wert als den Schalter behandelt.\nSeit: 1.x (RDG)",
args = "(mode)",
returns = "()",
},
lightNew = {
type = "function",
description = "Erzeugt einen neuen Knoten, der ein Licht trägt, und gibt das Knoten-Handle zurück. Das Licht beginnt weiß mit Intensität 1, ohne Reichweitenbegrenzung und, bei einem Spot, mit einem Kegel von 20 bis 30 Grad. Platziere und richte es mit den Knotenaufrufen aus: nodeSetPosition für ein Punkt- oder Spotlicht, nodeLookAt für ein Richtungs- oder Spotlicht. Ein Licht, das einem sich bewegenden Knoten untergeordnet ist, bewegt sich mit ihm, sodass ein Scheinwerfer an einem Auto oder eine Fackel in einer Hand nur ein Aufruf ist. Beendet das Skript bei einem unbekannten Typ oder wenn kein Knoten erzeugt werden kann.\nRückgabe: Das Knoten-Handle des Lichts, eine Ganzzahl.\nSeit: 3.00.",
args = "(type [, parent])",
returns = "(node)",
},
lightSetColor = {
type = "function",
description = "Die Farbe des Lichts, 0 bis 255 pro Kanal (Werte außerhalb des Bereichs werden begrenzt), als sRGB behandelt; standardmäßig weiß. Die Helligkeit gehört in lightSetIntensity, nutze die Farbe also für den Farbton (eine warme Glühbirne 255, 230, 190, ein kühler Mond 150, 190, 255) und lass mindestens einen Kanal nahe 255. Beendet das Skript, wenn der Knoten kein Licht trägt.\nSeit: 3.00.",
args = "(node, r, g, b)",
returns = "()",
},
lightSetCone = {
type = "function",
description = "Die Form des Kegels eines Spotlichts, beide Winkel von der Achse aus gemessen (der -Z-Achse des Knotens): volle Helligkeit innerhalb von innerDegrees, die bis outerDegrees sanft auf nichts abfällt. Die Standardwerte sind 20 und 30. Ein schmaler Abstand zwischen beiden ergibt einen hart umrandeten Bühnenspot, ein breiter einen weichen Lichtfleck. Die Werte werden für jedes Licht gespeichert, aber nur ein LIGHT_SPOT verwendet sie. Beendet das Skript, wenn der Knoten kein Licht trägt.\nSeit: 3.00.",
args = "(node, innerDegrees, outerDegrees)",
returns = "()",
},
lightSetIntensity = {
type = "function",
description = "Der Helligkeitsfaktor des Lichts im linearen Licht der Szene, standardmäßig 1. Ein Richtungslicht der Intensität 1 beleuchtet eine ihm zugewandte weiße Fläche bis zu Weiß. Ein Punkt- oder Spotlicht fällt mit der Entfernung als 1 / (1 + d^2) ab, seine Intensität ist also die Helligkeit am Licht selbst, die Hälfte davon eine Einheit entfernt und ein Hundertstel zehn Einheiten entfernt; Glühbirnen brauchen meist Werte deutlich über 1, 10 bis 50 für einen Raum, und sceneSetExposure holt die ganze Szene wieder in den Bereich. Beendet das Skript, wenn der Knoten kein Licht trägt.\nSeit: 3.00.",
args = "(node, intensity)",
returns = "()",
},
lightSetRange = {
type = "function",
description = "Wie weit ein Punkt- oder Spotlicht reicht, in Welteinheiten; 0 (der Standard) bedeutet keine Begrenzung. Das Licht fällt an der Reichweite zusätzlich zu seinem Abfall mit der Entfernung auf genau nichts ab, sodass Lichter nicht aufploppen, wenn Objekte sie überqueren. Eine Reichweite begrenzt auch, wie weit die Shadow Map eines schattenwerfenden Lichts reichen muss, was seine Schatten scharf hält. Richtungslichter ignorieren sie. Beendet das Skript, wenn der Knoten kein Licht trägt.\nSeit: 3.00.",
args = "(node, range)",
returns = "()",
},
lightSetShadow = {
type = "function",
description = "Lässt das Licht Schatten von allem Opaken in der Szene werfen oder beendet das; standardmäßig aus. Jedes der acht Lichter darf Schatten werfen, in beliebiger Kombination. Ein Spotlicht erhält eine Shadow Map; ein Richtungslicht erhält eine Map pro Kaskade (sceneSetShadowCascades); ein Punktlicht erhält eine Cube Map aus sechs Ansichten, die jede Richtung abdeckt (eine Glühbirne in einem Raum), zum sechsfachen Preis. nodeSetShadow befreit ein Mesh vom Schattenwerfen. Beendet das Skript, wenn der Knoten kein Licht trägt.\nSeit: 3.00.",
args = "(node, shadow)",
returns = "()",
},
lineDraw = {
type = "function",
description = "Zeichnet eine gerade Linie zwischen zwei Punkten in Weltkoordinaten über die Szene, nur für den aktuellen Frame, weiß, sofern keine Farbe angegeben ist. Ruf es in jedem Frame auf, um eine Linie auf dem Bildschirm zu halten, wie beim Overlay. Die Linie wird gegen die Tiefe der Szene getestet, schreibt aber keine Tiefe, versteckt sich also wie alles andere hinter Wänden und verdeckt selbst nie etwas. Solange die Szene deaktiviert ist, wird nichts gezeichnet. Sie ist dafür gedacht, zu sehen, was ein Skript tut (einen Raycast, einen Pfad, eine Bounding Box); physicsSetDebug und navDraw zeichnen über dieselben Linien.\nSeit: 3.00.",
args = "(x0, y0, z0, x1, y1, z1 [, r, g, b])",
returns = "()",
},
mainBezelLoaded = {
type = "function",
description = "Hypseus-Erweiterung. Ob --bezel Artwork für den Automaten geladen hat, und die Kennung der geladenen Datei. Die Kennung ist der 64-Bit-FNV-1a-Hash der Bytes der Datei, als Dezimalstring ausgeschrieben, und genau das meldet auch Hypseus, sodass ein Spiel, das ein bestimmtes Bezel an seiner Nummer erkennt, hier dieselbe Datei erkennt. Ist kein Artwork geladen, lauten die Antworten false und \"0\".\nRückgabe: Boolean und die Kennung als String.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "(loaded, id)",
},
materialDelete = {
type = "function",
description = "Gibt das Material und jede Textur frei, die es hochgeladen hat. Jeder Knoten, der damit gezeichnet wurde, fällt auf das Standardaussehen zurück (weiß, halb rau); weise diesen Knoten also zuerst mit nodeSetMaterial ein anderes zu, wenn sie ein Aussehen behalten sollen. Das Handle ist danach ungültig und beendet das Skript, wenn es erneut verwendet wird. Das private Material, das ein Knoten unter nodeSetSprite oder nodeSetText für sich selbst anlegt, gehört dem Knoten und kann nicht gelöscht werden; der Aufruf beendet das Skript, und es wird freigegeben, wenn das Sprite oder der Text entfernt wird. Materialien sind billig; sie zu löschen ist vor allem bei solchen wichtig, die große Texturen trugen.\nSeit: 3.00.",
args = "(material)",
returns = "()",
},
materialNew = {
type = "function",
description = "Legt ein neues Material an und gibt sein Handle zurück. Es beginnt weiß und deckend (Farbe 255, 255, 255, 255), mit Rauheit 0.5, Metallic 0, ohne Emissionsfarbe, mit Kachelung 1, 1, linearer Filterung, einseitig, beleuchtet und ohne Textur oder Maps. Setz, was davon abweicht, und übergib das Handle an nodeSetMesh. Geladene Modelle bringen ihre eigenen Materialien mit, dies ist also für Meshes, die im Skript gebaut werden. Beendet das Skript auf einem Rechner ohne nutzbare GPU.\nRückgabe: Das Material-Handle, eine Ganzzahl.\nSeit: 3.00.",
args = "()",
returns = "(material)",
},
materialSetBlend = {
type = "function",
description = "Bei true wird das Material durchscheinend gezeichnet, gemischt nach dem Alpha der Grundfarbe multipliziert mit dem Alpha der Textur, nach jedem deckenden Mesh und vom entferntesten an sortiert. Gemischte Meshes schreiben keine Tiefe, lass es also für feste Oberflächen auf false (der Standard): Bei einem deckenden Mesh mit eingeschaltetem Mischen können Dinge dahinter durchscheinen. Verwende es mit einem Alpha unter 255 aus materialSetColor oder einer Textur mit Transparenz.\nSeit: 3.00.",
args = "(material, blend)",
returns = "()",
},
materialSetColor = {
type = "function",
description = "Setzt die Grundfarbe, 0 bis 255 pro Kanal (Werte außerhalb des Bereichs werden begrenzt), wobei a standardmäßig 255 ist. Die Farbe wird als sRGB behandelt und in linearem Licht beleuchtet. Hat das Material eine Textur, ein Video oder eine Ansicht, wird diese mit der Farbe multipliziert, Weiß lässt das Bild also, wie es ist, und eine dunklere Farbe tönt es. Das Alpha wirkt nur mit materialSetBlend.\nSeit: 3.00.",
args = "(material, r, g, b [, a])",
returns = "()",
},
materialSetCutoff = {
type = "function",
description = "Verwirft jedes Texel, dessen Alpha unter cutoff liegt, und zeichnet den Rest vollständig deckend, im beleuchteten Durchgang wie im Schattendurchgang, sodass eine Blätterkarte den Schatten ihrer Blätter wirft statt den ihres Quads. Das ist das Alpha-Masking von glTF: Anders als materialSetBlend braucht es keine Sortierung, aber ein Texel wird ganz behalten oder verworfen, nie überblendet. Der Schwellwert wird auf 0 bis 1 begrenzt, und 0, der Standard, schaltet das Masking ab. Ein aus glTF geladenes Modell kommt mit dem Schwellwert, den seine Datei einem MASK-Material gibt.\nSeit: 3.00.",
args = "(material: integer, cutoff: number)",
returns = "()",
},
materialSetDoubleSided = {
type = "function",
description = "Zeichnet beide Seiten jedes Dreiecks, statt die Rückseite zu verwerfen. Nötig für offene Formen, die von hinten gesehen werden, etwa eine einzelne meshPlane, die von unten betrachtet wird, eine Flagge oder eine Blattkarte. Geschlossene Formen sehen so oder so gleich aus, lass es bei ihnen also auf false (der Standard): Ein doppelseitiges Material kostet Füllrate, und Schatten werden ebenfalls von beiden Seiten geworfen.\nSeit: 3.00.",
args = "(material, doubleSided)",
returns = "()",
},
materialSetEmissive = {
type = "function",
description = "Das Licht, das die Oberfläche von sich aus abgibt, 0 bis 255 pro Kanal (Werte außerhalb des Bereichs werden begrenzt), zusätzlich zur Beleuchtung: Bildschirme, Glühbirnen, Neon, Instrumententafeln. Der Standard ist Schwarz, kein Leuchten. Es beleuchtet nichts anderes und wirft kein Licht; setz dafür einen Lichtknoten an dieselbe Stelle. Mit materialSetEmissiveMap gibt die Map an, wo auf der Oberfläche diese Farbe gilt. Emittierende Oberflächen, die hell genug sind, um die Schwelle von sceneSetBloom zu überschreiten, leuchten.\nSeit: 3.00.",
args = "(material, r, g, b)",
returns = "()",
},
materialSetEmissiveMap = {
type = "function",
description = "materialSetEmissiveMap(material, sprite)\nmaterialSetEmissiveMap(material, \"file.ktx2\")\nmaterialSetEmissiveMap(material, nil)\nmaterialSetEmissiveMap(material)\nEine Textur, die angibt, welche Teile der Oberfläche leuchten. Ihre Farbe wird mit der Farbe aus materialSetEmissive multipliziert, setz diese also ebenfalls: Weiß, um die eigenen Farben der Map zu verwenden, oder eine Tönung. Das Bild stammt aus einem geladenen Sprite (eine Kopie wird hochgeladen, das Sprite darf danach also entladen werden) oder aus einer .ktx2-Datei nach Namen, komprimiert auf der GPU gehalten. Mit nil oder ohne zweites Argument wird die Map entfernt. Beendet das Skript, wenn die Textur nicht hochgeladen werden kann oder die Datei keine KTX2-Textur ist.\nSeit: 3.00.",
args = "(material, sprite)",
returns = "()",
},
materialSetFilter = {
type = "function",
description = "Wie die Texturen des Materials abgetastet werden. FILTER_LINEAR (der Standard) mischt zwischen Texeln und zwischen Mipmap-Stufen, mit anisotroper Filterung auf Oberflächen, die unter flachem Winkel gesehen werden. FILTER_NEAREST nimmt das nächstgelegene Texel und die nächstgelegene Mipmap-Stufe, sodass Pixel-Art auf einem Quad scharf bleibt. Jede Textur trägt eine vollständige Mipmap-Kette, eine klein gesehene Textur flimmert also in keinem Fall. Jeder andere Wert beendet das Skript.\nSeit: 3.00.",
args = "(material, filter)",
returns = "()",
},
materialSetGui = {
type = "function",
description = "materialSetGui(material, gui)\nmaterialSetGui(material, nil)\nmaterialSetGui(material)\nZeigt eine GUI aus guiNew als Grundfarbtextur des Materials, in jedem Frame aktualisiert: ein Monitor, ein Cockpit-Bedienfeld, ein Schild, mit demselben Dokument, das ein guiDraw flach zeigen würde. Meist kombiniert mit materialSetUnlit, damit die Seite nicht von den Lichtern schattiert wird, und wie jede Textur von der Grundfarbe getönt. Mit nil oder ohne zweites Argument kehrt das Material zu seiner eigenen Textur zurück, die darunter erhalten bleibt; das Löschen der GUI bewirkt dasselbe. Das Setzen einer GUI verwirft jedes Video und jede Ansicht, die das Material zeigte. Solange die GUI Eingaben annimmt, erreichen die Maus oder eine Lightgun, die auf eine mit dem Material gezeichnete Oberfläche zeigt, sie über dieselbe Abtastung wie sceneProbeGui. Beendet das Skript bei einem ungültigen GUI-Handle.\nSeit: 3.00.",
args = "(material, gui)",
returns = "()",
},
materialSetMetallic = {
type = "function",
description = "Wie metallisch die Oberfläche ist, 0 für Nichtmetalle (Lack, Kunststoff, Holz, Haut) bis 1 für Metalle, die ihre Glanzlichter und Spiegelungen mit der Grundfarbe tönen. Der Standard ist 0. Werte dazwischen sind für Mischungen und abgenutzte Oberflächen; die meisten Materialien wollen das eine oder das andere Ende. Mit materialSetMetallicRoughnessMap multipliziert der Blaukanal der Map diesen Wert. Ein Metall hat ohne einen Himmel aus sceneSetSky wenig zu spiegeln, kombiniere also beides.\nSeit: 3.00.",
args = "(material, metallic)",
returns = "()",
},
materialSetMetallicRoughnessMap = {
type = "function",
description = "materialSetMetallicRoughnessMap(material, sprite)\nmaterialSetMetallicRoughnessMap(material, \"file.ktx2\")\nmaterialSetMetallicRoughnessMap(material, nil)\nmaterialSetMetallicRoughnessMap(material)\nEine Textur, die die Oberflächenbeschaffenheit über die Fläche variiert: Ihr Grünkanal multipliziert die Rauheit aus materialSetRoughness und ihr Blaukanal den Metallic-Wert aus materialSetMetallic, so wie glTF sie packt, eine Map aus einem glTF-Werkzeug funktioniert also unverändert. Setz beide Faktoren auf 1, um allein die Werte der Map zu verwenden. Das Bild stammt aus einem Sprite oder einer .ktx2-Datei nach Namen; nil oder kein zweites Argument entfernt die Map. Beendet das Skript, wenn die Textur nicht hochgeladen werden kann.\nSeit: 3.00.",
args = "(material, sprite)",
returns = "()",
},
materialSetNormalMap = {
type = "function",
description = "materialSetNormalMap(material, sprite)\nmaterialSetNormalMap(material, sprite, strength)\nmaterialSetNormalMap(material, \"file.ktx2\")\nmaterialSetNormalMap(material, \"file.ktx2\", strength)\nmaterialSetNormalMap(material, nil)\nmaterialSetNormalMap(material)\nEine Normal Map im Tangentenraum (die übliche bläuliche Art, flach bei 128, 128, 255), die die Beleuchtung pro Texel neigt, sodass Ziegel, Rillen und Nieten ohne zusätzliche Geometrie das Licht einfangen. Jedes Mesh hat Tangenten dafür: die eigenen eines Modells, wenn die Datei sie enthält, sonst aus den UVs berechnet. Das Bild stammt aus einem Sprite oder einer .ktx2-Datei nach Namen; nil oder kein zweites Argument entfernt die Map. Beendet das Skript, wenn die Textur nicht hochgeladen werden kann.\nSeit: 3.00.",
args = "(material, sprite)",
returns = "()",
},
materialSetOccluder = {
type = "function",
description = "Lässt das Material Tiefe und keine Farbe schreiben. Was das Mesh verdeckt, ist verborgen, als wäre das Mesh massiv, aber das Mesh selbst ist nicht zu sehen: Alles dahinter Gezeichnete -- ein gemalter Hintergrund, die Disc -- scheint durch. Es ist der Stellvertreter für etwas, das im Bild, aber nicht in der Szene ist: eine Säule in einem gemalten Raum, hinter der eine 3D-Figur hergehen muss, ein Türrahmen, ein Tisch. Ein Occluder wirft keinen Schatten, da das Gemälde schon einen hat, und nimmt kein Licht an. false (der Standard) macht das Material wieder gewöhnlich.\nSeit: 3.00.",
args = "(material, occluder)",
returns = "()",
},
materialSetOcclusionMap = {
type = "function",
description = "materialSetOcclusionMap(material, sprite)\nmaterialSetOcclusionMap(material, sprite, strength)\nmaterialSetOcclusionMap(material, \"file.ktx2\")\nmaterialSetOcclusionMap(material, \"file.ktx2\", strength)\nmaterialSetOcclusionMap(material, nil)\nmaterialSetOcclusionMap(material)\nEine Ambient-Occlusion-Map, die Verdeckung im Rotkanal (Weiß für offen, dunkel für Spalten), die das Umgebungs- und Himmelslicht in Ecken und Falten abdunkelt. Direktes Licht von Lichtknoten ist davon nicht betroffen, wie in glTF. Das Bild stammt aus einem Sprite oder einer .ktx2-Datei nach Namen; nil oder kein zweites Argument entfernt die Map. Beendet das Skript, wenn die Textur nicht hochgeladen werden kann.\nSeit: 3.00.",
args = "(material, sprite)",
returns = "()",
},
materialSetRoughness = {
type = "function",
description = "Wie rau die Oberfläche ist, 0 für ein spiegelscharfes Glanzlicht bis 1 für matt. Der Standard ist 0.5. Glanzlichter folgen dem GGX-Modell, niedrige Werte ergeben also einen kleinen hellen Fleck und scharfe Himmelsspiegelungen, hohe Werte einen breiten weichen Schimmer und verschwommene Spiegelungen. Mit materialSetMetallicRoughnessMap multipliziert der Grünkanal der Map diesen Wert.\nSeit: 3.00.",
args = "(material, roughness)",
returns = "()",
},
materialSetTexture = {
type = "function",
description = "materialSetTexture(material, sprite)\nmaterialSetTexture(material, \"file.ktx2\")\nmaterialSetTexture(material, nil)\nmaterialSetTexture(material)\nVerwendet das Bild eines Sprites als Grundfarbtextur (eine Kopie wird hochgeladen, das Sprite darf danach also entladen werden) oder eine KTX2-Datei nach Namen, die auf der GPU im Blockformat komprimiert gehalten wird, das der Rechner hat (siehe Komprimierte Texturen unter 3D-Szenen). Mit nil oder ohne zweites Argument wird die Textur entfernt, und das Material zeigt nur seine Grundfarbe. Das Setzen einer Textur verwirft außerdem jedes Video und jede Ansicht, die das Material zeigte. Texturkoordinaten stammen aus dem Mesh; die Grundformen legen ein Bild einmal über jede Fläche, und materialSetTiling wiederholt es. Ein Name, der keine KTX2-Datei ist, beendet das Skript (lade andere Bilder mit spriteLoad), ebenso ein fehlgeschlagenes Hochladen.\nSeit: 3.00.",
args = "(material, sprite)",
returns = "()",
},
materialSetTiling = {
type = "function",
description = "Wie oft sich die Texturen des Materials (Grundtextur und Maps gleichermaßen) über den UV-Bereich 0 bis 1 einer Oberfläche wiederholen, standardmäßig 1 und 1. 24, 24 auf einer 120 Einheiten breiten Heightmap kachelt eine Textur alle fünf Einheiten. Texturen wiederholen sich über ihre Ränder hinaus, das Bild muss also nahtlos kacheln. Werte unter 1 zeigen einen Teil des Bildes; negative Werte spiegeln es.\nSeit: 3.00.",
args = "(material, u, v)",
returns = "()",
},
materialSetUnlit = {
type = "function",
description = "Zeigt die Grundfarbe und die Textur genau so, wie sie sind, und ignoriert jedes Licht, das Umgebungslicht und den Himmel: für Videobildschirme, Monitore, die eine Ansicht zeigen, Skyboxen und flach schattierte Looks. Nebel wirkt weiterhin. Die Emissionsfarbe und die Maps werden bei einem unbeleuchteten Material nicht verwendet. Der Standard ist false.\nSeit: 3.00.",
args = "(material, unlit)",
returns = "()",
},
materialSetVideo = {
type = "function",
description = "Verwendet die Laserdisc (ohne video) oder ein mit videoLoad geladenes Video als Grundfarbtextur, in jedem Frame aktualisiert, solange es läuft. Meist kombiniert mit materialSetUnlit, damit das Bild nicht von den Lichtern getönt wird. Das Video läuft weiter, ob es zusätzlich auf dem Overlay gezeichnet wird oder nicht, und mehrere Materialien dürfen dasselbe zeigen. Das Setzen eines Videos verwirft jede Textur und jede Ansicht, die das Material hatte; materialSetTexture entfernt es wieder.\nSeit: 3.00.",
args = "(material [, video])",
returns = "()",
},
materialSetView = {
type = "function",
description = "materialSetView(material, view)\nmaterialSetView(material, nil)\nmaterialSetView(material)\nZeigt eine gerenderte Ansicht aus viewNew als Grundfarbtextur des Materials, in jedem Frame aktualisiert: ein Überwachungsmonitor, ein Rückspiegel, ein Portal. Meist kombiniert mit materialSetUnlit, damit das Bild nicht von den Lichtern schattiert wird, und wie jede Textur von der Grundfarbe getönt. Mit nil oder ohne zweites Argument kehrt das Material zu seiner eigenen Textur zurück, die darunter erhalten bleibt. Das Setzen einer Ansicht verwirft jedes Video, das das Material zeigte. Beendet das Skript bei einem ungültigen Ansichts-Handle.\nSeit: 3.00.",
args = "(material, view)",
returns = "()",
},
meshBox = {
type = "function",
description = "Ein Quader, width entlang X, height entlang Y und depth entlang Z, auf den Ursprung zentriert. Jede der sechs Flächen hat ihre eigenen vier Vertices mit einer flachen Normale, sodass Kanten scharf schattiert werden, und die Textur wird einmal über jede Fläche gelegt. Kisten, Wände, Böden und Autokarosserien sind allesamt Quader.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(width, height, depth)",
returns = "(mesh)",
},
meshCone = {
type = "function",
description = "Ein auf Y stehender Kegel mit geschlossener Grundfläche: der Grundkreis mit radius bei -height / 2 und die Spitze bei height / 2. segments (Standard 24, mindestens 3) gibt an, wie viele Facetten ihn umlaufen; die Seiten werden über sie hinweg weich schattiert. Die Textur legt sich einmal um die Seiten und einmal über die Grundfläche.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(radius, height [, segments])",
returns = "(mesh)",
},
meshCylinder = {
type = "function",
description = "Ein Zylinder entlang Y, an beiden Enden geschlossen, von -height / 2 bis height / 2. segments (Standard 24, mindestens 3) gibt an, wie viele Facetten ihn umlaufen, weich schattiert. Für ein Rad oder eine Münze dreh den Knoten um 90 Grad um X oder Z, sodass die Achse dort liegt, wo du sie brauchst.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(radius, height [, segments])",
returns = "(mesh)",
},
meshDelete = {
type = "function",
description = "Gibt die GPU-Puffer des Meshs und seine CPU-Kopie frei. Knoten, die es verwendet haben, bleiben ohne Mesh (und ohne Morph-Gewichte) zurück und zeichnen nichts, bis sie ein anderes erhalten; das Handle wird ungültig und kann von einem späteren Konstruktor wiederverwendet werden. Meshes werden nicht freigegeben, wenn ein Knoten gelöscht wird, lösch ein Mesh also selbst, wenn nichts es mehr verwenden wird.\nSeit: 3.00.",
args = "(mesh)",
returns = "()",
},
meshHeightmap = {
type = "function",
description = "Ein Geländemesh aus einem Graustufenbild, 2 bis 1025 Pixel in jede Richtung: ein Vertex pro Pixel über sizeX mal sizeZ Einheiten, auf den Knoten zentriert, jeder angehoben um den Rotkanal des Pixels (0 Schwarz bis 255 Weiß) mal sizeY, wobei die oberste Zeile des Bildes am fernen (-Z-)Rand liegt. Normalen werden aus den Steigungen berechnet, und die Texturkoordinaten laufen über das Ganze von 0 bis 1, sodass materialSetTiling die Wiederholung der Textur festlegt. Die Höhenwerte werden behalten: terrainGetHeight liest sie, und ein SHAPE_MESH-Körper auf dem Knoten wird zu einem Höhenfeld. Eine Datei, die sich nicht öffnen oder dekodieren lässt, die falsche Größe oder kein 3D-Renderer bricht das Skript ab.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(image, sizeX, sizeY, sizeZ)",
returns = "(mesh)",
},
meshNew = {
type = "function",
description = "Baut Geometrie aus Zahlentabellen. Tangenten für Normal Mapping werden für dich berechnet, und ebenso weiche Normalen, wenn normals nil ist, indem die Dreiecke gemittelt werden, die sich jeden Vertex teilen. Dreiecke zeigen nach vorn, wenn ihre Vertices von außen gesehen gegen den Uhrzeigersinn laufen; gib dem Material materialSetDoubleSided, wenn die Rückseite zu sehen sein muss. Eine Tabelle der falschen Form oder ein Index außerhalb der Vertexliste bricht das Skript mit einer Meldung ab, die sagt, was davon.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(positions, normals, uvs, indices)",
returns = "(mesh)",
},
meshPlane = {
type = "function",
description = "Ein flaches Rechteck in der XZ-Ebene, nach +Y gewandt, width entlang X und depth entlang Z, auf den Ursprung zentriert, mit der Textur einmal darüber gelegt. Zwei Argumente ergeben ein einzelnes Quad. columns (und rows, das standardmäßig columns ist) unterteilen es in so viele Quads in jede Richtung, was ein Soft Body (softNew) braucht, um sich wie Stoff zu biegen; beide müssen mindestens 1 sein. Dreh den Knoten um 90 Grad um X, um es nach +Z gewandt aufzurichten. Es ist einseitig, sofern sein Material nicht doppelseitig ist.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(width, depth [, columns, rows])",
returns = "(mesh)",
},
meshSphere = {
type = "function",
description = "Eine Kugel mit radius, auf den Ursprung zentriert, aus Breiten- und Längenbändern gebaut: segments (Standard 32, mindestens 3) um den Äquator und halb so viele von Pol zu Pol. Die Textur legt sich einmal um sie herum, v vom oberen Pol zum unteren. Weniger Segmente ergeben ein leichteres Mesh für Bälle, die aus der Ferne gesehen werden; mehr ergeben aus der Nähe eine glattere Silhouette.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(radius [, segments])",
returns = "(mesh)",
},
meshTorus = {
type = "function",
description = "Ein Ring, der in der XZ-Ebene um Y liegt, auf den Ursprung zentriert: radius vom Mittelpunkt bis zur Mitte des Rohrs und tubeRadius der eigene Radius des Rohrs. segments (Standard 32, mindestens 3) laufen um den Ring und halb so viele (mindestens 3) um das Rohr. Die Textur legt sich in u einmal um den Ring und in v einmal um das Rohr.\nRückgabe: Das Mesh-Handle.\nSeit: 3.00.",
args = "(radius, tubeRadius [, segments])",
returns = "(mesh)",
},
micCalibrate = {
type = "function",
description = "Misst die Latenz des Mikrofons: Spielt fünf Klicks über die Lautsprecher ab, im Abstand von Sekundenbruchteilen, und misst für jeden, wann er über das Mikrofon zurückkommt. Das dauert ein paar Sekunden; micCalibration sagt, wann es fertig ist. Das Ergebnis ist das des mittleren der gehörten Klicks und wird für diesen Rechner behalten. Mach es in einem ruhigen Raum, mit Lautsprechern, die laut genug sind, dass das Mikrofon sie hört.\nRückgabe: true, wenn die Messung gestartet wurde; false, wenn kein Mikrofon geöffnet ist oder kein Lautsprecher die Klicks abspielen kann.\nSeit: 3.00.",
args = "()",
returns = "(started)",
},
micCalibration = {
type = "function",
description = "Wie eine Kalibrierung vorankommt.\nRückgabe: state, eines von \"idle\", \"running\", \"done\" oder \"failed\" (weniger als drei der Klicks wurden zurück gehört), und die Latenz in Millisekunden, sobald eine bekannt ist, sonst nil.\nSeit: 3.00.",
args = "()",
returns = "(state, latency)",
},
micClose = {
type = "function",
description = "Hört auf zuzuhören und beendet damit auch jedes Aufnehmen und Mithören. Das Mikrofon wird auch geschlossen, wenn das Spiel endet.\nSeit: 3.00.",
args = "()",
returns = "()",
},
micIsOpen = {
type = "function",
description = "Rückgabe: true, solange ein Mikrofon geöffnet ist.\nSeit: 3.00.",
args = "()",
returns = "(open)",
},
micLatency = {
type = "function",
description = "Rückgabe: die Zeit zwischen dem Entstehen eines Klangs und dem Moment, in dem das Spiel ihn hört, wie auf diesem Rechner von micCalibrate gemessen (zu einem beliebigen Zeitpunkt, in einem beliebigen Spiel) oder von micSetLatency gesetzt; bis dahin nil.\nSeit: 3.00.",
args = "()",
returns = "(milliseconds)",
},
micLevel = {
type = "function",
description = "Wie laut der zuletzt gehörte Moment war.\nRückgabe: der RMS- und der Spitzenwert des letzten Sample-Blocks, jeweils 0 bis 1. Ein gleichmäßiger Ton bei Vollaussteuerung ergibt etwa 0.71 RMS. Beide sind 0, wenn kein Mikrofon geöffnet ist.\nSeit: 3.00.",
args = "()",
returns = "(rms, peak)",
},
micList = {
type = "function",
description = "Rückgabe: eine Liste der Namen der Mikrofone, die dieser Rechner hat, für micOpen. Sie wird jedes Mal neu erstellt, sodass ein seit dem letzten Aufruf angeschlossenes Mikrofon erscheint.\nSeit: 3.00.",
args = "()",
returns = "(names)",
},
micMonitor = {
type = "function",
description = "Spielt das, was das Mikrofon hört, über die Lautsprecher zurück, sodass sich ein Sänger über der Musik selbst hört. Aus, bis es verlangt wird: Auf den meisten Geräten kommt die Stimme so spät zurück, dass es irritiert, und bei einem Laptop speisen die Lautsprecher das Mikrofon. Alles, was länger als eine Zehntelsekunde auf die Wiedergabe wartet, wird verworfen, statt verspätet gehört zu werden.\nRückgabe: true oder false, wenn kein Mikrofon geöffnet ist oder kein Lautsprecher zum Abspielen da ist.\nSeit: 3.00.",
args = "(on [, volume])",
returns = "(ok)",
},
micOpen = {
type = "function",
description = "Beginnt zuzuhören, und zwar dem genannten Mikrofon (aus micList) oder dem Standardmikrofon des Rechners. Ein bereits geöffnetes Mikrofon wird zuerst geschlossen.\nRückgabe: true, wenn es geöffnet wurde.\nSeit: 3.00.",
args = "([name])",
returns = "(opened)",
},
micPitch = {
type = "function",
description = "Der gesungene Ton, ermittelt aus den neuesten 43 Millisekunden, die gehört wurden. Es findet einen Grundton zwischen 50 und 2000 Hz, was jede Singstimme abdeckt, und trifft bei einem sauberen Ton auf ein, zwei Hertz genau.\nRückgabe: der Grundton in Hz und wie eindeutig der Klang ein einzelner Ton ist, 0 bis 1. Bei nichts Stimmhaftem -- Stille, einem Atemzug, einem Husten, einer Menschenmenge -- ist hz gleich 0. Wandle Hz mit 69 + 12 * math.log(hz / 440, 2) in eine Notennummer um: 69 ist das A über dem mittleren C, und jede 1 ist ein Halbton.\nSeit: 3.00.",
args = "()",
returns = "(hz, clarity)",
},
micRead = {
type = "function",
description = "Was seit dem letzten Aufruf gehört wurde, das Älteste zuerst.\nRückgabe: ein String aus 16-Bit-Samples, je zwei Bytes, Little Endian, ein Kanal mit 48000 pro Sekunde: #samples / 2 davon. Lies eines mit string.unpack(\"<i2\", samples, n * 2 - 1). Ein Spiel, das länger als acht Sekunden nicht liest, verliert die ältesten.\nSeit: 3.00.",
args = "([max])",
returns = "(samples)",
},
micRecordStart = {
type = "function",
description = "Schreibt alles, was von jetzt an gehört wird, in eine WAV-Datei (ein Kanal, 16 Bit, 48000 pro Sekunde) bis micRecordStop. Der Name ist eine beliebige Datei, die das Spiel schreiben darf, und landet dort, wo die anderen geschriebenen Dateien des Spiels landen.\nRückgabe: true, wenn die Datei geöffnet wurde.\nSeit: 3.00.",
args = "(name)",
returns = "(started)",
},
micRecordStop = {
type = "function",
description = "Beendet die Aufnahme.\nSeit: 3.00.",
args = "()",
returns = "()",
},
micSetLatency = {
type = "function",
description = "Setzt die Mikrofonlatenz dieses Rechners, wie es ein Service-Menü anhand einer auf anderem Weg gemachten Messung tut; nil vergisst sie. Sie wird mit den anderen Einstellungen des Rechners gespeichert.\nSeit: 3.00.",
args = "(milliseconds | nil)",
returns = "()",
},
midiCloseInput = {
type = "function",
description = "Hört auf, dem Eingabeport zuzuhören. onMidiMessage wird nicht mehr ausgelöst. Einen Port zu schließen, der nicht geöffnet ist, bewirkt nichts.\nRückgabe: nichts.\nSeit: 3.00.",
args = "()",
returns = "()",
},
midiCloseOutput = {
type = "function",
description = "Gibt den Ausgabeport frei. Die Sende-Aufrufe antworten von nun an false. Einen Port zu schließen, der nicht geöffnet ist, bewirkt nichts.\nRückgabe: nichts.\nSeit: 3.00.",
args = "()",
returns = "()",
},
midiControlChange = {
type = "function",
description = "Bewegt einen Controller auf dem geöffneten Ausgabeport: Lautstärke ist Controller 7, Panorama 10, das Haltepedal 64.\nRückgabe: true, wenn die Nachricht hinausging.\nSeit: 3.00.",
args = "(channel: number, control: number, value: number)",
returns = "(sent)",
},
midiInputCount = {
type = "function",
description = "Wie viele MIDI-Eingabeports dieser Rechner hat. 0, wenn es keine gibt oder die Plattform gar kein MIDI hat.\nRückgabe: eine Zahl.\nSeit: 3.00.",
args = "()",
returns = "(count)",
},
midiInputName = {
type = "function",
description = "Der Name eines Eingabeports, für einen Einstellungsbildschirm, auf dem ein Spieler einen auswählen kann.\nRückgabe: ein String oder nil, wenn der Index keinen Port bezeichnet.\nSeit: 3.00.",
args = "(index: number)",
returns = "(name)",
},
midiIsInputOpen = {
type = "function",
description = "Ob ein Eingabeport geöffnet ist.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "()",
returns = "(open)",
},
midiIsOutputOpen = {
type = "function",
description = "Ob ein Ausgabeport geöffnet ist. Es lohnt sich, vor einer Reihe von Nachrichten zu fragen, da sonst jede einzeln false antworten würde.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "()",
returns = "(open)",
},
midiNoteOff = {
type = "function",
description = "Lässt einen Ton auf dem geöffneten Ausgabeport los. Ein nicht beendeter Ton klingt, bis etwas ihn stoppt, deshalb braucht jedes midiNoteOn einen dieser Aufrufe.\nRückgabe: true, wenn die Nachricht hinausging.\nSeit: 3.00.",
args = "(channel: number, key: number)",
returns = "(sent)",
},
midiNoteOn = {
type = "function",
description = "Lässt einen Ton auf dem geöffneten Ausgabeport erklingen.\nRückgabe: true, wenn die Nachricht hinausging.\nSeit: 3.00.",
args = "(channel: number, key: number, velocity: number)",
returns = "(sent)",
},
midiOpenInput = {
type = "function",
description = "Hört einem Eingabeport zu. onMidiMessage wird dann für jede ankommende Nachricht ausgelöst. Welcher Eingabeport auch immer geöffnet war, wird zuerst geschlossen.\nRückgabe: true, wenn der Port geöffnet wurde.\nSeit: 3.00.",
args = "(index: number)",
returns = "(opened)",
},
midiOpenOutput = {
type = "function",
description = "Nimmt einen Ausgabeport für die Sende-Aufrufe. Welcher Ausgabeport auch immer geöffnet war, wird zuerst geschlossen.\nRückgabe: true, wenn der Port geöffnet wurde.\nSeit: 3.00.",
args = "(index: number)",
returns = "(opened)",
},
midiOutputCount = {
type = "function",
description = "Wie viele MIDI-Ausgabeports dieser Rechner hat.\nRückgabe: eine Zahl.\nSeit: 3.00.",
args = "()",
returns = "(count)",
},
midiOutputName = {
type = "function",
description = "Der Name eines Ausgabeports.\nRückgabe: ein String oder nil, wenn der Index keinen Port bezeichnet.\nSeit: 3.00.",
args = "(index: number)",
returns = "(name)",
},
midiPitchBend = {
type = "function",
description = "Verbiegt die Tonhöhe eines Kanals. 8192 ist die Mitte und bedeutet keine Verbiegung; wie weit 0 und 16383 reichen, ist eine Einstellung des empfangenden Geräts, meist zwei Halbtöne.\nRückgabe: true, wenn die Nachricht hinausging.\nSeit: 3.00.",
args = "(channel: number, value: number)",
returns = "(sent)",
},
midiProgramChange = {
type = "function",
description = "Wählt den Klang, den ein Kanal spielt. Die Nummern sind die des empfangenden Geräts; auf einem General-MIDI-Gerät ist 0 ein Konzertflügel.\nRückgabe: true, wenn die Nachricht hinausging.\nSeit: 3.00.",
args = "(channel: number, program: number)",
returns = "(sent)",
},
midiRescan = {
type = "function",
description = "Sucht erneut nach Ports, für ein Gerät, das angeschlossen wurde, während das Spiel läuft. Ein geöffneter Port bleibt geöffnet. Indizes sind nur so stabil wie die Liste, lies die Namen danach also neu, statt anzunehmen, dass Port 2 immer noch derselbe ist.\nRückgabe: nichts.\nSeit: 3.00.",
args = "()",
returns = "()",
},
midiSend = {
type = "function",
description = "sent = midiSend(byte [, byte [, byte]])\nsent = midiSend(string)\nJede beliebige Nachricht, für die, die die benannten Aufrufe nicht abdecken. Mit Zahlen sendet es diese so, wie sie sind, also ein Statusbyte und bis zu zwei Datenbytes -- und beachte, dass das Statusbyte den Kanal in seinen unteren vier Bits trägt, ab 0 gezählt, anders als jeder andere Aufruf hier. Mit einem String sendet es den ganzen String; so geht eine System-Exclusive-Nachricht hinaus.\nRückgabe: true, wenn die Nachricht hinausging.\nSeit: 3.00.",
args = "(byte [, byte [, byte]])",
returns = "(sent)",
},
modelDelete = {
type = "function",
description = "Gibt die Meshes, Materialien und eingelesenen Daten des Modells frei. Jede daraus erzeugte Instanz wird zugleich vergessen: Ihre Knoten bleiben in der Szene (Position, Elternknoten und Kinder unverändert), zeichnen aber nichts, ihre Animationen bleiben stehen, wo sie sind, und ein späterer animation*-Aufruf auf ihrer Wurzel beendet das Skript, weil der Knoten keine Modellinstanz mehr ist. Lösch die Wurzeln der Instanzen mit nodeDelete, wenn die Knoten auch nicht mehr gebraucht werden. Ein Handle, das kein geladenes Modell ist, beendet das Skript.\nSeit: 3.00.",
args = "(model)",
returns = "()",
},
modelGetAnimations = {
type = "function",
description = "Listet die Animationsclips des Modells in Dateireihenfolge als Tabelle von Strings auf, sodass names[3] der Clip ist, den animationPlay(node, 3) abspielt. Ein Clip, den der Exporter unbenannt gelassen hat, ergibt einen leeren String; er kann trotzdem über seine Nummer abgespielt werden. Ein Modell ohne Animationen ergibt eine leere Tabelle. Ein Handle, das kein geladenes Modell ist, beendet das Skript.\nRückgabe: Eine Tabelle von Strings, ab 1 indiziert.\nSeit: 3.00.",
args = "(model)",
returns = "(names)",
},
modelInstance = {
type = "function",
description = "Baut den Knotenbaum des Modells unter einem neuen Wurzelknoten auf, der selbst unter parent oder der Wurzel der Szene hängt. Die Wurzel ist ein gewöhnlicher Knoten: Positioniere, drehe, skaliere oder verknüpfe sie wie jeden anderen und lösch sie mit nodeDelete, um die ganze Instanz zu entfernen. Die eigenen Knoten des Modells übernehmen ihre glTF-Namen (oder den Namen ihres Meshs, wenn der Knoten unbenannt ist), sodass nodeFind(name, node) sie erreicht; ein Mesh mit mehreren Materialien wird zu einem Kindknoten pro Teil; Lichter in der Datei werden zu Szenenlichtern mit der Farbe, Intensität, Reichweite und dem Kegel aus der Datei; Skins werden angehängt und Morph-Gewichte gesetzt. Die Knoten stehen in der Pose der Datei, bis eine Animation läuft. Ein Handle, das kein geladenes Modell ist, oder ein parent, das kein Knoten ist, beendet das Skript, ebenso, wenn die Knoten ausgehen.\nRückgabe: Das Handle des Wurzelknotens der Instanz.\nSeit: 3.00.",
args = "(model [, parent])",
returns = "(node)",
},
modelLoad = {
type = "function",
description = "Liest eine .glb über dieselbe Suche wie jedes andere Asset (Spieleverzeichnis, Datenordner, gepackte Datenbank), lädt ihre Meshes und Materialien einmal auf die GPU hoch und behält ihren Knotenbaum, ihre Skins und Animationen zum Instanzieren. Ruf es einmal beim Start auf und instanziere das Handle so oft wie nötig; dieselbe Datei zweimal zu laden erzeugt zwei Kopien auf der GPU. Es braucht die 3D-Szene und schlägt deshalb auf einem Rechner ohne geeignete GPU fehl wie jeder andere 3D-Aufruf. Eine fehlerhafte Datei beendet das Skript mit einer Meldung, die das Problem nennt: Die Datei konnte nicht gelesen werden, ist kein glTF, verweist auf einen externen Puffer oder ein externes Bild, besteht die Validierung nicht, enthält eine Grundform, die nicht hochgeladen werden konnte, hat einen Skin mit mehr als 128 Gelenken oder hat ein geskinntes Mesh, das ein Gelenk mit der Nummer 128 oder höher nennt. Ein geskinntes Mesh, das ein Gelenk jenseits der Skins nennt, die es verwenden, wird geladen, ebenso eine Animation, deren Keyframes nicht gelesen werden können (dieser Sampler wird übersprungen); beides wird im Programm-Trace vermerkt. Eine Textur, die nicht dekodiert werden kann, oder ein fehlendes KTX2-Bild lässt das Laden nicht fehlschlagen; das Material kommt ohne diese Map aus, und der Programm-Trace (--program) sagt, welche es ist.\nRückgabe: Das Modell-Handle, eine Ganzzahl.\nSeit: 3.00.",
args = "(name)",
returns = "(model)",
},
mouseDisable = {
type = "function",
description = "Schaltet die Mauseingabe aus, genau wie mouseSetEnabled(false). Es ist eine in Framework.singe definierte Funktion, die erhalten bleibt, damit ältere Spiele unverändert laufen.\nSeit: 1.18 (RDG)",
args = "()",
returns = "()",
},
mouseEnable = {
type = "function",
description = "Schaltet die Mauseingabe ein, genau wie mouseSetEnabled(true), und bleibt wie dieses aus, wenn Singe mit --nomouse gestartet wurde. Es ist eine in Framework.singe definierte Funktion, die erhalten bleibt, damit ältere Spiele unverändert laufen.\nSeit: 1.18 (RDG)",
args = "()",
returns = "()",
},
mouseGetName = {
type = "function",
description = "Der Name, den der Maustreiber einem Gerät gibt, oder nil, wenn es kein Gerät mit diesem Index gibt. Damit lassen sich zwei Pistolen an einem Automaten auf einem Service-Bildschirm unterscheiden, was sonst Raterei ist, wenn sich beide als Maus 0 und 1 melden. Ein Index außerhalb von 0 bis 3 bricht das Skript ab.\nRückgabe: String oder nil.\nSeit: 3.00",
args = "(mouse)",
returns = "(string)",
},
mouseGetPadding = {
type = "function",
description = "Hypseus-Erweiterung, immer 0, aus dem Grund, den controllerGetPadding nennt. Hypseus addiert diesen Offset zu den Eingabecodes, die seine Mäuse im relativen Modus melden; die Codes von Singe tragen keinen solchen Offset, es gibt also nichts abzuziehen.\nRückgabe: eine Ganzzahl, immer 0.\nSeit: 3.00",
args = "()",
returns = "(padding)",
},
mouseGetPosition = {
type = "function",
description = "Gibt die zuletzt gemeldete Position einer Maus in Overlay-Koordinaten zurück, dieselben Werte, die das jüngste onMouseMoved für dieses Gerät trug. Im Einzelmausmodus bewegt sich nur Maus 0; im Mehrmausmodus hat jedes Gerät seine eigene Position, die in der Mitte des Videos beginnt. Die Position wird nicht mehr aktualisiert, solange die Mauseingabe ausgeschaltet ist. Frag sie in onOverlayUpdate oder singeMain ab, wenn das einfacher ist, als den Callback zu verfolgen. Ein Index außerhalb von 0 bis 3 bricht das Skript ab.\nRückgabe: zwei Ganzzahlen, x und y, in Overlay-Koordinaten.\nSeit: 2.00",
args = "(index)",
returns = "(x, y)",
},
mouseHowMany = {
type = "function",
description = "Gibt die Anzahl der Mäuse zurück, die die Engine beim Start gefunden hat, 0 bis 4. Später angeschlossene Geräte werden nicht gezählt. Wurde keine gefunden, bleibt die Maus ausgeschaltet. Entscheide damit, ob du einen zweiten Lightgun-Spieler anbietest.\nRückgabe: Ganzzahl, 0 bis 4.\nSeit: 1.18 (RDG)",
args = "()",
returns = "(integer)",
},
mouseHowManyReal = {
type = "function",
description = "Ein Alias von mouseHowMany. Hypseus zählt echte Mäuse getrennt von denen, die es aus einem Gamepad ableitet; Singe hat keine abgeleiteten Mäuse, seine Zahl ist also schon die echte.",
args = "()",
returns = "()",
anchor = "_hypseus_compatibility",
},
mouseSetCaptured = {
type = "function",
description = "Fängt die Maus ein, beschränkt sie auf das Singe-Fenster und versteckt den Cursor, oder gibt sie frei und zeigt den Cursor wieder. Die Engine fängt die Maus beim Start ein, die meisten Spiele rufen dies also nie auf; ein Level-Editor im Fenster oder ein Spiel, das den Desktop-Cursor sichtbar haben will, gibt sie frei. Der Schalter, der in controls.cfg mit INPUT_GRAB belegt ist, schaltet denselben Zustand über die Tastatur um.\nSeit: 2.00",
args = "(captured: boolean)",
returns = "()",
},
mouseSetEnabled = {
type = "function",
description = "Schaltet die Mauseingabe ein oder aus. Solange sie aus ist, werden Bewegungs-, Tasten- und Radereignisse verworfen, bevor sie das Skript erreichen: onMouseMoved wird nicht mehr ausgelöst, Maustasten erzeugen keine Schalter mehr, und mouseGetPosition gibt weiter die letzte Position zurück, die es hatte. Der Cursor selbst bewegt sich weiterhin. Das Einschalten beachtet --nomouse; wurde Singe mit dieser Option gestartet, bleibt die Maus aus. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 3.00",
args = "(enabled)",
returns = "()",
},
mouseSetMode = {
type = "function",
description = "Wählt, wie Mäuse gelesen werden. Im MOUSE_SINGLE (der Standard) steuern die Zeigerereignisse des Fensters einen Cursor, der als Gerät 0 gemeldet wird, wobei absolute Positionen und relative Bewegung beide in Overlay-Koordinaten umgerechnet werden. Im MOUSE_MANY wird jedes physische Gerät getrennt gelesen: Relative Bewegung wird zu einer Position pro Gerät aufsummiert, die auf den Videobereich begrenzt ist, absolute Geräte wie Grafiktabletts und manche Lightguns werden auf das Video abgebildet, und onMouseMoved meldet den Geräteindex. Beide Modi liefern dieselben fünf Tasten und das senkrechte Mausrad als Schalter. SINGLE_MOUSE und MANY_MOUSE werden als ältere Schreibweisen akzeptiert; jeder andere Wert bricht das Skript ab. --manymouse ist die eigene Entscheidung des Benutzers und hat Vorrang vor diesem Aufruf: Ist es angegeben, ist der Modus von Anfang an MOUSE_MANY, und mouseSetMode(MOUSE_SINGLE) schaltet ihn nicht ab, sodass ein Automat mit zwei Pistolen von außen auch mit einem Spiel funktioniert, das nie danach fragt.\nSeit: 1.18 (RDG)",
args = "(mode)",
returns = "()",
},
musicGetPosition = {
type = "function",
description = "Wo sich der Zuhörer in einem laufenden Stück befindet, in Sekunden: die eigene Position des Mixers abzüglich dessen, was noch auf dem Weg zu den Lautsprechern ist -- die Gerätewarteschlange, die Audiokalibrierung des Rechners und die Audioverzögerung des Spiels -- und so kommt ein darauf abgestimmtes Bild zusammen mit dem Klang an. Es ist die Uhr, nach der animiert wird, wenn die Musik führt, wie in einer Demo oder einem Rhythmusspiel, und sie bleibt beim Lied, wie lange es auch läuft, während das Zählen von Frames oder Ticks abdriftet. Der Mixer bewegt seine Position jeweils um einen Puffer, zwischen den Sprüngen läuft die Antwort also mit der Uhr weiter, nie mehr als 50 ms, und sie bewegt sich in jedem Frame gleichmäßig. Ein pausiertes Stück steht still. Ein Stück, das nicht läuft, antwortet -1.\nRückgabe: Zahl; Sekunden seit Beginn des Stücks oder -1.\nSeit: 3.00",
args = "(id: number)",
returns = "(number)",
},
musicIsPlaying = {
type = "function",
description = "Hypseus-Erweiterung. Ob dieses Stück läuft oder -- ohne Handle -- ob irgendeine Musik läuft. Ein pausiertes Stück läuft nicht.\nRückgabe: Boolean.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "([id])",
returns = "(boolean)",
},
musicLoad = {
type = "function",
description = "Hypseus-Erweiterung. Lädt ein Musikstück über das virtuelle Dateisystem und gibt sein Handle zurück. Die ganze Datei wird vorab dekodiert, wie bei einem Sound, ein langes Stück kostet also Speicher -- außer einem Chiptune, der seine Länge nicht angibt, oder etwas, das dekodiert mehr als 512 MB hätte, die beide beim Abspielen dekodiert werden; das Handle gilt bis musicUnload oder zu einem Neuladen.\nRückgabe: Zahl, das Musik-Handle.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(filename: string)",
returns = "(number)",
},
musicPause = {
type = "function",
description = "Hypseus-Erweiterung. Pausiert dieses Stück an seiner Stelle oder jede Musik, wenn kein Handle angegeben ist. musicResume setzt es wieder fort.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "([id])",
returns = "()",
},
musicPlay = {
type = "function",
description = "Hypseus-Erweiterung. Spielt ein Stück von seinem Anfang an und antwortet mit seinem Handle, so wie die Spiele von Hypseus es aufbewahren (sndHandle = musicPlay(music)), um das Stück später zu stoppen. loops bedeutet dasselbe wie bei soundPlay: 0, der Standard, spielt einmal, -1 spielt endlos, und N wiederholt N-mal zusätzlich. Die Anzahl wird auf -1 bis 64 begrenzt, so wie Hypseus sie begrenzt, damit ein Spiel, das mehr verlangt, bekommt, was es dort bekommen hätte.\nRückgabe: Zahl; das Handle, das es bekommen hat.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id [, loops])",
returns = "(number)",
},
musicResume = {
type = "function",
description = "Hypseus-Erweiterung. Setzt ein pausiertes Stück fort oder jede pausierte Musik, wenn kein Handle angegeben ist.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "([id])",
returns = "()",
},
musicSetVolume = {
type = "function",
description = "Hypseus-Erweiterung. Setzt die Verstärkung für alle Musik auf einmal, auf der Skala 0 bis 128 von Hypseus, und antwortet mit dem übernommenen Pegel. Es verändert nichts außer Musik: Die Soundeffekte behalten, was soundSetVolume ihnen gegeben hat, und soundSetVolume lässt die Musik in Ruhe.\nRückgabe: Zahl, der gesetzte Pegel.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(volume: number)",
returns = "(number)",
},
musicStop = {
type = "function",
description = "Hypseus-Erweiterung. Stoppt dieses Stück oder jede Musik, wenn kein Handle angegeben ist (ein nil-Handle zählt als keines). fadeMs blendet es über so viele Millisekunden aus, statt es abzuschneiden; 0, der Standard, stoppt sofort. Eine negative Ausblendzeit beendet das Skript.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "([id [, fadeMs]])",
returns = "()",
},
musicUnload = {
type = "function",
description = "Hypseus-Erweiterung. Stoppt das Stück und gibt es frei. Das Handle ist danach ungültig, und es zu verwenden beendet das Skript.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id: number)",
returns = "()",
},
navAddNode = {
type = "function",
description = "Fügt das Mesh des Knotens und das Mesh jedes Knotens darunter der Geometrie hinzu, aus der das Navigationsmesh gebacken wird, so wie sie gerade in der Welt stehen; platziere sie also zuerst. Der Wurzelknoten einer Modellinstanz fügt das ganze Modell hinzu, und ein aus Grundformen gebautes Level lässt sich Knoten für Knoten hinzufügen. Nur Mesh-Geometrie zählt: Körper, Sprites und Text fügen nichts hinzu. Beendet das Skript, sobald das Mesh gebaut ist.\nSeit: 3.00.",
args = "(nav, node)",
returns = "()",
},
navAgentDelete = {
type = "function",
description = "Nimmt den Agenten vom Mesh und gibt sein Handle frei; der Knoten bleibt, wo er ist, und wird nicht mehr bewegt. Das Löschen des Meshs mit navDelete tut das für jeden Agenten darauf. Ein ungültiges Handle beendet das Skript.\nSeit: 3.00.",
args = "(agent)",
returns = "()",
},
navAgentGetVelocity = {
type = "function",
description = "Wie die Crowd den Agenten in diesem Frame bewegt, in Welteinheiten pro Sekunde entlang jeder Achse; die Länge reicht bis zur Geschwindigkeit des Agenten und fällt auf null, wenn er anhält. Damit wählst du zwischen einer Steh-, einer Geh- und einer Laufanimation oder passt den Gehzyklus an die zurückgelegte Strecke an.\nRückgabe: Drei Zahlen.\nSeit: 3.00.",
args = "(agent)",
returns = "(x, y, z)",
},
navAgentIsArrived = {
type = "function",
description = "Ob der Agent das letzte Ziel erreicht hat, das navAgentMoveTo ihm gegeben hat: höchstens anderthalb seiner Radien vom Ziel entfernt und fast zum Stehen gekommen. Es wird true in dem Moment, in dem onNavArrived ausgelöst wird, und bleibt true bis zum nächsten navAgentMoveTo; für einen Agenten, der nie irgendwohin geschickt oder unterwegs angehalten wurde, ist es false.\nRückgabe: Wahr oder falsch.\nSeit: 3.00.",
args = "(agent)",
returns = "(arrived)",
},
navAgentMoveTo = {
type = "function",
description = "Schickt den Agenten zu Fuß zu dem Punkt des Meshs, der x, y, z am nächsten liegt, und sucht diesen bis zu 2 Einheiten seitlich und 4 nach oben oder unten. Die Crowd plant die Route über die folgenden Frames und steuert den Agenten unterwegs um die anderen Agenten herum; onNavArrived wird ausgelöst, sobald er dort ankommt. Gibt false zurück und lässt den Agenten, wie er war, wenn kein Punkt des Meshs nah genug ist oder die Crowd die Anfrage ablehnt. Ein neues Ziel ersetzt das alte jederzeit.\nRückgabe: Wahr, wenn der Agent losgegangen ist.\nSeit: 3.00.",
args = "(agent, x, y, z)",
returns = "(ok)",
},
navAgentNew = {
type = "function",
description = "Setzt einen Agenten dieser Größe auf das Mesh, an den Punkt, der der Weltposition des Knotens am nächsten liegt (die unveränderte Position, wenn innerhalb von 2 Einheiten seitlich und 4 nach oben oder unten nichts liegt), mit einer Gehgeschwindigkeit von speed Einheiten pro Sekunde und einer Beschleunigung von 8 Einheiten pro Sekunde zum Quadrat. Radius und Höhe werden auf mindestens 0.01 gehalten, so wie navNew seine eigenen hält. Von da an bewegt die Engine den Knoten in jedem Frame entlang des Meshs, im Koordinatensystem seines Elternknotens, und dreht ihn um Y in seine Laufrichtung, wann immer er sich schneller als 0.05 Einheiten pro Sekunde bewegt; Knoten blicken entlang -Z, wie Modelle. Die Crowd steuert Agenten umeinander herum, nimmt Kurven vorweg und hält sie auseinander. Um eine Spielfigur auf dem Knoten zu steuern, statt den Knoten zu platzieren, siehe navAgentSetPlayer. Beendet das Skript, wenn das Mesh nicht gebaut ist oder schon 128 Agenten darauf sind.\nRückgabe: Das Handle des Agenten, eine Ganzzahl.\nSeit: 3.00.",
args = "(nav, node, radius, height, speed)",
returns = "(agent)",
},
navAgentSetPlayer = {
type = "function",
description = "Mit true hört der Agent auf, seinen Knoten zu platzieren, und gibt stattdessen in jedem Frame seine Geschwindigkeit als playerMove (nur waagerecht) an die Spielfigur auf dem Knoten weiter, sodass Treppen, Steigungen, Schieben und Kollisionen weiter funktionieren; vor jeder Aktualisierung der Crowd wird die Weltposition des Controllers als die eigene des Agenten zurückgelesen, sodass ein Abdrängen vom Kurs in der Planung berücksichtigt wird. Der Knoten dreht sich weiterhin in seine Laufrichtung. Der Knoten braucht einen Controller von playerNew, sonst bewegt sich nichts. Mit false platziert der Agent den Knoten wieder selbst.\nSeit: 3.00.",
args = "(agent, player)",
returns = "()",
},
navAgentStop = {
type = "function",
description = "Vergisst das Ziel des Agenten: Die Crowd steuert ihn auf nichts mehr zu, er bremst an Ort und Stelle bis zum Stillstand ab, und onNavArrived wird nicht ausgelöst. Andere Agenten gehen weiterhin um ihn herum. Schick ihn mit navAgentMoveTo irgendwohin, damit er wieder losgeht.\nSeit: 3.00.",
args = "(agent)",
returns = "()",
},
navBuild = {
type = "function",
description = "Backt das begehbare Mesh aus allem, was navAddNode hinzugefügt hat: Böden und Steigungen bis zum Winkel des Meshs, Stufen bis zu seiner Höhe, wobei um jede Wand und jede Abbruchkante der Radius des Agenten abgeschnitten und alles weggelassen wird, über dem weniger als die Höhe des Agenten frei ist. Das Backen arbeitet mit Zellen, die ein Drittel des Agentenradius breit sind, und umfasst höchstens 4096 mal 4096 davon, ein kleiner Radius über einem großen Level ist also langsam und kann fehlschlagen; eine Zehntelsekunde für Sponza auf einem Desktop, ein paar Sekunden auf einem Raspberry Pi. Die hinzugefügte Geometrie wird danach freigegeben, und es kann nichts mehr hinzugefügt werden; back stattdessen ein weiteres Mesh. navSave bewahrt das Ergebnis auf. Beendet das Skript, wenn nichts hinzugefügt wurde, das Mesh schon gebaut ist oder das Backen fehlschlägt.\nSeit: 3.00.",
args = "(nav)",
returns = "()",
},
navDelete = {
type = "function",
description = "Gibt das Mesh und jeden Agenten darauf frei; ihre Knoten bleiben, wo sie sind. Das Mesh-Handle und die Agenten-Handles sind danach ungültig und beenden das Skript, wenn sie verwendet werden. Der Platz ist frei für ein neues navNew oder navLoad.\nSeit: 3.00.",
args = "(nav)",
returns = "()",
},
navDraw = {
type = "function",
description = "Zeichnet die Polygone des gebackenen Meshs für diesen Frame als Linien über die Szene, cyan, sofern keine Farbe angegeben ist, jedes Polygon als Fächer aus Dreiecken, sodass ein Polygon mit mehr als drei Seiten seine Diagonalen zeigt. Ruf es in jedem Frame auf, solange du hinsiehst; es kostet drei Linien pro Dreieck, und ein noch nicht gebautes Mesh zeichnet nichts. Damit prüfst du, neben physicsSetDebug, ob ein gebackenes Mesh den Boden abdeckt und die Möbel auslässt.\nSeit: 3.00.",
args = "(nav [, r, g, b])",
returns = "()",
},
navLoad = {
type = "function",
description = "Lädt ein Mesh, das navSave geschrieben hat, und sucht es zuerst unter den Dateien des Spiels (so kann ein gebackenes Mesh mit dem Spiel ausgeliefert werden, gepackt oder nicht) und dann im Datenordner des Spiels. Das Mesh kommt gebaut zurück, bereit für Agenten und Abfragen, und nimmt kein navAddNode mehr an. Steigung und Stufe, mit denen es gebacken wurde, stehen in der Datei; Radius und Höhe der Agenten sind das, womit die Crowd steuert, gib also die Werte an, für die es gebacken wurde. Beendet das Skript, wenn die Datei nicht gelesen werden kann, kein Navigationsmesh ist, kürzer ist als das Mesh, das ihr Kopf beschreibt (abgeschnitten oder von Hand bearbeitet), oder kein Mesh-Platz frei ist.\nRückgabe: Das Mesh-Handle, eine Ganzzahl.\nSeit: 3.00.",
args = "(name, agentRadius, agentHeight)",
returns = "(nav)",
},
navNearest = {
type = "function",
description = "Der Punkt des Meshs, der einem Punkt am nächsten liegt, gesucht bis zu 2 Einheiten seitlich und 4 nach oben oder unten, oder nil, wenn nichts so nah ist. Damit rastest du einen Spawnpunkt, einen Abwurfpunkt oder einen Klick auf dem Boden ein, bevor du ihn einem Agenten übergibst, und findest die Höhe des Bodens unter einem Punkt.\nRückgabe: Drei Zahlen oder nil.\nSeit: 3.00.",
args = "(nav, x, y, z)",
returns = "(x, y, z)",
},
navNew = {
type = "function",
description = "Beginnt ein Navigationsmesh für Agenten mit diesem Radius und dieser Höhe, die Stufen bis maxStep Einheiten und Steigungen bis maxSlope Grad erklimmen können. Radius und Höhe werden auf mindestens 0.01 gehalten, die Steigung zwischen 0 und 89 und die Stufe auf mindestens 0. Der Radius legt auch die Auflösung des Backens fest, da eine Zelle ein Drittel davon ist; er entscheidet also, wie lange navBuild braucht und wie groß ein Level sein kann, das es abdeckt. Füge Geometrie mit navAddNode hinzu, dann navBuild. Beendet das Skript, wenn schon acht Meshes existieren.\nRückgabe: Das Mesh-Handle, eine Ganzzahl.\nSeit: 3.00.",
args = "(agentRadius, agentHeight, maxSlope, maxStep)",
returns = "(nav)",
},
navPath = {
type = "function",
description = "Die Eckpunkte des kürzesten Wegs von einem Punkt zu einem anderen, beide zuerst auf das Mesh eingerastet, als Tabelle von { x, y, z }-Tabellen, die erste am Start und die letzte am Ende; bis zu 256 Eckpunkte. Kann das Ende nicht erreicht werden, endet der Weg am nächsten erreichbaren Punkt unterwegs, sodass der letzte Eckpunkt immer dort liegt, wo ein Agent stehen kann. nil, wenn eines der Enden nicht in der Nähe des Meshs liegt oder kein Weg gefunden wird. Damit zeichnest du eine Route, misst, wie weit etwas zu Fuß entfernt ist, oder bewegst selbst etwas daran entlang; Agenten tun das von sich aus.\nRückgabe: Eine Tabelle von { x, y, z }-Tabellen oder nil.\nSeit: 3.00.",
args = "(nav, x0, y0, z0, x1, y1, z1)",
returns = "(points)",
},
navRandomPoint = {
type = "function",
description = "Ein zufälliger Punkt auf dem begehbaren Mesh, irgendwo innerhalb seiner Reichweite, zum Umherwandern, zum Verstreuen von Gegenständen zum Aufsammeln oder zum Platzieren eines Spawnpunkts. nil nur, wenn das Mesh nicht gebaut ist.\nRückgabe: Drei Zahlen oder nil.\nSeit: 3.00.",
args = "(nav)",
returns = "(x, y, z)",
},
navRaycast = {
type = "function",
description = "Ob ein gerader Weg von einem Punkt zu einem anderen das Mesh verlässt, an einer Wand oder einer Abbruchkante, und wo er es täte. Der Start wird auf das Mesh eingerastet; false allein heißt, dass der Weg frei ist oder dass der Start nicht in der Nähe des Meshs liegt. Ist er blockiert, ist der Punkt dort, wo die Linie den Rand des Meshs kreuzt, mit einer zwischen den beiden Enden interpolierten Höhe. Eine billige Prüfung, ob eine Abkürzung existiert, bevor du navPath fragst.\nRückgabe: false oder true und der Punkt, an dem der Weg das Mesh verlässt.\nSeit: 3.00.",
args = "(nav, x0, y0, z0, x1, y1, z1)",
returns = "(blocked, x, y, z)",
},
navSave = {
type = "function",
description = "Schreibt das gebackene Mesh unter name in den Datenordner des Spiels, für navLoad beim nächsten Mal oder zum Kopieren in den Spielordner, um es auszuliefern. Das Mesh muss gebaut sein. Beendet das Skript, wenn es das nicht ist oder die Datei nicht geschrieben werden kann.\nSeit: 3.00.",
args = "(nav, name)",
returns = "()",
},
netTrustSystem = {
type = "function",
description = "Fügt die eigenen vertrauenswürdigen Stammzertifikate des Rechners zu einem LuaSec-Client-Kontext hinzu, zusätzlich zu dem, was der Kontext schon enthält (normalerweise das mitgelieferte Singe/cacerts.pem). Eine mit dem Kontext aufgebaute Verbindung wird dann bestätigt, wenn eine der beiden Listen die Wurzel des Servers kennt. Die Liste des Rechners ist, der Reihe nach: die Datei oder das Verzeichnis, das SSL_CERT_FILE oder SSL_CERT_DIR nennt, wenn gesetzt; sonst unter Linux das Bündel der Distribution (der erste der üblichen sechs Orte, der existiert), unter Windows der Stammzertifikatspeicher des Systems oder unter macOS die Vertrauensanker des Systems. cacerts.local.pem im Datenordner wird ebenfalls hinzugefügt, wenn es existiert; die Engine schreibt es nie.\nSeit: 3.00.",
args = "(context)",
returns = "(lists, report)",
},
nodeDelete = {
type = "function",
description = "Entfernt den Knoten und alles darunter und gibt jedes Handle in diesem Teilbaum frei; ein Sprite oder Text auf einem davon wird ebenfalls freigegeben. Meshes und Materialien, die die Knoten gezeichnet haben, bleiben unberührt, da andere Knoten sie teilen können. War der gelöschte Knoten die Kamera, fällt die Szene auf die Standardansicht zurück. Der Wurzelknoten kann nicht gelöscht werden; der Versuch bricht das Skript ab.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
nodeFind = {
type = "function",
description = "Sucht per Tiefensuche nach dem ersten Knoten namens name, beginnend bei root (der Wurzel der Szene, wenn weggelassen), und prüft root selbst vor seinen Kindern, den Teilbaum jedes Kindes der Reihe nach. Gibt nil zurück, wenn nichts passt. Modellknoten tragen die Namen aus ihrer glTF-Datei, sodass ein Knochen, ein Mesh oder ein in Blender als Markierung platziertes Empty unter der Wurzel der Instanz über diesen Namen gefunden werden kann. Mit nodeSetName gesetzte Namen werden genauso gefunden.\nRückgabe: Ein Knoten-Handle oder nil.\nSeit: 3.00.",
args = "(name [, root])",
returns = "(node)",
},
nodeGetChildren = {
type = "function",
description = "Die direkten Kinder des Knotens als Tabelle von Handles, in der Reihenfolge, in der sie angehängt wurden; ein Knoten, der einen neuen Elternknoten bekommt, kommt ans Ende von dessen Liste. Enkel sind nicht enthalten; geh rekursiv vor, um einen ganzen Teilbaum abzulaufen. Eine leere Tabelle heißt, dass der Knoten keine Kinder hat.\nRückgabe: Eine Tabelle von Knoten-Handles.\nSeit: 3.00.",
args = "(node)",
returns = "(children)",
},
nodeGetMorph = {
type = "function",
description = "Das aktuelle Gewicht eines Morph-Ziels des Meshs des Knotens, angegeben über den Namen oder über die Nummer ab 1 in der Reihenfolge, in der nodeGetMorphs sie auflistet. Der Knoten ist der, der das Mesh trägt, nicht die Wurzel einer Modellinstanz. Ein Name oder eine Nummer, die das Mesh nicht hat, bricht das Skript ab.\nRückgabe: Eine Zahl, 0, bis etwas das Ziel setzt.\nSeit: 3.00.",
args = "(node, nameOrIndex)",
returns = "(weight)",
},
nodeGetMorphs = {
type = "function",
description = "Die Morph-Ziele des Meshs des Knotens als Tabelle von Namen, in der Reihenfolge, in der die Datei sie speichert; diese Reihenfolge ist die Nummerierung, die nodeSetMorph und nodeGetMorph annehmen. Exporter, die keine Namen schreiben, ergeben leere Strings, und diese Ziele lassen sich trotzdem über die Nummer setzen. Ein Knoten ohne Mesh oder ein Mesh ohne Ziele ergibt eine leere Tabelle.\nRückgabe: Eine Tabelle von Strings.\nSeit: 3.00.",
args = "(node)",
returns = "(names)",
},
nodeGetName = {
type = "function",
description = "Der Name des Knotens: was auch immer nodeSetName ihm gegeben hat, bei einem Modellknoten sein glTF-Name, ein leerer String, wenn er keines von beiden hat. Der Wurzelknoten heißt root.\nRückgabe: Ein String.\nSeit: 3.00.",
args = "(node)",
returns = "(name)",
},
nodeGetParent = {
type = "function",
description = "Das Handle des Elternknotens oder nil für die Wurzel. Jeder andere Knoten hat einen Elternknoten, und sei es nur die Wurzel.\nRückgabe: Ein Knoten-Handle oder nil.\nSeit: 3.00.",
args = "(node)",
returns = "(parent)",
},
nodeGetPosition = {
type = "function",
description = "Die Position des Knotens relativ zu seinem Elternknoten, wie zuletzt von nodeSetPosition, nodeMove oder der Engine gesetzt (ein Körper, ein Fahrzeug oder eine Animation, die ihn bewegt). Wo der Knoten in der Welt ist, sagt nodeGetWorldPosition.\nRückgabe: Drei Zahlen.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z)",
},
nodeGetQuaternion = {
type = "function",
description = "Die Rotation des Knotens relativ zu seinem Elternknoten als Einheitsquaternion, die Form, in der Modelle und Animationen sie speichern. Damit kopierst du eine Rotation zwischen Knoten oder bewahrst eine Pose ohne die Mehrdeutigkeit von Euler-Winkeln auf.\nRückgabe: Vier Zahlen.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z, w)",
},
nodeGetRotation = {
type = "function",
description = "Die Rotation des Knotens relativ zu seinem Elternknoten als Euler-Winkel in Grad, auf dieselbe Weise zerlegt, wie nodeSetRotation sie zusammensetzt: um Y gedreht, dann um X geneigt, dann um Z gerollt. Die Winkel beschreiben dieselbe Rotation, die gesetzt wurde, müssen aber nicht dieselben Zahlen sein: X kommt zwischen -90 und 90 zurück, und wenn es 90 oder -90 erreicht, wird die Verdrehung Y zugeschlagen und Z als 0 gemeldet.\nRückgabe: Drei Zahlen.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z)",
},
nodeGetScale = {
type = "function",
description = "Die eigene Skalierung des Knotens pro Achse, wie von nodeSetScale gesetzt (1, 1, 1 bei einem neuen Knoten). Die Skalierungen der Elternknoten sind nicht eingerechnet.\nRückgabe: Drei Zahlen.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z)",
},
nodeGetWorldPosition = {
type = "function",
description = "Wo der Ursprung des Knotens in Weltkoordinaten liegt, mit der Transformation jedes Elternknotens angewandt, Stand des zuletzt gerenderten Frames. In diesem Frame gemachte Änderungen (deine oder die eines Körpers) zeigen sich nach dem nächsten Rendern, und ein in diesem Frame erzeugter Knoten meldet bis dahin 0, 0, 0. Das ist die Position, die du sceneProject oder einer Abstandsprüfung übergibst.\nRückgabe: Drei Zahlen.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z)",
},
nodeLookAt = {
type = "function",
description = "Dreht den Knoten so, dass sein eigenes -Z auf eine Position in der Welt zeigt, und hält sein +Y so nah an der Aufwärtsrichtung der Welt, wie die Richtung es zulässt. Das wollen Kameras und Lichter, und es dient ebenso einem Geschützturm oder einem Kopf, der ein Ziel verfolgt. Nur die Rotation des Knotens ändert sich; seine Position bleibt. Fällt das Ziel mit der Position des Knotens zusammen, ändert sich nichts.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
nodeMove = {
type = "function",
description = "Bewegt den Knoten entlang seiner eigenen Achsen: Der Versatz wird mit der aktuellen Rotation des Knotens gedreht und zu seiner Position addiert, sodass nodeMove(ship, 0, 0, -0.1) das Schiff vorwärts fährt, wohin es auch zeigt, und nodeMove(ship, 0.1, 0, 0) es seitlich nach rechts versetzt. Für einen absoluten Ort in den Koordinaten des Elternknotens nimm nodeSetPosition.\nSeit: 3.00.",
args = "(node, dx, dy, dz)",
returns = "()",
},
nodeNew = {
type = "function",
description = "Erzeugt einen leeren Knoten im Ursprung seines Elternknotens, ungedreht, mit Skalierung 1, sichtbar, Schatten werfend, ohne Mesh oder Material. Ohne parent kommt der Knoten unter die Wurzel; mit einem wird er das letzte Kind dieses Knotens und bewegt sich von da an mit ihm. Leere Knoten dienen als Drehpunkte und Gruppen: Platziere einen, häng dann Meshes, Lichter oder eine Kamera darunter und beweg die Gruppe als Ganzes.\nRückgabe: Das Knoten-Handle.\nSeit: 3.00.",
args = "([parent])",
returns = "(node)",
},
nodeRotate = {
type = "function",
description = "Dreht den Knoten um die angegebenen Grad um seine eigenen Achsen, zusätzlich zu seiner aktuellen Rotation: nodeRotate(wheel, 5, 0, 0) in jedem Frame lässt das Rad um sein eigenes X kreisen, wie auch immer die Achse geneigt ist. Die drei Winkel werden so kombiniert, wie nodeSetRotation sie kombiniert (Y, dann X, dann Z), bevor sie angewandt werden. Positive Winkel drehen gegen den Uhrzeigersinn, wenn man entlang der Achse zum Ursprung blickt.\nSeit: 3.00.",
args = "(node, dx, dy, dz)",
returns = "()",
},
nodeSetBillboard = {
type = "function",
description = "Dreht den Knoten in jedem Frame zur Kamera hin. BILLBOARD_ALL richtet ihn frontal zu ihr aus und übernimmt alle drei Achsen von der Kamera; BILLBOARD_Y dreht nur um die Hochachse der Welt, sodass der Knoten aufrecht bleibt (Bäume, Lebensbalken); BILLBOARD_NONE, der Standard, dreht gar nicht. Weltposition und Skalierung des Knotens bleiben erhalten, und seine eigene Rotation wird ignoriert, solange ein Modus gesetzt ist. Jeder andere Wert bricht das Skript ab. Es funktioniert bei Meshes ebenso wie bei Sprites und Text und dreht sich zu der Kamera, die gerade zeichnet: Auch eine Ansicht sieht das Billboard von vorn, während sein Schatten der Kamera des Fensters folgt.\nSeit: 3.00.",
args = "(node, mode)",
returns = "()",
},
nodeSetLayer = {
type = "function",
description = "Wählt, wo im Fenster der Knoten gezeichnet wird. LAYER_SCENE, der Standard, zeichnet ihn in der Szene unter dem Overlay; LAYER_FRONT zeichnet ihn nach dem Overlay, mit derselben Kamera und denselben Lichtern, in eine eigene transparente Ebene. Ein Knoten in der vorderen Ebene nimmt seine Kinder mit, gleich wie sie selbst eingestellt sind. Jeder andere Wert bricht das Skript ab. Siehe Vor dem Overlay.\nSeit: 3.00.",
args = "(node, layer)",
returns = "()",
},
nodeSetMaterial = {
type = "function",
description = "nodeSetMaterial(node, material)\nnodeSetMaterial(node, nil)\nLegt ein Material auf das Mesh, das der Knoten hat, und behält das Mesh. nil entfernt es und lässt das Standardaussehen: weiß, halb rau, ohne Textur. Damit gestaltest du ein Teil eines Modells um, wechselst ein Hervorhebungsmaterial ein und aus oder kleidest ein Mesh ein, das die Engine für dich gemacht hat, etwa die Röhre eines Seils aus softNew. Ein Material-Handle, das nicht existiert, bricht das Skript ab.\nSeit: 3.00.",
args = "(node, material)",
returns = "()",
},
nodeSetMesh = {
type = "function",
description = "Gibt dem Knoten ein Mesh zum Zeichnen, mit einem Material oder, wenn weggelassen, dem Standardaussehen (weiß, halb rau). Beide Argumente müssen gültige Handles sein; ein fehlendes Mesh oder Material bricht das Skript ab. Jeder Knoten kann zeichnen, auch einer innerhalb einer Modellinstanz, und beliebig viele Knoten können sich ein Mesh teilen. Die Morph-Gewichte des Knotens werden auf die Ziele des neuen Meshs bemessen und beginnen bei 0.\nSeit: 3.00.",
args = "(node, mesh [, material])",
returns = "()",
},
nodeSetMorph = {
type = "function",
description = "Legt fest, wie viel eines Morph-Ziels (Blend Shape) das Mesh des Knotens zeigt, über den Namen oder über die Nummer ab 1; Gewichte liegen meist zwischen 0 und 1, und mehrere Ziele addieren sich. Der Knoten ist der, der das Mesh trägt, bei einem Modell also ein Kind der Instanzwurzel (nodeFind mit dem Namen des Meshs oder nodeGetChildren). Ein Ziel, das das Mesh nicht hat, bricht das Skript ab. Eine Animation mit einem Gewichtskanal schreibt die Gewichte in jedem Frame, solange sie läuft, und überschreibt, was du gesetzt hast.\nSeit: 3.00.",
args = "(node, nameOrIndex, weight)",
returns = "()",
},
nodeSetName = {
type = "function",
description = "Benennt den Knoten, damit nodeFind ihn später finden kann, und ersetzt jeden Namen, den er hatte (den glTF-Namen eines Modellknotens eingeschlossen). Namen müssen nicht eindeutig sein; nodeFind gibt den ersten Treffer in der Reihenfolge der Tiefensuche zurück.\nSeit: 3.00.",
args = "(node, name)",
returns = "()",
},
nodeSetParent = {
type = "function",
description = "Verschiebt den Knoten mit seinem ganzen Teilbaum unter einen anderen Elternknoten, als dessen letztes Kind. Lokale Position, Rotation und Skalierung des Knotens bleiben, wie sie sind, er sitzt nun also mit diesem Versatz zum neuen Elternknoten und bewegt sich mit ihm; übergib 0, um ihn zur Wurzel zurückzubringen. Die Wurzel kann nicht verschoben werden, und ein Knoten kann nicht unter sich selbst oder einen seiner eigenen Nachkommen; beides bricht das Skript ab.\nSeit: 3.00.",
args = "(node, parent)",
returns = "()",
},
nodeSetPosition = {
type = "function",
description = "Setzt den Knoten auf x, y, z in den Koordinaten seines Elternknotens; für einen Knoten unter der Wurzel sind das Weltkoordinaten. Kinder kommen mit. Ein Knoten mit einem dynamischen Körper wird danach von der Physik bewegt; setz seine Position vor bodyNew oder teleportiere ihn über die Körper-Aufrufe.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
nodeSetQuaternion = {
type = "function",
description = "Setzt die Rotation des Knotens relativ zu seinem Elternknoten als Quaternion, für Werte, die aus nodeGetQuaternion, einem Modell oder deiner eigenen Rechnung stammen. Die Quaternion wird beim Übernehmen normalisiert, muss also nicht die Länge eins haben.\nSeit: 3.00.",
args = "(node, x, y, z, w)",
returns = "()",
},
nodeSetRotation = {
type = "function",
description = "Setzt die Rotation des Knotens relativ zu seinem Elternknoten als Euler-Winkel in Grad und ersetzt, was er hatte: Der Knoten wird zuerst um sein Y gedreht (Gieren), dann um sein X geneigt (Nicken), dann um sein Z gerollt. Positive Winkel drehen gegen den Uhrzeigersinn, wenn man entlang der Achse zum Ursprung blickt, sodass nodeSetRotation(plane, 90, 0, 0) eine Bodenebene aufrichtet, bis sie nach +Z zeigt.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
nodeSetScale = {
type = "function",
description = "nodeSetScale(node, scale)\nnodeSetScale(node, x, y, z)\nSkaliert den Knoten und alles darunter, gleichmäßig mit einem Faktor oder pro Achse mit dreien. Geladene Modelle sind oft in Zentimetern oder Metern; skaliere die Instanzwurzel einmal passend zu deiner Szene und platziere Dinge darunter in den eigenen Einheiten des Modells. Sprites und Text auf dem Knoten werden ebenfalls skaliert, zusätzlich zu ihrer height.\nSeit: 3.00.",
args = "(node, scale)",
returns = "()",
},
nodeSetShadow = {
type = "function",
description = "Ob das Mesh des Knotens in Shadow Maps gezeichnet wird; true bei jedem neuen Knoten. Schalte es für das Mesh um ein Licht herum aus (eine Glühbirne, eine Flamme), damit es sein eigenes Licht nicht abschattet, und für alles, was leuchtet. Der Knoten zeichnet weiterhin und empfängt weiterhin Schatten von anderen. Es gilt nur für den Knoten, nicht für seine Kinder.\nSeit: 3.00.",
args = "(node, casts)",
returns = "()",
},
nodeSetSprite = {
type = "function",
description = "nodeSetSprite(node, sprite)\nnodeSetSprite(node, sprite, height)\nnodeSetSprite(node, sprite, height, lit)\nnodeSetSprite(node, nil)\nnodeSetSprite(node)\nZeigt ein geladenes Sprite auf dem Knoten: ein Quad, height Welteinheiten hoch (Standard 1) und so breit, wie das Seitenverhältnis des Bilds es ergibt, nach dem Alpha des Bilds geblendet, von beiden Seiten gezeichnet und von der Szene beleuchtet, sofern lit nicht false ist. Jeder Frame eines animierten Sprites wird hochgeladen, und der erste wird gezeigt; nodeSetSpriteFrame wählt einen anderen. Das Quad wird zum Mesh des Knotens mit einem eigenen Material und ersetzt jedes Mesh, Sprite oder jeden Text, den er hatte; nil oder kein zweites Argument nimmt das Bild ab und lässt den Knoten leer. Es bricht das Skript ab, wenn der 3D-Renderer nicht verfügbar ist.\nSeit: 3.00.",
args = "(node, sprite)",
returns = "()",
},
nodeSetSpriteFrame = {
type = "function",
description = "Welcher Frame des animierten Sprites des Knotens gezeigt wird, gezählt ab 0. Das Sprite des Knotens läuft nicht von selbst weiter; treib es aus onOverlayUpdate an. Ein Knoten ohne Sprite oder ein Frame, den es nicht hat, bricht das Skript ab; Text und ein unbewegtes Sprite haben nur Frame 0.\nSeit: 3.00.",
args = "(node, frame)",
returns = "()",
},
nodeSetText = {
type = "function",
description = "nodeSetText(node, text)\nnodeSetText(node, text, height)\nnodeSetText(node, nil)\nnodeSetText(node)\nZeigt eine Textzeile auf dem Knoten, gerendert in der gewählten Schriftart (fontSelect) in der aktuellen Qualität (fontQuality) in der Vordergrundfarbe (colorForeground), auf einem Quad, height Welteinheiten hoch (Standard 1) und so breit, wie der gerenderte Text es ergibt. Er ist unbeleuchtet, geblendet und von beiden Seiten gezeichnet: Namensschilder, Schilder, ein Punktestand über einem Tisch. Wie ein Sprite wird er zum Mesh des Knotens und ersetzt jedes Mesh, Sprite oder jeden Text dort; ruf es erneut auf, um den Text zu ändern, und mit nil oder ohne zweites Argument, um ihn abzunehmen. Ohne gewählte Schriftart oder ohne den 3D-Renderer bricht es das Skript ab.\nSeit: 3.00.",
args = "(node, text)",
returns = "()",
},
nodeSetVisible = {
type = "function",
description = "Versteckt oder zeigt den Knoten und alles darunter; das eigene Flag eines Kindes gilt weiterhin, wenn sein Elternknoten wieder gezeigt wird. Versteckte Meshes werden nicht gezeichnet, und versteckte Lichter hören auf zu leuchten. Damit hältst du eine Markierung oder eine Ersatz-Requisite bereit, ohne sie zu löschen und neu zu bauen.\nSeit: 3.00.",
args = "(node, visible)",
returns = "()",
},
onCollision = {
type = "function",
description = "Wird nach einem Physikschritt einmal für jeden neuen Kontakt zwischen zwei Körpern aufgerufen, nie wieder für ein Paar, das in Berührung bleibt. Eine Kiste, die landet, ein Ball, der den Automaten trifft, das Auto des Spielers, das eine Wand streift. Kontakte mit Triggern melden sich stattdessen über onTrigger. Die Ereignisse eines Schritts werden danach gemeinsam geliefert, bevor der Frame gezeichnet wird.\nSeit: 3.00.",
args = "(nodeA, nodeB, x, y, z, speed)",
returns = "()",
},
onControllerMoved = {
type = "function",
description = "Wird für jedes Achsenbewegungsereignis eines verbundenen Controllers aufgerufen, auch für Bewegung innerhalb der Totzone, ein Stick unter einem Daumen löst ihn also viele Male pro Sekunde aus. Richtungen jenseits von SINGE_DEAD_ZONE wirken außerdem als Schalter, wenn controls.cfg sie belegt, ein Spiel, das nur digitale Lenkung braucht, kann also GAMEPAD_0.AXIS_LEFT_X_L und GAMEPAD_0.AXIS_LEFT_X_R belegen und diesen Callback ignorieren. Der Wert wird für controllerGetAxis gespeichert, bevor der Callback läuft.",
args = "(axis, value, which)",
returns = "()",
},
onInputPressed = {
type = "function",
description = "Wird aufgerufen, wenn eine logische Eingabe gedrückt oder losgelassen wird. Was ankommt, hängt vom Tastaturmodus ab. In MODE_NORMAL ist what ein SWITCH_*-Wert: Tasten, Controller-Knöpfe, Achsenrichtungen jenseits der Totzone, Mausknöpfe und das Mausrad kommen alle auf diesem Weg an, übersetzt durch controls.cfg, jeder Druck einmal und ohne Tastenwiederholung, und Eingaben, die keinem Schalter zugeordnet sind, werden ignoriert. SWITCH_PAUSE kommt nur nach singeSetPauseKeyEnabled(false) an; sonst friert die Engine das Spiel bei dieser Taste ein, und das Skript sieht sie nie. In MODE_FULL ist what das Keysym der Taste (der Zeichenwert, nicht der Scancode), Wiederholungen werden geliefert, und Controller- und Mausknöpfe übergeben 0; jedes Ereignis erreicht außerdem onKeyPressed und onKeyReleased, die den Scancode oder Knopfcode tragen. Wenn die Pausentaste das Spiel einfriert, wird zuerst jeder Schalter, den das Skript gedrückt hält, über onInputReleased losgelassen, und beim Auftauen wird alles, was noch tatsächlich gedrückt ist, erneut gedrückt, sodass ein Spiel nie einen veralteten Knopf sieht. Was in der ersten Sekunde nach dem Start des Skripts oder nachdem das Fenster den Fokus zurückerhalten hat, gedrückt wird, gilt als von vorher gehalten und wird samt seinem Loslassen verschluckt. Ein Schalter kommt von gar keinem Bedienelement: SWITCH_MOUSE_DISCONNECT wird von der Engine ausgelöst, wenn eine Maus oder Lightgun abgezogen wird, einmal als Druck und sofort danach einmal als Loslassen, sodass ein Lightgun-Spiel merkt, dass seine Lightgun weg ist (siehe Mäuse, Lightguns und wer entscheidet).",
args = "(what)",
returns = "()",
anchor = "oninputpressedoninputreleased",
},
onInputReleased = {
type = "function",
description = "Wird aufgerufen, wenn eine logische Eingabe gedrückt oder losgelassen wird. Was ankommt, hängt vom Tastaturmodus ab. In MODE_NORMAL ist what ein SWITCH_*-Wert: Tasten, Controller-Knöpfe, Achsenrichtungen jenseits der Totzone, Mausknöpfe und das Mausrad kommen alle auf diesem Weg an, übersetzt durch controls.cfg, jeder Druck einmal und ohne Tastenwiederholung, und Eingaben, die keinem Schalter zugeordnet sind, werden ignoriert. SWITCH_PAUSE kommt nur nach singeSetPauseKeyEnabled(false) an; sonst friert die Engine das Spiel bei dieser Taste ein, und das Skript sieht sie nie. In MODE_FULL ist what das Keysym der Taste (der Zeichenwert, nicht der Scancode), Wiederholungen werden geliefert, und Controller- und Mausknöpfe übergeben 0; jedes Ereignis erreicht außerdem onKeyPressed und onKeyReleased, die den Scancode oder Knopfcode tragen. Wenn die Pausentaste das Spiel einfriert, wird zuerst jeder Schalter, den das Skript gedrückt hält, über onInputReleased losgelassen, und beim Auftauen wird alles, was noch tatsächlich gedrückt ist, erneut gedrückt, sodass ein Spiel nie einen veralteten Knopf sieht. Was in der ersten Sekunde nach dem Start des Skripts oder nachdem das Fenster den Fokus zurückerhalten hat, gedrückt wird, gilt als von vorher gehalten und wird samt seinem Loslassen verschluckt. Ein Schalter kommt von gar keinem Bedienelement: SWITCH_MOUSE_DISCONNECT wird von der Engine ausgelöst, wenn eine Maus oder Lightgun abgezogen wird, einmal als Druck und sofort danach einmal als Loslassen, sodass ein Lightgun-Spiel merkt, dass seine Lightgun weg ist (siehe Mäuse, Lightguns und wer entscheidet).",
args = "(what)",
returns = "()",
anchor = "oninputpressedoninputreleased",
},
onKeyPressed = {
type = "function",
description = "Wird nur in MODE_FULL aufgerufen, für jede Taste, die gedrückt oder losgelassen wird, mit dem logischen Keysym (dem Zeichen, das die Taste im aktuellen Layout erzeugt) und dem physischen Scancode (der Position der Taste, verglichen mit der Tabelle SCANCODE). Gehaltene Tasten wiederholen sich in diesem Modus, und genau das will eine Texteingabe. Controller- und Mausknöpfe kommen ebenfalls durch, mit keysym 0 und ihrem GAMEPAD_N- oder MOUSE_N-Code als scancode. Für Text verwende keysym; für Steuerungen, bei denen Tasten als Knöpfe dienen, verwende scancode, damit die Belegung auf jedem Layout gleich ist. Tastaturbelegungen der eigenen Schalter der Engine wirken in diesem Modus nicht, ein Spiel in MODE_FULL muss also seinen eigenen Ausweg bieten.",
args = "(keysym, scancode)",
returns = "()",
anchor = "onkeypressedonkeyreleased",
},
onKeyReleased = {
type = "function",
description = "Wird nur in MODE_FULL aufgerufen, für jede Taste, die gedrückt oder losgelassen wird, mit dem logischen Keysym (dem Zeichen, das die Taste im aktuellen Layout erzeugt) und dem physischen Scancode (der Position der Taste, verglichen mit der Tabelle SCANCODE). Gehaltene Tasten wiederholen sich in diesem Modus, und genau das will eine Texteingabe. Controller- und Mausknöpfe kommen ebenfalls durch, mit keysym 0 und ihrem GAMEPAD_N- oder MOUSE_N-Code als scancode. Für Text verwende keysym; für Steuerungen, bei denen Tasten als Knöpfe dienen, verwende scancode, damit die Belegung auf jedem Layout gleich ist. Tastaturbelegungen der eigenen Schalter der Engine wirken in diesem Modus nicht, ein Spiel in MODE_FULL muss also seinen eigenen Ausweg bieten.",
args = "(keysym, scancode)",
returns = "()",
anchor = "onkeypressedonkeyreleased",
},
onMidiMessage = {
type = "function",
description = "Wird für jede Nachricht aufgerufen, die auf dem MIDI-Eingangsport ankommt, den midiOpenInput geöffnet hat, einmal pro Nachricht, zusammen mit den übrigen Eingaben des Frames. Die drei Zahlen sind die Nachricht, wie ein Gerät sie sendet: status trägt die Art in seinen oberen vier Bits und den Kanal in seinen unteren vier, gezählt ab 0, eine Note auf dem ersten Kanal kommt also als 0x90 an. bytes ist die ganze Nachricht als String, was eine System-Exclusive-Nachricht braucht und woraus eine Nachricht, die länger als drei Bytes ist, gelesen werden muss.\nSeit: 3.00.",
args = "(status: number, data1: number, data2: number, bytes: string)",
returns = "()",
},
onMouseMoved = {
type = "function",
description = "Wird für jedes Mausbewegungsereignis aufgerufen, mit der Position und der Bewegung seit dem vorigen Ereignis in Overlay-Koordinaten. Im Modus MOUSE_SINGLE wird die Zeigerposition des Fensters in Overlay-Koordinaten umgerechnet, und which ist immer 0. Im Modus MOUSE_MANY wird die relative Bewegung jedes Geräts zu seiner eigenen Position aufsummiert, begrenzt auf den Videobereich, und which ist der Geräteindex; ein absolutes Gerät wie ein Grafiktablett meldet seine abgebildete Position mit xRelative und yRelative gleich 0. Die Position wird für mouseGetPosition gespeichert, bevor der Callback läuft, ein Spiel kann diesen Callback also ignorieren und stattdessen abfragen. Gezeichnet werden muss trotzdem erst in onOverlayUpdate: Behalte hier die letzte Position in globalen Variablen und zeichne den Cursor dort.",
args = "(x, y, xRelative, yRelative, which)",
returns = "()",
},
onNavArrived = {
type = "function",
description = "Wird aufgerufen, wenn ein Navigationsagent das Ziel erreicht, das navAgentMoveTo ihm gegeben hat, einmal pro Ankunft, nach der Navigationsaktualisierung des Frames. Schick den Agenten woandershin oder spiel seine Leerlaufanimation ab. Ein Skript, das lieber abfragt, kann stattdessen navAgentIsArrived aufrufen.\nSeit: 3.00.",
args = "(agent)",
returns = "()",
},
onOverlayUpdate = {
type = "function",
description = "Der eine Callback, in dem Zeichnen erlaubt ist. Singe ruft ihn höchstens einmal alle 15 Millisekunden auf, solange das Spiel nicht eingefroren ist, gezählt ab dem Beginn des vorigen Aufrufs, die Zeit, die das Skript selbst braucht, fällt also in diese 15 Millisekunden, statt zu ihnen hinzuzukommen; jeder anderswo gemachte Aufruf von overlay*, spriteDraw, videoDraw, fontPrint oder Ähnlichem erscheint nicht auf dem Bildschirm und kann das Overlay beschädigen. Gib OVERLAY_UPDATED (1) zurück, wenn sich das Overlay geändert hat, damit Singe es erneut über das Video legt, oder OVERLAY_NOT_UPDATED (0), wenn sich nichts geändert hat, damit das vorige Gesamtbild wiederverwendet wird; gar nichts zurückzugeben zählt als OVERLAY_NOT_UPDATED. Die Anzeige wird ohnehin neu gezeichnet, sobald ein neuer Video-Frame ankommt oder eine 3D-Szene eingeschaltet ist, der Rückgabewert ist also eine Optimierung für statische Bildschirme. Nachdem er zurückgekehrt ist, löscht die Engine die Werte hinter keyboardGetLastDown und keyboardGetLastUp. Im Thread-Modell definiert Framework.singe diese Funktion selbst, um singeMain fortzusetzen, und gibt immer OVERLAY_UPDATED zurück; definiere sie nicht zusätzlich.\nRückgabe: OVERLAY_UPDATED oder OVERLAY_NOT_UPDATED.",
args = "()",
returns = "()",
},
onShutdown = {
type = "function",
description = "Wird einmal aufgerufen, wenn das Skript endet, ob durch singeQuit, den Beenden-Schalter, das Schließen des Fensters, scriptExecute oder scriptPush, nach dem letzten Frame und bevor der Lua-Zustand verworfen wird. singeReload ruft ihn nicht auf. Speichere hier Einstellungen und gib die Sprites, Sounds, Schriftarten und Videos frei, die das Skript geladen hat; die Engine stoppt danach jeden Sound und gibt frei, was übrig ist, ein vergessenes Handle ist also kein Leck, aber ausdrückliches Entladen behält die Reihenfolge beim Herunterfahren unter der Kontrolle des Skripts. Ruf von hier aus nicht singeQuit auf.",
args = "()",
returns = "()",
},
onSoundCompleted = {
type = "function",
description = "Wird jedes Mal mit der Kanalnummer aufgerufen, wenn ein Kanal stoppt: wenn sein Clip endet, wenn die letzte Schleife fertig ist und wenn soundStop oder soundFullStop ihn anhält, ein Skript, das von hier aus Sounds verkettet, sollte also wissen, welche Kanäle es selbst gestoppt hat. Der Mixer bemerkt den Stopp auf seinem eigenen Thread, und die Engine liefert den Callback zwischen den Frames auf dem Spiel-Thread; solange die Pausentaste das Spiel eingefroren hält, warten die Meldungen, und sie werden verworfen, wenn ein Skript endet oder neu geladen wird. Bis zu 64 Abschlüsse werden zwischen den Frames eingereiht; was in einem Frame darüber hinausgeht, geht verloren.",
args = "(channel)",
returns = "()",
},
onTextInput = {
type = "function",
description = "Wird nur in MODE_FULL aufgerufen, nachdem Umschaltzustand und Layout der Tastatur angewendet wurden, mit dem Text, den ein Tastendruck erzeugt hat -- ein Zeichen oder ein paar, in UTF-8. So kommt ein Großbuchstabe, ein Anführungszeichen oder ein Buchstabe aus einem nicht englischen Layout so an, wie die Person ihn getippt hat. onKeyPressed liefert denselben Druck als sein Keysym ohne Umschaltung und seinen Scancode und ist der richtige für Tasten, die Befehle sind; dieser hier ist der richtige für Tasten, die Text sind. Eine GUI mit einem fokussierten Textfeld bekommt den Text zuerst, und das Skript hört nichts davon.\nSeit: 3.00.",
args = "(text)",
returns = "()",
},
onTrigger = {
type = "function",
description = "Wird aufgerufen, wenn ein Körper einen mit bodySetTrigger gemachten Trigger betritt oder verlässt, einmal auf dem Weg hinein und einmal auf dem Weg hinaus, unabhängig von den beteiligten Formen (ein Mesh oder eine zusammengesetzte Form, die an mehreren Stellen berührt, zählt trotzdem als ein Körper). Trigger schieben nie etwas, das hier ist also der Weg, zu bemerken, dass ein Körper eine Tür durchquert, einen Checkpoint erreicht oder in eine Todeszone fällt.\nSeit: 3.00.",
args = "(trigger, other, entered)",
returns = "()",
},
opusDecode = {
type = "function",
description = "Ein Paket zurück zu Samples. nil für ein Paket, das nie angekommen ist, bittet Opus, die Lücke mit etwas Plausiblem zu füllen, so lang wie das letzte Paket.\nRückgabe: die Samples.\nSeit: 3.00.",
args = "(decoder, packet | nil)",
returns = "(samples)",
},
opusDecoderNew = {
type = "function",
description = "Rückgabe: das Handle des Decoders.\nSeit: 3.00.",
args = "([rate [, channels]])",
returns = "(decoder)",
},
opusEncode = {
type = "function",
description = "Ein Frame aus Samples als ein Paket. Ein Frame umfasst 2,5, 5, 10, 20, 40 oder 60 Millisekunden an Samples; alles andere wird abgelehnt.\nRückgabe: das Paket, ein String.\nSeit: 3.00.",
args = "(encoder, samples)",
returns = "(packet)",
},
opusEncoderNew = {
type = "function",
description = "Rückgabe: das Handle des Encoders.\nSeit: 3.00.",
args = "([rate [, channels [, application]]])",
returns = "(encoder)",
},
opusEncoderSet = {
type = "function",
description = "Seit: 3.00.",
args = "(encoder, bitrate [, complexity])",
returns = "()",
},
overlayBanner = {
type = "function",
description = "Hypseus-Erweiterung. Zeigt eine kurze Meldung über dem Bild für etwa dreißig gezeichnete Frames und nimmt sie dann wieder weg. height ist, wo sie sitzt, in Prozent von oben über das Bild, von 1 bis 95; der Standard ist 47, der von Hypseus selbst, und eine Zahl außerhalb dieses Bereichs wird durch den Standard ersetzt statt abgelehnt.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(text [, height])",
returns = "()",
},
overlayBox = {
type = "function",
description = "Zeichnet den Umriss des achsenparallelen Rechtecks mit den gegenüberliegenden Ecken (x1, y1) und (x2, y2) als vier ein Pixel breite Linien in der Vordergrundfarbe. Beide Ecken gehören dazu und können in beliebiger Reihenfolge angegeben werden. Eine gefüllte Variante gibt es nicht; füll das ganze Overlay mit overlayClear auf einer Hintergrundfarbe oder eine Fläche mit einem gestreckten Sprite.\nSeit: 2.00",
args = "(x1, y1, x2, y2)",
returns = "()",
},
overlayCircle = {
type = "function",
description = "Zeichnet einen ein Pixel breiten Kreisumriss in der Vordergrundfarbe, zentriert auf (x, y), mit dem Mittelpunktalgorithmus. Ein Radius von 0 oder weniger zeichnet nichts. Koordinaten und Radius sind Ganzzahlen in Overlay-Einheiten; Nachkommastellen werden abgeschnitten.\nSeit: 2.00",
args = "(x, y, radius)",
returns = "()",
},
overlayClear = {
type = "function",
description = "Füllt das ganze Overlay mit der aktuellen Hintergrundfarbe. Ist die Farbe dieselbe wie beim letzten Löschen, wird nur das neu gefüllt, was seitdem gezeichnet wurde, sodass das Löschen eines Overlays mit ein paar Textzeilen fast nichts kostet, wie groß es auch ist. Der Hintergrund beginnt als transparentes Schwarz, ohne einen Aufruf von colorBackground löscht dies das Overlay also zurück zu unsichtbar, und das Video scheint durch. Ein teilweise deckender Hintergrund dämpft das Video; ein vollständig deckender verdeckt es. Die meisten Spiele rufen es als Erstes in onOverlayUpdate auf. Argumente werden ignoriert.\nSeit: 1.x",
args = "()",
returns = "()",
},
overlayEllipse = {
type = "function",
description = "Zeichnet einen ein Pixel breiten Ellipsenumriss in der Vordergrundfarbe, einbeschrieben in das achsenparallele Rechteck mit den gegenüberliegenden Ecken (x1, y1) und (x2, y2). Die Ecken können in beliebiger Reihenfolge angegeben werden. Ein Rechteck mit gleicher Breite und Höhe ergibt einen Kreis, das ist also auch der Weg, einen Kreis aus seinem umschließenden Rechteck statt aus seinem Mittelpunkt zu zeichnen.\nSeit: 2.00",
args = "(x1, y1, x2, y2)",
returns = "()",
},
overlayGetFontHeight = {
type = "function",
description = "Gibt die Höhe einer Zeichenzelle der eingebauten Konsolenschrift in Pixeln zurück, die Einheit, in der overlayPrint zählt. Die Konsolenschrift ist ein einziges eingebettetes Bild mit 256 Glyphen, das einmal geladen wird, bevor irgendein Skript läuft, der Wert ändert sich also nie, solange das Programm läuft. Argumente werden ignoriert.\nRückgabe: ganzzahlige Höhe einer Zelle in Pixeln.\nSeit: 3.00",
args = "()",
returns = "(integer)",
},
overlayGetFontWidth = {
type = "function",
description = "Gibt die Breite einer Zeichenzelle der eingebauten Konsolenschrift in Pixeln zurück, die Einheit, in der overlayPrint zählt. Nimm sie mit overlayGetWidth, um auszurechnen, wie viele Spalten passen, oder um Konsolentext an etwas auszurichten, das in Pixeln gezeichnet ist. Teile mit // statt /: Die gewöhnliche Division von Lua ergibt eine Zahl mit Nachkommastellen, und eine Zellenposition muss ganzzahlig sein. Argumente werden ignoriert.\nRückgabe: ganzzahlige Breite einer Zelle in Pixeln.\nSeit: 3.00",
args = "()",
returns = "(integer)",
},
overlayGetHeight = {
type = "function",
description = "Gibt die Höhe der Overlay-Fläche in Overlay-Einheiten zurück: den zuletzt an overlaySetResolution übergebenen Wert oder, vor jedem Aufruf, die halbe Videohöhe. Lies sie beim Start, nach dem Setzen der Auflösung, um Positionen nach der tatsächlichen Zeichenfläche anzuordnen. Argumente werden ignoriert.\nRückgabe: ganzzahlige Höhe.\nSeit: 1.x",
args = "()",
returns = "(integer)",
},
overlayGetWidth = {
type = "function",
description = "Gibt die Breite der Overlay-Fläche in Overlay-Einheiten zurück: den zuletzt an overlaySetResolution übergebenen Wert oder, vor jedem Aufruf, die halbe Videobreite. Nimm sie, um Elemente rechtsbündig auszurichten oder zu zentrieren, statt eine Breite fest einzutragen. Argumente werden ignoriert.\nRückgabe: ganzzahlige Breite.\nSeit: 1.x",
args = "()",
returns = "(integer)",
},
overlayLine = {
type = "function",
description = "Zeichnet eine ein Pixel breite Bresenham-Linie in der Vordergrundfarbe von (x1, y1) nach (x2, y2), beide Endpunkte eingeschlossen. Pixel außerhalb des Overlays werden verworfen, Endpunkte dürfen also außerhalb der Fläche liegen. Koordinaten werden auf Ganzzahlen abgeschnitten.\nSeit: 2.00",
args = "(x1, y1, x2, y2)",
returns = "()",
},
overlayPlot = {
type = "function",
description = "Setzt ein Overlay-Pixel auf die Vordergrundfarbe. Ein Punkt außerhalb der Fläche wird ignoriert. Jeder Aufruf sperrt und entsperrt das Overlay, Tausende Punkte pro Frame aus Lua zu setzen ist also langsam; nimm ein Sprite für alles mit Struktur und heb dies für Sterne, Funken und Debugging-Markierungen auf.\nSeit: 2.00",
args = "(x, y)",
returns = "()",
},
overlayPrint = {
type = "function",
description = "Gibt einen String in der eingebauten Konsolenschrift fester Breite der Engine aus. Anders als bei jedem anderen Zeichenaufruf ist die Position eine Zeichenzelle: Die Engine multipliziert column und row mit Breite und Höhe der Glyphen, sodass (0, 0) die Zelle oben links ist und (1, 0) eine Glyphe weiter rechts. Glyphen werden unverändert aus dem Schriftbild kopiert; die aktuellen Vorder- und Hintergrundfarben werden nicht angewandt, und nur der eigene Hintergrund der Schrift ist transparent. Jedes Byte des Strings wählt eine der 256 Glyphen der Schrift, der Text wird also als Bytes behandelt, nicht als UTF-8. Zeichen, die über den rechten Rand des Overlays hinausliefen, werden verworfen, und Text, der jenseits des Rands beginnt, zeichnet nichts.\nSeit: 1.x",
args = "(column, row, text)",
returns = "()",
},
overlaySetMonochrome = {
type = "function",
description = "Hypseus-Erweiterung. Zeigt das Overlay in Grau: Vor jedem Hochladen wandelt die Engine eine Kopie davon mit den Gewichten nach BT.601 in Luma um und lässt den Alphakanal, wie er ist (Hypseus wendet darauf einen Schwellenwert an). Die eigenen Pixel des Overlays bleiben farbig, nichts, was das Skript zurückliest, ändert sich also, und das Zeichnen geht wie gewohnt weiter. Kombiniere es mit vldpSetMonochrome für einen Schwarzweißmodus. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled)",
returns = "()",
},
overlaySetResolution = {
type = "function",
description = "Ersetzt das Overlay durch eine neue Fläche der angegebenen Größe und verwirft alles bisher Gezeichnete. Von da an ist jede Overlay-Koordinate, jede Sprite-Position und jedes Ergebnis von overlayGetWidth oder overlayGetHeight im neuen Koordinatenraum, den die Engine bei der Anzeige auf das Fenster skaliert. Ruf es einmal beim Start auf, vor dem Zeichnen; der Standard ist in jeder Dimension die halbe Videoauflösung. Eine Breite oder Höhe von 0 oder weniger beendet das Skript mit einem Fehler. Höhere Auflösungen bringen feinere Platzierung und schärferen Text für mehr Kompositionsarbeit pro Frame; die native Größe der Disc aus discGetWidth und discGetHeight ist die übliche Wahl.\nSeit: 2.00",
args = "(width, height)",
returns = "()",
},
physicsRaycast = {
type = "function",
description = "Findet den ersten Körper entlang eines Strahls von (x, y, z) in Richtung (dx, dy, dz), innerhalb von maxDistance Welteinheiten. Die Richtung wird normalisiert, jede Länge funktioniert also, aber eine Nullrichtung trifft nichts. Trigger und Spielfiguren werden wie jeder andere Körper getroffen; eine Spielfigur wird über ihren Knoten gemeldet. Liefert sceneUnproject zwei Punkte entlang der Maus, ist das die Objektauswahl per Maus; senkrecht nach unten von einem Punkt aus ist es eine Höhenmessung.\nRückgabe: Der Knoten des Körpers, der Trefferpunkt und die Oberflächennormale dort oder ein einzelnes nil, wenn nichts getroffen wird.\nSeit: 3.00.",
args = "(x, y, z, dx, dy, dz [, maxDistance])",
returns = "(node, hx, hy, hz, nx, ny, nz)",
},
physicsSet2D = {
type = "function",
description = "Mit true bewegen sich von nun an erzeugte Körper nur in X und Y und drehen sich nur um Z: die Welt eines 2D-Spiels, meist in Overlay-Koordinaten mit einer Schwerkraft in Richtung +Y, sodass Dinge den Bildschirm hinunterfallen. Bereits erzeugte Körper behalten ihre Freiheit, ruf es also vor jedem bodyNew auf; false kehrt für danach erzeugte Körper zu vollem 3D zurück. Spielfiguren sind anders: Solange der Modus an ist, läuft jede Spielfigur, wann immer sie erzeugt wurde, entlang X mit auf 0 gehaltenem Z, und playerMove nimmt einen einzigen Wert. Die 2D-Welt funktioniert ohne GPU, auch auf dem Raspberry Pi 3.\nSeit: 3.00.",
args = "(planar)",
returns = "()",
},
physicsSetDebug = {
type = "function",
description = "Zeichnet in jedem Frame, solange die Maske gesetzt ist, als Linien über die Szene, was die Simulation enthält: DEBUG_SHAPES die Form jedes bewegten Körpers als Drahtgitter (Soft Bodies eingeschlossen und eingeschaltete Spielfiguren in Gelb), DEBUG_CONSTRAINTS Gelenke, Ragdoll-Gelenke und Fahrzeug-Constraints mit ihren Grenzen, DEBUG_CONTACTS ein rotes Kreuz, wo sich Körper in diesem Schritt getroffen haben, und DEBUG_VELOCITIES eine Linie entlang der Geschwindigkeit jedes bewegten Körpers. Addiere die Flags; DEBUG_ALL sind alle vier. Die Formen statischer Körper bleiben aus, sofern nicht DEBUG_STATIC hinzukommt, weil ein Level-Mesh sehr viele Linien ergibt. DEBUG_NONE schaltet es ab, und solange es aus ist, wird nichts gezeichnet und nichts kostet etwas.\nSeit: 3.00.",
args = "(mask)",
returns = "()",
},
physicsSetEnabled = {
type = "function",
description = "Pausiert die Simulation mit false und setzt sie mit true fort. Solange sie pausiert ist, läuft kein Schritt: Dynamische Körper halten still und behalten ihre Geschwindigkeiten, kinematische Körper folgen ihren Knoten nicht mehr, Spielfiguren bewegen sich nicht mehr, und kein onCollision oder onTrigger wird ausgelöst. Während der Pause sammelt sich keine Zeit an, das Fortsetzen holt die verpassten Schritte also nicht nach. Die eigene Pause des Spiels tut dasselbe ohne diesen Aufruf; nimm ihn für ein Menü, eine Zwischensequenz oder ein Standbild, bei dem der Rest des Spiels weiterläuft.\nSeit: 3.00.",
args = "(enabled)",
returns = "()",
},
physicsSetGravity = {
type = "function",
description = "Setzt die Beschleunigung, die jeder dynamische Körper und jede Spielfigur spürt, in Welteinheiten pro Sekunde zum Quadrat entlang jeder Weltachse. Der Standard ist 0, -9.81, 0, die Erdschwerkraft in Metern; 0, 0, 0 ist der Weltraum, und ein 2D-Spiel in Overlay-Pixeln will etwa 0, 900, 0, da Y im Overlay den Bildschirm hinunterläuft. Die der Schwerkraft entgegengesetzte Richtung ist für Spielfiguren „oben“: die Richtung, in der sie stehen, springen und Stufen erklimmen.\nSeit: 3.00.",
args = "(x, y, z)",
returns = "()",
},
playerDelete = {
type = "function",
description = "Entfernt die Spielfigur; der Knoten und was darunter hängt bleiben, wo sie sind. Das Löschen des Knotens entfernt auch seine Spielfigur, ebenso, wenn der Knoten mit bodyNew einen Körper bekommt. Beendet das Skript, wenn der Knoten keine Spielfigur hat.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
playerGetGround = {
type = "function",
description = "Worauf die Spielfigur steht, und die Oberflächennormale des Bodens dort. Der Knoten ist der Körper unter den Füßen, ob begehbar oder nicht; in der Luft ist er nil, und die Normale ist dann 0, 1, 0. Unterscheide über den Knoten eine bewegliche Plattform, Eis oder eine Druckplatte vom Boden und neige über die Normale ein Modell in einen Hang.\nRückgabe: Der Knoten, auf dem sie steht, oder nil, dann die Normale.\nSeit: 3.00.",
args = "(node)",
returns = "(ground, nx, ny, nz)",
},
playerGetVelocity = {
type = "function",
description = "Die Geschwindigkeit der Spielfigur nach dem letzten Schritt, in Welteinheiten pro Sekunde entlang jeder Weltachse, einschließlich dessen, was der Boden, auf dem sie mitfährt, ihr gegeben hat. Lies den senkrechten Anteil, um Steigen von Fallen zu unterscheiden, oder das Ganze für ein dumpfes Landegeräusch.\nRückgabe: Drei Zahlen.\nSeit: 3.00.",
args = "(node)",
returns = "(x, y, z)",
},
playerIsOnGround = {
type = "function",
description = "Ob die Spielfigur beim letzten Schritt auf begehbarem Boden steht: einer Fläche, die nicht steiler als playerSetSlope ist. In der Luft oder auf einem zu steilen Hang ist es false. Das ist dieselbe Prüfung, die playerJump macht.\nRückgabe: Boolean.\nSeit: 3.00.",
args = "(node)",
returns = "(boolean)",
},
playerIsSwimming = {
type = "function",
description = "Ob die Spielfigur beim letzten Schritt im Wasser war: die Mitte ihrer Form unter der Oberfläche eines bodySetWater-Volumens. Beim Schwimmen steuert playerMove in drei Achsen, die Schwerkraft weicht der Sinkgeschwindigkeit, und die Strömung des Wassers trägt die Spielfigur mit.\nRückgabe: Boolean.\nSeit: 3.00.",
args = "(node)",
returns = "(boolean)",
},
playerJump = {
type = "function",
description = "Bittet die Spielfigur, beim nächsten Schritt mit dieser Aufwärtsgeschwindigkeit, in Welteinheiten pro Sekunde, vom Boden abzuheben. Das wird nur gewährt, wenn gerade begehbarer Boden unter den Füßen ist, sodass ein gehaltener Knopf die Spielfigur nicht hüpfen lässt und ein Sprung in der Luft nichts tut. Eine negative Geschwindigkeit wird als 0 behandelt. Die Spielfigur behält ihre waagerechte Geschwindigkeit während des Sprungs, und playerMove steuert sie auch in der Luft.\nRückgabe: true, wenn der Sprung gewährt wurde.\nSeit: 3.00.",
args = "(node, speed)",
returns = "(jumped)",
},
playerMove = {
type = "function",
description = "playerMove(node, vx, vz)\nplayerMove(node, vx, vy, vz)\nplayerMove(node, vx)\nTeilt der Spielfigur die Geschwindigkeit mit, die sie in diesem Frame will, in Welteinheiten pro Sekunde. Am Boden oder in der Luft werden die beiden waagerechten Werte so verwendet, wie sie angegeben sind, zusätzlich zu der Plattform, auf der sie steht; der senkrechte Anteil kommt von der Schwerkraft, dem Boden und playerJump, und vy wird ignoriert. Schwimmt die Spielfigur, steuern sie alle drei Werte, und das Wasser führt ihre Geschwindigkeit mit dem Widerstand aus playerSetSwim sanft an sie heran, wobei sie mit der Sinkgeschwindigkeit sinkt, wenn vy gleich 0 ist. In einer 2D-Welt läuft ein einzelnes vx entlang X, und jedes vz wird ignoriert. Ruf es in jedem Frame aus onOverlayUpdate auf: Die Anforderung wird von den Schritten dieses Frames verbraucht, und in einem Frame ohne Anforderung steht sie still.\nSeit: 3.00.",
args = "(node, vx, vz)",
returns = "()",
},
playerNew = {
type = "function",
description = "playerNew(node, radius, height)\nplayerNew(node, SHAPE_CAPSULE, radius, height)\nplayerNew(node, SHAPE_CYLINDER, radius, height)\nplayerNew(node, SHAPE_SPHERE, radius, 0)\nplayerNew(node, SHAPE_BOX, width, height, depth)\nplayerNew(node, SHAPE_HULL)\nSetzt eine Spielfigur auf den Knoten, dort, wo der Knoten gerade in der Welt ist: eine Kapsel mit diesem Radius und dieser Gesamthöhe oder jede konvexe bodyNew-Form mit ihren Größen, skaliert mit der Weltskalierung des Knotens. Die Form steht auf dem Ursprung des Knotens, der Knoten sind also die Füße. Sie beginnt mit einer Masse von 70 Kilogramm, einer Schubkraft von 300 Newton, einer Hanggrenze von 45 Grad, einer Stufenhöhe von 0.3, skaliert mit der Form, dem Schwerkraftfaktor 1 und den Standardwerten fürs Schwimmen. Ersetzt jeden Körper und jede Spielfigur, die der Knoten hatte. Beendet das Skript bei SHAPE_MESH (eine Spielfigur braucht eine konvexe Form; nimm SHAPE_HULL), wenn auf diesem Rechner keine Physik verfügbar ist oder wenn die Spielfigur nicht erzeugt werden kann (eine Hülle mit zu wenig Mesh oder schon sechzehn Spielfiguren).\nSeit: 3.00.",
args = "(node, radius, height)",
returns = "()",
},
playerSetEnabled = {
type = "function",
description = "Mit false verlässt die Spielfigur die Simulation: Ihr Körper wird aus der Welt entfernt, sie bewegt sich also nicht, fällt nicht, treibt ihren Knoten nicht und blockiert nichts, onTrigger meldet, dass sie jeden Trigger verlässt, in dem sie stand, und beim Debug-Zeichnen wird sie ausgelassen. true setzt den Körper zurück und nimmt ihn dort wieder auf, wo der Knoten gerade ist. Schalte eine Spielfigur aus, solange eine Ragdoll, eine Zwischensequenz oder ein Fahrzeug über die Figur verfügt.\nSeit: 3.00.",
args = "(node, enabled)",
returns = "()",
},
playerSetGravityScale = {
type = "function",
description = "Multipliziert die Schwerkraft der Welt für diese Spielfigur allein: 1 (der Standard) fällt wie alles andere, 0 schwebt, wo sie ist (eine Leiter, ein Raum ohne Schwerkraft, ein fliegendes Reittier), mehr fällt schneller und fühlt sich schwer an, und weniger ergibt einen schwebenden Sprung. Es ändert nicht, was playerJump beim Absprung tut, nur wie schnell die Spielfigur wieder herunterkommt. Beim Schwimmen tritt die Sinkgeschwindigkeit des Wassers an die Stelle der Schwerkraft.\nSeit: 3.00.",
args = "(node, scale)",
returns = "()",
},
playerSetMass = {
type = "function",
description = "Die Masse der Spielfigur, verwendet, wenn sie dynamische Körper schiebt, und als ihr Gewicht auf jedem, auf dem sie steht. Der Standard ist 70 Kilogramm; Werte unter 0.001 werden darauf angehoben. Die Masse wirkt sich nicht darauf aus, wie die Spielfigur fällt oder geht, nur auf das Schieben, kombiniere sie also mit playerSetPush.\nSeit: 3.00.",
args = "(node, kilograms)",
returns = "()",
},
playerSetPosition = {
type = "function",
description = "Teleportiert die Spielfigur an eine Position in der Welt, ohne unterwegs etwas zu berühren, und hält sie schlagartig an. Der Knoten bewegt sich mit und behält seine Rotation. Nimm es zum Erscheinen, Wiedererscheinen und für Levelwechsel; den Knoten stattdessen mit nodeSetPosition zu bewegen lässt die Spielfigur, wo sie war, und der Knoten wird beim nächsten Schritt zurückgezogen.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
playerSetPush = {
type = "function",
description = "Wie stark die Spielfigur dynamische Körper schiebt, in die sie hineinläuft, in Newton. Der Standard 300 bewegt Kisten und Bälle, aber keine Automaten; 0 geht um alles herum, als wäre es statisch. Negative Werte werden auf 0 begrenzt. Das eigene bodySetMass eines Körpers entscheidet, was eine gegebene Stärke bewegen kann.\nSeit: 3.00.",
args = "(node, strength)",
returns = "()",
},
playerSetSlope = {
type = "function",
description = "Der steilste Hang, den die Spielfigur hinaufgeht, in Grad gegen die Waagerechte; steilerer Boden gilt nicht als Stehen, die Spielfigur rutscht ihn also hinunter und kann nicht von ihm abspringen. Der Standard ist 45, und der Wert wird zwischen 0 und 89 begrenzt. Ein niedriger Wert macht Hügel zu Hindernissen, ein hoher lässt die Spielfigur fast alles erklimmen, was keine Wand ist.\nSeit: 3.00.",
args = "(node, degrees)",
returns = "()",
},
playerSetStep = {
type = "function",
description = "Die höchste Stufe, die die Spielfigur ohne Sprung erklimmt, in Welteinheiten; alles Höhere ist eine Wand, an der sie entlanggleitet. Der Standard ist 0.3 bei einer Form, deren kleinste halbe Ausdehnung 0.3 ist (eine Kapsel mit Radius 0.3), und skaliert mit der Form, sodass eine 30 Pixel große Spielfigur in einer 2D-Welt mit 30 Pixeln beginnt. Dieselbe Strecke ist, wie weit die Spielfigur über die Kante einer Stufe hinweg nach unten am Boden haftet, eine größere Stufe hält sie also auch auf Gefällen am Boden. Negative Werte werden auf 0 begrenzt.\nSeit: 3.00.",
args = "(node, height)",
returns = "()",
},
playerSetSwim = {
type = "function",
description = "Legt fest, wie sich die Spielfigur im Wasser verhält: wie schnell sie sinkt, in Welteinheiten pro Sekunde, wenn playerMove keine senkrechte Bewegung verlangt (Standard 0.3), und wie schnell das Wasser ihre Geschwindigkeit zu dem hinzieht, was playerMove verlangt, als Rate pro Sekunde (Standard 2, sodass der größte Teil des Unterschieds innerhalb einer Sekunde verschwunden ist; 0 ändert die Geschwindigkeit nie). Beide werden auf mindestens 0 begrenzt. Ein schwerer Taucher sinkt schnell, mit hohem Widerstand; ein Korken sinkt gar nicht.\nSeit: 3.00.",
args = "(node, sinkSpeed, drag)",
returns = "()",
},
playerSetVelocity = {
type = "function",
description = "Setzt die ganze Geschwindigkeit der Spielfigur, in Welteinheiten pro Sekunde entlang jeder Weltachse, und verwirft jede in diesem Frame gemachte playerMove-Anforderung. Der senkrechte Anteil ist das, was bleibt: Eine Aufwärtsgeschwindigkeit hebt die Spielfigur vom Boden, und sie fällt unter der Schwerkraft zurück, das ist ein Sprungfeld oder ein Abprallen. Der waagerechte Anteil hält nur bis zum nächsten Schritt, wenn er durch das ersetzt wird, was playerMove verlangt (nichts, wenn es nicht aufgerufen wird), weil eine Spielfigur keinen eigenen waagerechten Schwung hat. Ein Rückstoß oder ein Dash ist hier also ein Stoß nach oben plus eine playerMove-Geschwindigkeit, die über die folgenden Frames eingespeist wird.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
ragdollActivate = {
type = "function",
description = "Übergibt das Skelett aus seiner aktuellen Pose an die Physik: Jede Animationsebene auf dem Knoten stoppt, für jeden Knochen wird dort, wo sein Gelenk gerade steht, eine dynamische Kapsel erzeugt, zwischen ihnen werden die Swing-Twist-Gelenke erzeugt, und von da an treibt jeder Physikschritt die Gelenkknoten aus den Körpern, sodass das geskinnte Mesh folgt. Die Knochen kollidieren mit der Welt und miteinander, außer jeder Knochen mit seinem Elternknochen. Die Pose in diesem Moment ist das, wohin ragdollSetStrength zieht. Eine bereits aktive Ragdoll bleibt, wie sie ist. Beendet das Skript, wenn der Körper eines Knochens nicht erzeugt werden kann.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
ragdollApplyImpulse = {
type = "function",
description = "Gibt dem Körper des Knochens, der am genannten Gelenk beginnt, einen Impuls in Newtonsekunden entlang der Weltachsen: der Schlag, der Schuss, die Explosion. Die Ragdoll muss aktiv sein, ruf also zuerst ragdollActivate auf und stoß dann. Gibt false zurück und tut nichts, wenn die Ragdoll nicht aktiv ist oder kein Knochen diesen Namen hat (Endgelenke sind keine Knochen); der Name wird ohne Rücksicht auf Groß- und Kleinschreibung verglichen.\nRückgabe: Wahr, wenn der Knochen gefunden wurde und die Ragdoll aktiv war.\nSeit: 3.00.",
args = "(node, jointName, x, y, z)",
returns = "(hit)",
},
ragdollDeactivate = {
type = "function",
description = "Entfernt die Körper und Gelenke und gibt das Skelett zurück. Die Gelenkknoten behalten die Pose, in der die Ragdoll sie gelassen hat, und nichts bewegt sie, bis eine Animation läuft; ein animationPlay mit Überblendung blendet aus dieser Pose heraus, sodass eine am Boden liegende Figur aufstehen kann. Das Rezept bleibt, sodass ragdollActivate später wieder übernehmen kann, wo auch immer die Animation das Skelett hinbewegt hat. Tut nichts bei einer Ragdoll, die nicht aktiv ist.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
ragdollDelete = {
type = "function",
description = "Entfernt die Ragdoll: ihre Körper und Gelenke, wenn sie aktiv ist, dann das Rezept. Die Gelenkknoten bleiben, wo die Physik sie gelassen hat, das Modell liegt also, wie es gefallen ist, bis eine Animation es bewegt, und der Knoten ist frei für ein neues ragdollNew. Ein Knoten ohne Ragdoll beendet das Skript.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
ragdollIsActive = {
type = "function",
description = "Ob die Physik das Skelett gerade treibt: true von ragdollActivate bis ragdollDeactivate oder ragdollDelete. Ein Knoten ohne Ragdoll beendet das Skript.\nRückgabe: Wahr oder falsch.\nSeit: 3.00.",
args = "(node)",
returns = "(active)",
},
ragdollIsResting = {
type = "function",
description = "Ob der Körper jedes Knochens eingeschlafen ist, was die Physik tut, sobald ein Körper einen Moment lang still war. false, solange die Ragdoll nicht aktiv ist, es kann also nicht dazu dienen, ein untätiges Modell von einem zur Ruhe gekommenen zu unterscheiden; prüf auch ragdollIsActive.\nRückgabe: Wahr oder falsch.\nSeit: 3.00.",
args = "(node)",
returns = "(resting)",
},
ragdollNew = {
type = "function",
description = "Sucht am Knoten und darunter nach dem ersten geskinnten Mesh und baut aus seinem Skelett ein Ragdoll-Rezept: Jedes Gelenk, das ein Kindgelenk hat, wird zu einem Knochen, einer Kapsel, die vom Gelenk zu seinen Kindern verläuft und mit dem nächsten Knochen darüber durch ein Swing-Twist-Gelenk verbunden ist, begrenzt auf 45 Grad Schwenk und 30 Grad Verdrehung. Gelenke ohne Kindgelenk, etwa Fingerspitzen und die Spitze eines Schwanzes, bewegen sich mit ihrem Elternknochen mit und können in den anderen Aufrufen nicht genannt werden. Noch wird nichts simuliert: Das Modell animiert weiter bis ragdollActivate. Ein erneuter Aufruf auf demselben Knoten verwirft zuerst die alte Ragdoll. Beendet das Skript, wenn keine Physik verfügbar ist, wenn unter dem Knoten kein geskinntes Mesh mit Knochen liegt oder wenn schon acht Ragdolls existieren.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
ragdollSetJoint = {
type = "function",
description = "Stimmt das Rezept eines Knochens ab. Die Werte werden gelesen, wenn die Körper erzeugt werden, ruf es also vor ragdollActivate auf; eine bereits aktive Ragdoll behält ihre Körper, bis sie deaktiviert und erneut aktiviert wird. Der Radius 0 verlangt die automatische Kapsel, 0,22 der Knochenlänge und nie dünner als 0.02 Einheiten. Der Schwenk ist der halbe Öffnungswinkel des Kegels, durch den sich der Knochen relativ zu seinem Elternknochen bewegen darf, die Verdrehung, wie weit er sich um seine eigene Achse drehen darf; beide werden auf 0 bis 179 begrenzt. Nur Knochen können genannt werden, nicht die Endgelenke; der Name wird ohne Rücksicht auf Groß- und Kleinschreibung verglichen, und ein Name ohne Knochen beendet das Skript.\nSeit: 3.00.",
args = "(node, jointName, radius, swingDegrees, twistDegrees)",
returns = "()",
},
ragdollSetStrength = {
type = "function",
description = "Treibt jedes Gelenk mit einem Motor an, der zu der Pose zieht, in der die Ragdoll aktiviert wurde, begrenzt auf so viele Newtonmeter; 0 (Standard) schaltet die Motoren aus, und der Körper wird schlaff. Die Motoren sind Federn mit 4 Hz, kritisch gedämpft. Es kann vor dem Aktivieren oder während sich die Ragdoll bewegt gesetzt werden und wirkt ab dem nächsten Schritt. Einen Körper stellt es nicht auf, da sich nichts vom Boden abstößt: Ein paar Dutzend Newtonmeter verwandeln einen Sturz in ein Taumeln und lassen eine am Boden liegende Figur ihre Gliedmaßen einziehen.\nSeit: 3.00.",
args = "(node, strength)",
returns = "()",
},
random = {
type = "lib",
description = "Außerdem bindet Framework.singe random = { new = math.random } neu, damit Skripte aus der Zeit vor 2.00, die random.new() verwenden, weiterhin funktionieren. Neuer Code sollte direkt math.random verwenden.",
childs = {
new = {
type = "function",
description = "",
args = "(...)",
returns = "()",
},
},
},
ratioGetX = {
type = "function",
description = "Hypseus-Erweiterung. Gibt die als --xratio angegebene Zahl zurück oder 0, wenn die Option nicht verwendet wurde. Für Hypseus geschriebene Lightgun-Spiele lesen sie und strecken damit ihre eigenen Lightgun-Koordinaten, für einen Automaten, dessen Bildschirm nicht die Form hat, in der das Video gemastert wurde -- 1.33 bildet ein 16:9-Panel auf 4:3-Material ab. Singe wendet sie auf nichts an; die Rechnung macht das Spiel, genau wie in Hypseus, und deshalb behandelt jedes Spiel, das sie liest, 0 und alles unter 1 als 1.\nRückgabe: Zahl.\nSeit: 3.00 (Hypseus)",
args = "()",
returns = "(number)",
},
ratioGetY = {
type = "function",
description = "Hypseus-Erweiterung. Die senkrechte Hälfte des Paares: die als --yratio angegebene Zahl oder 0, wenn die Option nicht verwendet wurde. Siehe ratioGetX.\nRückgabe: Zahl.\nSeit: 3.00 (Hypseus)",
args = "()",
returns = "(number)",
},
rewriteStatus = {
type = "function",
description = "Stub, der false zurückgibt. In Hypseus meldet er, ob Asset-Pfade für eine Installation mit -espath umgeschrieben werden; das virtuelle Dateisystem von Singe findet die Dateien eines Spiels dort, wo sie installiert wurden, es wird also nichts umgeschrieben, und das Spiel behält seinen eigenen Asset-Ordner.",
args = "()",
returns = "()",
anchor = "_hypseus_compatibility",
},
saveClear = {
type = "function",
description = "Vergisst alles und schreibt den leeren Spielstand hinaus. Für das „Highscores zurücksetzen“ eines Service-Menüs.\nRückgabe: nichts.\nSeit: 3.00.",
args = "()",
returns = "()",
},
saveDelete = {
type = "function",
description = "Entfernt einen Schlüssel. Einen Schlüssel zu löschen, den es nie gab, ist kein Fehler.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(key)",
returns = "()",
},
saveFlush = {
type = "function",
description = "Schreibt den Spielstand jetzt statt am Ende des Frames. Nutze es nach etwas, das du auf keinen Fall verlieren willst -- einem neuen Highscore auf einem Automaten, der an der Steckdose ausgeschaltet wird.\nRückgabe: nichts.\nSeit: 3.00.",
args = "()",
returns = "()",
},
saveGet = {
type = "function",
description = "Was unter diesem Schlüssel gespeichert wurde. Wurde nichts gespeichert, kommt der Standardwert zurück, oder nil, wenn es keinen gibt -- so unterscheidet man den ersten Lauf von einem späteren.\nRückgabe: der gespeicherte Wert, der Standardwert oder nil.\nSeit: 3.00.",
args = "(key [, default])",
returns = "(value)",
},
saveGetAll = {
type = "function",
description = "Eine Kopie des ganzen Spielstands, zum Lesen: um ihn beim Debuggen auszugeben oder um Schlüssel durchzugehen, deren Namen das Spiel nicht im Voraus kennt. Zu ändern, was zurückkommt, ändert nichts -- eine ganze Tabelle schreibt saveSetAll.\nRückgabe: eine Tabelle; leer, wenn nichts gespeichert wurde.\nSeit: 3.00.",
args = "()",
returns = "(everything)",
},
saveSet = {
type = "function",
description = "Bewahrt einen Wert auf, bis das Spiel deinstalliert wird. Geschrieben wird am Ende des Frames, sodass zwanzig Schlüssel, in einer Schleife gesetzt, eine einzige Datei schreiben.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(key, value)",
returns = "()",
},
saveSetAll = {
type = "function",
description = "Ersetzt den ganzen Spielstand in einem Schritt durch diese Tabelle. Schlüssel, die da waren und in der übergebenen Tabelle fehlen, sind weg.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(everything: table)",
returns = "()",
},
sceneEnable = {
type = "function",
description = "Schaltet die 3D-Ebene ein oder aus. Knoten, Meshes und Materialien können gebaut werden, bevor sie an ist, und überstehen ihr Ausschalten; nur das Zeichnen hört auf. Beendet das Skript, wenn sie ohne nutzbare GPU eingeschaltet wird (siehe 3D-Szenen); ein Spiel mit einem 2D-Ersatz fragt deshalb zuerst singeCapabilities().SCENE ab. Die Anzeige wird in jedem Fall im nächsten Frame aufgefrischt.\nSeit: 3.00.",
args = "(enabled)",
returns = "()",
},
sceneGetSize = {
type = "function",
description = "Die Größe der Ebene, also die Auflösung des Overlays: der Raum, in dem sceneProject und sceneUnproject arbeiten, und die Größe, in der die Szene gerendert wird. Ändern lässt sie sich mit overlaySetResolution. Bevor die Ebene eine Größe hat, sind beide Werte 0.\nRückgabe: Zwei Ganzzahlen, die Breite und die Höhe in Overlay-Koordinaten.\nSeit: 3.00.",
args = "()",
returns = "(width, height)",
},
sceneGetStats = {
type = "function",
description = "Die Zahlen des letzten Frames von der Kamera des Fensters: die zum Zeichnen gesammelten Meshes, wie viele davon im Sichtfeld der Kamera lagen, die Zeichenaufrufe, die nach dem Instanzieren daraus wurden, und der Texturspeicher, den die Szene belegt, in Kilobyte. Zum Abstimmen: Eine Szene mit Hunderten drawn, aber einer Handvoll calls teilt ihre Meshes gut, und ein textureKB, das nicht in den Speicher eines Raspberry Pi passt, verlangt nach KTX2-Texturen. Gerenderte Ansichten zählen nicht.\nRückgabe: Vier Ganzzahlen.\nSeit: 3.00.",
args = "()",
returns = "(total, drawn, calls, textureKB)",
},
sceneMeasure = {
type = "function",
description = "sceneMeasure(on)\nms = sceneMeasure(false)\nMisst die Zeit der 3D-Szene. sceneMeasure(true) startet: Jeder Frame danach wartet, bis die GPU die Szene fertig hat, und zählt diese Zeit zusammen, sodass die Arbeit gemessen wird statt des Takts der Anzeige. sceneMeasure(false) hält an und gibt die Millisekunden zurück, die ein Frame im Schnitt brauchte, oder nil, wenn kein Frame gezeichnet wurde. Das Warten kostet Bildrate, also miss ein paar Sekunden, nicht ein ganzes Spiel.\nRückgabe: nichts beim Starten; eine Zahl oder nil beim Anhalten.\nSeit: 3.00.",
args = "(on)",
returns = "(ms)",
},
sceneProbeGui = {
type = "function",
description = "Welche GUI auf der Oberfläche unter einem Overlay-Punkt liegt und wo darauf: ein Strahl von der Kamera durch den Punkt, mit der Kamera des zuletzt gerenderten Frames, gegen die Dreiecke jedes sichtbaren Knotens, dessen Material eine GUI zeigt (materialSetGui), wobei die Texturkoordinaten des nächsten Treffers die Stelle auf der GUI angeben. Gibt das GUI-Handle und das Pixel in den eigenen Koordinaten dieser GUI zurück (0, 0 oben links, guiGetWidth, guiGetHeight unten rechts), oder nur nil, wenn der Punkt auf keiner solchen Oberfläche liegt, die Szene aus ist oder noch nichts gerendert wurde. Die Engine stellt dieselbe Frage, wenn die Maus oder eine Lightgun auf die Szene zeigt, während eine GUI, die Eingaben annimmt, auf einer Oberfläche liegt und nichts flach Gezeichnetes unter dem Zeiger ist, sodass Klicks auf einen Monitor in der Szene kein Skript brauchen; der Aufruf ist für ein Spiel, das die Antwort selbst haben will, für ein Laservisier, einen Hover-Effekt oder einen Test.\nRückgabe: Eine Ganzzahl und zwei Ganzzahlen, oder nil.\nSeit: 3.00.",
args = "(sx, sy)",
returns = "(gui, x, y)",
},
sceneProject = {
type = "function",
description = "Wo ein Weltpunkt in Overlay-Koordinaten landet, mit der Kamera des zuletzt gerenderten Frames. depth ist 0 an der nahen Clipping-Ebene und 1 an der fernen, zum Sortieren von Beschriftungen oder um sie mit der Entfernung auszublenden. inFront ist false, wenn der Punkt hinter der Kamera liegt, und x und y sind dann bedeutungslos; vor dem ersten gerenderten Frame gibt es nichts, wogegen projiziert werden kann, und jeder Wert kommt als 0 zurück, mit inFront false. Punkte vor der Kamera, aber außerhalb der Ansicht kommen mit Koordinaten jenseits der Ränder des Overlays zurück; prüf sie also vor dem Zeichnen gegen sceneGetSize. Der übliche Einsatz ist ein Namensschild oder Lebensbalken, mit fontPrint oder spriteDraw über einem 3D-Objekt gezeichnet.\nRückgabe: Zwei Zahlen, eine Zahl und ein Boolean.\nSeit: 3.00.",
args = "(wx, wy, wz)",
returns = "(x, y, depth, inFront)",
},
sceneSetAmbient = {
type = "function",
description = "Licht von überall, 0 bis 255 pro Kanal, als sRGB behandelt; der Standard ist ein mattes Grau von 26, 26, 26. Es hellt die Seiten auf, die kein Licht erreicht, damit sie nicht schwarz sind, und materialSetOcclusionMap dunkelt es in Ritzen ab. Ist ein Himmel gesetzt und sceneSetEnvironment an, ersetzt das Licht des Himmels diesen Wert.\nSeit: 3.00.",
args = "(r, g, b)",
returns = "()",
},
sceneSetAntialias = {
type = "function",
description = "Schaltet 4x-Multisampling ein oder aus; es ist standardmäßig an, wo immer die GPU es für die Formate der Ebene anbietet, und fehlt stillschweigend, wo nicht. Es auszuschalten bringt auf einem Raspberry Pi Geschwindigkeit. Die Renderziele werden sofort neu gebaut, ruf es also bei der Einrichtung auf statt in jedem Frame.\nSeit: 3.00.",
args = "(antialias)",
returns = "()",
},
sceneSetBackground = {
type = "function",
description = "Die Farbe, mit der die Ebene jeden Frame gelöscht wird, 0 bis 255 pro Kanal. a ist 255, wenn es weggelassen wird, ein deckender Hintergrund; unter 255 scheint das Video durch, und 0 (die übliche Wahl für ein Spiel mit Disc) macht den Hintergrund völlig transparent. Bis zum ersten Aufruf wird die Ebene schwarz und transparent gelöscht. Ein Himmel aus sceneSetSky wird über den Hintergrund gezeichnet, sodass das Video nicht mehr durchscheint, solange einer gesetzt ist.\nSeit: 3.00.",
args = "(r, g, b [, a])",
returns = "()",
},
sceneSetBloom = {
type = "function",
description = "Ein Leuchten um alles, was heller als threshold ist, genommen aus dem linearen Licht der Szene vor Belichtung und Tonkurve (wo 1 Weiß ist) und mit strength wieder hinzugefügt. Die Standards sind ein Schwellwert von 1 und eine Stärke von 0, also kein Bloom; 0.2 bis 0.4 ist dezent, 1 ist ein Dunst. Das Leuchten wird über eine Kette von Durchgängen in halber Größe weichgezeichnet, kostet also wenig, und nur die Kamera des Fensters bekommt es: Gerenderte Ansichten lassen es aus. Negative Werte werden auf 0 begrenzt.\nSeit: 3.00.",
args = "(threshold, strength)",
returns = "()",
},
sceneSetEnvironment = {
type = "function",
description = "Ob der mit sceneSetSky gesetzte Himmel die Szene beleuchtet: sein diffuses Licht aus allen Richtungen anstelle von sceneSetAmbient und seine Spiegelungen auf Metallen und glänzenden Oberflächen, scharf auf einem Spiegel und umso unschärfer, je höher die Rauheit. Standardmäßig an, sodass ein Himmel die Szene beleuchtet, sobald er gesetzt ist; false behält den Himmel nur als Hintergrund, und das flache Umgebungslicht kehrt zurück. Ohne Himmel hat es keine Wirkung.\nSeit: 3.00.",
args = "(lit)",
returns = "()",
},
sceneSetExposure = {
type = "function",
description = "Hellt die ganze Szene in fotografischen Blendenstufen auf oder dunkelt sie ab, -10 bis 10 (Werte außerhalb werden begrenzt): 1 verdoppelt das Licht, -1 halbiert es. Der Standard ist 0. Es wird nach dem Bloom und vor der Tonkurve angewandt, sodass eine helle Szene bei 2 zu Weiß hin gestaucht statt abgeschnitten wird und eine Höhle und ein Strand dieselben Lichter teilen können. Animiere es für eine langsame Anpassung beim Gang von drinnen ins Tageslicht.\nSeit: 3.00.",
args = "(stops)",
returns = "()",
},
sceneSetFog = {
type = "function",
description = "Entfernungsnebel: klar bis near Einheiten von der Kamera, ganz in der Nebelfarbe ab far, auf Meshes (auch unbeleuchteten) und Partikeln gleichermaßen; additive Partikel blenden aus, statt grau zu werden. Ohne Argumente oder mit einem far, das nicht größer als near ist, gibt es keinen Nebel. Der Himmel wird nicht vernebelt, wähl also eine Farbe nahe seinem Horizont oder, wenn es keinen Himmel gibt, nahe dem Hintergrund. Jede andere Anzahl von Argumenten beendet das Skript.\nSeit: 3.00.",
args = "([r, g, b, near, far])",
returns = "()",
},
sceneSetShadowCascades = {
type = "function",
description = "In wie viele Maps der Schatten eines Richtungslichts entlang der Blickrichtung aufgeteilt wird, 1 bis 4 (Werte außerhalb werden begrenzt; der Standard ist 3). Jede Kaskade deckt einen Ausschnitt des Blickfelds der Kamera bis sceneSetShadowDistance ab, der nächste Ausschnitt der kleinste, sodass Schatten nahe der Kamera scharf sind, egal wie groß das Level ist. 1 passt eine Map an die ganze Szene an, was für kleine Szenen richtig ist, und wird bei einer orthografischen Kamera immer verwendet. Jede Kaskade ist ein weiterer Schattendurchgang für jedes schattenwerfende Richtungslicht; 2 ist eine vernünftige Wahl auf einem Raspberry Pi.\nSeit: 3.00.",
args = "(count)",
returns = "()",
},
sceneSetShadowDistance = {
type = "function",
description = "Wie weit kaskadierte Schatten von der Kamera aus reichen, in Welteinheiten; der Standard ist 60, und Werte unter 1 werden auf 1 begrenzt. Dahinter wirft ein Richtungslicht keinen Schatten. Kürzere Entfernungen machen jede Kaskade schärfer, da dieselben Maps weniger Fläche abdecken; setz sie also etwa so weit, wie der Spieler einen Schatten erkennen kann. Es zählt nur bei mehr als einer Kaskade unter einer perspektivischen Kamera.\nSeit: 3.00.",
args = "(distance)",
returns = "()",
},
sceneSetShadowSize = {
type = "function",
description = "Texel pro Seite jeder Shadow Map, jeder Kaskade und jeder Würfelfläche, 256 bis 4096 (Werte außerhalb werden begrenzt; der Standard ist 1024). Größer ist schärfer und langsamer, im Speicher ebenso wie in der Zeit, denn jedes schattenwerfende Licht hat seine eigenen Maps in dieser Größe. 2048 passt zu einem Desktop, 512 zu einem Raspberry Pi. Die Maps werden im nächsten Frame neu gebaut.\nSeit: 3.00.",
args = "(size)",
returns = "()",
},
sceneSetSky = {
type = "function",
description = "sceneSetSky(file)\nsceneSetSky(nil)\nsceneSetSky()\nHüllt die Szene in ein äquirektanguläres Panorama: ein Radiance-.hdr (wie HDRI-Seiten sie ausliefern, mit vollem Umfang) oder ein PNG, JPEG oder anderes Bild, das SDL_image liest, aus sRGB decodiert. Der Name ist spielrelativ wie bei spriteLoad. Der Himmel wird hinter allem anstelle der Hintergrundfarbe gezeichnet (sodass das Video nicht mehr durchscheint) und beleuchtet die Szene, sofern nicht sceneSetEnvironment(false) gilt. Seine Mitte zeigt nach -Z und seine Oberseite nach oben. Er wird in einen Würfel mit bis zu 1024 Texeln pro Fläche umgerechnet, sodass ein Bild von 2048 mal 1024 reichlich ist und größere auf einem Raspberry Pi einen Moment zur Vorbereitung brauchen. Ohne Argument oder mit nil wird der Himmel entfernt. Beendet das Skript, wenn die Datei nicht gelesen werden kann oder 3D nicht verfügbar ist.\nSeit: 3.00.",
args = "(file)",
returns = "()",
},
sceneSetSkyIntensity = {
type = "function",
description = "Die Helligkeit des Himmels und des Lichts, das er wirft, 1 wie geladen; negative Werte werden auf 0 begrenzt. Nützlich, um einen zu hellen PNG-Himmel abzudunkeln, einen .hdr-Himmel zum Hauptlicht der Szene zu machen oder den Himmel ein- und auszublenden. Es multipliziert den Himmel selbst, anders als sceneSetExposure, das alles skaliert.\nSeit: 3.00.",
args = "(scale)",
returns = "()",
},
sceneSetTonemap = {
type = "function",
description = "Die Kurve, die das lineare Licht der Szene auf den Bildschirm abbildet, angewandt nach der Belichtung. TONEMAP_NEUTRAL (der Standard) hält die Farben getreu und staucht nur das hellste Licht; TONEMAP_ACES ist die filmische Kurve mit mehr Kontrast und einem wärmeren Auslauf; TONEMAP_NONE schneidet bei Weiß ab. Videomaterialien, unbeleuchtete Oberflächen und der Himmel durchlaufen dieselbe Kurve, sodass ein Spiel, dessen Disc genau wie gefilmt aussehen muss, TONEMAP_NONE mit einer Belichtung von 0 will. Jeder andere Wert beendet das Skript.\nSeit: 3.00.",
args = "(curve)",
returns = "()",
},
sceneUnproject = {
type = "function",
description = "Der Weltpunkt distance Einheiten entlang des Strahls durch ein Overlay-Pixel, mit der Kamera des zuletzt gerenderten Frames. Zwei Entfernungen ergeben einen Strahl zum Auswählen mit physicsRaycast; eine setzt ein Objekt dorthin, „wo der Spieler geklickt hat“. Bevor der erste Frame gezeichnet wurde, gibt es den Ursprung zurück.\nRückgabe: Drei Zahlen, der Weltpunkt.\nSeit: 3.00.",
args = "(sx, sy, distance)",
returns = "(x, y, z)",
},
scoreBegin = {
type = "function",
description = "Meldet, dass ein Durchgang beginnt. Optional, aber den Aufruf wert: siehe unten.",
args = "()",
returns = "()",
anchor = "onlinescores",
},
scoreBezelClear = {
type = "function",
description = "Hypseus-Erweiterung. Leert jedes Anzeigefeld der Punkteanzeige: Die Credits, beide Punktzahlen und beide Lebensanzeigen zeigen gar nichts mehr, nur die abgedunkelten Ziffern dahinter bleiben. Die Werte werden nicht vergessen, aber das nächste scoreBezelCredits, scoreBezelScore oder scoreBezelLives lässt die Anzeige wieder mit dem leuchten, was sie dann enthält. Kann bei ausgeschalteter Anzeige gefahrlos aufgerufen werden.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "()",
},
scoreBezelCredits = {
type = "function",
description = "Hypseus-Erweiterung. Setzt das Anzeigefeld für die Credits, das zwei Stellen hat. Lässt außerdem eine Anzeige wieder leuchten, die scoreBezelClear geleert hat.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(credits: integer)",
returns = "()",
},
scoreBezelEnable = {
type = "function",
description = "Hypseus-Erweiterung. Blendet die Punkteanzeige ein oder aus. Das erste true baut sie aus der eigenen scoreBezel.rml des Spiels neben seinem Skript, wenn es eine gibt, und sonst aus Singe/scoreBezel.rml; sie danach aus- und wieder einzublenden kostet nichts und behält ihre Werte. Sie startet ausgeblendet, so wie auch Hypseus ausgeliefert wird, sodass sich ein Spiel, das dies nie aufruft, genau wie zuvor verhält -- und es sollte scoreBezelGetState fragen, bevor es annimmt, dass es eine hat.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled [, type: integer])",
returns = "()",
},
scoreBezelGetState = {
type = "function",
description = "Hypseus-Erweiterung. Ob die Punkteanzeige zu sehen ist. Jedes Hypseus-Spiel fragt dies, bevor es die Anzeige benutzt, und zeichnet seine eigene Punktetafel mit Sprites, wenn die Antwort false ist, was der richtige Ausweg und kein Fehler ist.\nRückgabe: Boolean.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "(boolean)",
},
scoreBezelLives = {
type = "function",
description = "Hypseus-Erweiterung. Setzt das Anzeigefeld für die Leben eines Spielers, das eine Stelle hat. player ist 1 oder 2; jede andere Zahl wird ignoriert, ebenso 2, bis scoreBezelTwinScoreOn(true) die Anzeigefelder des zweiten Spielers auf die Anzeige gebracht hat. Lässt außerdem eine Anzeige wieder leuchten, die scoreBezelClear geleert hat.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(player, lives: integer)",
returns = "()",
},
scoreBezelScore = {
type = "function",
description = "Hypseus-Erweiterung. Setzt das Anzeigefeld für die Punktzahl eines Spielers, das sechs Stellen hat. player ist 1 oder 2, mit derselben Regel für 2 wie bei scoreBezelLives. Lässt außerdem eine Anzeige wieder leuchten, die scoreBezelClear geleert hat.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(player, score: integer)",
returns = "()",
},
scoreBezelTwinScoreOn = {
type = "function",
description = "Hypseus-Erweiterung. Bringt die Anzeigefelder für Punktzahl und Leben des zweiten Spielers auf die Anzeige oder nimmt sie wieder herunter und überlässt den Platz den anderen beiden. Sie abzuschalten leert auch die Anzeige, genau wie in Hypseus, also lass einen Wert folgen, wenn die Anzeigefelder des ersten Spielers leuchten sollen. Solange sie aus sind, tun scoreBezelScore(2, ...) und scoreBezelLives(2, ...) nichts. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled)",
returns = "()",
},
scoreBoard = {
type = "function",
description = "Holt die Bestenliste. onDone(ok, result) mit result.top (eine Liste von {name, value}), result.standing (value und rank dieses Spielers und die Anzahl der players) und result.order, \"highest\" oder \"lowest\", je nachdem, wie die Bestenliste ordnet. Ein Automat, der nicht angemeldet ist, kann sie auch holen: siehe unten.",
args = "(onDone [, board])",
returns = "()",
anchor = "onlinescores",
},
scoreGameId = {
type = "function",
description = "Die GAME_ID des Spiels aus seinem Eintrag in games.dat, oder nil, wenn es keine hat. Ein Spiel ohne sie lässt sich spielen, aber nicht in eine Rangliste eintragen.",
args = "()",
returns = "()",
anchor = "onlinescores",
},
scoreLowestWins = {
type = "function",
description = "Legt fest, dass eine Bestenliste die niedrigste Punktzahl zuerst einordnet. Ruf es vor der ersten Punktzahl der Bestenliste auf.",
args = "([board])",
returns = "()",
anchor = "onlinescores",
},
scorePlayerName = {
type = "function",
description = "Der Name, unter dem dieser Automat meldet, oder nil, wenn noch keiner gewählt wurde.",
args = "()",
returns = "()",
anchor = "onlinescores",
},
scoreSignedIn = {
type = "function",
description = "Ob dieser Automat bei einem Online-Konto angemeldet ist.",
args = "()",
returns = "()",
anchor = "onlinescores",
},
scoreSubmit = {
type = "function",
description = "Reiht eine Punktzahl in die Warteschlange ein. Gibt false zurück, wenn der Automat nicht angemeldet ist oder das Spiel keine GAME_ID hat.",
args = "(value [, board [, meta]])",
returns = "()",
anchor = "onlinescores",
},
scoreUpdate = {
type = "function",
description = "Einmal pro Frame, aus onOverlayUpdate. Ohne es geht nichts voran.",
args = "()",
returns = "()",
anchor = "onlinescores",
},
scoreWaiting = {
type = "function",
description = "Wie viele Punktzahlen in der Warteschlange stehen und noch nicht gesendet sind.",
args = "()",
returns = "()",
anchor = "onlinescores",
},
scriptExecute = {
type = "function",
description = "Ersetzt das laufende Skript durch das, welches die Tabelle beschreibt. Das aktuelle Skript hält am Ende dieses Frames an, und onShutdown läuft; die Kontrolle kehrt nie zu ihm zurück, und wenn das neue Skript endet, geht die Engine zu dem über, was sonst noch in der Warteschlange steht, oder beendet sich. Die String-Schlüssel, die die Engine kennt, sind SCRIPT, CONTAINER, VIDEO, STRETCH, NO_MOUSE, RESOLUTION_X, RESOLUTION_Y, SINDEN_GUN, AUDIO_TRACK, AUDIO_DELAY, LEGACY_SPRITE_ARGS, CANVAS_X und CANVAS_Y; andere Schlüssel werden ignoriert, und Schlüssel, die keine Strings sind, werden übersprungen. Ein SCRIPT, CONTAINER oder VIDEO, das kein String ist, bricht das Skript ab, und ebenso ein Argument, das keine Tabelle ist.\nSeit: 2.00",
args = "(config)",
returns = "()",
},
scriptPush = {
type = "function",
description = "Startet das Skript, das die Tabelle beschreibt, und stellt die aktuelle Konfiguration dahinter in die Warteschlange, sodass das aktuelle Skript, wenn das neue endet, wieder von vorn läuft. Nichts bleibt erhalten: onShutdown des aktuellen Skripts läuft jetzt, sein Lua-Zustand wird verworfen, und der spätere Lauf ist ein Neustart, weshalb Menu.singe seine Auswahl vor dem Push in eine Datei speichert. Die Tabelle nimmt dieselben Schlüssel wie scriptExecute.\nSeit: 2.00",
args = "(config)",
returns = "()",
},
setOverlayFullAlpha = {
type = "function",
description = "Hypseus-Erweiterung, angenommen und ignoriert. Hypseus blittet sein Overlay mit einem Schwellenwert von 128 auf dem Alphakanal, sodass ein halb transparentes Pixel entweder voll deckend oder verschwunden ist, und dies bittet es, die Fläche stattdessen so hochzuladen, wie sie ist, und richtig zu blenden. Das Overlay von Singe war schon immer volles RGBA mit echtem Alpha pro Pixel, was dies verlangt, gilt also bereits.\nRückgabe: nichts.\nSeit: 3.00",
args = "()",
returns = "()",
},
setOverlayLinearScale = {
type = "function",
description = "Hypseus-Erweiterung. Wählt, wie das Overlay auf dem Weg ins Fenster gefiltert wird. Mit true, dem Standard und dem, was ein Neuladen wiederherstellt, wird es linear abgetastet, sodass ein Overlay mit niedriger Auflösung weich wird statt klotzig; mit false wird das nächste Pixel genommen, was Pixel-Art, ein Pixel breite Umrisse und kleinen Text scharf hält. Linear ist der Standard, weil jede Version von Singe das Overlay so gezeichnet hat; Hypseus nimmt standardmäßig stattdessen das nächste Pixel, ein von Hypseus übernommenes Spiel, das dies nie aufruft, sieht also etwas weicher aus, bis es das tut. Am Zeichnen ändert sich nichts, nur die abschließende Skalierung von der Overlay-Auflösung auf das Fenster, sodass alles auf dem Overlay -- die Grundformen, Schriften, Sprites und die 3D-Ebene -- gemeinsam durch den einen Filter geht und das Disc-Bild dahinter unberührt bleibt. Die Einstellung übersteht overlaySetResolution, das das Overlay ersetzt. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled)",
returns = "()",
},
setOverlayOnTop = {
type = "function",
description = "Hypseus-Erweiterung. Wählt, ob das Overlay und die über das Bild gezeichneten GUIs über dem Bezel-Artwork liegen oder darunter. Nur Artwork, das vor dem Bild gezeichnet wird (--bezelflip), liegt überhaupt je über ihnen, bei Artwork dahinter -- dem Standard -- ändert dies also nichts. false ist die Einstellung, mit der ein Spiel beginnt, und der eigene Standard von Hypseus. Sie bleibt gespeichert, bis das Skript neu lädt.\nRückgabe: Boolean, ob Artwork geladen ist, und seine Kennung als String (\"0\", wenn keines geladen ist).\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled: boolean)",
returns = "(loaded, id)",
},
setOverlayOpacity = {
type = "function",
description = "Hypseus-Erweiterung. Wie deckend das ganze Overlay ist, von 0 (unsichtbar) bis 255 (so, wie das Spiel es gezeichnet hat). Es multipliziert das Alpha, das die eigenen Pixel des Overlays schon tragen, sodass ein halb transparentes Sprite halb so deckend bleibt wie der Rest; es ändert den Inhalt des Overlays nicht, und nichts muss neu gezeichnet werden.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(alpha: number)",
returns = "()",
},
setOverlayResolution = {
type = "function",
description = "Ein Alias von overlaySetResolution. Hypseus registriert eine Funktion unter beiden Namen.",
args = "(width, height)",
returns = "()",
anchor = "_hypseus_compatibility",
},
setOverlaySize = {
type = "function",
description = "overlaySetResolution mit einer gewählten Größe: 1 ist die Videogröße der Disc, 3 ist 360x240, 4 ist die angegebene Größe (ignoriert, wenn sie fehlt, wie in Hypseus), und alles andere, 2 eingeschlossen, ist die halbe Disc auf beiden Achsen. Ohne Disc melden discGetWidth und discGetHeight die Zeichenfläche, und in diese zeichnet ein Spiel ohne Disc.",
args = "(preset [, width, height])",
returns = "()",
anchor = "_hypseus_compatibility",
},
singeCapabilities = {
type = "function",
description = "Was dieser Rechner ausführen kann. Die Tabelle hat einen Eintrag pro Fähigkeitsname, den eine REQUIRES-Liste in games.dat verwenden kann (SCENE, GUI, SHADOWS, POST, SKIN, MORPH), jeder true oder false, sowie tier: die gemessene Leistungsklasse des Rechners von 0 (kein 3D) bis 3 (eine Desktop-GPU), oder nil, bevor das Menü sie gemessen hat. Ein Spiel fragt, damit es auf etwas verzichten kann, statt deswegen abgewiesen zu werden.\nRückgabe: eine Tabelle.\nSeit: 3.00.",
args = "()",
returns = "(capabilities)",
},
singeDisablePauseKey = {
type = "function",
description = "Übergibt die Pausentaste an das Skript, genau wie singeSetPauseKeyEnabled(false). Es ist eine in Framework.singe definierte Funktion, die erhalten bleibt, damit ältere Spiele unverändert laufen.\nSeit: 1.18 (RDG)",
args = "()",
returns = "()",
},
singeEnablePauseKey = {
type = "function",
description = "Gibt die Pausentaste an die Engine zurück, genau wie singeSetPauseKeyEnabled(true). Es ist eine in Framework.singe definierte Funktion, die erhalten bleibt, damit ältere Spiele unverändert laufen.\nSeit: 1.18 (RDG)",
args = "()",
returns = "()",
},
singeGetAudioCalibration = {
type = "function",
description = "Gibt die geltende Audioverzögerung des Rechners in Millisekunden zurück: den Wert, den der Kalibrierbildschirm des Menüs in machine.cfg im obersten Datenordner gespeichert hat, oder einen seitdem mit singeSetAudioCalibration gesetzten. Null, wenn der Rechner nie kalibriert wurde. Sie gilt für jedes Spiel auf dem Rechner, zusätzlich zur Verzögerung pro Spiel aus singeGetAudioDelay.\nRückgabe: ganzzahlige Millisekunden.\nSeit: 3.00",
args = "()",
returns = "(integer)",
},
singeGetAudioDelay = {
type = "function",
description = "Gibt die geltende Audioverzögerung des Spiels in Millisekunden zurück, ob sie aus --audiodelay, aus dem Schlüssel AUDIO_DELAY im games.dat-Eintrag des Spiels oder von singeSetAudioDelay kommt. Null, wenn keine gesetzt wurde. Sie wird zur Kalibrierung des Rechners und zur gemessenen Gerätelatenz addiert, wenn die Engine entscheidet, wann jeder Videoframe gezeigt wird.\nRückgabe: ganzzahlige Millisekunden.\nSeit: 3.00",
args = "()",
returns = "(integer)",
},
singeGetAudioLatency = {
type = "function",
description = "Gibt die Warteschlange des Audiogeräts zurück, die die Engine beim Öffnen des Mixers gemessen hat, in Millisekunden: die Zeit zwischen der Übergabe von Samples an den Mixer und ihrem Eintreffen am Gerät, vor jeder Kalibrierung oder Verzögerung pro Spiel. Die Engine gleicht sie bereits aus; ein Kalibrierbildschirm braucht sie, um sein Klicken und seinen Blitz zu planen, und in einer Diagnoseansicht lohnt es sich, sie auszugeben.\nRückgabe: ganzzahlige Millisekunden.\nSeit: 3.00",
args = "()",
returns = "(integer)",
},
singeGetDataPath = {
type = "function",
description = "Gibt den Ordner zurück, in den Singe für dieses Spiel schreibt, mit einem abschließenden Pfadtrenner, sodass ein Dateiname direkt angehängt werden kann. Es ist ein nach dem Spiel benannter Unterordner der Basis von --datadir (bei einem gepackten Spiel der Name der Datenbank und dann der Ordner des Skripts darin); ohne --datadir ist die Basis data im Spieleverzeichnis. Screenshots, Videoindizes und trace.txt landen dort, und dorthin gehören auch Spielstände, Highscores und Einstellungen; Singe 2.x schrieb sie neben das Spiel, das schreibgeschützt sein kann.\nRückgabe: String-Pfad, der auf einen Trenner endet.\nSeit: 2.00",
args = "()",
returns = "(string)",
},
singeGetGameId = {
type = "function",
description = "Die GAME_ID aus dem games.dat-Eintrag dieses Spiels, oder nil, wenn er keine hat. Es ist die ID, unter der der Online-Dienst das Spiel kennt, und der Schlüssel, unter dem eine Bestenliste geführt wird.\nRückgabe: String oder nil.\nSeit: 3.00.",
args = "()",
returns = "(string)",
},
singeGetHeight = {
type = "function",
description = "Gibt die Höhe des Singe-Fensters in Bildschirmpixeln zurück, nicht in Overlay-Einheiten, so wie das Fenster im Moment des Aufrufs ist. Zum Zeichnen nimm overlayGetHeight; dies ist für einen Einstellungsbildschirm, der die Anzeige meldet, oder um zu entscheiden, wie viel Detail sich eine Szene leisten kann.\nRückgabe: ganzzahlige Pixel.\nSeit: 1.x",
args = "()",
returns = "(integer)",
},
singeGetPauseFlag = {
type = "function",
description = "Gibt das Pausenflag der Engine zurück: true, solange das Spiel durch die Pausentaste oder durch singeSetPauseFlag pausiert ist. Das ist unabhängig davon, ob die Disc auf einem angehaltenen Frame steht (discGetState); lies es, um zu wissen, ob eine Pause absichtlich angefordert wurde. Solange die Pausentaste das Spiel eingefroren hält, läuft kein Callback, sodass das Flag aus einem Callback heraus nur nach dem eigenen singeSetPauseFlag(true) des Skripts als true zu sehen ist.\nRückgabe: Boolean.\nSeit: 1.x (RDG)",
args = "()",
returns = "(boolean)",
},
singeGetScriptPath = {
type = "function",
description = "Gibt den Pfad der laufenden Skriptdatei zurück, so wie die Engine ihn aufgelöst hat. Framework.singe leitet aus diesem Wert die globale Variable DIR ab, den Ordner des Skripts mit abschließendem Trenner, und mit DIR bauen die meisten Spiele die Pfade zu ihren Assets.\nRückgabe: String-Pfad.\nSeit: 1.15 (RDG)",
args = "()",
returns = "(string)",
},
singeGetSystemInfo = {
type = "function",
description = "Alles, was der Kopf des Trace über diesen Rechner und diesen Lauf weiß, in einer Tabelle. Sie ist für einen Service-Bildschirm und für Fehlerberichte gedacht: die Antwort auf „worauf lief es“, ohne den Spieler zu bitten, ein Log zu suchen.\nRückgabe: eine Tabelle mit diesen Feldern, alle Strings außer den vier Größen:\nSeit: 3.00.",
args = "()",
returns = "(info)",
},
singeGetTicks = {
type = "function",
description = "Gibt die Zeit der Uhr in Millisekunden seit dem Start der Engine zurück. Es ist die Uhr für Timer, Entprellung und Animation, und sie läuft weiter, während das Spiel durch die Pausentaste eingefroren ist; ein Timer, der pausierte Zeit nicht mitzählen darf, sollte also singeGetPauseFlag lesen oder ab dem Moment des Auftauens messen. Luas os.clock() misst normalerweise Prozessorzeit, die stillsteht, während die Engine untätig ist; Singe ersetzt sie durch echte Sekunden seit dem Start der Engine, sodass bestehende Spiele, die sie als Uhr benutzt haben, weiter funktionieren.\nRückgabe: ganzzahlige Millisekunden.\nSeit: 3.00",
args = "()",
returns = "(integer)",
},
singeGetWidth = {
type = "function",
description = "Gibt die Breite des Singe-Fensters in Bildschirmpixeln zurück, das Gegenstück zu singeGetHeight. Zum Zeichnen auf das Overlay dient stattdessen overlayGetWidth.\nRückgabe: ganzzahlige Pixel.\nSeit: 1.x",
args = "()",
returns = "(integer)",
},
singeHasGpu = {
type = "function",
description = "Ob das GPU-Gerät gestartet ist. Alles, was darüber gezeichnet wird, ist ohne eines nicht verfügbar: die 3D-Szene, 3D-Partikel und jedes GUI-Dokument. 2D-Partikel werden mit dem Overlay gezeichnet und brauchen kein Gerät. Frag dies ab, bevor du etwas davon anforderst, denn guiNew und die Szenenaufrufe beenden das Skript, statt false zu antworten -- es gibt keine Möglichkeit, es zu versuchen und sich davon zu erholen.\nRückgabe: Boolean; wahr, wenn ein GPU-Gerät vorhanden ist.\nSeit: 3.00.",
args = "()",
returns = "(boolean)",
},
singeIsRecording = {
type = "function",
description = "Ob eine Aufnahme läuft oder angefordert wurde und mit dem nächsten gezeichneten Frame beginnt. Siehe singeRecordStart.\nRückgabe: Boolean.\nSeit: 3.00",
args = "()",
returns = "(boolean)",
},
singeMain = {
type = "function",
description = "Der Einstiegspunkt des Thread-Modells. Definiert ein Skript sie, verpackt Framework.singe sie in eine Koroutine und installiert ein onOverlayUpdate, das die Koroutine einmal pro Frame fortsetzt, sodass die Funktion als gerade Linie aus Spiellogik läuft, die singeYield() (ein Alias von coroutine.yield) aufruft, wo immer sie einen Frame vergehen lassen will. Alles, was vor einem Yield gezeichnet wird, landet im Overlay dieses Frames. Die Rückkehr aus singeMain ruft singeQuit auf; ein Fehler darin beendet das Spiel mit einem Traceback. Die Callbacks für Eingabe, Sound, Physik und Navigation werden zwischen den Fortsetzungen weiterhin ausgelöst, ein Spiel im Thread-Modell kann sie also mit Abfragen mischen.",
args = "()",
returns = "()",
},
singePack = {
type = "function",
description = "Packt das Spiel in directory in die Einzeldatei-Datenbank database, genau wie singe --pack es von der Befehlszeile tut, und gibt true zurück, wenn es gelungen ist. Der Ordner muss der eigene Ordner eines Spiels sein: einer, der keinen Support-Ordner Singe/, keinen Launcher und nichts anderes enthält, was der Packer ablehnt, und die Gründe für eine Ablehnung werden wie bei der Befehlszeile auf der Konsole ausgegeben. So kann ein Autorenwerkzeug ein Spiel veröffentlichen, ohne die Engine zu verlassen.\nRückgabe: true bei Erfolg, sonst false.\nSeit: 3.00",
args = "(directory, database)",
returns = "(result)",
},
singeQuit = {
type = "function",
description = "Beendet das laufende Skript am Ende dieses Frames: Die Spielschleife hält an, onShutdown läuft, und die Engine geht zum nächsten wartenden Skript über oder beendet sich, wenn es keines gibt. Ein aus dem Menü mit scriptPush gestartetes Spiel kehrt deshalb zum Menü zurück, das von vorn beginnt. Im Thread-Modell erledigt das die Rückkehr aus singeMain für dich. Der Schalter, der in controls.cfg auf INPUT_QUIT gelegt ist, und das Schließen des Fensters beenden das Skript auf dieselbe Weise. Ruf es nicht aus onShutdown auf, das schon der Weg nach draußen ist.\nSeit: 1.x (RDG)",
args = "()",
returns = "()",
},
singeRecordStart = {
type = "function",
description = "Beginnt ab dem nächsten gezeichneten Frame, das Spiel aufzunehmen, Bild und Ton zusammen, als MP4 im Datenordner des Spiels (siehe singeGetDataPath). Ohne Namen heißen die Dateien singe000.mp4 aufwärts, wie bei Screenshots; mit einem Namen geht die Aufnahme in diese Datei, wobei .mp4 angehängt wird, wenn der Name keine Endung hat, und eine Datei dieses Namens ersetzt wird, und ein Name, der einen Ordner enthält, bricht das Skript ab. Ein Aufruf während einer laufenden Aufnahme wird ignoriert. Der Schalter, der in controls.cfg auf INPUT_RECORD gelegt ist, standardmäßig F10, startet und stoppt dieselben Aufnahmen.\nRückgabe: nichts.\nSeit: 3.00",
args = "([name])",
returns = "()",
},
singeRecordStop = {
type = "function",
description = "Schließt die Aufnahme beim nächsten gezeichneten Frame ab: Was noch wartet, wird codiert und die Datei geschlossen, sodass sie von Anfang bis Ende abspielbar ist. Wird ignoriert, wenn nichts aufgenommen wird. Eine Aufnahme, die beim Ende des Spiels noch läuft, wird auf dieselbe Weise abgeschlossen.\nRückgabe: nichts.\nSeit: 3.00",
args = "()",
returns = "()",
},
singeRelaunch = {
type = "function",
description = "Beendet die Engine wie singeQuit und startet, sobald alles abgebaut ist, die ausführbare Datei unter path an ihrer Stelle mit denselben Argumenten. So bringt das Tool Engine Update des Menüs einen Automaten auf ein neueres Singe, das es neben das laufende gelegt hat: Die neue Datei wird ausführbar gemacht und gestartet, und unter Windows, das ein laufendes Image nicht ersetzt, wird sie neben diesem unter ihrem eigenen Namen gestartet. Die Datei muss bereits existieren; andernfalls antwortet der Aufruf false, ohne etwas zu tun. Hier wird nichts entpackt oder kopiert: Das neue Singe entpackt seine eigenen Support-Dateien beim ersten Lauf.\nRückgabe: true, wenn der Neustart eingerichtet ist, false, wenn die Datei nicht da ist.\nSeit: 3.00",
args = "(path)",
returns = "(result)",
},
singeReload = {
type = "function",
description = "Führt das Spiel am Ende dieses Frames erneut von seinem Skript aus, wie es F5 und eine geänderte Datei unter --reload tun; dieser Aufruf funktioniert auch ohne die Option. Jeder Sound hört auf, der Lua-Zustand wird verworfen, ohne onShutdown aufzurufen, alles, was das Skript geladen hat, wird freigegeben, Szene, Physik (einschließlich ihrer Debug-Zeichnung), Partikel und Navigation werden zurückgesetzt, das Overlay kehrt zu seiner Standardauflösung zurück, und Lautstärke der Soundeffekte, Mausmodus, Mausfang, Tastaturmodus, Pausentaste, Zuhörer und Pausenflag kehren zu ihren Standards zurück. Tasten und Knöpfe, die über das Neuladen hinweg gehalten werden, werden bis zum Loslassen ignoriert, wie bei einem frischen Start, und die Disc wird angehalten auf ihrem ersten Frame geparkt, mit der Standard-Tonspur ausgewählt, wie beim Start. Die Engine selbst (das Fenster, die Controller, die Mäuse) bleibt, wie sie ist. Es passt zum Neustart-Eintrag eines Debug-Menüs oder zu einem Level-Editor, der neu lädt, was er gerade gespeichert hat.\nSeit: 3.00.",
args = "()",
returns = "()",
},
singeSaveGeometry = {
type = "function",
description = "Bewahrt die aktuelle Skalierung, Verschiebung und Drehung des Bildes für diesen Rechner auf. Sie kommen in machine.cfg im obersten Datenordner, neben die Audioverzögerung, und die Engine wendet sie auf jedes Spiel an, das sie danach startet, aus dem Menü oder von der Befehlszeile, und über singeReload hinweg. Eine tatsächlich auf der Befehlszeile eingetippte Option gewinnt: --scalefactor übersteuert die gespeicherte Skalierung, --shiftx oder --shifty die gespeicherte Verschiebung, --rotate die gespeicherte Drehung. Die Datei wird ganz geschrieben, sodass die Audioverzögerung erhalten bleibt, wie sie ist.\nRückgabe: nichts.\nSeit: 3.00.",
args = "()",
returns = "()",
},
singeSaveTier = {
type = "function",
description = "Bewahrt die Leistungsklasse dieses Rechners, 0 bis 3, in machine.cfg neben der Audioverzögerung und der Geometrie auf, wo singeCapabilities sie meldet und das Menü sie mit dem TIER jedes Spiels vergleicht. Das mitgelieferte Menü misst die Leistungsklasse selbst, daran, wie lange sein 3D-Hintergrund zum Zeichnen braucht (sceneMeasure), und speichert sie nur, wenn sie sich ändert; niemand fragt den Spieler.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(tier)",
returns = "()",
},
singeScreenshot = {
type = "function",
description = "Fordert einen Screenshot des ganzen Fensters an, Letterbox eingeschlossen, aufgenommen nach dem Zeichnen des nächsten Frames und als PNG im Datenordner des Spiels gespeichert (siehe singeGetDataPath). Ohne Namen heißen die Dateien singe000.png aufwärts; jeder Skriptlauf sucht ab null nach dem ersten freien Namen, und spätere Aufnahmen machen nach der zuletzt gespeicherten weiter. Mit einem Namen geht die Aufnahme in diese Datei, wobei .png angehängt wird, wenn der Name keine Endung hat, und eine Datei dieses Namens ersetzt wird; ein Name, der einen Ordner enthält, bricht das Skript ab. Den Screenshot zu benennen ist für Skripte gedacht, die absichtlich Bilder erzeugen, etwa die, die die Anleitungen eines Buches bebildern, damit ein erneuter Lauf das Bild ersetzt, statt eines hinzuzufügen. Der Aufruf erzwingt ein Neuzeichnen, sodass die Aufnahme auch gemacht wird, während die Anzeige ruht. Der Schalter, der in controls.cfg auf INPUT_SCREENSHOT gelegt ist, tut dasselbe.\nSeit: 1.x",
args = "([name])",
returns = "()",
},
singeSetAudioCalibration = {
type = "function",
description = "Setzt die Audioverzögerung des Rechners, wendet sie sofort an und schreibt sie in machine.cfg im obersten Datenordner, sodass jedes Spiel auf dem Rechner sie übernimmt. Der Kalibrierbildschirm des Menüs ruft es auf; ein Spiel mit eigenem Service-Menü darf das auch. Der Wert ist positiv, wenn der Ton später zu hören ist, als das Gerät meldet; die Engine verzögert die Videoanzeige um so viel. Werte außerhalb von -1000 bis 1000 brechen das Skript ab. Kann machine.cfg nicht geschrieben werden, gilt der Wert für diesen Lauf trotzdem, und eine Meldung geht an die Konsole.\nSeit: 3.00",
args = "(milliseconds: integer)",
returns = "()",
},
singeSetAudioDelay = {
type = "function",
description = "Setzt die Audioverzögerung des Spiels für diesen Lauf: wie viel später (positiv) oder früher (negativ) der Ton zu hören ist, als die Engine messen kann, sodass sich die Videoanzeige passend verschiebt. Sie gilt für die Disc und für jedes Video, das das Skript abspielt, zusätzlich zur Kalibrierung des Rechners. Nichts wird gespeichert; ein Spiel, das die Einstellung in einem Service-Menü anbietet, speichert den Wert mit seinen anderen Einstellungen und ruft dies beim Start erneut auf. Werte außerhalb von -1000 bis 1000 brechen das Skript ab.\nSeit: 3.00",
args = "(milliseconds: integer)",
returns = "()",
},
singeSetGameName = {
type = "function",
description = "Setzt den Titel des Singe-Fensters. Ruf es einmal beim Start mit dem Anzeigenamen des Spiels auf; nichts anderes verwendet den Wert. Das Argument muss ein String oder eine Zahl sein.\nSeit: 1.15 (RDG)",
args = "(title)",
returns = "()",
},
singeSetPauseFlag = {
type = "function",
description = "Setzt das Pausenflag der Engine aus dem Skript. true hält die Disc an, falls sie läuft, sowie jedes geladene Video und jeden Soundeffekt-Kanal und merkt sich, welche liefen; false setzt genau diese fort. Anders als die Pausentaste friert dies das Skript nicht ein: Callbacks werden weiter ausgelöst, sodass das Skript sein Pausenmenü zeichnen und entscheiden kann, wann es das Flag löscht. Spiele, die ihre eigene Pause verwalten, sollten außerdem mit singeSetPauseKeyEnabled(false) die Pausentaste übernehmen, denn die Taste der Engine schaltet dasselbe Flag um und würde sonst gegen das Skript arbeiten. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 1.x (RDG)",
args = "(paused)",
returns = "()",
},
singeSetPauseKeyEnabled = {
type = "function",
description = "Legt fest, wem die Pausentaste gehört, die in controls.cfg auf INPUT_PAUSE gelegt ist. Solange sie aktiviert ist (der Standard, bei jedem Neuladen wiederhergestellt), gehört sie der Engine: Ein Druck auf die Taste friert das Spiel vollständig ein (siehe Pausieren), und in MODE_NORMAL erhält das Skript nie SWITCH_PAUSE. Solange sie deaktiviert ist, ignoriert die Engine die Taste, und SWITCH_PAUSE erreicht onInputPressed und onInputReleased wie jeder andere Schalter, sodass das Spiel mit singeSetPauseFlag seine eigene Pause betreiben kann. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 3.00",
args = "(enabled)",
returns = "()",
},
singeSetQuitKeyEnabled = {
type = "function",
description = "Hypseus-Erweiterung. Legt fest, ob sich die Engine beim Schalter beendet, der in controls.cfg auf INPUT_QUIT gelegt ist, ob von der Tastatur oder einem Controller. Ist es aktiviert (der Standard, bei jedem Neuladen wiederhergestellt), beendet ein Druck darauf das Spiel. Ist es deaktiviert, ignoriert die Engine den Schalter, sodass ein Spiel erst nachfragen oder speichern kann; das Skript erhält SWITCH_QUIT in jedem Fall über onInputPressed und onInputReleased, und singeQuit beendet das Spiel weiterhin. Der Schließen-Knopf des Fensters beendet immer. Framework.singe definiert keyboardCatchQuit(catch), den Namen von Hypseus Singe für dieselbe Einstellung mit umgekehrtem Sinn. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled)",
returns = "()",
},
singeVersion = {
type = "function",
description = "Gibt die Version der Engine als Zahl zurück, Hauptversion plus Nebenversion als Bruchteil, sodass 3.00 als 3 zurückkommt. Vergleich sie mit < und >=, um eine zu alte Engine abzulehnen oder um Funktionen herum zu verzweigen; SINGE_VERSION_MAJOR, SINGE_VERSION_MINOR und SINGE_VERSION_STRING werden außerdem als globale Variablen gesetzt, für Skripte, die die Teile oder den Text wollen.\nRückgabe: Zahl.\nSeit: 1.x (RDG)",
args = "()",
returns = "(number)",
},
singeWantsCrosshairs = {
type = "function",
description = "Gibt true zurück, sofern Singe nicht mit --nocrosshair gestartet wurde. Zeichne das Software-Fadenkreuz nur, wenn es true zurückgibt; Spieler mit Lightguns, die ihr eigenes Fadenkreuz auf den Bildschirm bringen, schalten das der Software mit dieser Option ab. Der Wert ändert sich während eines Laufs nicht, lies ihn also einmal.\nRückgabe: Boolean.\nSeit: 2.00",
args = "()",
returns = "(boolean)",
},
softDelete = {
type = "function",
description = "Beendet die Simulation und gibt ihren Körper frei. Der Knoten behält sein Mesh in der Form, in der es zuletzt geschrieben wurde, sodass ein fallengelassenes Tuch über der Kiste drapiert bleibt und ein Seil seine Röhre behält; die ursprüngliche Form des Meshs wird nicht wiederhergestellt. Ein Knoten ohne Soft Body beendet das Skript.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
softNew = {
type = "function",
description = "softNew(node, SOFT_CLOTH)\nsoftNew(node, SOFT_BODY)\nsoftNew(node, SOFT_ROPE, x, y, z, segments, radius)\nBei SOFT_CLOTH und SOFT_BODY wird das Mesh des Knotens, mit drei oder mehr Vertices, zu den Partikeln: Vertices an derselben Position (innerhalb von 0.0001 Einheiten) werden zu einem verschweißt, dort platziert, wo die Transformation des Knotens sie in der Welt hinsetzt, und die Dreiecke ergeben die Dehnungs-, Scher- und Biege-Constraints. Stoff kollidiert auf beiden Seiten und ist das, was ein offenes Tuch braucht; ein Körper ist ein geschlossenes Mesh, das softSetPressure aufblasen kann. Bei SOFT_ROPE braucht der Knoten kein Mesh: segments + 1 Partikel laufen in einer Linie von der Weltposition des Knotens bis zum Weltpunkt, der Knoten bekommt ein neues sechsseitiges Röhren-Mesh mit diesem Radius um sie herum (und behält das Material, das er hatte), und die Partikel kollidieren als Kugeln mit diesem Radius, während Partikel von Stoff und Körpern Kugeln mit Radius 0.03 sind. Jede Art beginnt mit Dehnung 0.9, Biegung 0.2, Masse 1 Kilogramm, Dämpfung 0.1 und Druck 0. Ein Soft Body, der schon auf dem Knoten ist, wird entfernt, bevor der neue erzeugt wird, sodass ein fehlschlagender Aufruf den Knoten ohne einen zurücklässt; das Röhren-Mesh eines Seils geht mit, weshalb der Knoten eines Seils nicht zu Stoff oder einem Körper werden kann (der Aufruf scheitert mangels Mesh). Beendet das Skript, wenn Physik nicht verfügbar ist, die Art unbekannt ist, die Zahl der Argumente nicht zur Art passt, das Mesh fehlt, ein Seil keine Segmente oder keinen Radius hat oder schon 16 Soft Bodies existieren.\nSeit: 3.00.",
args = "(node, SOFT_CLOTH)",
returns = "()",
},
softPin = {
type = "function",
description = "Sucht das Partikel, das dem Weltpunkt am nächsten liegt, wo immer die Partikel gerade sind, und heftet es fest. Allein wird das Partikel festgehalten, wo es ist; mit otherNode wird es vor jedem Schritt an die Weltposition dieses Knotens versetzt, sodass ein Seil an einem schwingenden Kran hängt und ein Umhang den Schultern folgt. Der Punkt muss nicht auf dem Mesh liegen, da das nächste Partikel gewinnt, und dasselbe Partikel erneut anzuheften ändert nur, wem es folgt. Nach 32 Pins tut der Aufruf nichts.\nSeit: 3.00.",
args = "(node, x, y, z [, otherNode])",
returns = "()",
},
softSetDamping = {
type = "function",
description = "Wie schnell die Bewegung der Partikel abklingt, 0 aufwärts; Standard 0.1, und ein negativer Wert wird zu 0. Höhere Werte beruhigen eine Flagge, die nicht aufhört, Wellen zu schlagen, oder ein Seil, das ewig schwingt. Der Körper wird um die aktuelle Form herum neu gebaut, und jedes Partikel hält an.\nSeit: 3.00.",
args = "(node, damping)",
returns = "()",
},
softSetMass = {
type = "function",
description = "Die Masse des ganzen Körpers, gleichmäßig auf seine Partikel verteilt; Standard 1, mindestens 0.001. Angeheftete Partikel wiegen trotzdem nichts. Der Körper wird um die aktuelle Form herum neu gebaut, und jedes Partikel hält an, also setz sie vorab.\nSeit: 3.00.",
args = "(node, kilograms)",
returns = "()",
},
softSetPressure = {
type = "function",
description = "Bläst einen SOFT_BODY auf: 0 (Standard) ist ein schlaffer Beutel und ein paar Einheiten ein praller Ballon; ein negativer Wert wird zu 0. Es ändert den laufenden Körper, ohne ihn neu zu bauen, und weckt ihn, sodass ein Ballon aufgepumpt oder abgelassen werden kann, während er hüpft. Stoff und Seil haben kein Volumen zum Aufblasen.\nSeit: 3.00.",
args = "(node, pressure)",
returns = "()",
},
softSetStiffness = {
type = "function",
description = "Wie stark sich das Material dagegen wehrt, gedehnt (und, bei Stoff, geschert) und gefaltet zu werden, 0 bis 1; Werte außerhalb werden begrenzt. 1 ist starr, 0 das Lockerste, was der Solver zulässt. Standards 0.9 und 0.2. Der Körper wird um die aktuelle Form herum neu gebaut: Die Ruhelängen werden zu den Längen dieses Moments, und jedes Partikel hält an; richte das Material also ein, bevor sich der Stoff zu bewegen beginnt. Ein Seil hat nur Dehnung.\nSeit: 3.00.",
args = "(node, stretch, bend)",
returns = "()",
},
softUnpin = {
type = "function",
description = "Löst das angeheftete Partikel, das dem Weltpunkt am nächsten liegt. Ist dieses Partikel nicht angeheftet, passiert nichts. Der Körper wird um die aktuelle Form herum neu gebaut, was auch jedes Partikel schlagartig anhält, sodass eine losgelassene Flagge aus der Ruhe zu fallen beginnt.\nSeit: 3.00.",
args = "(node, x, y, z)",
returns = "()",
},
soundFullStop = {
type = "function",
description = "Stoppt jeden Effektkanal auf einmal, pausierte eingeschlossen, und gibt sie zur Wiederverwendung frei. Kein Clip wird entladen; die Handles aus soundLoad bleiben gültig. Jeder Kanal, der spielte oder pausiert war, meldet sich über onSoundCompleted, genau wie nach soundStop. Ruf es bei einem Szenenwechsel oder vor einer Zwischensequenz auf, statt jeden gestarteten Kanal zu verfolgen.\nSeit: 1.16",
args = "()",
returns = "()",
},
soundGetPosition = {
type = "function",
description = "Meldet, wo ein platzierter Kanal relativ zum Zuhörer sitzt, als Richtung der Länge eins im Bezugssystem des Zuhörers (x positiv nach rechts, y positiv nach oben, z positiv hinter den Zuhörer), und den Lautstärkefaktor, den ihm seine Entfernung gerade gibt, 0 bis 1. Die Werte werden einmal pro Frame aus dem Zuhörer und dem Knoten oder Punkt des Kanals aufgefrischt. Ein Kanal, der seit seinem Start nicht in der Szene platziert wurde, gibt 0, 0, 0, 1 zurück. Gedacht für Anzeigen im Radarstil und zum Prüfen einer Mischung aus einem Testskript; ein Kanal außerhalb von 0 bis 15 bricht das Skript ab.\nRückgabe: drei Zahlen für die Richtung und eine für die Abschwächung durch die Entfernung.\nSeit: 3.00.",
args = "(channel)",
returns = "(x, y, z, gain)",
},
soundGetVolume = {
type = "function",
description = "Gibt die Gesamtlautstärke der Effekte zurück, 0 bis 63. Beim Start spiegelt sie die Effektlautstärke von der Befehlszeile wider; ein Spiel, das eine Lautstärkeeinstellung zeigt, sollte sie also lesen, statt das Maximum anzunehmen.\nRückgabe: Ganzzahl, 0 bis 63.\nSeit: 1.16",
args = "()",
returns = "(integer)",
},
soundIsPlaying = {
type = "function",
description = "Prüft, ob ein Kanal gerade spielt. Ein pausierter Kanal meldet false, ebenso ein Kanal, dessen Clip zu Ende ist. Ein Kanal außerhalb von 0 bis 15 bricht das Skript ab; ein Kanal, der bloß verstummt ist, nicht.\nRückgabe: Boolean.\nSeit: 1.16 (RDG)",
args = "(channel)",
returns = "(boolean)",
},
soundLoad = {
type = "function",
description = "Lädt einen Audioclip in den Speicher und gibt sein Handle zurück. Der Pfad geht durch das virtuelle Dateisystem des Spiels, er funktioniert also aus einem losen Ordner genauso wie aus einem gepackten Spiel. Lade Clips einmal beim Start, nicht in einem Callback, der jeden Frame ausgelöst wird. Eine Datei, die sich nicht öffnen oder decodieren lässt, bricht das Skript ab.\nRückgabe: ganzzahliges Sound-Handle. Das ist ein Daten-Handle, keine Kanalnummer.\nSeit: 1.x",
args = "(filename)",
returns = "(integer)",
},
soundLoadData = {
type = "function",
description = "Hypseus-Erweiterung. Baut einen Sound aus Bytes in einem Lua-String statt aus einer Datei. Jedes Format, das soundLoad liest, wird hier gelesen, und das zurückgegebene Handle wird mit dem Rest der sound-Familie genau gleich verwendet.\nRückgabe: Zahl, das Sound-Handle.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(data: string)",
returns = "(number)",
},
soundPause = {
type = "function",
description = "Pausiert einen Kanal an Ort und Stelle; soundResume setzt ihn an derselben Stelle fort. Ein pausierter Kanal gilt weiter als belegt, soundPlay gibt ihn also nicht an einen anderen Clip aus, und soundIsPlaying meldet für ihn false. Einen Kanal zu pausieren, der nicht spielt, bewirkt nichts. Ein Kanal außerhalb von 0 bis 15 bricht das Skript ab.\nRückgabe: Boolean, true, wenn der Kanal im Moment des Aufrufs spielte.\nSeit: 1.16 (RDG)",
args = "(channel)",
returns = "(boolean)",
},
soundPlay = {
type = "function",
description = "Startet einen geladenen Clip auf dem ersten freien Kanal und gibt die Nummer dieses Kanals zurück. Ein Kanal gilt als frei, wenn er weder spielt noch pausiert ist. Der neue Kanal beginnt mit der Gesamtlautstärke (oder mit volume darunter), mittig, ohne Position in der Szene und mit dem Standardbereich, egal was die vorige Nutzung des Kanals gesetzt hat. Sind alle sechzehn Kanäle belegt, spielt nichts, und -1 (SOUND_ERROR_INVALID) kommt zurück; ein Spiel, das viele sich überlagernde Sounds abfeuert, sollte darauf prüfen. Ein Handle, das nicht geladen ist, bricht das Skript ab.\nRückgabe: ganzzahlige Kanalnummer, 0 bis 15, oder -1, wenn kein Kanal frei ist.\nSeit: 1.x; volume seit 3.00.",
args = "(id [, loops, volume])",
returns = "(integer)",
},
soundResume = {
type = "function",
description = "Setzt einen Kanal, den soundPause angehalten hat, dort fort, wo er aufgehört hat. Einen Kanal fortzusetzen, der nicht pausiert ist, bewirkt nichts. Ein Kanal außerhalb von 0 bis 15 bricht das Skript ab.\nRückgabe: Boolean, true, wenn der Kanal im Moment des Aufrufs pausiert war.\nSeit: 1.16 (RDG)",
args = "(channel)",
returns = "(boolean)",
},
soundSetChannelVolume = {
type = "function",
description = "Setzt die eigene Lautstärke eines Kanals, zusätzlich zur Gesamtlautstärke aus soundSetVolume: Der Kanal spielt mit der Gesamtlautstärke mal diesem Wert, mal seiner Abschwächung durch die Entfernung, wenn er in der Szene ist. Jeder Kanal beginnt mit voller Lautstärke, wenn soundPlay ihn nimmt, sofern soundPlay keine Lautstärke bekommen hat, sodass ein leiser Schritt und ein lauter Schuss sich eine Gesamtlautstärke teilen können. Werte außerhalb von 0 bis 63 brechen das Skript ab, ebenso ein Kanal außerhalb von 0 bis 15.\nSeit: 3.00",
args = "(channel, volume: integer)",
returns = "()",
},
soundSetListener = {
type = "function",
description = "Wählt den Knoten, von dem aus platzierte Kanäle gehört werden, in die Richtung blickend, in die er blickt. Ohne Argument oder mit nil ist der Zuhörer die Kamera der Szene, was für ein Spiel in der Ich-Perspektive oder mit fester Kamera richtig ist; ein Third-Person-Spiel nimmt meist lieber den Knoten der Spielfigur, damit Sounds um die Figur herum wandern statt um die Kamera. Wird der Knoten später gelöscht, fällt der Zuhörer auf die Kamera zurück. Ein Knoten-Handle, das nicht existiert, bricht das Skript ab.\nSeit: 3.00.",
args = "([node])",
returns = "()",
},
soundSetNode = {
type = "function",
description = "Hängt einen spielenden Kanal an einen Knoten der Szene, sodass er jeden Frame von dort zu hören ist, wo der Knoten gerade ist: Der Kanal wird im Stereobild in die Richtung des Knotens vom Zuhörer aus verteilt und gemäß soundSetRange nach seiner Entfernung abgeschwächt. Ein Aufruf ohne Knoten oder mit nil nimmt den Kanal mit voller Gesamtlautstärke wieder aus der Szene. Ein Kanal, dessen Knoten gelöscht wird, fällt von selbst auf einfache Wiedergabe zurück. Die Verbindung hält, bis der Kanal gestoppt oder von soundPlay wiederverwendet wird. Ein Kanal außerhalb von 0 bis 15 oder ein Knoten, der nicht existiert, bricht das Skript ab.\nSeit: 3.00.",
args = "(channel [, node])",
returns = "()",
},
soundSetPan = {
type = "function",
description = "Verteilt einen Kanal für Spiele ohne Szene im Stereobild: -1 ist ganz links, 1 ganz rechts, 0 mittig, und Werte außerhalb dieses Bereichs werden begrenzt. Weg von der Mitte wird nur der gegenüberliegende Lautsprecher leiser; bei pan = 0.5 spielt der linke Lautsprecher mit halber Verstärkung und der rechte mit voller. Der Aufruf nimmt den Kanal aus der Szene, falls soundSetNode oder soundSetPosition ihn dort platziert hatte. Ein Kanal außerhalb von 0 bis 15 bricht das Skript ab.\nSeit: 3.00.",
args = "(channel, pan)",
returns = "()",
},
soundSetPosition = {
type = "function",
description = "Setzt einen spielenden Kanal an einen festen Punkt in der Szene, in Welteinheiten, und ersetzt jeden Knoten, dem er gefolgt ist. Er wird dann wie ein an einen Knoten gehängter Kanal vom Zuhörer aus im Stereobild verteilt und abgeschwächt. Passt zu einem Sound, der an seinem Platz bleibt, etwa einem Wasserfall oder einem klingelnden Telefon; eine bewegte Quelle geht leichter mit soundSetNode. Ein Kanal außerhalb von 0 bis 15 bricht das Skript ab.\nSeit: 3.00.",
args = "(channel, x, y, z)",
returns = "()",
},
soundSetRange = {
type = "function",
description = "Legt fest, wie ein platzierter Kanal mit der Entfernung vom Zuhörer leiser wird. Innerhalb von near spielt er mit voller Lautstärke; darüber hinaus ist seine Verstärkung near geteilt durch die Entfernung; über das letzte Fünftel von far blendet er außerdem linear aus und erreicht bei far Stille. Die Standards sind 1 und 30 Welteinheiten und werden wiederhergestellt, wann immer soundPlay den Kanal wiederverwendet. Ein Flüstern will ein kleines far, ein Wasserfall ein großes.\nSeit: 3.00.",
args = "(channel, near, far)",
returns = "()",
},
soundSetVolume = {
type = "function",
description = "Setzt die Gesamtlautstärke der Effekte und wendet sie sofort auf jeden Kanal an, ob spielend oder pausiert. Die eigene Lautstärke jedes Kanals aus soundSetChannelVolume und, bei platzierten Kanälen, die Abschwächung durch die Entfernung wirken zusätzlich. Werte außerhalb von 0 bis 63 brechen das Skript ab.\nSeit: 1.16",
args = "(volume: integer)",
returns = "()",
},
soundStop = {
type = "function",
description = "Hält einen Kanal sofort an, ob spielend oder pausiert, und gibt ihn zur Wiederverwendung frei. Der Kanal meldet sich über onSoundCompleted, genau wie wenn der Clip von selbst endet; ein Skript, das in diesem Callback Sounds aneinanderreiht, sollte also prüfen, ob es den Kanal selbst gestoppt hat. Das nächste soundPlay kann dieselbe Nummer wieder ausgeben, verwirf die Nummer also auf der Lua-Seite. Ein Kanal außerhalb von 0 bis 15 bricht das Skript ab.\nRückgabe: Boolean, true, wenn der Kanal im Moment des Aufrufs spielte. Ein pausierter Kanal gibt false zurück, wird aber trotzdem gestoppt.\nSeit: 1.x (RDG)",
args = "(channel)",
returns = "(boolean)",
},
soundUnload = {
type = "function",
description = "Gibt einen geladenen Clip frei und macht sein Handle ungültig. Der Mixer hält die Daten des Clips am Leben, bis jeder Kanal, der ihn noch spielt, gestoppt hat, sodass das Entladen keinen spielenden Kanal abschneidet. Jede spätere Verwendung des Handles, auch ein weiteres soundUnload, bricht das Skript ab. Der übliche Ort dafür ist onShutdown.\nSeit: 2.00",
args = "(id)",
returns = "()",
},
spriteAnimGetFrame = {
type = "function",
description = "Ein Alias von spriteGetFrame.",
args = "(spr)",
returns = "()",
anchor = "_hypseus_compatibility",
},
spriteAnimIsPlaying = {
type = "function",
description = "Ein Alias von spriteIsPlaying.",
args = "(spr)",
returns = "()",
anchor = "_hypseus_compatibility",
},
spriteAnimLoop = {
type = "function",
description = "Ein Alias von spriteLoop.",
args = "(loop, spr)",
returns = "()",
anchor = "_hypseus_compatibility",
},
spriteAnimPause = {
type = "function",
description = "Ein Alias von spritePause.",
args = "(spr)",
returns = "()",
anchor = "_hypseus_compatibility",
},
spriteAnimPlay = {
type = "function",
description = "Ein Alias von spritePlay.",
args = "(spr)",
returns = "()",
anchor = "_hypseus_compatibility",
},
spriteAnimSetFrame = {
type = "function",
description = "Ein Alias von spriteSetFrame.",
args = "(frame, spr)",
returns = "()",
anchor = "_hypseus_compatibility",
},
spriteBlend = {
type = "function",
description = "Hypseus-Erweiterung, angenommen und ignoriert. Sie ist ein Notbehelf für jene Engine: Hypseus lädt Sprites mit ausgeschaltetem Blend-Modus von SDL, und dies schaltet ihn für ein Sprite wieder ein. Singe zeichnet jedes Sprite ohnehin mit seinem Alphakanal, das Blending ist also von vornherein nie aus. Das Sprite-Handle wird trotzdem geprüft, ein falsches ist also weiterhin ein Fehler. Um stattdessen das Licht eines Sprites zu addieren oder mit ihm zu multiplizieren, siehe spriteSetBlend.\nRückgabe: nichts.\nSeit: 3.00",
args = "(boolean, sprite)",
returns = "()",
},
spriteDraw = {
type = "function",
description = "spriteDraw(id, x, y)\nspriteDraw(id, x, y, centered)\nspriteDraw(id, x, y, x2, y2)\nspriteDraw(id, x, y, x2, y2, centered)\nBlittet das Sprite so auf das Overlay, wie es gerade gedreht und skaliert ist. Ruf es aus onOverlayUpdate auf. Die ersten beiden Formen zeichnen in der Größe, die spriteGetWidth und spriteGetHeight melden, mit (x, y) als oberer linker Ecke; die letzten beiden strecken dieses Bild in das Rechteck von (x, y) bis einschließlich (x2, y2), immer mit Nächster-Nachbar-Abtastung, was auch immer spriteQuality sagt. Ist das Sprite eine laufende Animation, rückt das Zeichnen sie zuerst um die echte Zeit weiter, die seit dem vorigen Zeichnen (oder seit spritePlay) vergangen ist, durchläuft so viele Frames, wie diese Zeit abdeckt, und zeigt jeden Frame mindestens 10 ms lang, auch wenn die Datei weniger verlangt. Ist der letzte Frame vorüber, springt die Wiedergabe auf Frame 0 zurück, falls spriteLoop gesetzt ist; ansonsten bleibt sie auf dem letzten Frame stehen und hält an. Teile außerhalb des Overlays werden abgeschnitten.\nSeit: 1.x. Zentrierte und gestreckt-zentrierte Formen in 2.10 hinzugefügt.",
args = "(id, x, y)",
returns = "()",
},
spriteDrawFrame = {
type = "function",
description = "spriteDrawFrame(id, x, y, frame)\nspriteDrawFrame(id, x, y, frame, scale)\nspriteDrawFrame(id, x, y, frame, scaleX, scaleY)\nHypseus-Erweiterung. Blittet einen Frame eines Sprite-Sheets (oder einer beliebigen Animation) mit (x, y) als oberer linker Ecke auf das Overlay, ohne zu ändern, auf welchem Frame das Sprite steht oder ob es läuft. Frames werden ab 1 gezählt, wie Hypseus sie zählt; ein Frame außerhalb von 1 bis zur Frame-Anzahl zeichnet Frame 1. Ein Standbild zeichnet sich selbst und ignoriert frame. Eine mit spriteFlip gesetzte Spiegelung gilt. Die eigene Drehung und Skalierung des Sprites aus spriteRotate und spriteScale werden ignoriert: Die erste Form zeichnet den Frame in seiner natürlichen Größe, die anderen multiplizieren die Breite des Frames mit scaleX (oder scale) und seine Höhe mit scaleY (oder scale), mit Nächster-Nachbar-Abtastung. Ruf es aus onOverlayUpdate auf.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id, x, y, frame)",
returns = "()",
},
spriteDrawGrid = {
type = "function",
description = "Hypseus-Erweiterung. Zeichnet ein Rechteck aus einem Sprite mit seiner oberen linken Ecke bei x, y: in seiner eigenen Größe oder, wenn x2 und y2 angegeben sind, so gestreckt, dass es den Kasten bis zu dieser Ecke füllt, so wie spriteDraw ein ganzes Sprite streckt. Es ist der einzige Aufruf, der ein Quellrechteck nimmt: spriteDraw nimmt das ganze Sprite und spriteDrawFrame einen ganzen Frame eines Sheets, während dieser ein beliebiges Rechteck nimmt. So schneidet ein Spiel eine Kachel, eine Ziffer oder einen Buchstaben aus einem Bild aus, ohne es viele Male zu laden.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe; die gestreckte Form ist neu in 3.00 und Singes eigene.",
args = "(id: number, x, y, sourceX, sourceY, width, height [, x2, y2])",
returns = "()",
},
spriteDrawRotatedFrame = {
type = "function",
description = "spriteDrawRotatedFrame(id, x, y)\nspriteDrawRotatedFrame(id, x, y, scale)\nspriteDrawRotatedFrame(id, x, y, scaleX, scaleY)\nHypseus-Erweiterung. Zeichnet den Frame, den spriteRotateFrame zuletzt gedreht hat, zentriert auf x, y. Dies ist das Gegenstück zu jenem Aufruf und der Grund, weshalb es beide gibt: spriteDrawFrame ignoriert absichtlich die Drehung und Skalierung eines Sprites, also verwendet ein Spiel, das einen Frame eines Sheets gedreht haben will, stattdessen diese beiden.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id: number, x, y)",
returns = "()",
},
spriteFlip = {
type = "function",
description = "Spiegelt das Sprite von links nach rechts, von oben nach unten oder beides, bis es wieder mit false, false aufgerufen wird. Die Spiegelung gilt für jedes Zeichnen des Sprites: spriteDraw, jeden Frame aus spriteDrawFrame und den gedrehten Frame aus spriteDrawRotatedFrame. Sie wird nach der Drehung und Skalierung aus spriteRotate und spriteScale angewendet, ein gedrehtes Sprite wird also so gespiegelt, wie es auf dem Bildschirm erscheint, und ein gedrehter Frame wird einfach in die andere Richtung gespiegelt, statt erneut gedreht zu werden. Das gespiegelte Bild wird nur neu aufgebaut, wenn sich die Flags ändern; ein von spriteDrawFrame gezeichneter Frame wird einmal gespiegelt und behalten, bis ein anderer Frame verlangt wird. spriteDrawGrid ignoriert die Spiegelung, da sein Rechteck aus dem ungespiegelten Bild geschnitten wird.\nRückgabe: nichts.\nSeit: 3.00",
args = "(id, horizontal, vertical)",
returns = "()",
},
spriteFrameHeight = {
type = "function",
description = "Hypseus-Erweiterung. Gibt die Höhe eines Frames des Sprites vor jeder Skalierung oder Drehung zurück: die Höhe des Streifens bei einem Sheet aus spriteLoadFrames, die Höhe eines Frames bei einer Animation und die Höhe des Bildes bei einem Standbild (Hypseus meldet hier die gezeichnete Fläche). spriteGetHeight meldet stattdessen die Größe, wie sie gezeichnet wird.\nRückgabe: Ganzzahl.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id)",
returns = "(integer)",
},
spriteFrameWidth = {
type = "function",
description = "Hypseus-Erweiterung. Gibt die Breite eines Frames des Sprites vor jeder Skalierung oder Drehung zurück: die Breite des Streifens geteilt durch die Frame-Anzahl bei einem Sheet aus spriteLoadFrames, die Breite eines Frames bei einer Animation und die Breite des Bildes bei einem Standbild (Hypseus meldet dort 0). spriteGetWidth meldet stattdessen die Größe, wie sie gezeichnet wird.\nRückgabe: Ganzzahl.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id)",
returns = "(integer)",
},
spriteGetFrame = {
type = "function",
description = "Gibt den nullbasierten Index des Frames zurück, den das Sprite gerade zeigt. Standbilder und Animationen, die nicht weitergerückt sind, melden 0. Frames rücken nur innerhalb von spriteDraw weiter, der Wert ändert sich also zwischen Zeichenaufrufen, nicht zwischen beliebigen Aufrufen. Verwende es, um Sound oder Spiellogik auf einen bestimmten Frame einer Animation abzustimmen.\nRückgabe: ganzzahliger Frame-Index, 0 bei einem Standbild.\nSeit: 2.10",
args = "(id)",
returns = "(integer)",
},
spriteGetFrames = {
type = "function",
description = "Hypseus-Erweiterung. Wie viele Frames ein Sprite hat: die Frame-Anzahl eines von spriteLoadFrames geladenen Sheets oder eines animierten GIF oder WEBP und 0 bei einem Standbild. Es ist die Anzahl, bis zu der die nullbasierte Frame-Nummer von spriteSetFrame läuft, und eins mehr als die größte, die es annimmt.\nRückgabe: Zahl; 0 bei einem Standbild.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id: number)",
returns = "(number)",
},
spriteGetHeight = {
type = "function",
description = "Gibt die Höhe des Sprites zurück, wie es jetzt gezeichnet würde, in Overlay-Koordinaten. Skalierung und Drehung, die mit spriteScale, spriteRotate oder spriteRotateAndScale angewendet wurden, sind eingeschlossen, ein gedrehtes Sprite meldet also die Höhe seines gedrehten Begrenzungsrahmens, nicht die des Quellbildes. Bei einer Animation wird der aktuelle Frame gemessen. Die gestreckten Formen von spriteDraw beeinflussen den Wert nicht.\nRückgabe: ganzzahlige Höhe.\nSeit: 2.00",
args = "(id)",
returns = "(integer)",
},
spriteGetWidth = {
type = "function",
description = "Gibt die Breite des Sprites zurück, wie es jetzt gezeichnet würde, in Overlay-Koordinaten, einschließlich jeder gerade angewendeten Skalierung und Drehung. Bei einer Animation wird der aktuelle Frame gemessen. Zusammen mit spriteGetHeight ist das der übliche Weg, ein Sprite in einem Kasten zu zentrieren oder mit fontToSprite gerenderten Text zu messen.\nRückgabe: ganzzahlige Breite.\nSeit: 2.00",
args = "(id)",
returns = "(integer)",
},
spriteIsPlaying = {
type = "function",
description = "Meldet, ob die Animation des Sprites gerade weiterrückt. Ein frisch geladenes Sprite meldet false; spritePlay schaltet sie ein, und spritePause oder das Ende einer Animation ohne Wiederholung schaltet sie aus. Frag es regelmäßig ab, um herauszufinden, wann eine einmalige Animation fertig ist.\nRückgabe: Boolean, true, solange die Animation läuft.\nSeit: 2.10",
args = "(id)",
returns = "(boolean)",
},
spriteLoad = {
type = "function",
description = "Lädt ein Bild und gibt ein ganzzahliges Handle für die anderen sprite*-Aufrufe zurück. Der Name geht durch das virtuelle Dateisystem der Engine, die Datei kann also ungepackt auf der Festplatte oder in einem gepackten Spiel liegen; er wird relativ zu dem Ordner aufgelöst, in dem Singe gestartet wurde, stelle also für Dateien, die mit deinem Spiel ausgeliefert werden, DIR voran. Jedes Format in Video-, Audio- und Containerformate wird gelesen. Ein animiertes GIF oder WEBP mit zwei oder mehr Frames lädt als Animation, auf Frame 0 abgestellt, nicht laufend und ohne Wiederholung; jede andere Datei, auch ein GIF mit nur einem Frame, lädt als Standbild. Ein Bild mit mehr als 8 Bit pro Kanal oder mit Gleitkommapixeln wird beim Laden in 8-Bit-RGBA umgewandelt und von da an als solches behandelt. Pixel mit dem Rohwert 0 im eigenen Pixelformat der Datei werden transparent. Das Laden ist synchron, und eine Datei, die sich nicht öffnen oder dekodieren lässt, beendet das Skript mit der Fehlermeldung des Laders, statt nil zurückzugeben.\nRückgabe: ganzzahliges Sprite-Handle.\nSeit: 1.x. Unterstützung für animierte GIF/WEBP in 2.10 hinzugefügt; die Vektorgröße in 3.00.",
args = "(filename: string [, width: number, height: number])",
returns = "(integer)",
},
spriteLoadData = {
type = "function",
description = "Hypseus-Erweiterung. Baut ein Sprite aus einem Bild, das in einem Lua-String steht, statt aus einer Datei. Jedes Format, das spriteLoad liest, wird hier gelesen, animierte GIF und WEBP eingeschlossen, und eine so geladene Animation verhält sich genau wie eine aus einer Datei geladene.\nRückgabe: Zahl, das Sprite-Handle.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(data: string)",
returns = "(number)",
},
spriteLoadFrames = {
type = "function",
description = "Hypseus-Erweiterung. Lädt ein Bild, das count gleich große Frames in einer einzigen Zeile enthält, und gibt ein Sprite-Handle zurück. Die Frame-Breite ist die Bildbreite geteilt durch count (ganzzahlige Division; übrige Spalten rechts fallen weg), und die Frame-Höhe ist die Bildhöhe. Das Sheet wird zu einer gewöhnlichen Animation, auf Frame 0 abgestellt, nicht laufend und ohne Wiederholung, sodass spriteDraw den aktuellen Frame zeigt statt des ganzen Streifens (wie Hypseus ihn zeichnet), und spriteDrawFrame wählt jeden Frame direkt. Der Name geht wie bei spriteLoad durch das virtuelle Dateisystem, und Pixel mit dem Rohwert 0 werden in jedem Frame transparent. Eine Anzahl außerhalb von 2 bis 512, ein Bild, das schmaler als count Pixel ist, oder eine Datei, die sich nicht lesen lässt, beendet das Skript mit einem Fehler.\nRückgabe: ganzzahliges Sprite-Handle.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(count: number, filename)",
returns = "(integer)",
},
spriteLoop = {
type = "function",
description = "Legt fest, ob die Animation nach ihrem letzten Frame wieder bei Frame 0 beginnt oder dort anhält. Neue Sprites wiederholen nicht. Die Einstellung wird jedes Mal abgefragt, wenn spriteDraw über den letzten Frame hinausgeht, sie kann also geändert werden, während die Animation läuft. Sie an einem Sprite zu setzen, das schon angehalten hat, startet die Wiedergabe nicht neu; dafür ruf spritePlay auf. Das Argument muss ein Lua-Boolean sein.\nSeit: 2.10",
args = "(id, loop)",
returns = "()",
},
spriteNew = {
type = "function",
description = "Erzeugt ein leeres Sprite, jedes Pixel transparent, das spriteSetPixels füllen soll: ein Bild, das das Skript selbst macht, statt es zu laden. Jede Seite ist 1 bis 4096 Pixel lang; alles andere beendet das Skript. Das Sprite ist ein Standbild und kann alles, was jedes andere Standbild kann: Es lässt sich zeichnen, drehen, skalieren, strecken und einfärben, und es kann die Textur eines Materials sein.\nRückgabe: Zahl, das Sprite-Handle.\nSeit: 3.00",
args = "(width, height)",
returns = "(number)",
},
spritePause = {
type = "function",
description = "Hält die Animation auf ihrem aktuellen Frame an. Der Frame wird von spriteDraw weiter gezeichnet, und die pausierte Zeit wird nicht mitgezählt, wenn spritePlay fortsetzt, der Frame springt also nicht vor. Ein Sprite zu pausieren, das nicht läuft, ändert nichts.\nSeit: 2.10",
args = "(id)",
returns = "()",
},
spritePlay = {
type = "function",
description = "Startet die Animation oder setzt sie von ihrem aktuellen Frame aus fort, wobei der erste Schritt ab dem Moment des Aufrufs gemessen wird. Ein Sprite, das bereits läuft, bleibt unberührt, der Frame-Timer wird also nicht zurückgesetzt. Ein neues Sprite muss mit diesem Aufruf gestartet werden; Laden allein animiert es nicht.\nSeit: 2.10",
args = "(id)",
returns = "()",
},
spriteQuality = {
type = "function",
description = "Wählt die Abtastung, die verwendet wird, wenn das Sprite für Drehung oder Skalierung neu aufgebaut wird. RENDER_PIXELATED behält harte Pixelkanten, RENDER_SMOOTH interpoliert. Neue Sprites sind pixelig. Die Einstellung zählt nur, solange eine Drehung oder ein Maßstab ungleich 1.0 wirkt; ein untransformiertes Sprite wird direkt aus seinem Quellbild gezeichnet, und die gestreckten Formen von spriteDraw verwenden immer Nächster-Nachbar-Abtastung. Den Modus zu ändern baut das transformierte Bild sofort neu auf, setze ihn also einmal nach dem Laden statt in jedem Frame.\nSeit: 2.10",
args = "(id, mode)",
returns = "()",
},
spriteResetColorKey = {
type = "function",
description = "Hypseus-Erweiterung. Wird aus Kompatibilitätsgründen angenommen und tut nichts. In Hypseus wendet das Flag die transparente Farbe erneut auf die Kopien an, die spriteRotate und spriteScale erzeugen und die ihren Hintergrund sonst deckend zeichnen würden; die transformierten Kopien von Singe tragen die Transparenz in ihrem Alphakanal, es gibt also nichts neu auszustanzen. Ein falsches Handle oder ein Argument, das kein Boolean ist, bricht das Skript ab, wie bei jedem anderen Sprite-Aufruf.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id, enabled: boolean)",
returns = "()",
},
spriteRotate = {
type = "function",
description = "Dreht das Sprite im Uhrzeigersinn um seinen Mittelpunkt. Der Winkel wird modulo 360 reduziert und darf gebrochen oder negativ sein. Der aktuelle Maßstab bleibt erhalten. Das gedrehte Bild wird nur neu aufgebaut, wenn sich der Winkel tatsächlich ändert; denselben Winkel in jedem Frame zu wiederholen kostet also nichts, während ein neuer Winkel in jedem Frame auch in jedem Frame neu aufbaut. Die Drehung vergrößert den Begrenzungsrahmen, also ändern sich spriteGetWidth und spriteGetHeight, und die zentrierte Form von spriteDraw ist die richtige.\nSeit: 2.10",
args = "(id, degrees)",
returns = "()",
},
spriteRotateAndScale = {
type = "function",
description = "spriteRotateAndScale(id, degrees, scale)\nspriteRotateAndScale(id, degrees, scaleX, scaleY)\nSetzt Drehung und Maßstab zusammen. Das Ergebnis ist dasselbe wie spriteRotate gefolgt von spriteScale, aber das transformierte Bild wird einmal statt zweimal neu aufgebaut, und gar nicht, wenn sich nichts geändert hat. Skalierungsfaktoren sollten größer als 0 sein; ein negativer wird ohne sein Vorzeichen genommen, und einer, der keine Pixel übrig ließe, null eingeschlossen, lässt stattdessen eines übrig.\nSeit: 2.10",
args = "(id, degrees, scale)",
returns = "()",
},
spriteRotateFrame = {
type = "function",
description = "Hypseus-Erweiterung. Nimmt einen Frame aus einem Sprite-Sheet, dreht ihn um degrees im Uhrzeigersinn, skaliert ihn mit dem eigenen spriteScale des Sprites und behält das Ergebnis für spriteDrawRotatedFrame. Die eigene gezeichnete Fläche des Sprites bleibt unberührt, also zeigen spriteDraw und spriteDrawFrame weiter, was sie gezeigt haben.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(id: number, degrees: number, frame: number)",
returns = "()",
},
spriteScale = {
type = "function",
description = "spriteScale(id, scale)\nspriteScale(id, scaleX, scaleY)\nSkaliert das Sprite um seinen Mittelpunkt, einheitlich oder pro Achse, und behält die aktuelle Drehung. Faktoren müssen größer als 0 sein; 1.0 ist natürliche Größe, und ein Faktor von genau 1.0 auf beiden Achsen ohne Drehung zeichnet das Quellbild direkt. Das skalierte Bild wird nur neu aufgebaut, wenn sich ein Faktor ändert, mit der von spriteQuality gewählten Abtastung. Nimm lieber die gestreckte Form von spriteDraw, wenn sich die Zielgröße in jedem Frame ändert, da sie nichts neu aufbaut.\nSeit: 2.10",
args = "(id, scale)",
returns = "()",
},
spriteSetAlpha = {
type = "function",
description = "Multipliziert bei jedem Zeichnen des Sprites, in jeder Form, das Alpha jedes Pixels mit alpha / 255: spriteDraw, spriteDrawFrame, spriteDrawGrid und spriteDrawRotatedFrame, gedreht oder nicht. 255, der Standard, zeichnet es, wie es ist, und 0 gar nicht, ein Logo blendet also ohne zweites Bild ein und aus. Werte außerhalb des Bereichs werden begrenzt.\nRückgabe: nichts.\nSeit: 3.00",
args = "(id: number, alpha: number)",
returns = "()",
},
spriteSetBlend = {
type = "function",
description = "Wie jedes Zeichnen des Sprites es über das legt, was schon auf dem Overlay ist. SPRITE_ALPHA, der Standard, zeichnet es nach seinem Alpha darüber. SPRITE_ADD addiert seine Farbe, skaliert mit seinem Alpha, zu dem, was da ist, und kann also nur aufhellen: Leuchten, Licht, Funken und die Shadebobs der alten Demos, bei denen ein Ball, der immer wieder über sich selbst gezeichnet wird, zu Weiß ausbrennt. SPRITE_MULTIPLY dunkelt das, was da ist, mit seiner Farbe ab, für Schatten und getöntes Glas.\nRückgabe: nichts.\nSeit: 3.00",
args = "(id: number, SPRITE_ALPHA | SPRITE_ADD | SPRITE_MULTIPLY)",
returns = "()",
},
spriteSetFrame = {
type = "function",
description = "Springt mit einer Animation auf den angegebenen Frame und startet den Verzögerungstimer dieses Frames neu, sodass der Frame seine volle Dauer gezeigt wird, bevor der nächste kommt. Der Wiedergabezustand ändert sich nicht: Ein pausiertes Sprite bleibt auf dem neuen Frame pausiert, und ein laufendes macht von dort aus weiter. Der Aufruf wird ignoriert bei Standbildern, bei Frames außerhalb von 0 bis zum letzten Frame und wenn das Sprite diesen Frame schon zeigt.\nSeit: 2.10",
args = "(id, frame)",
returns = "()",
},
spriteSetPixels = {
type = "function",
description = "Ersetzt jedes Pixel eines Standbild-Sprites aus einem String, Zeile für Zeile von oben. Ohne Palette hat der String vier Bytes pro Pixel: Rot, Grün, Blau und Alpha. Mit einer ist es ein Byte pro Pixel, jeweils die Nummer einer Farbe in der Palette, die aus 256 Farben zu je drei Bytes (Rot, Grün und Blau, alle deckend) oder vier (mit Alpha) besteht. Ein String der falschen Länge, eine Palette der falschen Länge oder ein animiertes Sprite beendet das Skript.\nRückgabe: nichts.\nSeit: 3.00",
args = "(id: number, pixels: string [, palette: string])",
returns = "()",
},
spriteSetTint = {
type = "function",
description = "Multipliziert bei jedem Zeichnen des Sprites, in jeder Form, die Farbe jedes Pixels mit r, g, b / 255. Ein weißes Sprite zeichnet in jeder Farbe, und jedes Sprite lässt sich ohne zweites Bild abdunkeln oder zu einer Farbe hin verschieben: Aus einem weißen Ball wird ein ganzer Regenbogen davon, und ein weißes Sprite von einem Pixel, mit spriteDraw gestreckt, wird zu einem gefüllten Rechteck in jeder Farbe. 255, 255, 255, der Standard, zeichnet es, wie es ist. Werte außerhalb des Bereichs werden begrenzt.\nRückgabe: nichts.\nSeit: 3.00",
args = "(id: number, r, g, b)",
returns = "()",
},
spriteUnload = {
type = "function",
description = "Gibt das Sprite frei: das Quellbild, die transformierte Kopie, falls es eine gibt, und alle Animations-Frames. Das Handle ist danach ungültig, und jede weitere Verwendung beendet das Skript mit einem Fehler. Von fontToSprite erzeugte Sprites werden genauso freigegeben. Sprites, die beim Ende des Spiels noch geladen sind, gibt die Engine frei, aber Spiele, die während des Spielens Sprites erzeugen (zum Beispiel Text, der neu gerendert wird, wenn sich der Punktestand ändert), müssen die alten entladen, sonst wächst der Speicher ohne Grenze.\nSeit: 2.00",
args = "(id)",
returns = "()",
},
srtClear = {
type = "function",
description = "Hypseus-Erweiterung. Nimmt sofort vom Bildschirm, was dort steht -- einen Cue oder ein Banner -- und lässt die geladenen Cues und den Eingeschaltet-Zustand in Ruhe. Der Cue, der zu sehen war, bleibt weg, bis die Disc den nächsten erreicht; nichts muss neu geladen und nichts wieder eingeschaltet werden.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "()",
},
srtEnable = {
type = "function",
description = "Hypseus-Erweiterung. Ob die geladenen Cues angezeigt werden, während die Disc läuft. Ausschalten nimmt einen gerade sichtbaren Cue mit weg; erneutes Einschalten zeigt den Cue an, der den Frame abdeckt, auf dem die Disc steht. Ein Skript beginnt mit ausgeschalteten Untertiteln, ein Spiel, das welche lädt, muss sie also einschalten.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled)",
returns = "()",
},
srtLoad = {
type = "function",
description = "Hypseus-Erweiterung. Liest eine SubRip-Datei über das virtuelle Dateisystem und wandelt ihre Zeitstempel in Disc-Frames bei der eigenen Bildrate der Disc um. Laden ersetzt, was vorher geladen war; srtEnable zeigt es dann an.\nRückgabe: Boolean, ob ein Cue geladen wurde.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(filename: string)",
returns = "(boolean)",
},
srtLoadTrack = {
type = "function",
description = "Dasselbe wie srtLoad, nur dass die Untertitel aus dem eigenen Container der Disc kommen statt aus einer .srt-Datei daneben. Alles nach dem Laden ist gleich: Die Cues werden zu Disc-Frame-Nummern bei der Bildrate der Disc, sie werden also nach jedem Sprung wiedergefunden, und srtEnable, srtPosition und srtClear funktionieren genauso.\nRückgabe: true, wenn mindestens ein Cue gelesen wurde.\nSeit: 3.00.",
args = "(track: number)",
returns = "(loaded)",
},
srtPosition = {
type = "function",
description = "Hypseus-Erweiterung. Wo ein Untertitel sitzt, in Prozent der Bildhöhe von oben, von 1 bis 95. Der Standard ist 80. Eine Zahl außerhalb dieses Bereichs wird ignoriert, wie Hypseus sie ignoriert, statt begrenzt oder abgelehnt zu werden.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(percent: number)",
returns = "()",
},
statsEnable = {
type = "function",
description = "Zeigt das Overlay an oder blendet es aus. Solange es angezeigt wird, wird das Bild in jedem Frame neu gezeichnet, die Zahlen bewegen sich also weiter, auch wenn sich sonst nichts auf dem Bildschirm bewegt.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(enabled)",
returns = "()",
},
statsIsEnabled = {
type = "function",
description = "Ob das Overlay eingeschaltet ist.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "()",
returns = "(shown)",
},
takeScreenshot = {
type = "function",
description = "Ein Alias von singeScreenshot. Hypseus verweigert einen zweiten Screenshot innerhalb von fünf Sekunden; Singe hat keine solche Drosselung.",
args = "()",
returns = "()",
anchor = "_hypseus_compatibility",
},
terrainGetHeight = {
type = "function",
description = "Die Welthöhe des Höhenkarten-Meshes auf node an der Weltposition x, z, interpoliert zwischen den nächsten vier Abtastwerten, oder nil jenseits seiner Ränder oder wenn das Mesh des Knotens keine Höhenkarte ist. Weltposition und Maßstab des Knotens zählen; seine Drehung wird ignoriert, da Gelände flach liegt. Verwende es, um Bäume zu platzieren, Dinge auf dem Boden erscheinen zu lassen oder für eine Kamera, die der Oberfläche folgt, ohne die Kosten eines Raycasts. Beendet das Skript bei einem Knoten-Handle, das nicht gültig ist.\nRückgabe: Eine Zahl oder nil außerhalb des Geländes.\nSeit: 3.00.",
args = "(node, x, z)",
returns = "(height)",
},
timerAfter = {
type = "function",
description = "Ruft die Funktion einmal auf, später. Die Funktion bekommt die eigene id des Timers, sodass eine Funktion mehreren Timern dienen kann.\nRückgabe: eine Zahl; die id des Timers.\nSeit: 3.00.",
args = "(milliseconds: number, function)",
returns = "(id)",
},
timerCancel = {
type = "function",
description = "Stoppt einen Timer. Einen abzubrechen, der schon gefeuert hat, ist kein Fehler, also muss nichts vorher prüfen.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(id: number)",
returns = "()",
},
timerEvery = {
type = "function",
description = "Ruft die Funktion immer wieder auf, bis der Timer abgebrochen wird.\nRückgabe: eine Zahl; die id des Timers.\nSeit: 3.00.",
args = "(milliseconds: number, function)",
returns = "(id)",
},
timerIsActive = {
type = "function",
description = "Ob der Timer noch einmal feuern wird: true für einen wiederholenden, bis er abgebrochen wird, false für einen einmaligen, der schon ausgelöst hat.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(id)",
returns = "(running)",
},
tweenCancel = {
type = "function",
description = "Stoppt einen Tween, wo er gerade ist. Keine der beiden Funktionen wird wieder aufgerufen, und der Wert bleibt, wo immer er angekommen war.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(id: number)",
returns = "()",
},
tweenIsActive = {
type = "function",
description = "Ob der Tween noch läuft.\nRückgabe: true oder false.\nSeit: 3.00.",
args = "(id)",
returns = "(running)",
},
tweenValue = {
type = "function",
description = "Bewegt eine Zahl über milliseconds von from nach to und ruft dabei in jedem Frame onUpdate(value, progress) auf -- progress läuft von 0 bis 1 und ignoriert die Kurve -- und am Ende einmal onDone(). Das letzte onUpdate landet immer genau auf to, sodass nichts ein Pixel zu kurz endet.\nRückgabe: eine Zahl; die id des Tweens.\nSeit: 3.00.",
args = "(from, to, milliseconds: number, easing, onUpdate [, onDone])",
returns = "(id)",
},
utilDeepCopy = {
type = "function",
description = "Eine Kopie von value bis ganz nach unten: Eine Tabelle wird Schlüssel für Schlüssel kopiert, ihre Schlüssel, Werte und ihre Metatabelle ihrerseits kopiert; alles andere kommt unverändert zurück.",
args = "(value)",
returns = "()",
anchor = "frameworkhelpers",
},
utilDump = {
type = "function",
description = "value als Text zum Ausgeben. Eine Tabelle wird zu { [\"key\"] = value,}, verschachtelte Tabellen in eigenen Klammern; alles andere geht durch tostring. Für eine Tabelle, die sich zu lesen lohnt, macht es require(\"inspect\") besser.",
args = "(value)",
returns = "()",
anchor = "frameworkhelpers",
},
utilGetTableSize = {
type = "function",
description = "Wie viele Schlüssel t enthält, alle, nicht nur die Folge, die #t misst.",
args = "(t)",
returns = "()",
anchor = "frameworkhelpers",
},
utilOffsetTable = {
type = "function",
description = "Eine tiefe Kopie einer Tabelle in der Form von SCANCODE, { NAME = { name = NAME, value = N } }, mit offset zu jedem value addiert.",
args = "(source, offset)",
returns = "()",
anchor = "frameworkhelpers",
},
utilSha256 = {
type = "function",
description = "SHA-256 eines Strings, als 64 Hexadezimalzeichen in Kleinbuchstaben. Binärsicher, funktioniert also mit den Bytes einer Datei ebenso gut wie mit Text.\nRückgabe: String, 64 Hexadezimalzeichen in Kleinbuchstaben.\nSeit: 3.00.",
args = "(data)",
returns = "(string)",
},
utilTrim = {
type = "function",
description = "s ohne die Leerzeichen an beiden Enden.",
args = "(s)",
returns = "()",
anchor = "frameworkhelpers",
},
vehicleAddWheel = {
type = "function",
description = "Fügt dem Fahrzeug ein Rad hinzu, dort, wo wheelNode relativ zum Chassis steht, wenn das Fahrzeug das nächste Mal gebaut wird. Die Federung hängt das Rad unbelastet suspension Einheiten unter diesen Punkt und federt bis auf die Hälfte davon ein. Von da an schreibt die Engine nach jedem Schritt die Welttransformation des Radknotens, mit X als Achse und Y oben, also gehört der sichtbare Reifen auf einen Kindknoten: ein um 90 Grad um Z gedrehter meshCylinder. Räder, die entlang der Front vor der durchschnittlichen Radposition liegen, zählen als Vorderräder: Sie lenken standardmäßig und haben keine Handbremse. Ein Panzer ordnet seine Räder der linken oder rechten Kette zu, je nachdem, auf welcher Seite des Chassis sie sitzen, und braucht mindestens eines auf jeder Seite. Werte unter 0.001 werden darauf angehoben. Beendet das Skript beim 17. Rad.\nRückgabe: Der Index des Rads, ab 0, für vehicleSetWheel, vehicleIsWheelOnGround und vehicleGetWheelSlip.\nSeit: 3.00.",
args = "(node, wheelNode, radius, width, suspension)",
returns = "(index)",
},
vehicleDelete = {
type = "function",
description = "Entfernt das Fahrzeug von seinem Chassis: den Rad-Constraint, die Fahrereingabe und die ganze Abstimmung. Der Körper bleibt ein gewöhnlicher dynamischer Körper, ein Wrack rutscht und überschlägt sich also weiter, und die Radknoten bleiben, wo der letzte Schritt sie hingestellt hat; nichts bewegt sie wieder, außer das Skript tut es. Ein Knoten ohne Fahrzeug beendet das Skript.\nSeit: 3.00.",
args = "(node)",
returns = "()",
},
vehicleDrive = {
type = "function",
description = "Setzt die Eingabe des Fahrers, die bis zum nächsten Aufruf gilt, ruf es also in jedem Frame aus onOverlayUpdate auf. Gas und Lenkung reichen von -1 bis 1, Bremse und Handbremse von 0 bis 1; Werte außerhalb werden begrenzt, und weggelassene Eingaben sind 0. Ein Auto oder Motorrad bekommt alle vier als Fahrereingabe von Jolt, wobei negatives Gas über den Rückwärtsgang zurücksetzt. Ein Panzer nimmt forward als sein Gas, und right bremst die innere Kette ab; ohne Gas laufen die Ketten gegeneinander, sodass sich der Rumpf auf der Stelle dreht, und die Handbremse wird ignoriert. Ein Boot nimmt forward als Gas des Propellers, right als Ruder und brake als Widerstand gegen die Geschwindigkeit des Rumpfs, ignoriert die Handbremse und tut gar nichts, solange der Propeller außerhalb des Wassers ist. Jede Eingabe ungleich null weckt ein Chassis, das eingeschlafen ist.\nSeit: 3.00.",
args = "(node, forward, right [, brake, handBrake])",
returns = "()",
},
vehicleGetGear = {
type = "function",
description = "Der Gang, den das Getriebe eingelegt hat: 0 im Leerlauf, -1 im Rückwärtsgang, ab 1 aufwärts für die Vorwärtsgänge in der Reihenfolge, in der vehicleSetGears sie angegeben hat. 0 für ein Boot und für ein Fahrzeug, das noch nicht gebaut wurde.\nRückgabe: Eine Ganzzahl.\nSeit: 3.00.",
args = "(node)",
returns = "(gear)",
},
vehicleGetRpm = {
type = "function",
description = "Die Drehzahl des Motors in Umdrehungen pro Minute, zwischen der Leerlaufdrehzahl und der Drehzahlgrenze aus vehicleSetEngine, für einen Drehzahlmesser oder die Tonhöhe einer Motorgeräuschschleife. 0 für ein Boot, das keinen Motor hat, und für ein Fahrzeug, das noch nicht gebaut wurde, weil ihm Räder fehlen.\nRückgabe: Eine Zahl.\nSeit: 3.00.",
args = "(node)",
returns = "(rpm)",
},
vehicleGetSpeed = {
type = "function",
description = "Die Geschwindigkeit des Chassis-Körpers entlang seiner Front, in Welteinheiten pro Sekunde, negativ, während er rückwärts fährt; seitliche Bewegung in einem Drift zählt nicht. Funktioniert für jede Art, Boote eingeschlossen, ab dem Moment, in dem vehicleNew aufgerufen wird.\nRückgabe: Eine Zahl.\nSeit: 3.00.",
args = "(node)",
returns = "(speed)",
},
vehicleGetWheelSlip = {
type = "function",
description = "Wie stark das Rad entlang seiner Rollrichtung durchdreht oder rutscht, von 0 haftend bis 1 durchdrehend oder blockiert, für Reifenquietschen, Rauch und Bremsspuren. Immer 0 für die Räder eines Panzers, für einen Index, für den das Fahrzeug kein Rad hat, und für ein Fahrzeug, das noch nicht gebaut wurde.\nRückgabe: Eine Zahl.\nSeit: 3.00.",
args = "(node, index)",
returns = "(slip)",
},
vehicleIsWheelOnGround = {
type = "function",
description = "Ob der Cast der Federung dieses Rads in diesem Schritt etwas gefunden hat, gegen das sie drücken kann. false für einen Index, für den das Fahrzeug kein Rad hat, und für ein Fahrzeug, das noch nicht gebaut wurde; in keinem der beiden Fälle wird ein Fehler ausgelöst.\nRückgabe: Wahr oder falsch.\nSeit: 3.00.",
args = "(node, index)",
returns = "(touching)",
},
vehicleNew = {
type = "function",
description = "Macht aus dem dynamischen Körper auf node das Chassis eines Fahrzeugs. Ein Auto, Motorrad oder Panzer braucht mindestens zwei Räder aus vehicleAddWheel, bevor der nächste Physikschritt es baut; ein Boot hat keine Räder und wird von einem Propeller geschoben, der nur unter einer mit bodySetWater gemachten Oberfläche wirkt. Das neue Fahrzeug beginnt mit den Standardwerten: ein Motor mit 500 Nm, der bei 6000 U/min sein Maximum erreicht und im Leerlauf mit 1000 dreht, das Fünfgang-Automatikgetriebe von Jolt, 35 Grad Lenkeinschlag, Bremsen mit 1500 Nm und eine Handbremse mit 4000 Nm, eine Federung mit 1,5 Hz bei 0,5 Dämpfung und keine Stabilisatoren. Ein erneuter Aufruf auf demselben Knoten verwirft zuerst das alte Fahrzeug und seine Räder. Beendet das Skript bei einer unbekannten Art, einem Knoten, dessen Körper nicht dynamisch ist, einer Art mit Rädern in einer 2D-Welt oder wenn schon 16 Fahrzeuge existieren.\nSeit: 3.00.",
args = "(node, kind)",
returns = "()",
},
vehicleSetAntiRoll = {
type = "function",
description = "Fügt an jeder Achse einen Stabilisator hinzu, in Newton pro Meter; 0 (Standard) baut keinen ein, und ein negativer Wert wird zu 0. Ein Stabilisator verbindet die beiden angetriebenen Räder einer Achse, eine Achse, deren Räder nicht angetrieben sind, bekommt also keinen, und ein Motorrad hat keinen. Ein paar Hundert halten ein Auto in Kurven flach; zu viel hebt die kurveninneren Räder an. Ein Panzer ignoriert den Aufruf. Wirkt beim Neuaufbau im nächsten Schritt.\nSeit: 3.00.",
args = "(node, stiffness)",
returns = "()",
},
vehicleSetBrakes = {
type = "function",
description = "Stellt das Bremsmoment ein, das jedes Rad bei voll getretenem Pedal aufbringen kann, Standard 1500 Newtonmeter, und das Moment der Handbremse an den Hinterrädern, Standard 4000; die Vorderräder, also die vor der durchschnittlichen Radposition, haben keine Handbremse. Negative Werte werden zu 0. Ein Panzer bremst seine Ketten mit den Kettenstandardwerten von Jolt und ignoriert den Aufruf, und ein Boot bremst durch einen Widerstand gegen seine eigene Geschwindigkeit, also ignoriert es den Aufruf ebenfalls. Wirkt beim Neuaufbau im nächsten Schritt.\nSeit: 3.00.",
args = "(node, brakeTorque, handBrakeTorque)",
returns = "()",
},
vehicleSetEngine = {
type = "function",
description = "Stellt den Motor ein: Spitzendrehmoment in Newtonmetern, die Drehzahlgrenze und die Leerlaufdrehzahl in Umdrehungen pro Minute. Die Standardwerte sind 500, 6000 und 1000, und die Leerlaufdrehzahl ist wieder 1000, wenn sie weggelassen wird. Das Drehmoment wird auf 1 oder mehr gehalten, die Drehzahlgrenze auf 100 oder mehr und die Leerlaufdrehzahl zwischen 1 und der Drehzahlgrenze. Ein Boot hat keinen Motor und ignoriert den Aufruf. Wirkt beim Neuaufbau im nächsten Schritt.\nSeit: 3.00.",
args = "(node, maxTorque, maxRpm [, minRpm])",
returns = "()",
},
vehicleSetGears = {
type = "function",
description = "Stellt das Getriebe ein: ein bis acht Vorwärtsübersetzungen, den ersten Gang zuerst, die Übersetzung des Rückwärtsgangs (Standard 2.9, als positive Zahl angegeben) und ob das Getriebe selbst schaltet (Standard true). Ein Fahrzeug, das diesen Aufruf nie bekommt, fährt mit dem Fünfganggetriebe von Jolt, 2.66, 1.78, 1.3, 1.0 und 0.74, mit demselben Rückwärtsgang. Ist automatic false, schaltet das Getriebe nicht mehr von selbst, und es gibt keinen Aufruf, um es aus dem Skript zu schalten. Ein Boot hat kein Getriebe und ignoriert den Aufruf. Wirkt beim Neuaufbau im nächsten Schritt. Beendet das Skript, wenn die Tabelle leer ist oder mehr als acht Übersetzungen enthält.\nSeit: 3.00.",
args = "(node, { ratio, ... } [, reverseRatio, automatic])",
returns = "()",
},
vehicleSetRudder = {
type = "function",
description = "Stellt das Ruder eines Boots ein: das Drehmoment um die Hochachse des Rumpfs bei voller Lenkeingabe, Standard 800 Newtonmeter. Das Ruder greift mit der Geschwindigkeit, ein Fünftel des Drehmoments im Stand und das volle ab 3 Welteinheiten pro Sekunde, und es dreht andersherum, während das Boot rückwärts fährt. Es wirkt nur, solange der Propellerpunkt unter Wasser ist. Ein negatives Drehmoment wird zu 0; Arten mit Rädern ignorieren den Aufruf.\nSeit: 3.00.",
args = "(node, maxTorque)",
returns = "()",
},
vehicleSetSteering = {
type = "function",
description = "Legt fest, wie weit die gelenkten Räder bei vollem Einschlag einschlagen, in Grad; Standard 35, begrenzt auf 0 bis 89. Eine Lenkeingabe von -1 oder 1 aus vehicleDrive erreicht diesen Winkel, kleinere Eingaben einen entsprechenden Anteil davon. Wirkt beim Neuaufbau im nächsten Schritt. Ein Panzer lenkt mit seinen Ketten und ein Boot mit seinem Ruder, also ignorieren beide den Aufruf.\nSeit: 3.00.",
args = "(node, maxDegrees)",
returns = "()",
},
vehicleSetSuspension = {
type = "function",
description = "Stellt die Feder jedes Rads ein: ihre Eigenfrequenz in Hertz (Standard 1.5, auf 0.1 oder mehr gehalten; höher ist härter) und ihren Dämpfungsgrad (Standard 0.5; 0 schwingt nach, 1 kommt ohne Überschwingen zur Ruhe). Wirkt beim Neuaufbau im nächsten Schritt, auf alle Räder gleichzeitig; eine Feder pro Rad gibt es nicht. Ein Boot hat keine Federung und ignoriert den Aufruf.\nSeit: 3.00.",
args = "(node, frequency, damping)",
returns = "()",
},
vehicleSetThrust = {
type = "function",
description = "Stellt den Propeller eines Boots ein: die Kraft, mit der er bei Vollgas schiebt, Standard 2000 Newton, und den Punkt im Bezugssystem des Rumpfs, an dem er schiebt, Standard 0, -0.2, 1, knapp unter Deck am Heck. Der Schub wirkt entlang der Front des Rumpfs und nur, solange dieser Punkt unter einer Wasseroberfläche ist; derselbe Punkt entscheidet, ob Ruder und Bremse wirken. Eine negative Kraft wird zu 0. Arten mit Rädern speichern die Werte und ignorieren sie.\nSeit: 3.00.",
args = "(node, maxForce, x, y, z)",
returns = "()",
},
vehicleSetWheel = {
type = "function",
description = "Legt fest, ob ein Rad mit der Lenkeingabe einschlägt und ob der Motor es antreibt, und ersetzt die Standardwerte für dieses Rad: Vorderräder lenken, und jedes Rad wird angetrieben außer dem vorderen eines Motorrads. Angetriebene Räder werden quer über das Chassis paarweise zu Differenzialen zusammengefasst, eines pro Achse, und das Drehmoment des Motors wird gleichmäßig auf die Achsen verteilt; ein angetriebenes Rad ohne Partner ist eine eigene Achse. Ein Panzer ignoriert beide Flags, da seine Ketten jedes Rad antreiben und den Rumpf drehen. Wirkt beim Neuaufbau im nächsten Schritt. Beendet das Skript bei einem Index, für den das Fahrzeug kein Rad hat.\nSeit: 3.00.",
args = "(node, index, steered, driven)",
returns = "()",
},
videoDraw = {
type = "function",
description = "videoDraw(id, x, y, x2, y2)\nvideoDraw(id, x, y, centered)\nBringt ein Video zu dem Frame, den seine Uhr verlangt, und zeichnet diesen Frame auf das Overlay. Die Uhr folgt dem Audio des Videos, wenn es welches hat, und sonst der realen Zeit, ein Aufruf kann also null, einen oder mehrere Frames weiterrücken; ein Video, das sein Ende erreicht, springt zu Frame 0 zurück. Die Form mit fünf Argumenten streckt den Frame in das Rechteck von (x, y) bis einschließlich (x2, y2), immer mit Nearest-Neighbor-Abtastung und ohne Rücksicht auf videoScale, videoRotate und videoQuality. Die Form mit vier Argumenten zeichnet den Frame in seiner nativen Größe, transformiert durch videoScale und videoRotate, verankert an seiner linken oberen Ecke oder, wenn centered true ist, an seiner Mitte; der transformierte Frame wird nur neu erzeugt, wenn sich der Frame oder die Transformation ändert, und gedrehte Ecken sind transparent. Hat der Decoder noch keinen Frame erzeugt, wird nichts gezeichnet.\nSeit: 2.00. Die skalierte/gedrehte Form mit dem Flag centered kam in 2.10 hinzu.",
args = "(id, x, y, x2, y2)",
returns = "()",
},
videoGetAudioTrack = {
type = "function",
description = "Gibt den nullbasierten Index der Tonspur zurück, die ein geladenes Video abspielt. videoLoad wählt die durch --audio oder den Eintrag AUDIO_TRACK in games.dat genannte Spur (Standard 0), sofern die Datei so viele Spuren hat; ein Video ganz ohne Audio meldet -1.\nRückgabe: ganzzahliger Spurindex.\nSeit: 2.10",
args = "(id)",
returns = "(integer)",
},
videoGetAudioTracks = {
type = "function",
description = "Gibt zurück, wie viele Audiostreams ein geladenes Video enthält. Ein stummer Clip meldet 0; sichere Schleifen und Modulo-Rechnungen dagegen ab.\nRückgabe: ganzzahlige Anzahl, 0 oder mehr.\nSeit: 2.10",
args = "(id)",
returns = "(integer)",
},
videoGetFrame = {
type = "function",
description = "Gibt den Frame zurück, auf dem ein geladenes Video steht, nullbasiert. Die Position ändert sich nur, während das Video läuft und gezeichnet wird, und springt auf 0 zurück, wenn der Clip von vorn beginnt. Vergleiche sie mit deinen eigenen Start- und Endmarken, um einen Abschnitt als Schleife zu spielen, oder mit videoGetFrameCount, um das Ende eines einmal abgespielten Clips zu erkennen.\nRückgabe: ganzzahlige Frame-Nummer.\nSeit: 2.00",
args = "(id)",
returns = "(integer)",
},
videoGetFrameCount = {
type = "function",
description = "Gibt die Gesamtzahl der Frames eines geladenen Videos zurück, gezählt aus der Frame-Tabelle der Datei, als sie indiziert wurde. Die Frames reichen von 0 bis count - 1. Verwende es für Fortschrittsbalken, um eine Schleife umlaufen zu lassen oder um zu erkennen, wann ein einmal abgespielter Clip fast fertig ist.\nRückgabe: ganzzahlige Anzahl der Frames.\nSeit: 2.00",
args = "(id)",
returns = "(integer)",
},
videoGetHeight = {
type = "function",
description = "Gibt die Höhe der Frames eines geladenen Videos in Pixeln zurück, die native Größe der Datei und nicht die Größe, in der es gezeichnet wird. Kombiniere es mit videoScale, um einen Clip unter Beibehaltung seines Seitenverhältnisses in einen Kasten einzupassen.\nRückgabe: ganzzahlige Höhe in Pixeln.\nSeit: 2.00",
args = "(id)",
returns = "(integer)",
},
videoGetLanguage = {
type = "function",
description = "Gibt das in der Datei gespeicherte Sprach-Tag für eine Tonspur eines geladenen Videos zurück. Das Tag ist ein dreibuchstabiger ISO-639-Code wie \"eng\" oder \"jpn\"; eine Spur ohne dreibuchstabiges Tag ergibt \"unk\". Eine Spur außerhalb von 0 bis videoGetAudioTracks(id) - 1 beendet das Skript.\nRückgabe: String mit dem Sprachcode.\nSeit: 2.10",
args = "(id, track)",
returns = "(string)",
},
videoGetLanguageDescription = {
type = "function",
description = "Schlägt den englischen Namen eines Sprachcodes nach. Anders als die übrigen video*-Funktionen nimmt sie kein Handle; sie ist ein reines Nachschlagen in einer Tabelle, das zweibuchstabige Codes nach ISO 639-1 und dreibuchstabige Codes nach ISO 639-2 (sowohl die T- als auch die B-Form) annimmt, verglichen ohne Rücksicht auf Groß- und Kleinschreibung. Unbekannte Codes, auch das \"unk\", das für Spuren ohne Tag zurückkommt, ergeben \"Unknown\". Framework.singe stellt sie zur Symmetrie mit der Disc-API auch als discGetLanguageDescription bereit.\nRückgabe: String mit dem Namen der Sprache oder \"Unknown\".\nSeit: 2.10",
args = "(code)",
returns = "(string)",
},
videoGetVolume = {
type = "function",
description = "Gibt die Stereolautstärke eines geladenen Videos als zwei Prozentwerte zurück. Ein frisch geladenes Video steht auf beiden Kanälen auf dem Pegel von --volume_nonvldp (Standard 100). Beachte, dass zwei Werte zurückkommen, der linke zuerst.\nRückgabe: zwei Ganzzahlen, links und rechts, jeweils 0 bis 100; oder ohne Argument eine Ganzzahl, 0 bis 64.\nSeit: 2.00, die Disc-Form ohne Argument 3.00",
args = "([id])",
returns = "(left, right)",
},
videoGetWidth = {
type = "function",
description = "Gibt die Breite der Frames eines geladenen Videos in Pixeln zurück, die native Größe der Datei und nicht die Größe, in der es gezeichnet wird.\nRückgabe: ganzzahlige Breite in Pixeln.\nSeit: 2.00",
args = "(id)",
returns = "(integer)",
},
videoIsPlaying = {
type = "function",
description = "Meldet, ob ein geladenes Video im Wiedergabezustand ist, also ob seit dem letzten videoPause videoPlay aufgerufen wurde. Auch ein laufendes Video rückt nur weiter, während es gezeichnet wird. Nach videoLoad beginnen Videos pausiert.\nRückgabe: Boolean.\nSeit: 2.00",
args = "(id)",
returns = "(boolean)",
},
videoLoad = {
type = "function",
description = "Öffnet eine Videodatei und gibt ihr Handle zurück. Jeder Container und jeder Codec, den das mitgelieferte FFmpeg dekodieren kann, wird angenommen. Die Engine erzeugt oder liest einen Frame-Index in einem Datenordner, der nach dem Ort des Videos unter Singes oberstem Datenordner benannt ist, das erste Laden einer großen Datei kann also einen Moment dauern; lässt sich dieser Ordner nicht anlegen, wird das Skript beendet. Das Video beginnt pausiert auf Frame 0, mit der Tonspur aus --audio oder dem Eintrag AUDIO_TRACK in games.dat (Standard 0), sofern die Datei so viele Spuren hat, und mit beiden Kanälen auf dem Pegel von --volume_nonvldp. Die Frames werden nach RGB dekodiert, damit sie auf das Overlay gezeichnet werden können.\nRückgabe: ganzzahliges Video-Handle.\nSeit: 2.00",
args = "(filename)",
returns = "(integer)",
},
videoPause = {
type = "function",
description = "Pausiert ein geladenes Video. Seine Uhr bleibt stehen, seine Tonspur pausiert, und videoDraw zeichnet weiter den Frame, auf dem es angehalten hat. Ein bereits pausiertes Video noch einmal zu pausieren schadet nicht.\nSeit: 2.00",
args = "(id)",
returns = "()",
},
videoPlay = {
type = "function",
description = "Startet ein geladenes Video ab seinem aktuellen Frame oder setzt es dort fort. Die Uhr wird bei diesem Frame neu gestartet, ein nach langer Pause fortgesetztes Video macht also dort weiter, wo es angehalten hat, statt nach vorn zu springen, und die Tonspur läuft mit ihm weiter. Das Video rückt nur weiter, während es mit videoDraw gezeichnet oder als Material verwendet wird.\nSeit: 2.00",
args = "(id)",
returns = "()",
},
videoQuality = {
type = "function",
description = "Wählt die Filterung, die verwendet wird, wenn die Form von videoDraw mit vier Argumenten das Video skaliert oder dreht. Jeder Wert ungleich null wählt RENDER_SMOOTH (bilinear), null wählt RENDER_PIXELATED (Nearest-Neighbor), den Standard. Eine Änderung markiert den transformierten Frame für die Neuerzeugung beim nächsten Zeichnen. Sie wirkt weder auf die gestreckte Form mit fünf Argumenten, die immer Nearest-Neighbor verwendet, noch auf ein nicht transformiertes Video.\nSeit: 2.10",
args = "(id, smooth)",
returns = "()",
},
videoRotate = {
type = "function",
description = "Setzt die Drehung, die die Form von videoDraw mit vier Argumenten anwendet, in Grad im Uhrzeigersinn, nach derselben Konvention wie spriteRotate. Der Winkel wird modulo 360 reduziert und behält sein Vorzeichen, 450 und 90 sind also gleich, und -90 dreht eine Vierteldrehung gegen den Uhrzeigersinn. Der mit videoScale gesetzte Maßstab bleibt erhalten. Gedreht wird um die Mitte des Frames, zeichne gedrehte Videos also mit centered auf true. Ein geänderter Winkel markiert den transformierten Frame für die Neuerzeugung beim nächsten Zeichnen.\nSeit: 2.10",
args = "(id, degrees)",
returns = "()",
},
videoRotateAndScale = {
type = "function",
description = "videoRotateAndScale(id, degrees, scale)\nvideoRotateAndScale(id, degrees, scaleX, scaleY)\nSetzt Drehung und Maßstab in einem Aufruf, nach denselben Regeln wie videoRotate und videoScale: Grad im Uhrzeigersinn, modulo 360 reduziert, und Maßstabsfaktoren, die größer als 0 sein müssen. Verwende es, wenn sich beides in jedem Frame ändert, damit der transformierte Frame einmal statt zweimal neu erzeugt wird.\nSeit: 2.10",
args = "(id, degrees, scale)",
returns = "()",
},
videoScale = {
type = "function",
description = "videoScale(id, scale)\nvideoScale(id, scaleX, scaleY)\nSetzt den Maßstab, den die Form von videoDraw mit vier Argumenten anwendet, als Faktor der nativen Größe; 1.0 ist unskaliert. Die mit videoRotate gesetzte Drehung bleibt erhalten. Ein geänderter Maßstab markiert den transformierten Frame für die Neuerzeugung beim nächsten Zeichnen. Faktoren von 0 oder weniger lassen sich nicht rendern und lassen die Engine beim nächsten videoDraw abbrechen, halte animierte Maßstäbe also über null. Die gestreckte Form von videoDraw mit fünf Argumenten ignoriert diese Einstellung.\nSeit: 2.10",
args = "(id, scale)",
returns = "()",
},
videoSeek = {
type = "function",
description = "Setzt ein geladenes Video auf frame und startet dort seine Uhr neu. Der Wiedergabe- oder Pausenzustand bleibt unverändert: ein laufendes Video macht beim nächsten Zeichnen ab dem neuen Frame weiter, ein pausiertes zeigt ihn. Die Frame-Nummer wird modulo der Anzahl der Frames umgebrochen, -1 ist also der letzte Frame, und ein Wert hinter dem Ende landet wieder innerhalb des Clips.\nSeit: 2.00",
args = "(id, frame)",
returns = "()",
},
videoSetAudioTrack = {
type = "function",
description = "Schaltet ein geladenes Video auf eine andere seiner Tonspuren um. Bereits eingereihtes Audio der alten Spur wird verworfen, und die Wiedergabe richtet sich neu aus, die Änderung ist also fast sofort zu hören. Die bereits verwendete Spur zu wählen tut nichts. Eine Spur außerhalb von 0 bis videoGetAudioTracks(id) - 1 beendet das Skript, was bei einem stummen Clip jeden beliebigen Wert bedeutet.\nSeit: 2.10",
args = "(id, track)",
returns = "()",
},
videoSetVolume = {
type = "function",
description = "videoSetVolume(id, left, right)\nvideoSetVolume(volume)\nSetzt die Stereolautstärke eines geladenen Videos als Prozentwerte. Die Werte werden kommentarlos auf 0 bis 100 begrenzt. Die Einstellung wird auch bei einem stummen Clip gemerkt und von videoGetVolume zurückgemeldet.\nSeit: 2.00",
args = "(id, left, right)",
returns = "()",
},
videoUnload = {
type = "function",
description = "Hält den Decoder an und gibt alles frei, was ein geladenes Video belegt: Decoder, Tonspur, zwischengespeicherte Frames und die transformierte Fläche. Das Handle ist danach ungültig, und es an irgendeine video*-Funktion zu übergeben beendet das Skript, leere also die Variable, die es enthielt. Videos, die beim Ende des Skripts noch geladen sind, gibt die Engine frei.\nSeit: 2.00",
args = "(id)",
returns = "()",
},
viewDelete = {
type = "function",
description = "Gibt die Ansicht und ihre Texturen frei und beendet den zusätzlichen Render-Durchgang, den sie gekostet hat. Materialien, die sie zeigen, kehren zu ihrer eigenen Textur zurück. Das Handle ist danach ungültig und beendet das Skript, wenn es wieder verwendet wird; da es nur vier Ansichten gleichzeitig gibt, lösche die, die ein Level nicht mehr braucht.\nSeit: 3.00.",
args = "(view)",
returns = "()",
},
viewNew = {
type = "function",
description = "Erzeugt eine Kamera, die in jedem Frame in eine Textur von width mal height gerendert wird (jeweils auf 1 bis 4096 begrenzt), aus der Standardansicht, bis viewSetCamera einen Knoten nennt, und gibt das Ansicht-Handle für materialSetView zurück. Die Ansicht verwendet die Projektion aus cameraSetPerspective oder cameraSetOrthographic in ihrem eigenen Seitenverhältnis. Die Szene rendert pro Ansicht einmal mehr, also reichen 512 mal 384 für einen Monitor völlig, und ein Raspberry Pi will es kleiner. Beendet das Skript, wenn 3D nicht verfügbar ist oder schon vier Ansichten in Gebrauch sind.\nRückgabe: Das Ansicht-Handle, eine Ganzzahl.\nSeit: 3.00.",
args = "(width, height)",
returns = "(view)",
},
viewSetCamera = {
type = "function",
description = "viewSetCamera(view, node)\nviewSetCamera(view, nil)\nviewSetCamera(view)\nDer Knoten, von dem aus die Ansicht schaut, entlang seiner eigenen -Z-Achse wie die Hauptkamera, also zählt die Bewegung seiner Elternknoten. Mit nil oder ohne zweites Argument kehrt die Ansicht zur Standardansicht von (0, 0, 5) mit Blick auf den Ursprung zurück. Hänge den Knoten für einen Rückspiegel an ein Auto, oder spiegle die Position der Hauptkamera an einer Wand für einen Spiegel darin. Beendet das Skript bei einem Knoten-Handle, das nicht gültig ist.\nSeit: 3.00.",
args = "(view, node)",
returns = "()",
},
vldpFlash = {
type = "function",
description = "Hypseus-Erweiterung. Legt ein weißes Bild auf die Disc, so wie ein echter Laserdisc-Player aufblitzt, wenn er sucht. Es erscheint sofort, und die nächste Aktualisierung der Disc nimmt es wieder weg, es hält also einen gezeichneten Frame lang, ob die Disc läuft, pausiert oder gestoppt ist.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "()",
},
vldpFocusArea = {
type = "function",
description = "Hypseus-Erweiterung. Zeigt nur ein Rechteck des Disc-Frames, angegeben in Disc-Pixeln, gestreckt auf den Raum, den sonst der ganze Frame füllt, mit der üblichen weichen Skalierung des Renderers; das Seitenverhältnis folgt dem, was width und height ergeben. Das Rechteck wird innerhalb des Frames gehalten, und eines, das ganz außerhalb liegt, bricht das Skript ab. Ohne Argumente wird wieder der ganze Frame gezeigt (Hypseus ignoriert diesen Aufruf und verwendet vldpResetFocus; Singe nimmt beides an). Der Fokus ist nur ein Anzeigeeffekt: vldpGetPixel, vldpGetYUVPixel, die Mauszuordnung und die Disc auf einem 3D-Material behalten alle die ungezoomten Koordinaten, Treffererkennung auf einem gezoomten Bild muss der Aufrufer also selbst skalieren. Ohne Disc tut der Aufruf nichts. Wird zurückgesetzt, wenn das Skript neu geladen wird.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "([x, y, width, height])",
returns = "()",
},
vldpGetHeight = {
type = "function",
description = "Gibt die Höhe des Disc-Videos in Pixeln zurück oder ohne Disc die Höhe der Zeichenfläche. Das ist dieselbe Bindung wie discGetHeight, registriert unter ihrem Namen aus der Zeit vor 2.00.\nRückgabe: ganzzahlige Höhe in Pixeln.\nSeit: 1.x",
args = "()",
returns = "(integer)",
},
vldpGetPixel = {
type = "function",
description = "Liest die Farbe eines Pixels des Disc-Frames, der gerade auf dem Bildschirm ist. Die Koordinaten sind Overlay-Koordinaten: Die Engine teilt sie durch den Maßstab von Overlay zu Video und schneidet die Nachkommastellen ab, du übergibst also dieselben Zahlen, mit denen du zeichnest. Gibt 0, 0, 0 zurück, wenn es keine Disc gibt, wenn noch kein Frame dekodiert wurde oder wenn die skalierten Koordinaten außerhalb des Videos liegen. Spiele, die es verwenden, markieren Ziele im Quellmaterial typischerweise mit einer markanten Farbe und prüfen beim Betätigen des Abzugs das Pixel unter dem Fadenkreuz, statt für jeden Frame Trefferzonen anzulegen.\nRückgabe: drei Ganzzahlen, Rot, Grün und Blau, jeweils 0 bis 255.\nSeit: 1.x",
args = "(x, y)",
returns = "(r, g, b)",
},
vldpGetRotate = {
type = "function",
description = "Hypseus-Erweiterung. Gibt die Drehung der Darstellung in Grad im Uhrzeigersinn zurück: die Option --rotate oder das, was vldpSetRotate zuletzt gesetzt hat, und 0, wenn keins von beiden. Zurückgegeben werden immer nur 0, 90, 180 und 270, denn das sind die einzigen Winkel, in die Singe dreht.\nRückgabe: Ganzzahl, 0, 90, 180 oder 270.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "(integer)",
},
vldpGetScale = {
type = "function",
description = "Hypseus-Erweiterung. Gibt den Skalierungsfaktor der Anzeige als Prozentwert zurück: die Option --scalefactor oder das, was vldpSetScale zuletzt angewendet hat, und 100, wenn keins von beiden angegeben wurde. Hypseus-Spiele teilen 100 durch ihn, um die Geometrie ihres Overlays an das verkleinerte Bild anzupassen. Er hat nichts mit vldpFocusArea oder der Overlay-Auflösung zu tun.\nRückgabe: Ganzzahl, 25 bis 100.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "(integer)",
},
vldpGetShift = {
type = "function",
description = "Der Versatz des Bildes innerhalb des Fensters als Prozentwerte, die Optionen --shiftx und --shifty oder das, was vldpSetShift zuletzt angewendet hat, und 0, 0, wenn keins von beiden angegeben wurde. Im Extremfall füllt eine Verschiebung genau den Platz, den --scalefactor übrig gelassen hat, 100 bei einem Maßstab von 100 bewegt also nichts.\nRückgabe: zwei Ganzzahlen, jeweils -100 bis 100.\nSeit: 3.00.",
args = "()",
returns = "(x, y)",
},
vldpGetWidth = {
type = "function",
description = "Gibt die Breite des Disc-Videos in Pixeln zurück oder ohne Disc die Breite der Zeichenfläche. Das ist dieselbe Bindung wie discGetWidth, registriert unter ihrem Namen aus der Zeit vor 2.00.\nRückgabe: ganzzahlige Breite in Pixeln.\nSeit: 1.x",
args = "()",
returns = "(integer)",
},
vldpGetYUVPixel = {
type = "function",
description = "Hypseus-Erweiterung. Liest die rohen Abtastwerte eines Pixels des gerade gezeigten Disc-Frames, vor jeder Farbumrechnung: den Luma-Wert und die zwei Chroma-Werte, jeweils 0 bis 255, mit Chroma in der 4:2:0-Auflösung des dekodierten Bildes (neutral ist 128). Die Koordinaten sind Overlay-Koordinaten, skaliert und abgeschnitten genau wie bei vldpGetPixel. Gibt -1, -1, -1 zurück, wenn es keine Disc gibt, wenn noch kein Frame dekodiert wurde oder wenn die skalierten Koordinaten außerhalb des Videos liegen. Unbeeinflusst von vldpFocusArea und vldpSetMonochrome. Günstiger als vldpGetPixel, wenn nur die Helligkeit zählt.\nRückgabe: drei Ganzzahlen, Y, U und V, jeweils 0 bis 255, oder -1, -1, -1.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(x, y)",
returns = "(y, u, v)",
},
vldpResetFocus = {
type = "function",
description = "Hypseus-Erweiterung. Zeigt nach vldpFocusArea wieder den ganzen Disc-Frame, genau wie vldpFocusArea() ohne Argumente. Der eigene Name von Hypseus für das Zurücksetzen, erhalten, damit seine Spiele unverändert laufen.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "()",
returns = "()",
},
vldpSetBlend = {
type = "function",
description = "Hypseus-Erweiterung. Glättet das Disc-Bild von Zeile zu Zeile: Jeder Luma-Wert wird zum Mittelwert aus sich selbst und den Werten direkt darüber und darunter. Das ist der eigene Drei-Tap-Blendfilter von Hypseus, und es gibt ihn, um einer Überspielung im Zeilensprungverfahren die harten Kanten zu nehmen, ohne das Bild seitlich weicher zu machen.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled)",
returns = "()",
},
vldpSetLuma = {
type = "function",
description = "Hypseus-Erweiterung. Macht das Disc-Bild heller oder dunkler. level reicht von 0 bis 8, und 4, der Standard, ändert nichts: Der Abstand zu 4 wird in Achteln zu jedem Luma-Wert addiert, 0 halbiert also die Helligkeit, 8 hebt sie um die Hälfte an, und die Stufen dazwischen sind gleichmäßig. Eine Stufe außerhalb von 0 bis 8 beendet das Skript.\nRückgabe: nichts.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled [, level])",
returns = "()",
},
vldpSetMonochrome = {
type = "function",
description = "Hypseus-Erweiterung. Zeigt die Disc nur in Luma: Die Chroma-Ebenen werden beim Hochladen jedes Frames durch neutrale Werte ersetzt, eine pausierte Disc ändert sich also sofort. Mit einer Frame-Datei folgt die Einstellung der Wiedergabe von Segment zu Segment. vldpGetPixel und vldpGetYUVPixel geben weiterhin die Farbwerte zurück, und zusätzliche, mit videoDraw gezeichnete Videos sind nicht betroffen. Kombiniere es mit overlaySetMonochrome für einen Schwarzweißmodus. Ohne Disc tut der Aufruf nichts; wird zurückgesetzt, wenn das Skript neu geladen wird. Ein Argument, das kein Boolean ist, bricht das Skript ab.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(enabled)",
returns = "()",
},
vldpSetRotate = {
type = "function",
description = "Hypseus-Erweiterung. Dreht die ganze Darstellung im Uhrzeigersinn: Disc, Overlay, GUIs, 3D-Szene und Partikel drehen sich alle zusammen, und Maus- und Lightgun-Positionen werden zurückgedreht, sodass ein Klick weiterhin dort landet, wo gezeichnet wird. Eine Vierteldrehung vertauscht die Form der dargestellten Fläche, sodass ein Hochformatfenster ausgefüllt wird, statt das Bild mit Letterbox in einen Streifen zu setzen.\nRückgabe: Boolean, true, wenn die Drehung angewendet wurde.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(degrees: integer)",
returns = "(boolean)",
},
vldpSetScale = {
type = "function",
description = "Hypseus-Erweiterung. Verkleinert das Bild um seine Mitte auf percent des Fensters, das Gegenstück zu --scalefactor zur Laufzeit, und baut das Videorechteck neu auf, sodass Disc, Overlay, GUIs, 3D-Szene, Partikel, ein etwaiger Sinden-Rahmen und die Mauszuordnung ihm alle folgen. Werte außerhalb von 25 bis 100 ergeben false und ändern nichts, statt das Skript zu beenden.\nRückgabe: Boolean, true, wenn der Maßstab angewendet wurde.\nSeit: 3.00, als Erweiterung von Hypseus Singe.",
args = "(percent: integer)",
returns = "(boolean)",
},
vldpSetShift = {
type = "function",
description = "Verschiebt das Bild innerhalb des Fensters, das Gegenstück zu --shiftx und --shifty zur Laufzeit, und baut das Videorechteck neu auf, sodass Disc, Overlay, GUIs, 3D-Szene, Partikel, ein etwaiger Sinden-Rahmen und die Mauszuordnung ihm alle folgen. Die Werte sind Prozentwerte des Platzes, den --scalefactor übrig gelassen hat, bei einem Maßstab von 100 gibt es also nichts, wohin es sich bewegen könnte. Ein Wert außerhalb von -100 bis 100 beendet das Skript, anders als bei vldpSetScale, das false ergibt.\nRückgabe: nichts.\nSeit: 3.00.",
args = "(x: integer, y: integer)",
returns = "()",
},
vldpSetVerbose = {
type = "function",
description = "Tut nichts. Früher schaltete es die Protokollierung im ursprünglichen Videoplayer um; der Aufruf nimmt beliebige Argumente an, schreibt eine Trace-Zeile und kehrt zurück. Das Tracing von Engine und Skript läuft jetzt über Befehlszeilenoptionen (--program und --trace).\nSeit: 1.x",
args = "(...)",
returns = "()",
},
voiceFree = {
type = "function",
description = "Gibt einen Opus-Encoder oder -Decoder, einen Sprachprozessor oder einen Jitter-Buffer frei.\nSeit: 3.00.",
args = "(handle)",
returns = "()",
},
voiceProcess = {
type = "function",
description = "Ein Frame vom Mikrofon, gereinigt: das Echo dessen, was die Lautsprecher spielten, herausgenommen, Hintergrundgeräusche unterdrückt und der Pegel ausgeglichen.\nRückgabe: der gereinigte Frame und true, wenn er wie eine Stimme klingt -- so sendet man nichts, solange niemand spricht.\nSeit: 3.00.",
args = "(processor, mic [, speaker])",
returns = "(cleaned, voiced)",
},
voiceProcessorNew = {
type = "function",
description = "Rückgabe: das Handle des Prozessors.\nSeit: 3.00.",
args = "([frame [, rate [, tailMs]]])",
returns = "(processor)",
},
}