Ir al contenido

Sintaxis

El documento es una lista de pilas. Cada pila es una baldosa, y dentro van sus wireds de abajo arriba, en el mismo orden en el que están apilados en la sala.

// Sala 4021 · 3/1/2025, 10:15:32
// Esta vista es la sala completa: los wireds como bloques y el resto
// de furnis de suelo como `furni`. Los de pared no aparecen.
// Quitar un bloque o una línea `furni` = recogerlo al inventario.
// Cambiar su pila = moverlo. Cambiar `z` = cambiar su altura (:setz).
stack (3, 1) {
trigger.says #48211 {
text = "abre"
only_owner = true
match_type = any
}
effect.teleport_to #48212 {
furni_source = triggering
user_source = signal
furnis = [ #48360, #48361 ]
delay = 5
}
condition.has_furni_on #48213 {
matching = all
furnis = [ #48301, #48302 ]
furni_source = triggering
}
}
stack (4, 1) {
trigger.periodically #48220 {
time = 5
}
effect.show_message #48221 {
user_source = signal
message = "[b]Bienvenido[/b]"
visibility = whole_room
notification_style = blue
delay = 9
}
}

Eso de arriba es literalmente lo que escribe el editor al volcar una sala: nada está abreviado.

stack (x, y) { …wireds… }

x e y son la baldosa. La llave { va en la misma línea que la cabecera: el analizador no admite un salto de línea entre stack (3, 1) y su {.

La posición no es solo informativa: si el bloque tiene #id y lo pones bajo una stack (x, y) distinta de la que trae de la sala, al aplicar se mueve ahí — ver Crear, borrar y mover.

familia.nombre [etiqueta] [#id] { …campos… }
Parte Obligatoria Qué es
familia sí trigger, effect, condition, selector, extra o variable
nombre sí El nombre del wired dentro de su familia (says, teleport_to…)
etiqueta no Cómo referenciar este wired desde otro bloque, sin usar su #id — ver Etiquetas
#id no El id del furni en la sala. Sin él, el bloque es un wired nuevo — ver Crear, borrar y mover
{ … } sí Los campos, o vacío

familia.nombre no te lo inventas: sale del esquema del editor, y la lista completa está en la Referencia. Un familia.nombre que no exista es un error.

No hay nada más en la cabecera: detrás de familia.nombre (y del #id, si lo hay) solo puede venir {. Escribir cualquier otra cosa ahí, como una cadena entre comillas, es un error de sintaxis — ver Editar y aplicar.

Un wired sin campos que cambiar se escribe con las llaves vacías:

extra.exec_in_order #48232 {
}

La vista es la sala completa: junto a los wireds (que salen como bloques), una pila también declara los furnis que no son wired (baldosas, puertas, tapices…) para poder referenciarlos desde un campo y para poder editarlos igual que con el ratón:

furni <etiqueta> "classname" [#id] [{ z = N, rot = N }]

Al volcar la sala, el editor escribe todos los furnis de suelo de la sala: los wireds con ventana como bloques (lo de siempre) y todo lo demás —furni normal, tablones y cualquier wired sin ventana— como línea furni. Los furnis de pared no aparecen.

Parte Obligatoria Qué es
etiqueta sí Cómo referenciar este furni desde otro campo — ver Etiquetas
"classname" sí El nombre interno del furni, entre comillas
#id no El id del furni en la sala. Sin él, es un furni nuevo que se compra y se coloca — ver Furnis normales
z = N no (el volcado lo escribe siempre) La altura, entera y en centésimas (250 = 2,50), de -4000 a 8000 — sí, admite negativos: hundir un furni bajo el suelo se escribe z = -50. En un furni nuevo, si no la escribes, se apoya encima de lo que haya en la casilla; en uno existente, cambiarla cambia su altura, como :setz — ver Furnis normales
rot = N no (el volcado lo escribe siempre) La rotación como índice, contando desde 0 entre las posiciones que admite ese furni: el mismo número que enseña el infostand y que da @rotation. Un furni con dos posiciones solo acepta 0 y 1. Si no lo escribes, un furni nuevo sale con 0 y uno existente conserva la suya; cambiarlo en un furni existente lo rota — ver Furnis normales
stack (2, 1) {
furni tile1 "dice_wired_grey" #48300 { z = 250, rot = 0 }
}

Una línea furni no es un wired: no tiene familia ni ventana propia, así que no lleva más campos que z y rot. Es la misma línea tanto si declaras un furni para referenciarlo desde otro campo como si lo estás editando (moviéndolo, subiéndolo, rotándolo o recogiéndolo) — ver Crear, borrar y mover.

Es siempre un furni de suelo: los furnis de pared no se pueden declarar así, y por tanto tampoco se pueden referenciar por #id — ver Crear, borrar y mover.

La altura (z) no es un dato suelto: la compara condition.has_altitude, decide cómo se apilan unos furnis encima de otros y la usan los proyectiles para saber a qué altura impactan — por eso el documento la enseña y la deja cambiar, como si fuera :setz a mano.

Una antena (ver Señales y pilas remotas) puede ser cualquier furni, pero usa siempre una Antena Wired (wf_antenna1 o wf_antenna2); no tiene ventana, así que se declara con una línea furni y el Recibir Señal la referencia en furnis:

stack (1, 1) {
furni ant "wf_antenna1" #48400
}
stack (5, 1) {
trigger.recv_signal #48410 {
furnis = [ ant ]
}
effect.show_message #48411 {
message = "ha llegado la señal"
user_source = signal
}
}

El Enviar Señal marca sus antenas en el campo antennas, que es una lista como furnis: admite #id y etiquetas, y la antena puede ser un furni nuevo del mismo documento (se resuelve al crearlo, como cualquier etiqueta):

stack (1, 1) {
furni ant "wf_antenna1"
}
stack (3, 1) {
trigger.says {
text = "dispara"
}
effect.send_signal {
antenna_source = selected
users_to_advance = triggering
antennas = [ ant ]
}
}
stack (5, 1) {
trigger.recv_signal {
furnis = [ ant ]
}
effect.show_message {
message = "ha llegado la señal"
user_source = signal
}
}

antenna_source = selected es lo que hace que el envío use las antenas de antennas; con triggering, selector o signal la antena sale de la pila y el campo sobra. Como antena vale cualquier furni —la señal se empareja por el furni concreto, no por su tipo—, pero usa siempre wf_antenna1 o wf_antenna2 (ver La antena).

Nueve wireds tienen dos listas de furnis marcadas a mano en vez de una: el conjunto A (la fuente selected / primary_selection) y el conjunto B (secondary_selection). En el DSL son dos campos de tipo lista, los dos opcionales (omitidos = vacíos):

Wired Conjunto A Conjunto B
effect.send_signal, effect.neg_send_signal antennas secondary_furnis
effect.change_var furnis secondary_furnis
effect.furni_to_furni furnis secondary_furnis
effect.modify_highscore furnis secondary_furnis
condition.var_val_match furnis secondary_furnis
condition.stuff_is, condition.not_stuff_is furnis secondary_furnis
extra.mov_physics furnis secondary_furnis
effect.furni_to_furni {
moved_furni_source = selected // mueve el conjunto A…
target_furni_source = secondary_selection // …hasta el conjunto B
furnis = [ caja1, caja2 ]
secondary_furnis = [ destino ]
}

Una etiqueta identifica un bloque —furni o wired— dentro del documento, para referenciarlo desde un campo sin usar su #id:

furnis = [ tile1, #48360 ]
  • Es un identificador ([A-Za-z_][A-Za-z0-9_]*), único en todo el documento.
  • No puede llamarse stack, furni, true, false, ni como ninguna familia (trigger, effect, condition, selector, extra, variable).
  • La lleva siempre un furni; un wired solo si algún otro bloque lo va a referenciar.
  • Dentro de una lista [ … ] de furnis se pueden mezclar etiquetas y #id libremente.
  • Es solo texto del documento, no algo que guarde el servidor: puedes renombrarla sin más. Cambia su nombre y el de todas las referencias que la usan.

Al volcar la sala, el editor genera una etiqueta para cada furni normal (todos llevan línea furni) y para cada wired que otro wired referencia:

  • Furnis: el classname saneado a identificador (_ en vez de lo que no sea letra, dígito o _; si empezara por dígito, f_ delante) y, si se repite en el documento, _2, _3… — tile_dark, tile_dark_2.
  • Wireds: el nombre del wired seguido de _N, empezando siempre en _1 — periodically_1, periodically_2…

Un wired que ningún otro bloque referencia sale sin etiqueta.

Mensaje Cuándo
etiqueta repetida 'x' (línea L) Dos bloques del documento (furni o wired) usan la misma etiqueta. Sale en el segundo
'furnis': etiqueta desconocida 'x' Un campo referencia una etiqueta que ningún bloque del documento declara

Una baldosa declarada y un wired que la usa como fuente:

stack (2, 1) {
furni tile1 "dice_wired_grey" #48300
}
stack (3, 1) {
condition.has_furni_on #48213 {
matching = all
furnis = [ tile1 ]
furni_source = triggering
}
}
nombre = valor

Se separan por salto de línea o por coma. Las dos formas valen y se pueden mezclar:

trigger.says #48211 { text = "abre", only_owner = true }

Dos reglas que ahorran disgustos:

  • Un campo que no escribes vale su valor por defecto. Por eso el editor omite al volcar todo lo que esté en su defecto: lo que ves escrito es lo que está cambiado. La columna «Por defecto» de la referencia dice cuál es en cada caso.
  • Un campo que ese wired no tiene es un error. No se ignora en silencio.
Tipo Se escribe Ejemplo
bool true / false only_owner = true
int un entero, con signo si hace falta delay = 5, offset = -3
enum el nombre del valor, sin comillas furni_source = triggering
string entre comillas dobles text = "abre"
raw_string igual que string, pero su contenido tiene formato interno raw = "a\tb\tc"
ids lista de referencias a furni furnis = [ #48360, #48361 ]
variable el nombre de la variable, entre comillas variable = "puntos"

El nombre es lo normal, pero también se acepta el entero suelto. Sirve para los valores que la ventana ya no ofrece y que aún viven en wireds antiguos; el editor los vuelca así, con un comentario:

mode = 7 // sin nombre en el enumerado

Los nombres y sus números están en la referencia, wired a wired.

Van entre corchetes, con comas, y pueden ocupar varias líneas:

furnis = [
#48360,
#48361
]

Una lista vacía es []. Las de ids llevan # delante de cada número o una etiqueta. Los wireds con dos conjuntos manuales (antenas, furnis y secondary_furnis) usan dos listas de este tipo — ver Los dos conjuntos manuales.

Un #id dentro de una lista tiene que ser un furni que esté en la sala — salvo que ya estuviera así en el volcado, que entonces se respeta tal cual (un furni recogido hace tiempo no puede impedirte guardar el resto).

Las de ids también aceptan etiquetas del documento, mezcladas con #id en la misma lista: furnis = [ tile1, #48361 ] — ver Etiquetas.

Se escriben por su nombre:

effect.change_var #48230 {
variable = "puntos"
var_target = 2
operation = add
reference_variable = "puntos"
reference_var_target = 3
use_reference = true
delay = 4
}

Dos casos en los que el editor escribe la id en vez del nombre, con un comentario:

variable = "~113" // sin resolver
variable = "~113" // nombre ambiguo
  • sin resolver: la sala no tiene (ya) ninguna caja con esa id. Se conserva tal cual.
  • nombre ambiguo: hay dos o más variables con ese mismo nombre y el wired no dice de cuál habla (la misma caja replicada en dos furnis, por ejemplo). Escribir el nombre reapuntaría el wired a otra variable sin avisar, así que se escribe la id, que sí es única. Si escribes tú el nombre ambiguo, el editor te lo dice y te ofrece las ids entre las que elegir.

Las internas repetidas se resuelven solas por el ámbito. @position.x, @position.y, @altitude y @type existen dos veces, una de furni y otra de usuario, con la misma palabra. No hace falta escribir ids: el editor mira qué portador pide el wired —el fijo del wired, como en los selectores por variable, o el que tú pongas en su campo de ámbito (scope, reference_scope…)— y se queda con la variable de ese portador:

selector.filter_furni_by_var {
variable = "@position.y" // selector de furnis → la @position.y de furni
amount = 1
}
effect.change_var {
variable = "@position.y" // scope = user → la @position.y de usuario
scope = user
operation = assign
literal_value = 3
}

Solo si ni así queda una sola candidata verás el aviso de nombre ambiguo. Escribir la id a mano para esquivarlo es la forma más fácil de acertar la del portador equivocado: un selector de furnis con la variable de usuario no filtra nada y no avisa.

De // hasta el final de la línea. Se pueden poner en cualquier sitio y el editor los ignora del todo: no se guardan. Al recargar, el documento vuelve a salir del servidor y tus comentarios desaparecen.

// Pila de la puerta
stack (3, 1) {
trigger.says #48211 { text = "abre" } // la contraseña
}

El editor sí escribe comentarios propios al volcar: la cabecera con la sala y la fecha, las notas de los campos de solo lectura, y el aviso de un wired que no conoce.

Escape Es
\" comilla doble
\\ barra invertida
\n salto de línea
\t tabulador
\r retorno de carro

El tabulador importa más de lo que parece: es el separador interno de varios wireds (los diálogos de bot, la ropa de bot, los premios…), así que verás cadenas como "Hola\tAdiós\tHasta luego".

Cualquier otra barra invertida se come a sí misma y deja pasar el carácter tal cual: "\x" es x, y "C:\ruta" acaba siendo C:ruta. No es un error, no avisa. Si quieres una barra invertida de verdad, escríbela doble: "C:\\ruta".

Una cadena no puede contener un salto de línea de verdad: se escribe \n. Si te dejas la comilla de cierre, el editor lo marca como Cadena sin cerrar.

El caso típico es la tabla del Conector de texto: en su ventana escribes una pareja por línea, pero en Wired Code esas líneas van en una sola cadena, separadas por los dos caracteres \n (barra invertida y ene), nunca por un salto de línea de verdad:

extra.var_text_connector {
table = "1=rojo\n2=naranja\n3=amarillo\n4=verde"
}

Así NO, aunque sea lo que ves en la ventana del conector — cada pareja en su propia línea dentro de las comillas da Cadena sin cerrar en cascada:

extra.var_text_connector {
table = "1=rojo
2=naranja"
}

Algunos wireds reciben del servidor un valor calculado que la ventana solo enseña y que no se devuelve al guardar. El editor los escribe marcados:

variable.room #48240 {
availability = permanent
current_value = 137 // solo lectura
}

Puedes cambiar el número: no pasará nada. Al aplicar, ese hueco no viaja.

Todos los nombres —familias, wireds, campos y valores de enumerado— van en inglés y en snake_case, y solo admiten letras minúsculas, dígitos y _. Es el mismo vocabulario que la referencia, y no cambia con el idioma del cliente.