El Bloque Programable lleva en tu menú G desde que lo desbloqueaste, y seguramente hayas sacado la misma conclusión que saca todo el mundo: automatizar una estación en Space Engineers significa aprender C#. La propia documentación del juego opina lo contrario, y lo hace con una franqueza poco habitual. La página del Bloque Programable en la wiki oficial incluye un apartado titulado «When NOT to use PBs?» que te dice que compruebes primero si un Autopiloto, un Controlador de Eventos o un Automaton pueden hacer el trabajo de una forma más sencilla, y califica al Bloque Programable de excesivo cuando la velocidad de milisegundos y el ajuste preciso de valores no son esenciales.
No es falsa modestia de un desarrollador que esconde una función difícil. En abril de 2023, la actualización 1.202 «Automatons» añadió el Controlador de Eventos: un añadido gratuito, vanilla y de un solo cubo que Keen Software House construyó, en sus propias palabras, como un bloque fácil de usar y fácil de entender, y al que la wiki oficial atribuye el haber expuesto una gran cantidad de funcionalidad al juego vanilla que antes solo era accesible mediante scripting y modding. Funciona en Xbox y PlayStation, donde los scripts in-game nunca han funcionado y siguen sin hacerlo.
Así que el sistema lógico de Space Engineers es una escalera, no un muro. Los Bloques de Temporizador reproducen un conjunto guardado de acciones cuando se lo pides. Los Controladores de Eventos le dan a una cuadrícula sentidos sobre su propio estado y se ramifican según lo que encuentran. Los Bloques Programables añaden computación arbitraria en C# por encima de ambos. Cada escalón supera un techo que el de abajo no puede superar, y la tarea que de verdad quieres automatizar —la esclusa que abres a mano cada sesión, los reactores que enciendes cuando las baterías flaquean, el dron que desacoplas manualmente porque la secuencia nunca acaba de funcionar— casi con toda seguridad vive más abajo en esa escalera de lo que crees. Lo que viene a continuación es cómo funciona cada escalón, dónde se rompe cada uno y cómo saber cuál necesita tu tarea antes de perder una noche en el equivocado.
Todos los bloques de lógica de Space Engineers hacen una sola cosa: pulsar los botones de tu barra de herramientas
Antes de que esa escalera pueda ayudarte, los escalones tienen que dejar de parecer cuatro tecnologías sin relación entre sí. Quita las interfaces y todos los bloques de lógica del juego están haciendo una cosa pequeña: pulsar botones que podrías haber pulsado tú.
Eso es una regla, no una metáfora. La definición que da la wiki de lo que un Bloque de Temporizador, un Sensor o un Controlador de Eventos tiene permitido activar es exacta: tiene que ser una acción disponible en la barra de herramientas de un bloque de la misma cuadrícula, o de una cuadrícula conectada a ella. Es el mismo menú que obtienes cuando arrastras un bloque a una ranura de la barra de herramientas de tu cabina, y varía según el bloque: Open y Close en una puerta, Lock y Unlock en un conector, On y Off en una luz, Stockpile en un tanque, Extend y Reverse en un pistón. La capa lógica no tiene vocabulario privado ni comandos ocultos. Todo lo que puede hacerle a tu base es algo que el Terminal ya te deja hacer a mano, lo que significa que ya te has aprendido la mitad de cualquier automatización que llegues a construir.
Piensa en la puerta del hangar que abres a mano al final de cada ronda de minería. Sentado en la cabina, pulsas la ranura de la barra de herramientas que contiene su acción Open. Ahora dale esa misma acción a un Bloque de Temporizador: guarda Open y la reproduce cada vez que algo lo pone en marcha. Dásela a un Sensor: Open se dispara cuando tu nave entra en el volumen que está vigilando. Dásela a un Controlador de Eventos apuntando al conector en el que atraca tu nave: Open se dispara cuando el conector se declara conectado. Cuatro construcciones distintas, una acción, una entrada de Terminal. Nada de lo que le pasa a la puerta ha cambiado; solo ha cambiado el motivo por el que la puerta se entera.
Ese es el cambio de mentalidad que merece la pena hacer esta noche. No estás buscando un bloque, estás buscando un disparador. Cualquier tarea que puedas describir como «pulso estos interruptores cuando pasa esto» ya está medio especificada: la lista de interruptores es la parte que ya conoces, y elegir un bloque de lógica es solo elegir quién se da cuenta del «cuando».
El modelo de la barra de herramientas también explica, sin ningún juego de manos, dónde se acaba toda esta capa. Los límites documentados no son huecos arbitrarios en el conjunto de funciones; son cosas que una acción de barra de herramientas no puede expresar. Un Temporizador no puede pilotar una nave, usar una herramienta de mano, apuntar un arma de mano, colocar un bloque ni medir tiempos por debajo de un segundo: ninguna de esas cosas es una acción que esté en el Terminal de un bloque, y las tres primeras pertenecen a bloques completamente distintos. Tampoco puede alcanzar un bloque a través del terminal remoto: «la misma cuadrícula o una conectada» significa unida físicamente, así que una estación al otro lado del cielo desde tu cabina queda fuera de alcance por mucho que tu antena la vea. Incluso una conexión que hayas hecho tú puede caducar: las acciones que asignes a bloques de una subcuadrícula unida mediante un conector solo se ejecutan mientras ese conector está realmente conectado, y por eso una secuencia de desacople que funcionaba en la plataforma no hace nada en vuelo.
El vocabulario de acciones, por su parte, no deja de crecer por su cuenta. La actualización 1.208, en noviembre de 2025, añadió un lote de nuevas acciones de fijar valor en bloques como Antenas, Balizas, Giroscopios, Generadores de Gravedad y Suspensiones de Rueda: los bloques de lógica en sí quedaron intactos, pero todo lo que pueden decirle al resto de tu cuadrícula se hizo más largo.
¿Y por qué tiene esta capa fama de ser solo para programadores? Porque durante los primeros ocho años lo fue de verdad. El Bloque Programable llegó el 1 de enero de 2015, en la actualización 01.063, y Keen fue explícito entonces: programar se había convertido en una parte integral de la jugabilidad. Durante la mayor parte de la vida del juego fue el único escalón de esta escalera, y por eso tantos consejos que siguen circulando —respuestas en foros, guías en vídeo antiguas, la mitad de los resultados que encontrarás buscando tu problema exacto— empiezan con «para eso necesitas un script». Mucho de eso era cierto cuando se escribió.
La otra suposición que conviene soltar es que algo de esto esté detrás de un muro de pago. Los cuatro bloques son de 1×1×1 en ambos tamaños de cuadrícula, así que te cuestan un cubo de espacio cada uno. Un Bloque de Temporizador consume 0.1 W, una cifra tan pequeña que la wiki te hace la cuenta: una batería pequeña puede alimentar 500,000 Temporizadores durante una hora. Con la Progresión activada también se desbloquean pronto: construir cualquier luz desbloquea el Bloque de Temporizador, y un Ensamblador básico más un bloque de iluminación desbloquean el Controlador de Eventos. Sí existe un Automatons Pack de pago, y conviene ser preciso sobre lo que vende: un Emotion Controller, cabinas tipo silla de montar, tuberías decorativas y aspectos cosméticos Automaton para el Bloque Programable, el Bloque de Temporizador y el Sensor. Aspectos. Los bloques funcionales que hay debajo, y el Controlador de Eventos junto a ellos, son contenido vanilla gratuito.
Ni es maquinaria heredada que estés desempolvando. La actualización más reciente de Space Engineers, la 1.210 «Prosperity» de julio de 2026, sigue trayendo correcciones para el Controlador de Eventos: un cálculo mejorado de Distance to Locked Target, un arreglo de sincronización del Detailed Info para servidores dedicados, un arreglo para un Merge Block vigilado que se disparaba al recolorear. Aunque conviene fijar un límite antes de que te pongas a buscar: Space Engineers 2 es un juego aparte, y tiene su propio Controlador de Eventos con una lista de condiciones distinta y sin Bloque Programable alguno. Si una guía que encuentres enumera condiciones como masa o porcentaje de atmósfera, no está describiendo este juego.
Lo que deja exactamente una pregunta. Si todos pulsan los mismos botones, lo único que queda por decidir es cuál construyes para una tarea dada, y eso depende de las dos cosas que estos bloques no comparten.
Elige el escalón más bajo que resuelva la tarea: qué puede calcular cada bloque de lógica y hasta dónde llega
Las dos cosas son estas: qué puede deducir un bloque y hasta dónde puede darse cuenta. Toda decisión en este sistema se reduce a esas dos escaleras, y ambas son lo bastante cortas como para tenerlas en la cabeza mientras estás de pie en tu base mirando la tarea que estás harto de hacer a mano.
Empieza por la capacidad, porque es la escalera que decide si alguna vez necesitas escribir código. Un Bloque de Temporizador reproduce una lista fija de interruptores accionados. Un Sensor se da cuenta de algo cercano. Un Controlador de Eventos se da cuenta de algo de tu propia cuadrícula y reacciona con una rama para verdadero y otra para falso. Un Bloque Programable lee, calcula y escribe cualquier valor al que pueda llegar. Cuatro frases, cuatro escalones, y solo el último paso entre ellos es caro.
La wiki traza esa última línea en una palabra: valor. Un Temporizador puede encender y apagar bloques —luces, propulsores, energía, torretas— y puede aumentar y disminuir un puñado pequeño de valores en intervalos fijos, cosas como la altura de la suspensión de las ruedas, la inversión de rotores, pistones y bisagras, o la anulación de propulsores. Eso es escalonar, no fijar. Puedes decirle a un Temporizador que empuje un valor; no puedes decirle que aterrice en un número. Un script no tiene esa restricción: puede leer, calcular y escribir cualquier valor que un bloque exponga. Los tres ejemplos de la propia wiki son la formulación más clara de esa diferencia que hay en toda la documentación: atenuar el color de una luz de blanco a rojo, girar un rotor, un pistón o una bisagra hasta cualquier posición que indiques, poner un propulsor a cualquier velocidad.
La misma división aparece en el lado de la lectura. Un Sensor detecta proximidad, y punto; sabe que hay algo dentro de su volumen y nada más sobre ello. Un script puede leer cualquier información de estado que un bloque o una cuadrícula exponga y reaccionar a ella: el contenido de los inventarios, la configuración de dirección de las ruedas, el estado de daño, posiciones, velocidad, propiedad. El Controlador de Eventos vive explícitamente en medio, y la wiki lo dice con todas las letras: es más fácil de usar que un script, pero solo admite un subconjunto de lo que los scripts pueden hacer. Ese subconjunto es toda la cuestión. Si el subconjunto cubre tu tarea, el resto de la subida no te compra nada.
La segunda escalera es el alcance, y conviene separarla con cuidado de algo que ya sabes. La regla de «la misma cuadrícula o una conectada» de hace un momento gobierna sobre qué puede actuar un bloque de lógica. Esta escalera gobierna de qué puede darse cuenta, y los números son bastante distintos:
- Controlador de Eventos: su propia cuadrícula, más cualquier cosa conectada o fusionada a ella. Reacciona a cosas que le pasan a sí mismo.
- Sensor: hasta 50 metros del mundo a su alrededor. Este es el bloque que reacciona a cosas externas: otras cuadrículas, meteoritos, jugadores.
- Bloques de IA Automaton y de torretas: otras cuadrículas hasta a 2–2.5 km de distancia.
- Action Relay: hasta donde llegue tu antena.
El techo del Controlador de Eventos aquí es un muro de verdad y no un ajuste que puedas subir, y es la razón por la que un Sensor no queda obsoleto por un controlador que vigila veinte estados distintos de la cuadrícula. Un Controlador de Eventos no puede decirte que se acerca una nave. Solo puede decirte que le ha pasado algo a tu estación. El Action Relay está en esta escalera por otro motivo distinto: no detecta nada en absoluto, lo que hace es llevar un disparador a través de una frontera entre cuadrículas que nada más en esta capa puede cruzar. Y ya que estamos, un límite: los bloques de IA Automaton y de torretas de ese tercer nivel son un subsistema distinto con un trabajo distinto. Ellos pilotan y combaten. Los bloques de lógica conmutan y secuencian. Comparten una tabla de alcances y muy poco más.
Junta las dos escaleras y la regla sale sola: sube al escalón más bajo que resuelva tu tarea, y párate. Esto no es una preferencia estilística, es el consejo documentado del juego. La propia guía de la página del Bloque Programable sobre cómo pilotar un dron es que consideres primero si el Autopiloto estándar, un Controlador de Eventos o un Automaton pueden hacer lo que necesitas de una forma más sencilla, y su veredicto sobre el caso general es tajante. Si la velocidad de milisegundos y el cálculo y ajuste precisos de valores no son esenciales, un Bloque Programable es excesivo, y deberías usar antes métodos menos pesados en recursos. Ese «pesado en recursos» está haciendo trabajo real en la frase; la recomendación está planteada como un argumento de coste, no estético, y la aritmética que hay detrás viene más adelante. El escalón de arriba también trae requisitos que los otros tres no tienen, y eso es toda una sección propia más abajo.
Así que coge tres tareas y bájalas por las escaleras.
«Abre la puerta del hangar cuando mi nave se acerque». El disparador es la proximidad y nada más. Esa es la definición entera de lo que hace un Sensor, y 50 metros es más de lo que necesita una aproximación a un hangar. No hay ningún valor que calcular ni ningún estado de cuadrícula que inspeccionar. Subir más alto aquí te compra una versión más complicada de un problema resuelto.
«Enciende los reactores cuando las baterías bajen del 20 %». La proximidad es irrelevante, así que un Sensor no ayuda. Lo que se vigila es un estado de tu propia cuadrícula —la energía almacenada— y la reacción tiene dos mitades: encender los reactores cuando cae, apagarlos cuando se recupera. Una rama verdadera y una rama falsa, vigilando tu propia estación. Esa es la forma exacta de un Controlador de Eventos, y la mayor parte de lo que ahora haces a mano tiene este aspecto.
«Mantén un propulsor a una salida exacta mientras la nave sale de la gravedad». Ahora la escalera muerde. Un Temporizador puede escalonar la anulación del propulsor hacia arriba o hacia abajo en incrementos fijos, pero no puede dejarla en el 43 %, porque el número no es la posición de un interruptor. Solo un script puede leer la velocidad y la posición de la nave, calcular la cifra que quiere y escribir esa cifra en el bloque. La tarea se define por necesitar un valor y no un estado, y esa es la única frontera que nada por debajo del escalón superior cruza.
Esa última distinción es la útil para llevar encima, porque puedes aplicarla a tu propia lista de pendientes ahora mismo, antes de construir nada. Repasa la lista de tareas que repites cada sesión y pregúntale a cada una: ¿esto necesita un número, o solo necesita que se accione un interruptor cuando algo es cierto? Esclusas, puertas de hangar, triaje de reactores, producción de gas, atraque, recuperación de drones: casi todo es del segundo tipo. La mayoría de lo que la gente da por hecho que es un problema de scripting es un problema de escalón intermedio que se ha quedado sin hacer porque el escalón intermedio no existió durante los primeros ocho años que el Bloque Programable estuvo en el juego.
Lo que significa que el sitio sensato para empezar no es la parte de arriba de la escalera sino la de abajo: con el bloque que ya está en tu menú G, y con el que todos los escalones por encima acaban delegándole el trabajo de todas formas.
Bloques de Temporizador: un conjunto grabado de pulsaciones que puedes reproducir cuando quieras
El Bloque de Temporizador es lo más viejo y lo más simple de este artículo, y la wiki lo enseña con una metáfora que merece la pena tomar prestada: las acciones son canciones y un Temporizador es una lista de reproducción. Lo cargas con pulsaciones de botón y luego las reproduce: a la orden, o tras una espera. Ese es todo el concepto. Lo que lo eleva por encima de un temporizador de cocina es cuánto cabe en una sola lista y cuántas cosas distintas tienen permiso para darle al play.
Empieza por la capacidad, porque es la parte que la gente subestima y la razón por la que un Temporizador es una primitiva de verdad y no una comodidad. Su barra de herramientas funciona exactamente igual que la de tu cabina: nueve ranuras en la página que tienes delante, y nueve páginas detrás, a las que llegas con ctrl+1 hasta ctrl+9. Nueve barras de herramientas de nueve acciones, y el detalle que las hace valiosas es que las páginas no son alternativas entre las que eliges. Todas las páginas se disparan juntas, cada vez que el Temporizador se ejecuta.
Hay una restricción que acaba siendo una función: solo puedes asignar una acción dada una vez por barra de herramientas. Por eso el ejemplo de la propia wiki es poner «aumentar la anulación de propulsión» una vez en cada una de las nueve páginas: nueve copias de un mismo paso, disparadas en una sola pulsación, es como un Temporizador empuja un valor nueve muescas de golpe en vez de una.
Delante de ese conjunto de acciones hay un solo número: el retardo, escrito como horas:minutos:segundos. Va de 0:00:01 a 1:00:00: un segundo en el suelo, una hora en el techo. Esos límites conviene conocerlos antes de diseñar en torno a ellos. No puedes pedirle a un Temporizador que se dispare dentro de un tercio de segundo, y un solo Temporizador no puede aguantar una espera de más de una hora.
Luego están los tres controles del propio bloque. Trigger Now se salta el retardo y reproduce las acciones inmediatamente. Start cuenta el retardo hacia atrás y las reproduce al final. Stop detiene las acciones que el Temporizador está ejecutando.
Esos tres se sienten mejor de lo que se leen, así que construye el bloque. Llámalo Undock. En su barra de herramientas van las tres cosas que ahora haces a mano en secuencia cada vez que sales de la plataforma: desbloquear el conector, soltar el tren de aterrizaje, encender los propulsores. Pon el retardo en 0:00:10.
Ahora tienes un bloque con dos comportamientos, y eliges entre ellos en el momento en que pulsas. Start te da diez segundos —tiempo para despejar la plataforma y acomodarte en el asiento— y luego las tres acciones se disparan juntas. Trigger Now, en el mismo bloque, con las mismas tres acciones y el mismo retardo de diez segundos todavía en el campo, dispara las tres en el instante en que lo tocas. Nada del bloque ha cambiado. Simplemente no se consulta el retardo.
Y como esos tres controles son a su vez acciones de barra de herramientas, no eres tú el único que puede pulsarlos. Un Panel de Botones montado junto a la puerta del hangar puede llevar el Start de Undock. Otro Temporizador puede pulsar cualquiera de los tres desde el otro extremo de la cuadrícula. Otros bloques también pueden pulsarlos, por motivos propios, y de eso van las próximas secciones.
Esta es la parte que los lectores se saltan camino de los bloques más interesantes, así que conviene decirlo sin rodeos: cualquier tarea que puedas describir como «acciona estos interruptores, todos a la vez» ya está resuelta. Sin condición, sin script: un cubo, una lista de acciones que ya sabes disparar a mano y un nombre que seguirás reconociendo en una barra de herramientas dentro de seis meses. Las luces del hangar, la puerta y la baliza en una pulsación. Todo el banco de reactores encendido. Todos los taladros, transportadores y luces de la plataforma minera apagados cuando cierras sesión. Puedes construir tres de esos esta noche y no volver a pensar en ellos.
El techo no es cuánto guarda un Temporizador. Es lo que un Temporizador es: un momento. Todo lo que hay en esas nueve páginas ocurre en el mismo instante, diez segundos después de pedirlo o en el momento de pedirlo, y ahí se acaba el bloque. En cuanto una tarea tiene un segundo paso que tiene que ocurrir después de que el primero haya seguido su curso, un solo Temporizador deja de bastar, y el segundo trae una pregunta que el primero nunca planteó.
Encadenar temporizadores en secuencias y bucles: por qué un Temporizador nunca comprueba que el último paso funcionó
El segundo Temporizador existe por una regla que el primero esconde. Las acciones dentro de un mismo Temporizador no se esperan entre sí. Todas se disparan en el mismo instante, y luego el bloque ha terminado, tanto si la puerta del hangar que abrieron tarda dos segundos en deslizarse del todo como si tarda veinte. Así que en cuanto tu procedimiento tiene un paso que debe ocurrir después de que otra cosa haya seguido su curso, no puedes resolverlo añadiendo otra acción a la misma página. La wiki es tajante: si estás automatizando una secuencia de acciones largas, tienes que imponer tú las pausas, y lo único de esta capa que sostiene una pausa es otro Temporizador.
Eso te da el patrón sobre el que está construido todo el lado sin código de Space Engineers. Cada paso del procedimiento tiene su propio Temporizador. El retardo de ese Temporizador es tu estimación de cuánto necesita el paso anterior. Su última acción arranca el siguiente Temporizador de la línea, que cuenta su propio retardo, dispara sus propias acciones y arranca al de después. Paso, espera, paso, espera: una cadena de bloques de un solo propósito, cada uno pasando el testigo.
Por eso la respuesta de la wiki a «¿cuántos Temporizadores voy a necesitar?» es, literalmente, «Muchos. :-)». Un Temporizador por cada conjunto de acciones que ocurren juntas, y un bloque aparte siempre que dos conjuntos sean mutuamente excluyentes, siempre que solo ocurran juntos parte del tiempo, siempre que necesiten una pausa entre ellos, o siempre que una acción tenga que esperar a que otra se complete. Si te encuentras intentando ser listo con un solo Temporizador, casi siempre estás mirando dos.
Construye la secuencia de atraque y notarás la forma de esto enseguida. Dock-1-Open lleva una acción: abrir la puerta del hangar. Su segunda acción arranca Dock-2-Secure, cuyo retardo es 0:00:20 —bastante para que la puerta termine y para que tú vueles el último tramo hacia dentro— y cuyas acciones bloquean el conector, cierran la puerta detrás de ti y ponen las luces del hangar en su estado de atracado. Pulsas un botón al entrar y la bahía se abre, espera, recoge tu nave y se cierra sola. Dos bloques, sin condiciones, nada que se parezca a código.
Ahora mete un pedazo de escombro en el riel de la puerta.
Dock-1-Open dispara la acción Open exactamente como se le indicó. La puerta fuerza contra el obstáculo y se queda cerrada. Veinte segundos después, puntualmente, Dock-2-Secure bloquea un conector que no tiene nada encima, cierra una puerta que nunca se abrió y pone las luces para decir que estás atracado sano y salvo, mientras tu nave sigue fuera de un hangar sellado. Nada dio error. Los dos bloques hicieron exactamente lo que construiste.
Ese es el techo honesto de este escalón, y merece decirse sin suavizarlo: un retardo no es una comprobación. Los Temporizadores, en palabras de la propia wiki, simplemente esperan literalmente el número de segundos que les digas, y nunca confirman que la acción anterior se completara de verdad. Una puerta que está bloqueada en vez de cerrada no informa de nada. La cadena sigue sin más al paso siguiente y se desacompasa calladamente de la realidad.
Dos imprecisiones menores viajan con ella. Los Temporizadores tampoco son precisos con sus retardos, y por eso el consejo estándar es añadir un poco de tiempo extra en vez de cronometrar el paso al milímetro; y no pueden hacer nada por debajo de un segundo, así que la coordinación verdaderamente fina —el ejemplo de la wiki son las articulaciones de una máquina que camina— queda fuera del alcance del bloque por mucho que organices la cadena.
La holgura absorbe parte de esto. Si tu puerta tarda ocho segundos, dale doce al siguiente Temporizador. Pero sé honesto sobre lo que has hecho: no has verificado nada, has adivinado con generosidad, y una suposición solo aguanta mientras las condiciones sigan siendo normales.
Los bucles son la otra mitad del patrón, y salen de un permiso pequeño. Arrancar y parar un Temporizador es a su vez una acción de barra de herramientas, lo que significa que un Temporizador puede arrancar o parar a otro Temporizador, incluido él mismo. Un bloque cuya última acción se reinicia a sí mismo funciona para siempre con su propio retardo. Ese único truco convierte la cadena en un ciclo, y así es como los transbordadores automatizados hacen sus rondas de (des)atraque, como se reabastecen los drones de patrulla, como una impresora 3D avanza y se reinicia.
Cuando una construcción tiene varios ciclos funcionando a ritmos distintos, puedes poner un Temporizador director por encima: un bloque cuyo único trabajo es arrancar y parar a los demás, con un retardo largo propio y una última acción que lo reinicia a sí mismo.
Dos notas prácticas acompañan a todo esto. Terminar un bucle significa disparar la acción Stop en todos los bloques que estén en bucle, no solo en el que estabas mirando. Y cuando los retardos empiecen a parecer demasiado complicados para tenerlos en la cabeza, el consejo de la wiki es el poco glamuroso: dibuja cajas y flechas en papel hasta que el orden, los tiempos y las agrupaciones se vean.
No confundas esto con un cronómetro con pasos extra. El truco de fiesta de la propia wiki es un aleatorizador que funciona sin una sola línea de código: SurpriseTimer contiene algún evento que preferirías no predecir —digamos armar y detonar una ojiva— y ToggleTimer, en un bucle de tres segundos que se reinicia solo, no hace más que encender y apagar SurpriseTimer, una y otra vez. Un Sensor que vigila la puerta apaga ToggleTimer en cuanto alguien entra, congelando SurpriseTimer en el estado en que le haya pillado. Pulsas el botón y es cara o cruz. Dos Temporizadores, un Sensor y una rama aleatoria de verdad.
Lo que nos lleva al bloque que deberías construir antes que todo eso: el RESET.
Una cadena que puede desincronizarse necesita una forma de volver a un estado conocido, porque los estados se acumulan más rápido de lo que crees. Una cuadrícula en funcionamiento arrastra ajustes de propulsión, direcciones de control remoto, modo de precisión, evitación de colisiones, modo de batería, rotación mecánica y pasos que todavía está esperando. Arráncala desde la combinación equivocada de todo eso y, como dice la wiki, puede perderse, atascarse o destruirse a sí misma.
Así que construye un Temporizador que lo devuelva todo a su sitio: los bloques mecánicos a sus límites de extensión, ángulos iniciales, velocidades y direcciones; la cuadrícula de vuelta en su punto seguro de atraque; propulsores, amortiguadores, giroscopios y control de vuelo de vuelta a sus valores por defecto. Nómbralo de forma consistente —RESET o RESTART en cada cuadrícula que construyas— y déjate una nota en un panel de texto pequeño sobre cualquier cosa que tengas que ajustar a mano primero, como los waypoints o los nombres de las antenas.
Es el bloque que más usarás y en el que menos pensarás. También es el procedimiento de reparación: cuando un pistón dañado ha descolocado una secuencia mecánica, el arreglo después de soldar es parar todos los temporizadores, resetear y volver a arrancarlos en el orden correcto.
El RESET trae consigo una disciplina más, y es la diferencia entre un sistema de lógica que podrás depurar dentro de un año y otro que acabarás reconstruyendo. No repartas conjuntos de acciones complicados por las ranuras de disparo de sensores, controladores y paneles de botones sueltos por tu base. Apunta cada uno de ellos a un Temporizador con nombre y pon el trabajo real ahí. Entonces los Temporizadores son lo único que mantienes, y hay exactamente un sitio donde mirar cuando una secuencia se porta mal.
Así que: Temporizadores de un solo propósito, nombres descriptivos, un RESET, holgura generosa en cada retardo y un diagrama cuando crezca. Hasta ahí llega este escalón, y para buena parte del trabajo de estación es suficiente. Pero fíjate en lo que está haciendo realmente la holgura. Está sustituyendo a un dato que no tienes: si el último paso terminó. Si un retardo no puede decirte que la puerta se cerró de verdad, algo tiene que darse cuenta por ti. Lo curioso es que varios bloques que ya llevas atornillados a tu estación llevan todo este tiempo dándose cuenta, con sus dos ranuras de disparo vacías.
Sensores y la docena de bloques que ya disparan eventos por ti
Esas ranuras vacías no son una forma de hablar. Una barra de herramientas de disparo es equipamiento estándar en una cantidad sorprendente de bloques que ya has atornillado a la estación por motivos completamente distintos, y nada en el Terminal te lo señala: las ranuras simplemente están ahí, sin usar, en hardware que pagaste hace años. Antes de construir nada nuevo, conviene saber qué está ya vigilando. Empieza por el único bloque de esa lista que construirías a propósito: el Sensor.
El trabajo del Sensor es darse cuenta de cosas que no forman parte de tu cuadrícula. La propia lista de usos de la wiki es el comportamiento de drones, abrir esclusas y puertas de hangar, luces activadas por movimiento, alambres de tropiezo de seguridad y trampas, y, memorablemente, evitar que los jugadores se metan en una amoladora en marcha. Lo que te da es una caja, y la caja es tuya para darle forma. El campo de detección se ajusta por separado en seis direcciones —izquierda, derecha, arriba, abajo, atrás y adelante— y cada una va desde el mínimo, un cubo de 0.1 metros pegado al bloque, hasta 50 metros. Como los seis números son independientes, la forma es la verdadera decisión de diseño: una losa fina cruzada en una puerta, una franja poco profunda por una pared de un pasillo, una columna alta sobre una plataforma de aterrizaje. Activa Show on HUD mientras lo configuras y el volumen se te dibuja en el mundo, para que puedas confirmar que la caja que imaginaste es la caja que has ajustado.
Lo que cuenta como detección está desglosado con la misma finura, y marcas la combinación que quieras: jugadores, filtrados por relación (propietario, amistoso, neutral, enemigo); naves pequeñas y bloques pequeños; naves grandes y bloques grandes; estaciones, bases y plataformas; objetos flotantes, que cubre chatarra, minerales, herramientas soltadas, munición y materiales sueltos; subcuadrículas; y asteroides y terreno de vóxeles en planetas. Ese último par parece una rareza hasta que estás construyendo una plataforma de perforación o un módulo de aterrizaje que necesita saber que está a punto de encontrarse con tierra. El filtro de relación es el que merece la pena notar esta noche, porque hace un trabajo que si no intentarías construir: «jugadores enemigos, y nada más» es una casilla, no un artilugio.
Donde el Sensor se separa claramente del Temporizador es en su barra de herramientas. Tiene exactamente dos ranuras de acción: la izquierda se dispara cuando un objetivo entra en el campo, la derecha cuando lo abandona. Hay nueve páginas de esas, de ctrl+1 a ctrl+9, pero todas las páginas te dan los mismos dos momentos; no hay un tercer tipo de cosa de la que un Sensor pueda darse cuenta. Esa restricción decide calladamente la forma de cualquier construcción con sensor que llegues a hacer. En cuanto tu reacción sea más que uno o dos interruptores, la ranura no debería llevar la reacción en absoluto. Debería llevar el Start de un Temporizador que lleve la reacción.
Así que construye la alarma antiintrusos, y constrúyela así. Pon un Sensor en el pasillo entre tu hangar y el resto de la base, ajusta el campo para que cubra el ancho del pasillo y nada más allá, y pon los objetivos solo en jugadores enemigos. En la ranura de entrada, una acción: arrancar un Temporizador llamado AlarmOn. En la ranura de salida, una acción: arrancar AlarmOff. AlarmOn es donde vive la alarma de verdad: encender una Baliza que hayas etiquetado con algo que un compañero de facción pueda leer de un vistazo, disparar un Broadcast Controller para meter un mensaje en el chat y que se enteren los que no están en la sala, poner las luces del pasillo en su estado de aviso. AlarmOff devuelve las tres cosas a su sitio. Un Sensor con dos acciones, dos Temporizadores con tantas como haga falta, y toda la alarma editable en un solo sitio si más adelante decides que además debería cerrar una puerta.
Ahora el fallo que hace que esta alarma merezca entenderse en vez de copiarse. Los jugadores sentados en una cabina, en una criocápsula o en cualquier otro asiento no se detectan como jugadores en absoluto. El asaltante que baja por tu pasillo dispara la alarma exactamente según lo diseñado; el asaltante que baja por tu pasillo y se sienta en un asiento, para el Sensor, ya no está. Nada da error, nada te avisa y la baliza sigue apagada. Es el mismo punto ciego, visto desde el otro lado, que hace que un Sensor no sea fiable para contar cabezas: responde «¿ha cruzado algo esta línea?» mucho mejor de lo que responde «¿hay alguien en esta sala ahora mismo?». Construye alambres de tropiezo con él, y ten cuidado al construir comprobaciones de presencia.
Y el Sensor es solo el bloque más llamativo de la lista. Todo un conjunto de bloques que ya están en tu cuadrícula exponen sus propias barras de herramientas de eventos, sin ningún controlador de por medio:
- Ventilación de Aire: la sala se ha presurizado, o ya no está despresurizada. Este es el socio clásico de las esclusas, y la razón es que informa de algo real en vez de algo programado.
- Panel de Botones: un jugador pulsó el botón.
- Bloque de Temporizador: la cuenta atrás llegó a cero. Esa es la cadena que construiste en la sección anterior, vista desde el lado del disparo.
- Action Relay: llegó una señal.
- Cabinas y Remote Controls: algo ha fijado el blanco sobre esta cuadrícula, y ha dejado de hacerlo; la reacción que sugiere la wiki es desplegar señuelos.
- AI Basic, AI Recorder y Remote Control: se alcanzó un waypoint.
- AI Offensive y AI Defensive: se detectó al primer enemigo, y ya no quedan enemigos; huir, lanzar drones, despertar las torretas.
- Custom Turret Controller: la torreta se alineó con su objetivo, o perdió la alineación.
- Target Dummy: el maniquí fue golpeado o destruido, que es como la gente construye un campo de tiro con puntuación.
Lee esa lista como una pregunta de inventario, no como un menú. Antes de diseñar un disparador nuevo para una tarea, mira qué está físicamente implicado en la tarea y comprueba si uno de esos bloques ya está ahí metido, ya dándose cuenta, con sus dos ranuras vacías. Un hangar con un Panel de Botones junto a la puerta y una Ventilación de Aire en el techo es un hangar que ya puede contarte dos cosas sobre sí mismo gratis.
La otra cosa que hay que sacar de la lista es que todos los bloques de ella comparten la forma del Sensor: un número pequeño de ranuras, con un número pequeño de acciones, en un bloque cuyo trabajo principal es algo completamente distinto. Esa forma es exactamente por lo que la disciplina de la sección anterior se aplica a todos ellos: apunta cada uno a un Temporizador con nombre y guarda el trabajo real ahí.
Lo que ninguno de ellos te dirá es el estado de tu propia estación. Un Sensor responde «¿hay algo ahí fuera?» —de maravilla, hasta 50 metros, en una caja que dibujaste tú—. No puede responder «¿me estoy quedando sin hidrógeno, está lleno ese contenedor de carga, la puerta a la que le dije que se cerrara terminó de cerrarse?». Esas son preguntas sobre la cuadrícula que las hace, y durante ocho años lo único en el juego que podía responderlas era un script. Entonces Keen lanzó un bloque cuyo propósito entero es ese segundo tipo de pregunta.
Los Controladores de Eventos le dan a una cuadrícula sentidos sobre sí misma
Ese bloque es el Controlador de Eventos, y la descripción que hace de él la wiki es la frase más útil de esta guía: le da a tus cuadrículas «sentidos» para sus propios bloques. Vigila los estados de los bloques por ti, y cuando un valor cambia reacciona disparando las acciones de barra de herramientas que elegiste. Keen lo lanzó en abril de 2023, en la actualización 1.202 «Automatons», como contenido gratuito del juego base junto a los cinco bloques de IA, así que lleva tres años ahí, ocupando un cubo en tu menú G, bajo un nombre que suena bastante más técnico que lo que hace. Lo que hace es formular una pregunta sobre tu estación, de forma continua, y actuar sobre la respuesta en los dos sentidos.
Los dos sentidos es la parte que importa, y es donde el bloque se separa de todo lo anterior. Abre uno y encontrarás dos ranuras de acción, y no son las dos del Sensor. Las ranuras de un Sensor las fija el mundo: algo entró, algo salió. La primera ranura de un Controlador de Eventos se dispara cuando la condición que escribiste tú se vuelve verdadera, y la segunda cuando esa condición se vuelve falsa. Como tú defines la condición, tú defines las dos ramas —la reacción y el reinicio— y las defines en el mismo bloque, al mismo tiempo, mirando el mismo umbral. «Baterías por debajo del veinte por ciento» te da el arranque de los reactores en la ranura uno y su apagado en la ranura dos, y ninguna puede desviarse de la otra, porque solo hay un número de por medio.
Detrás de cada ranura hay nueve páginas de barra de herramientas, igual que en un Temporizador, así que una ranura puede llevar tantas acciones como haga falta. Merece la pena conocer una rareza antes de que te confunda: si quieres la misma acción en las dos ranuras, tiene que ir en páginas distintas, así que pon la copia de verdadero en la página uno y la de falso en la página dos.
Lo que puedes preguntar es un menú fijo, y es más largo de lo que la mayoría se imagina: más de veinte tipos de evento distintos, cada uno con su propio rango de valores. Los eventos de porcentaje van de 0 a 100 % y son los que cubren la mayor parte del trabajo de estación: Stored Power %, Power Output %, Gas Tank Filled %, Cargo Filled %, Piston Position %, Block Integrity %, Thrust %. Junto a ellos están los cambios de estado simples, sin umbral alguno —Door Opened, Connector Connected, Connector Ready to Lock, Landing Gear Locked, Merge Block Merged, Rotor/Hinge Attached, Cockpit Occupied, Block On/Off Switched, Block Added/Removed—, donde la ranura uno toma el primer estado y la ranura dos su opuesto.
Y luego un puñado de medidas sobre la propia cuadrícula, cada una con un techo duro: Altitude de 1 a 50,000 m, Distance to Locked Target de 1 a 2,500 m, Grid Speed de 0 a 100 m/s, Natural Gravity de 0 a 10 g y Angle Changed en todo el rango de −360 a +360°.
Dos detalles de ese catálogo te morderán si nadie los menciona. El primero es que las dos opciones de comparación incluyen igual: la condición es «igual o mayor que» o «igual o menor que», nunca un mayor-que a secas. Así que con un umbral de 20, una lectura exacta de 20 satisface el lado verdadero, y la acción de falso nunca es la que se dispara justo en tu número. Fija un umbral esperando una desigualdad estricta y la rama que obtienes es la otra. El segundo tiene que ver con Altitude en concreto: se mide contra el mapa de alturas original de la superficie del planeta, lo que significa que los agujeros excavados, las rocas y las cuadrículas se ignoran. Un módulo de aterrizaje al que le dices que suelte el tren a 20 m está midiendo desde el terreno tal y como lo generó el juego, no desde el pozo que excavaste ni desde la plataforma que soldaste ahí abajo.
La otra regla estructural es que un Controlador de Eventos vigila un evento. No estás configurando un motor de reglas; estás eligiendo una sola pregunta y cableando sus dos respuestas.
Así que construye la pareja que mantiene viva una estación mientras no la miras, y constrúyela como el bloque espera. Coloca un Controlador de Eventos, abre su pantalla de Control Panel y baja por los ajustes en orden:
- Event: Stored Power %.
- Condition: el valor es igual o menor que el umbral.
- Threshold: 20.
- Available Blocks: como este es un evento de bloque y no una medida de cuadrícula, ahora eliges qué vigila. Busca en tu cuadrícula, selecciona tu banco de baterías y haz clic en Add Blocks.
- Selected Blocks: cualquier cosa que hayas añadido mal sale de aquí, con Remove Blocks.
- Select Actions: la ranura uno es cómo reaccionar, la ranura dos es cómo deshacerlo.
(También hay un interruptor AND Gate al fondo de esa pantalla. Déjalo en paz por ahora: es el tema de la siguiente sección.)
En esas dos ranuras van exactamente dos acciones, y ninguna es un reactor. La ranura uno arranca un Temporizador llamado Power-Reserve-On, que es donde vive el trabajo real: encender el banco de reactores, poner las luces de aviso del pasillo en ámbar y cualquier otra cosa que decidas que debe significar poca energía. La ranura dos arranca Power-Reserve-Off, que lo devuelve todo a su sitio. Es la misma disciplina de las dos secciones anteriores y aquí se paga más rápido que en ninguna otra parte, porque una regla de energía es una regla que vas a editar: el día que decidas que poca energía también debería apagar la refinería, editas un Temporizador en vez de rebuscar entre controladores. Y ya que estás, llama al controlador Power-Low, porque dentro de seis meses vas a estar leyendo su nombre, no sus ajustes.
Un segundo controlador cierra la historia de la energía por el otro extremo. Apúntalo a Power Output %, vigilando tus paneles solares o tus turbinas eólicas, y deja que apague las fuentes con combustible cuando las renovables llevan la carga; ese es el fraseo de la propia wiki para el patrón. Ahora tus reactores se encienden cuando las baterías flaquean y se callan cuando el sol hace el trabajo, y nada de eso implicó una línea de código.
El gas es la misma forma con otra pregunta. Un tercer controlador en Gas Tank Filled % puede vigilar un Tanque de Oxígeno, un Tanque de Hidrógeno o un Motor de Hidrógeno. Pon la condición en igual o menor que, el umbral en algo que te dé holgura —digamos 30— y selecciona el tanque de hidrógeno. La ranura uno arranca H2-Produce: encender el Generador de O2/H2 y poner un tanque en Stockpile para que se llene en vez de alimentar. La ranura dos arranca H2-Idle, que apaga el generador y saca el tanque de Stockpile cuando ya estés tranquilo. La wiki formula el bucle entero en una frase —si el hidrógeno baja, entonces produce más y pon un tanque de hidrógeno en Stockpile— y esa frase es ahora una característica permanente de tu base en vez de algo que te acuerdas de hacer antes de un vuelo largo.
Una vez que hayas construido dos de estos, el resto del catálogo se lee distinto, porque cada entrada es la misma configuración de tres pasos apuntada a otra pregunta. Cargo Filled % es el ejemplo de «si esto entonces aquello» de la propia wiki: un dron minero configurado para volver a la base al 80 % de carga deja de necesitar que le vigiles el inventario.
Piston Position % detiene un ascensor en una planta y abre las puertas, con el matiz útil de que el porcentaje se mide dentro del mínimo y el máximo propios de ese pistón, así que 50 % significa a mitad del recorrido que configuraste, no a mitad del límite absoluto del pistón. Block Integrity % y Block Added/Removed convierten una estación en algo que se repara solo: cuando se destruyen bloques esenciales, enciende los autoproyectores y los soldadores, y deja que la plataforma suelde el agujero mientras tú todavía estás averiguando qué te ha dado.
Y Connector Connected es el que hace que atracar se sienta acabado: la ranura uno extiende la pasarela y abre las puertas en cuanto el conector se declara bloqueado, la ranura dos las retrae y sella al marcharte, con un segundo controlador en Connector Ready to Lock encargándose del bloqueo mientras te dejas caer en posición.
Mira esa lista contra tu propia lista de pendientes y el patrón es difícil de no ver. Energía, gas, carga, daños, puertas, conectores, ascensores, atraque: las tareas que repites cada sesión son casi todas un valor cruzando una línea, en una dirección o en la otra. Esa es exactamente la observación sobre la que actuó Keen. El Controlador de Eventos se construyó para exponer en el juego vanilla un conjunto de funcionalidad que antes solo era alcanzable mediante scripting y modding, y lo hizo a propósito, en un bloque diseñado para entenderse en vez de programarse. La consecuencia merece deletrearse para el lector al que iba dirigido: todo lo de esta sección funciona en Xbox y PlayStation. No hay ninguna opción de mundo que cambiar, ningún modo que activar, nada que pedirle a un administrador de servidor y ni una línea de C# en ningún sitio. Si juegas en consola, esto no es un adelanto de la herramienta de verdad: es la herramienta, y cubre la mayor parte del trabajo.
Por eso la forma honesta de la mayoría de la automatización de estación es más pequeña de lo que suena: un Controlador de Eventos vigilando un valor, y dos Temporizadores con nombre haciendo el trabajo. Construye eso esta noche para el banco de reactores y habrás automatizado una tarea que has hecho cien veces.
Un controlador vigilando un bloque es simple. Sigue siendo simple hasta justo el momento en que lo apuntas a varios bloques a la vez, o le das una acción que alterna un estado en vez de fijarlo, y esas son las dos trampas que rompen la mayoría de las construcciones reales.
Un evento por controlador: puertas AND, disparos dobles y por qué tus acciones reales van en temporizadores
Las dos trampas vienen del mismo hueco. Un Controlador de Eventos es una máquina más simple que la frase que dices en voz alta cuando describes lo que quieres, e implementará la regla que configuraste y no la que querías decir. «Dispara cuando las puertas estén cerradas» y «dispara cuando una puerta se cierre» son instrucciones distintas. «Bloquea ese conector» y «alterna el bloqueo de ese conector» son instrucciones distintas. Una casilla y una elección descuidada de acción explican la mayoría de las construcciones que funcionan a medias.
Primero la casilla. Al fondo de la pantalla de configuración, debajo de los bloques que seleccionaste, está AND Gate. Solo aparece para eventos de bloque —una medida de cuadrícula como Altitude o Grid Speed no tiene nada que agregar— y con un solo bloque seleccionado no cambia nada, y por eso es fácil encontrártela por primera vez el día que añades un segundo bloque y tu construcción deja de comportarse. Decide cómo se reducen varios bloques vigilados a una sola respuesta de verdadero o falso, y los dos ajustes no son imágenes especulares el uno del otro:
- AND Gate desactivada. La ranura 1 se dispara cuando alguno de los bloques elegidos cumple la condición. La ranura 2 se dispara cuando ninguno de los bloques elegidos la cumple.
- AND Gate activada. La ranura 1 se dispara cuando todos los bloques elegidos cumplen la condición. La ranura 2 se dispara cuando algunos o ninguno la cumplen.
Lee esas dos líneas de la ranura 2 dos veces, porque ahí es donde vive la diferencia. Con la puerta desactivada, la rama falsa es un «vía libre»: ni uno solo de los bloques vigilados está en el estado por el que preguntaste. Con la puerta activada, la rama falsa se dispara en cuanto el conjunto deja de ser unánime, lo que puede significar perfectamente «tres de los cuatro siguen en ese estado».
La wiki oficial enseña la elección con tres preguntas en vez de con una regla, y son mejores que una regla porque te obligan a responder por tu propia base. ¿Encender los reactores cuando algún tanque o batería esté vacío, o solo cuando lo estén todos? ¿Sonar una alarma cuando algún bloque de armamento esté dañado, o solo cuando lo estén todos? ¿Represurizar la sala cuando alguna de sus puertas se cierre, o cuando se hayan cerrado todas? Di cada versión en voz alta y una de ellas es obviamente la base en la que quieres vivir. Ningún ajuste es el valor seguro por defecto; son dos reglas distintas y tienes que elegir.
Coge la última de esas y constrúyela de las dos maneras, sobre el mismo par de puertas a ambos lados de una cámara pequeña. Un Controlador de Eventos, evento Door Opened, las dos puertas añadidas en Available Blocks.
Con AND Gate desactivada, la ranura 1 se dispara en el instante en que cualquiera de las dos puertas se declara totalmente abierta, y la ranura 2 se dispara solo cuando ninguna lo está; es decir, cuando la última puerta del par termina de cerrarse. La ranura 2 es una señal genuina de «la cámara está sellada», y no se disparará antes de tiempo sin importar qué puerta uses ni en qué orden.
Activa AND Gate y el mismo controlador se comporta como un bloque distinto. La ranura 1 ahora espera hasta que las dos puertas estén abiertas a la vez, que es algo perfectamente razonable de querer si estás iluminando un pasaje o dejando que un rover lo cruce del tirón. Pero la ranura 2 ahora se dispara en cuanto el conjunto deja de ser unánime: cierra una puerta y la rama falsa se ejecuta mientras la otra sigue abierta de par en par.
Así que la pregunta que de verdad decide el ajuste no es «¿mi regla es un AND o un OR?». Es: ¿qué rama lleva la acción de la que necesito estar seguro? Pon una acción crítica para la seguridad en la ranura 2 y quieres la puerta desactivada, porque desactivada es el ajuste cuya rama falsa significa «ni uno de ellos». Ponla en la ranura 1 y quieres la puerta activada, porque activada es el ajuste cuya rama verdadera significa «todos y cada uno».
Esa distinción —reaccionar al estado de un conjunto de bloques frente a reaccionar a un evento que le acaba de pasar a uno de ellos— tiene algo de historia detrás, y conviene conocerla porque todavía aparece en construcciones antiguas. Antes de la actualización 1.203 «Warfare Evolution», en agosto de 2023, un Controlador de Eventos con la AND Gate desactivada no evaluaba el estado agregado en absoluto.
Reaccionaba a los eventos en el momento en que ocurrían, y la ilustración con la que la propia wiki lo trabaja es memorable: las dos puertas cerradas, así que ranura 2. La puerta A se abre, así que ranura 1. La puerta B se abre, así que ranura 1 otra vez. Entonces la puerta A se cierra, y se dispara la ranura 2, aunque la puerta B siga abierta. Las situaciones dos y cuatro eran físicamente idénticas —una puerta abierta y una cerrada— y el bloque las reportaba de forma distinta.
La línea del changelog de la 1.203 es una sola frase: se añadió funcionalidad para hacer una puerta AND/OR en condiciones. Ese es el comportamiento descrito arriba, y hoy no es defectuoso. Pero un montaje que guardaste como plano antes de agosto de 2023, o una guía escrita antes de esa fecha, puede haberse construido en torno al comportamiento antiguo y puede que necesite una revisión.
La segunda trampa es de la que nadie te avisa, porque no produce ningún error y no deja rastro. El Controlador de Eventos a veces se dispara dos veces en la misma ranura. Que eso importe o no depende enteramente del tipo de acción que hayas puesto ahí. Algunas acciones fijan un valor: «unlock», «on», «off», «open». Dispara una de esas dos veces y el segundo disparo no cambia nada, porque el bloque ya está en el estado que se le exige. Otras acciones alternan el estado actual: «switch lock» es el ejemplo de la propia wiki. Dispara esa dos veces y el conector se bloquea y luego se desbloquea. Tu controlador hizo exactamente lo que le pediste, dos veces, y tu nave está ahora en una plataforma sin bloquear, con una construcción que pasa la prueba perfectamente cada vez que la miras y falla la noche en que no.
No puedes ver esto pasar mirando la base. Las luces, los emisivos y los LCD no pueden mostrar una repetición, porque una luz a la que se le dice que se encienda dos veces se ve exactamente igual que una luz a la que se le dice que se encienda una. La forma documentada de cazarlo es poner un Broadcast Controller en cada ranura con un mensaje distinto en cada una, y mirar el chat mientras ejercitas la condición. Dos líneas de «ranura 1» seguidas y has encontrado tu fallo.
El arreglo limpio no es arreglarlo, es dejar de usar alternadores. «Unlock» en la ranura 1 y «lock» en la ranura 2 hace el mismo trabajo que «switch lock» en las dos, y es inmune a las repeticiones por construcción. Cuando de verdad no puedas evitar un alternador, hay dos formas documentadas que absorben el disparo doble por ti.
La primera gasta un segundo controlador. El primer Controlador de Eventos no lleva ninguna acción real: la ranura 1 enciende algún bloque con estado de encendido/apagado, y la ranura 2 lo apaga. Esas son acciones de fijar valor, así que las repeticiones son inofensivas. Un segundo Controlador de Eventos vigila entonces el estado de encendido de ese bloque y lleva el trabajo de verdad.
La segunda gasta dos Temporizadores, y es la versión que merece la pena construir porque usa la disciplina que ya tienes. La ranura 1 del Controlador de Eventos hace una cosa: Trigger Now sobre un Temporizador llamado Dock-Lock. La ranura 2 hace una cosa: Trigger Now sobre Dock-Release. Después, la barra de herramientas de cada Temporizador empieza apagándose a sí mismo y encendiendo al otro Temporizador, antes de ejecutar las acciones reales: bloquear el conector, extender la pasarela, abrir las puertas; o desbloquear, retraer, sellar. Una repetición aterriza ahora en un bloque que ya se ha apagado solo y no está escuchando, así que el segundo disparo no hace nada. La plataforma se arma y se desarma sola, un lado cada vez.
Eso sí significa que la mitad de tu batería de Temporizadores estará en rojo en cualquier momento, y rojo en un Temporizador significa apagado o sin energía, lo cual aquí es correcto y no una avería. Los propios controladores se leen igual de un vistazo: rojo para apagado o sin energía, verde para con energía pero sin haber disparado todavía, cian cuando la ranura 1 fue la última en dispararse, azul cuando lo fue la ranura 2. Un aviso te ahorra una tarde de confusión: ni el cian ni el azul aparecen si esa ranura está vacía en todas las páginas. Un controlador cuya ranura 2 dejaste en blanco a propósito nunca se pondrá azul, y no le pasa nada.
Lo que nos lleva a qué aspecto tiene de verdad la lógica de una estación real, porque no es un controlador ingenioso. Cuenta con uno o dos Controladores de Eventos para automatización básica y bastantes más para cadenas. Cada frase de «si este valor pasa de tal número, entonces haz esto, si no haz aquello» que tengas en la cabeza es un Controlador de Eventos y uno o dos Temporizadores en la pared, y la wiki no suaviza el panorama: al final, tu puente parecerá la sala de servidores de un mainframe y tu dron tendrá un cerebro grande dentro del cráneo. Nómbralos a todos por lo que hacen, porque dentro de seis meses los nombres serán toda la documentación que tengas. Si la batería empieza a comerse el suelo de tu estación, construye todo el conjunto con Controladores de Eventos y Temporizadores de cuadrícula pequeña y engánchalo a la cuadrícula grande mediante un rotor bloqueado: la misma lógica, una fracción del espacio y de los componentes.
La impresora 3D es a lo que se parece esa batería cuando ya está haciendo algo impresionante. Un proyector sobre un rotor sobre pistones, soldadores en sus propios pistones, y detrás de ellos un banco de Controladores de Eventos, cada uno respondiendo exactamente una pregunta física sobre la plataforma: ¿se ha fusionado el Merge Block?, ¿se ha acoplado o desacoplado el rotor o la bisagra?, ¿ha alcanzado Block Integrity el valor que significa que esta impresión está terminada? Cada movimiento en sí vive en un Temporizador. Nadie diseñó eso como un solo sistema; se ensambló una pregunta y un movimiento cada vez, que es precisamente por lo que se puede depurar cuando una impresión se atasca a medias.
Así que: prefiere acciones que fijen un valor antes que acciones que lo alternen, y reserva los alternadores para las dos formas de arriba. Decide ALGUNO o TODOS deliberadamente cada vez que un controlador vigile más de un bloque, preguntándote de qué rama te estás fiando. Guarda el trabajo real en Temporizadores con nombre para que haya un sitio donde editar y un sitio donde mirar. Y deja de esperar una construcción ordenada: una estación que automatiza una docena de tareas parece una batería de cubos baratos, y esa es la forma que sigue siendo diagnosticable.
Todas las trampas hasta aquí han estado dentro de una cuadrícula. Lo único que esta capa genuinamente no podía hacer —llegar a una cuadrícula distinta— no era una trampa en absoluto. Era un límite duro, y un bloque lo arregló en 2024.
Cuando lo que quieres disparar está en otra cuadrícula: el Action Relay
El bloque es el Action Relay, y llegó en la actualización 1.204 «Signal» en mayo de 2024. La wiki registra el límite que eliminó en un paréntesis que merece leerse despacio: antes del Action Relay era posible —salvo con scripts o fallos— disparar acciones solo en la misma cuadrícula. Esa es toda la razón por la que la respuesta honesta a «¿puedo abrir la puerta del hangar de la estación desde la cabina de mi nave?» solía ser un script. La tarea nunca fue difícil computacionalmente. Nada en la capa de barra de herramientas podía cruzar sin más una frontera entre cuadrículas, así que la única herramienta que podía cruzarla era la que ignoraba la capa por completo.
La comparación que hace la propia wiki para el arreglo es un mando de puerta de garaje, o un mando de televisión. Pulsas algo aquí y algo de allí responde. Mecánicamente son dos bloques, uno en cada cuadrícula, hablando por la red de antenas, lo que significa que el primer requisito no es el relé en absoluto. Cada cuadrícula necesita una antena con alcance suficiente para cubrir la distancia, y el alcance de esa antena es el alcance del relé.
Los ajustes son pocos y caben en una lista. Channel es un número del 1 al 100, por defecto 1, y tiene que coincidir en los dos extremos: ese es todo el esquema de direccionamiento. Accept Signal From es propietario, facción o todos, y el consejo de la wiki es permitir solo a ti mismo o a tu facción; un relé configurado para aceptar de todos es un botón que cualquiera con un relé y una corazonada sobre tu canal tiene derecho a pulsar. Set Up Actions contiene lo que pasa cuando llega una señal, y hay un botón Send Signal en el bloque para disparar una a mano. El relé también funciona en los dos sentidos en vez de ser un transmisor o un receptor dedicado: el mismo bloque puede recibir una señal y disparar acciones en su propia cuadrícula, o enviar una que dispare acciones en el relé de otra cuadrícula.
La única restricción que da forma a tu construcción es la capacidad. Cada Action Relay guarda un conjunto de acciones y escucha un canal, así que necesitas un relé por cada conjunto de acciones, y la nota de la propia wiki es que esas acciones pueden vivir en Bloques de Temporizador, que es la misma disciplina que llevas aplicando desde el Sensor. El relé es un timbre, no una sala de control.
Así que construye la puerta de hangar remota. En la estación, un Action Relay llamado Hangar-Remote-Open, canal 7, Accept Signal From en facción, y una sola acción en su conjunto: Trigger Now sobre un Temporizador llamado Hangar-Open que sube la puerta, enciende las luces de la bahía y hace cualquier otra cosa que deba significar que llegas. Como un relé lleva un conjunto de acciones, cerrar de nuevo es un segundo relé: Hangar-Remote-Close en el canal 8, apuntando a Hangar-Close. En la nave, un relé a juego en cada canal, con su Send Signal disponible para ti desde la cabina o aparcado en un Temporizador junto al resto de tu secuencia de aproximación. Las dos cuadrículas necesitan una antena con alcance para cubrir la distancia que de verdad vuelas. Esa es toda la construcción: cuatro cubos baratos, dos antenas que ya tenías y dos Temporizadores del tipo que llevas nombrando desde la cadena de atraque.
Luego fíjate en qué aspecto tenía esa misma tarea antes de mayo de 2024. Hangar idéntico, puerta idéntica, Temporizador idéntico, y la única forma de dispararlo desde la nave era un Bloque Programable, un script que alguien hubiera escrito y un mundo que permitiera ejecutar scripts.
La misma forma cubre todo aquello para lo que la wiki lista el bloque, y todo ello es trabajo de estación reconocible: apagar tus propias torretas antes de remolcar un pecio capturado a la bahía, llamar a los drones para que atraquen, despachar drones de defensa mientras estás fuera, pedir ayuda a un dron, o recoger un panel solar o un satélite de antena láser. En todos ellos la parte que suena difícil no es la acción: es que lo que actúa y lo que decide están en cuadrículas separadas.
Que es la comprobación que merece la pena hacer antes de concluir que una tarea necesita código. Pregúntate qué la está haciendo difícil de verdad. Si la respuesta es que necesitas un número exacto calculado y escrito, eso sí es un escalón más alto. Pero si la respuesta es solo que el disparador está aquí y la maquinaria está allí, el hueco es una frontera entre cuadrículas, y una frontera entre cuadrículas cuesta ahora dos bloques y una antena.
Con eso se cierra lo último que esta capa no podía hacer. A partir de aquí, el scripting ya no hereda ninguna tarea por defecto: tiene que ganarse su sitio por sus propios méritos, y el primero de esos méritos es si puedes ejecutar un script siquiera.
Antes de nada de C#: la puerta de acceso y cómo cargar el script de otra persona
Todos los bloques de esta guía hasta ahora te han pedido una cosa: los componentes para construirlos. El Bloque Programable es el primero que además pide permiso. Cuatro requisitos se plantan delante de cualquier script in-game, y solo el último vive dentro del bloque:
- Los scripts solo funcionan en PC —Steam o la Microsoft Store— y en servidores dedicados. En consolas no.
- Los scripts solo funcionan si el modo Experimental está activado en las Opciones.
- Los scripts solo funcionan si los scripts in-game están activados en los World Settings.
- Un Bloque Programable ejecuta un script solo mientras tiene energía.
Tres ajustes y un fusible. En tu propio PC ninguno es difícil de satisfacer, pero se apilan en un orden concreto, y ese orden es la razón por la que tantos jugadores concluyen que la función no existe en vez de que está apagada.
El modo Experimental es el primer interruptor porque es el que hace visible al segundo. Se activa desde la pantalla principal, en Options > Game > General, y es global: una propiedad de tu instalación, no de una partida. Si lo encuentras en gris cuando vayas a buscarlo, no es un fallo ni un problema de permisos: tienes un mundo abierto, y tienes que guardarlo y volver a la pantalla principal antes de poder cambiar la opción. Solo una vez activado el modo Experimental aparece la entrada de scripts in-game entre los ajustes avanzados de un mundo; antes de eso, estás buscando un control que el juego no ha dibujado.
La parte en la que conviene detenerse es que esta decisión no se deshace del todo. Puedes volver a desactivar el modo Experimental más adelante, pero cualquier mundo que hayas creado mientras estaba activo funcionará solo en modo Experimental, de forma permanente. Activarlo para probar un script sale barato; empezar una partida nueva mientras está activo compromete esa partida al modo Experimental para el resto de su vida. También tendrás un aviso permanente dentro del juego mientras el modo esté activo, que se puede silenciar en las opciones de avisos pero que por lo demás es un recordatorio constante de que estás fuera de la configuración por defecto. Si quieres probar el scripting sin ese compromiso, hazlo en un mundo que ya exista.
El requisito de energía suena demasiado obvio para mencionarlo hasta la tarde en que te cuesta una hora. Un Bloque Programable cuya sección de cuadrícula se ha quedado a oscuras no es un bloque que da error, es un bloque silencioso. Cuando un script que funcionaba ayer no hace nada hoy y la puerta de acceso no ha cambiado, comprueba que el bloque tiene energía antes de comprobar cualquier otra cosa.
En el servidor de otra persona aparecen dos puertas más, y ninguna es un ajuste tuyo. La primera es el rol de scripter —un permiso de rango que concede un administrador— y su síntoma es preciso: el botón Edit del Bloque Programable aparece en gris en vez de no aparecer. La segunda es sencillamente la política del administrador, porque un administrador puede prohibir algunos scripts o todos. El aviso de la wiki sobre esto es más contundente que ninguna otra cosa de la página: muchos administradores de servidores multijugador castigarán o directamente banearán a los jugadores que ejecuten scripts intensivos en rendimiento, y te pide que seas considerado con los demás jugadores con los que compartes el servidor. La razón es el rendimiento: cada script de ese servidor está gastando algo que comparte el servidor entero, y la aritmética que hay detrás es una sección propia más abajo. La consecuencia práctica por ahora es el consejo de la propia wiki: no te apoyes en scripts fuera de tus partidas en solitario, porque el permiso se puede retirar y la tarea que construiste a su alrededor deja de funcionar.
Luego está la línea de plataformas, y conviene ser directo sobre a quién excluye. Space Engineers llegó a PlayStation 4 y 5 en mayo de 2023; esos jugadores nunca han podido ejecutar un script in-game en un mundo alojado por ellos, y los de Xbox tampoco. Hay una vía de escape, y es real: la restricción es sobre los mundos alojados en consola. Un jugador de consola puede unirse a un servidor dedicado que tenga los scripts in-game activados y jugar en un mundo donde los scripts se ejecutan. Lo que un jugador de consola no puede hacer es activar esto en su propia partida. Que es precisamente por lo que el Controlador de Eventos importaba tanto tres secciones atrás: todo lo de ese escalón funciona en tu consola sin nada de esto por delante.
Un consejo que encontrarás circulando merece una corrección antes de que te haga perder el tiempo. La actualización 1.206 «Fieldwork», en abril de 2025, sí eliminó el requisito de Experimental, para los mods. Desde esa actualización puedes instalar mods en un mundo normal, en modo Safe. Los scripts no formaron parte de ese cambio, y el Bloque Programable sigue estando en la propia lista de funciones experimentales del juego. Así que cuando encuentres una publicación que diga que la puerta del Experimental ha desaparecido, lee la palabra siguiente con cuidado: si dice mods, es correcta y no va contigo.
Superado todo eso, la realidad del día a día de usar scripts es un anticlímax, porque la mayoría de quienes ejecutan scripts no los escriben. Empieza en el Steam Workshop y filtra por Type: InGameScript. Esto importa más de lo que parece: hay un filtro aparte de «Mod category: Script», y la wiki señala la confusión por su nombre, porque ese devuelve mods, que son otra cosa distinta, se cargan de otra forma y no se pueden pegar en un bloque. Suscríbete a lo que quieras.
En el juego llegas al editor de dos maneras: haz clic derecho sobre la interfaz del Bloque Programable en el mundo, o pulsa F mirándolo; o abre el Terminal de la cuadrícula y haz clic en Edit en la pantalla de Control Panel. El editor se abre sobre un script por defecto vacío con los ganchos básicos ya puestos. A partir de ahí:
- Browse Scripts: elige uno de tus scripts suscritos.
- Copy to Editor: pasa al editor que tienes delante.
- Cambia las líneas que la descripción del script te haya dicho que cambies.
- Check Code: o informa de «Compilation successful» o te señala el error.
- OK: esto lo guarda.
- Custom Data: si el script admite configuración, escribe ahí los valores y confirma.
- Recompile: el bloque no recoge los custom data hasta que lo hagas.
- Argument: si el script admite uno, escríbelo en este campo.
- Run. Lo que el script tenga que decirte aparece en la esquina inferior derecha de tu pantalla.
Cuenta con que esa descripción te pida algo. Los scripts del Workshop suelen exigir que edites ciertas líneas, que introduzcas ciertos argumentos, que renombres ciertos bloques de tu cuadrícula o que introduzcas ciertas palabras clave como custom data. El requisito de renombrar es el que la gente se salta y luego reporta como script roto: si las instrucciones del autor dicen que tus contenedores de carga necesitan una palabra concreta en el nombre, el script no hará nada útil hasta que la tengan. Leer la descripción forma parte de instalar el script, no es contexto opcional a su alrededor.
Lo que nos lleva a los dos partes de incidencia que todo jugador con scripts acaba presentando, porque desde fuera parecen idénticos y no tienen nada en común.
«El botón Edit no está o está en gris». Esto siempre es la puerta de acceso, y lo diagnosticas recorriéndola hacia atrás. En gris concretamente, en un servidor, significa el rol de scripter: pídeselo a un administrador. Ausente del todo, en tu propio mundo, significa que los scripts in-game están desactivados en los World Settings; y si no encuentras ese ajuste para activarlo, es porque el modo Experimental está apagado y el juego no lo está mostrando. En consola, en un mundo alojado en consola, ningún ajuste de ningún sitio lo arregla, porque no hay nada que arreglar.
«Mi script de inventario ha dejado de ver mis contenedores de carga nuevos». Esto no tiene nada que ver con permisos y no produce ningún error. Añadir bloques, quitar bloques, renombrar bloques y añadir o quitar grupos de bloques no lo detecta la mayoría de los scripts. El script sigue trabajando con la foto de tu cuadrícula que tenía la última vez que se compiló, y tu reforma ocurrió después. Haz clic en Recompile y vuelve a mirar. Por eso un script que funcionó impecablemente durante seis meses «se rompe» la tarde después de que amplíes la bahía de carga, y por eso Recompile merece ser lo primero que pruebes, no lo último.
Un fallo es de permisos y el otro es de obsolescencia, y ninguno se anuncia. Así que convierte las dos comprobaciones en costumbre. Antes de planificar cualquier parte de una base alrededor de un script, confirma que de verdad puedes ejecutarlo, sobre todo en el servidor de otra persona, donde la respuesta puede ser no y donde es una pregunta mucho más barata de hacer antes de construir la cuadrícula que después. Y después de cualquier cambio significativo en una nave o estación que lleve un script, pulsa Recompile por reflejo, antes de ponerte a buscar un fallo que no existe.
Ese es todo el precio de la entrada, y para un jugador de PC en su propio mundo se reduce a dos ajustes y un pegado. Lo que deja la pregunta más interesante para quien acaba de soltar cien líneas de C# ajeno en un bloque y pulsar Run: ¿qué hay ahí dentro exactamente, y a qué puede llegar un script que nada más abajo en esta escalera alcanza?
Qué aspecto tiene realmente un script de Bloque Programable, y a qué puede llegar
Abre el editor en un Bloque Programable que acabas de colocar y no está en blanco. Quítale los comentarios a lo que pone ahí el juego y te quedan tres métodos:
public Program()
{
}
public void Save()
{
}
public void Main(string argument)
{
}
Ese es el marco. Las cien líneas que pegaste hace un momento son el trabajo de alguien rellenado a su alrededor, y todos los scripts in-game que existen —los gestores de inventario, los alineadores solares, los sistemas de vuelo de empuje vectorial— se sientan dentro de esos mismos tres puntos de entrada. Dos de ellos puedes borrarlos.
public Program() es el constructor. Es para la inicialización de una sola vez, y se ejecuta una vez cada vez que se instancia tu script, lo que en la práctica significa una vez después de que cargue tu partida y una vez después de que pulses Recompile. Ese es el mismo Recompile de la sección anterior, visto desde dentro: pulsarlo no le da un empujón a un script en marcha, construye una instancia nueva y ejecuta este método otra vez desde arriba. Opcional.
public void Save() se llama cada vez que se guarda la partida, o justo antes de que recompiles. Es donde guardas cualquier cosa que tenga que sobrevivir entre sesiones de juego. También opcional, y la mayoría de los scripts cortos no lo tienen.
public void Main(string argument) es el obligatorio: el punto de entrada principal, llamado muchas veces durante la vida de un script. El argumento se pasa desde el juego según tu configuración de barra de herramientas. Cuando arrastras el Bloque Programable a la barra de un panel de botones, un sensor o un temporizador y eliges Run, te dan una caja de entrada, y lo que escribas ahí llega aquí como esa cadena. Se pasa literalmente: sin recortar espacios, sin cambiar mayúsculas, sin interpretar. Si las instrucciones del script dicen que el argumento es reset y tú escribes Reset , le has entregado una palabra distinta.
Lo que nunca ves es la clase en la que viven esos tres métodos. Una clase de script se llama siempre Program y hereda siempre de MyGridProgram; Space Engineers envuelve tu código en namespace IngameScript { partial class Program : MyGridProgram { ... } } por detrás, y solo lo que hay dentro de esa clase es realmente tu script. La envoltura no es papeleo. Es de donde vienen GridTerminalSystem y Echo: los heredas, y por eso funcionan en un archivo que nunca los declara y por eso pegar un fragmento en un proyecto de C# normal fuera del juego no te da nada. (Esta es también la superficie que la gente confunde: la API de modding y el Visual Script Editor también son C#, y ninguno de los dos es lo que ejecuta un Bloque Programable.)
El primer script de la propia wiki usa casi todo lo anterior a la vez:
public void Main()
{
IMyInteriorLight light;
light = GridTerminalSystem.GetBlockWithName("That Important Light") as IMyInteriorLight;
if (light == null)
{
Echo("Oh my! I couldn't find that block...");
return;
}
light.Enabled = !light.Enabled;
Echo("I have toggled the button!");
}
Léelo en orden. GetBlockWithName le pide al Grid Terminal System un bloque por su nombre personalizado, el nombre del Terminal, exactamente como está escrito. as IMyInteriorLight es un cast seguro: si el bloque que encontró no es una luz interior, no obtienes un error, obtienes null. Luego la guarda, que existe porque la búsqueda puede fallar calladamente, y Echo, que escribe texto de diagnóstico en el propio panel de detalles del Bloque Programable: es la única forma que tiene el script de hablar contigo. Por último, light.Enabled = !light.Enabled invierte el estado en el que estuviera la luz.
El procedimiento que lo acompaña merece hacerse una vez, porque lleva dos minutos. Coloca una luz interior y un Bloque Programable. Renombra la luz exactamente a That Important Light: los espacios importan. Abre el editor, pega, haz clic en Check code, luego en Remember & Exit, y después pulsa Run. La luz responde al cabo de aproximadamente un segundo.
Ahora rómpelo a propósito: pon un espacio de más en el nombre de la luz. El script sigue compilando, sigue ejecutándose, y ahora imprime «Oh my! I couldn't find that block…» para siempre. GetBlockWithName es exacto, distingue mayúsculas y distingue espacios, y devuelve null cuando no coincide nada. Esa es la razón más común, con diferencia, por la que un script del Workshop «deja de funcionar» tras una reforma, y es la misma fragilidad que hacía necesario el Recompile una sección atrás: los scripts se dirigen a tu base por nombre, y los nombres los rompes tú.
Hay búsquedas más indulgentes cuando las quieres. SearchBlocksOfName encuentra todos los bloques cuyo nombre meramente contiene el texto, sin distinguir mayúsculas, y por eso tantos scripts te piden poner una palabra de etiqueta en los nombres de tus contenedores. GetBlocksOfType<T> llena una lista con todo lo de un tipo dado y limpia esa lista primero, y admite un filtro opcional: GetBlocksOfType(lights, light => light.Enabled) recoge solo las luces que están encendidas. Junto a esas están GetBlockGroupWithName (exacto y sensible a mayúsculas, como su primo de un solo bloque), GetBlockWithId para el ID de entidad de un bloque, y CanAccess, que devuelve falso si un bloque ha sido destruido, desconectado o le han cambiado la propiedad por debajo al script.
Ese último apunta a la frontera de todo el sistema, y la frontera es más específica de lo que supondrías. El Grid Terminal System da acceso a todos los bloques de la misma cuadrícula en la que está el Bloque Programable, más cualquier cuadrícula conectada mediante rotores, pistones o conectores —no trenes de aterrizaje—, y solo mientras esos bloques compartan la misma propiedad que el Bloque Programable en ejecución. Dos líneas de eso merecen subrayarse. Un tren de aterrizaje es una unión mecánica perfectamente válida que el Grid Terminal System no atraviesa, así que una plataforma que funciona atracada en un conector se queda ciega cuando la sujetas con él. Y la propiedad es una condición viva, no una comprobación de una sola vez: los bloques que pertenecen a otra persona no están en el mundo del script en absoluto, y por eso una cuadrícula enemiga capturada no cae sin más bajo tu script cuando le sueldas un conector.
La segunda cosa que hace un script y nada por debajo puede es programarse a sí mismo. Runtime.UpdateFrequency permite que un Bloque Programable se ejecute por su cuenta sin ningún Bloque de Temporizador en la construcción. Admite Once (el siguiente fotograma, y para), Update1 (cada tick), Update10, Update100, o None, que es el valor por defecto y la razón por la que un bloque recién puesto se queda quieto hasta que pulsas Run. Se fija en el constructor. Es un enum de banderas, así que los valores se combinan bit a bit: UpdateFrequency.Once | UpdateFrequency.Update100 pide una primera pasada inmediata y luego un ritmo estable.
Sé honesto sobre lo que vale ese ritmo, eso sí, porque la documentación lo es. Fijar esas banderas no garantiza el intervalo que pediste; la wiki las llama más una sugerencia educada que una orden, y en un caso peor poco frecuente el hueco podría estirarse hasta casi el doble de lo que pediste. Update1 y Once son las excepciones y están prácticamente garantizadas, que es exactamente la opción con la que hay que tener cuidado, por razones de las que se ocupa la siguiente sección. Para dimensionar todo esto: un tick es una sesentava parte de segundo, unos 16.667 ms, y a efectos de scripting puedes asumir 60 ticks por segundo haga lo que haga tu sim-speed.
Una vez que un bloque puede ser arrancado por un botón, un temporizador, otro script y su propia programación, necesita saber cuál de esas cosas acaba de ocurrir. Esa es la segunda forma del punto de entrada:
public void Main(string argument, UpdateType updateType)
{
if ((updateType & (UpdateType.Trigger | UpdateType.Terminal)) != 0)
RunCommand(argument);
if ((updateType & UpdateType.Update100) != 0)
RunContinuousLogic();
}
UpdateType informa de por qué ocurrió esta ejecución. Trigger significa un botón, un temporizador, un sensor u otro disparador simple. Script significa otro bloque programable. Terminal significa tú, a mano, desde el terminal. Mod significa que lo llamó un mod. IGC significa que llegó un mensaje por el sistema de comunicación por antena. Y Once, Update1, Update10 y Update100 son las llamadas automáticas del UpdateFrequency correspondiente.
El & no es estilístico. Puede haber más de una bandera activa en la misma llamada —si tienes Update1 y Update100 activados a la vez y coinciden en el mismo tick, el parámetro lleva las dos—, así que un switch simple no puede clasificarlo. Compruebas los bits. (updateType.HasFlag existe y hace el mismo trabajo, pero tiene un impacto significativo en el rendimiento y no se recomienda.) Fíjate también en que la bandera que compruebas tiene que ser la frecuencia que realmente pediste en el constructor; las dos líneas son una pareja, y un ejemplo mal emparejado es un script cuyo bucle nunca se ejecuta.
Ese bloquecito es el momento concreto en que un script deja de sentarse encima de la escalera y empieza a sustituir escalones de ella. La mitad de arriba se ocupa de que tú pulses un botón; la de abajo es el bucle, y el bucle no es una cadena de Temporizadores reiniciándose unos a otros con retardos estimados, es el bloque pidiéndole al juego que lo vuelva a llamar. Todo el montaje del Temporizador director de antes, con su diagrama de cajas y flechas, se colapsa en una línea dentro de un constructor.
Viene con una trampa, y pilla a quien acaba de descubrir los argumentos. Un argumento se pasa a Main() solo para esa única invocación. Si el script sigue ejecutándose después mediante UpdateFrequency, esas llamadas automáticas reciben una cadena vacía. El comando que escribiste no persiste dentro del bucle; si el bucle necesita recordarlo, el script tiene que guardarlo deliberadamente.
Así que ya puedes leer un script que no escribiste. Puedes ver, en las primeras veinte líneas, si quiere nombres de bloque exactos o etiquetados, si se programa solo o espera a que le digan, y cuáles de tus bloques sencillamente no encontrará nunca. Y más útil todavía: puedes saber si la tarea que tienes delante necesita uno de verdad. Dos cosas aquí arriba son genuinamente inalcanzables abajo: escribir un valor exacto y ejecutarse con una programación que mantiene el juego. Si tu tarea no necesita ninguna de las dos —y la mayoría de las tareas de estación no necesitan ninguna—, lo que tienes delante es una tarea de escalón intermedio con bata de laboratorio.
Lo que plantea la pregunta obvia sobre un bloque que puede pedir que lo llamen sesenta veces por segundo, en cada cuadrícula, en un mundo lleno de bloques de otra gente haciendo lo mismo. Alguien está pagando eso, y la respuesta a quién es por lo que el escalón de arriba lleva un coste social que los otros no.
Por qué los administradores banean scripts: el presupuesto de 16.667 milisegundos que estás gastando
Todo el mundo. Esa es la respuesta entera, y la aritmética que hay detrás es lo bastante corta como para comprobarla tú mismo.
Ya tienes el número de hace un momento: un tick es una sesentava parte de segundo, unos 16.667 ms. Lo que mide ese número merece deletrearse, porque no es un presupuesto para scripts. Es el presupuesto para todo el juego. Dentro de cada una de esas ventanas Space Engineers tiene que ejecutar su lógica de juego, gestionar la red, simular la física, ejecutar el código de mods que haya cargado y ejecutar todos los bloques programables del mundo, y tiene que hacerlo todo en secuencia, porque es un solo hilo. Un Bloque Programable no tiene un carril propio. Se ejecuta en el hilo principal, en la misma cola que la física que mantiene tu estación de una pieza. Cuando el tiempo total de un tick pasa de 16.667 ms, el juego no lo recupera: se queda atrás. Eso es lo que es una sim-speed baja, vista desde dentro.
Y luego la wiki aporta la escala, y la escala es la parte que lo reencuadra todo: para contextualizar, 1 ms es muy lento. Un milisegundo. Una dieciseisava parte del fotograma, para un script, en una cuadrícula.
Ahora haz la multiplicación, porque esta es la parte que nadie hace antes de pulsar Run. Tu programa no es un bloque. Un script es una cosa que se pega, así que se pega: en el Bloque Programable de tu base, en el de la plataforma minera, en el de cada uno de los drones, y en las cuadrículas de tus compañeros de facción después de que les digas que es bueno. Si una copia tarda 1 ms, diez Bloques Programables ejecutándolo se comen 10 ms de un tick de 16.667 ms, y el servidor los ejecuta todos. En ese punto no ha ido nada mal. Ningún script se ha colgado, no se ha superado ningún límite, nadie ha escrito nada malicioso. Diez personas instalaron cada una un ordenador de inventario útil y entre todas se comieron casi todo el fotograma, y la caída de sim-speed le cae a todo el mundo por igual, incluidos los jugadores que no han abierto un Bloque Programable en su vida.
Ese es el baneo, explicado. No es control de acceso ni un juicio sobre quién merece la herramienta. Es una persona decidiendo cómo gastar algo que no es solo suyo.
Hay un número para tu propio script, y merece la pena saber dónde vive. Runtime.LastRunTimeMs te da el tiempo real, en milisegundos fraccionarios, que tardó la última ejecución de Main: existe precisamente para que puedas medir el tiempo de ejecución en vez de suponerlo. Imprímelo con Echo y podrás ver tu propia aportación al fotograma, en las unidades en las que el fotograma está denominado.
Lo que no te dirá eso, pese a parecer exactamente que debería, es el contador de instrucciones, y esta es la lectura errónea más común de los límites documentados, así que conviene ser preciso sobre qué son esos límites y para qué sirven. Hay tres. Ningún script puede tener más de 100,000 caracteres. Ninguna ejecución individual puede pasar de 50,000 uniones de código, donde una unión es una llamada a método, un switch, un condicional, un bucle o algo similar; las sentencias simples como 1+1 no cuentan para él. Y una whitelist de .NET restringe a qué partes del framework puedes llegar siquiera, y por eso un tipo como System.Threading.Thread sencillamente no está disponible: no hay escapatoria a un hilo propio, porque la whitelist no te deja pedirlo.
El tope de caracteres y la whitelist son fronteras sobre lo que puedes escribir. El tope de instrucciones es otra cosa completamente distinta, y la wiki es inusualmente directa al respecto: el límite de instrucciones es simplemente una salvaguarda contra bucles infinitos, y no tiene ninguna relevancia para el rendimiento. Existe para que un script con un bucle desbocado se detenga en vez de congelar el mundo. Es un fusible, no un medidor. CurrentInstructionCount y MaxInstructionCount están ahí para leerlos —con la salvedad de que la cuenta incluye cualquier otro Bloque Programable que tu script haya invocado directamente—, pero la wiki te dice que los uses solo para depurar, y solo si de verdad te has topado con la excepción de «script demasiado complejo».
Lo que significa que pasar la comprobación no demuestra absolutamente nada. Un script que se queda en una fracción cómoda de 50,000 uniones puede seguir siendo lo que hace tartamudear a tu servidor, y un script que no se acerca ni de lejos puede seguir ejecutándose sesenta veces por segundo en nueve cuadrículas. La lectura que hace la propia wiki del número va justo en la dirección contraria: si estás siquiera remotamente cerca del límite de instrucciones, tu script probablemente está haciendo demasiadas cosas. El límite no es un objetivo que llenar. Es un muro que no deberías ni llegar a ver.
El presupuesto de verdad es el tick, y es compartido. Todo lo que la documentación les dice a los autores de scripts se deriva de ese único hecho, y merece leerse aunque no pienses escribir una línea, porque además sirve para juzgar los scripts que pegas:
- Cachea tus bloques; no los busques en cada llamada. Recuperar un bloque es una operación costosa en tiempo, y un script que busca sus luces en cada ejecución está pagando ese coste sesenta veces por segundo por una información que cambió una vez. Si la caché de verdad tiene que seguir el ritmo de una cuadrícula sobre la que la gente sigue soldando, refréscala cada pocos ticks —
Update100o más lento—, no constantemente. - Reutiliza tus listas. Inicialízalas una vez y consérvalas durante la vida del script. Reasignarlas en cada ejecución es, en palabras de la wiki, muy lento.
- No asignes objetos nuevos en código que se ejecuta a menudo, y diseña tus propios objetos de forma que el tiempo de ejecución general no necesite asignar nada. Cada asignación es trabajo ahora y recolección de basura después.
- Evita los campos y propiedades
static. Son una fuente potencial de fugas de memoria; pasa tus instancias de un sitio a otro en su lugar. Los métodos estáticos están bien. - Prefiere llamar a los miembros directamente desde sus interfaces antes que a través de Terminal Properties and Actions. La vía directa es órdenes de magnitud más rápida, y las Terminal Properties and Actions son para cuando no tienes otra opción.
- Recuerda dónde se va a ejecutar el script. Un script en tu propio mundo en solitario tiene muchísimo más tiempo disponible que ese mismo script en un servidor multijugador, porque en un servidor los demás jugadores también están ejecutando scripts, y todos vosotros estáis tirando de los mismos 16.667 ms.
Pon eso frente a los dos bloques a los que ha estado apuntando el resto de este artículo y la comparación no está ni reñida. Un Controlador de Eventos consume 500 W. Un Bloque de Temporizador consume 0.1 W. Esas cifras parecen el mismo tipo de coste que el milisegundo de un script, y no son en absoluto el mismo tipo de coste: son consumo eléctrico, que es una moneda que tú fabricas. Si la batería de lógica de una estación consume demasiada energía, sueldas otro panel solar y el problema desaparece. Nadie más en el servidor se ve afectado, y nada cambia en su tasa de fotogramas.
El tiempo de tick no se puede generar. No hay ningún bloque que fabrique más, ninguna mejora que añada un segundo hilo y ninguna versión de «pues añado capacidad» que funcione. Los escalones de abajo de esta escalera te cuestan algo que puedes producir en mayor cantidad. El escalón de arriba le cuesta a todo el mundo algo que nadie puede. Esa es toda la asimetría, y es por lo que el mismo servidor que nunca pregunta qué hacen tus Bloques de Temporizador quiere saber qué hace tu Bloque Programable.
Así que se derivan tres cosas, y todas son cosas sobre las que puedes actuar esta noche.
Pon Update100 en vez de Update1 a menos que la tarea necesite de verdad una decisión en cada tick. Vigilar una batería, un tanque de gas, un contenedor de carga o una puerta no lo necesita; esos valores no cambian de forma significativa en una sesentava parte de segundo, y hacer la comprobación sesenta veces más a menudo no te compra más que sesenta veces el coste. Update1 es para bucles de control que de verdad están pilotando algo.
Sé capaz de decir para qué sirve cada script de un servidor compartido. No a la defensiva, simplemente sé capaz de responderlo. Un script que sobrevive a esa pregunta es uno que puedes quedarte; un script que instalaste hace un año, en el que no has vuelto a pensar, corriendo en una cuadrícula que has desmantelado a medias, es exactamente el tipo que consigue que baneen a alguien sin que nadie haya actuado de mala fe.
Y lee el veredicto de «excesivo» de la wiki del principio de esta guía como lo que realmente es: no una nota de estilo sobre elegancia, sino una afirmación sobre rendimiento, denominada en los mismos milisegundos que todo lo demás de esta sección. El Controlador de Eventos y el par de Temporizadores que hacen tu triaje de reactores no le cuestan nada al tick. Hacer la misma tarea con un script que sondea en cada fotograma le cuesta algo real, en cada fotograma, para siempre.
Lo que pone toda la escalera sobre la mesa con un precio en cada escalón. Así que coge una cosa que hagas a mano cada sesión, la que más notarías si dejara de necesitarte, y constrúyela.
Automatiza una esclusa esta noche: la misma tarea construida en tres escalones de la escalera
Que sea la esclusa. Casi todo el mundo tiene una, casi nadie la ha automatizado, y es la tarea a la que la propia documentación vuelve una y otra vez. La página del Bloque de Temporizador usa un ciclo de esclusa esperando a que una sala se despresurice como su ejemplo trabajado de cómo imponer pausas en una secuencia. La lista de la página del Controlador de Eventos sobre para qué sirve el bloque abre con una frase distinta sobre la misma tarea: cuando alguien pasa por la esclusa, abrir las puertas automáticamente y conservar el oxígeno. Dos partes de la documentación oficial eligieron la misma tarea y echaron mano de herramientas distintas. Eso no es una contradicción que resolver. Es la elección que estás a punto de hacer, y la esclusa es el sitio más limpio de tu base para hacerla, porque el mismo hardware soporta las tres respuestas.
Fija primero el hardware, porque nada de él cambia entre las construcciones: una cámara con una puerta interior a tu base, una puerta exterior al vacío, una Ventilación de Aire en la cámara y un Panel de Botones a cada lado. Lo que cambia abajo es solo qué arranca el ciclo y —la parte que de verdad decide esto— qué le dice a la segunda mitad del ciclo que la primera mitad ocurrió de verdad.
Construcción uno: cuatro Temporizadores y dos botones. Al salir, Airlock-Out-1 lleva tres acciones: cerrar la puerta interior, poner la Ventilación de Aire a despresurizar y arrancar Airlock-Out-2. Airlock-Out-2 lleva un retardo de 0:00:10 y una acción: abrir la puerta exterior. Al entrar es la imagen especular: Airlock-In-1 cierra la puerta exterior, pone la ventilación a presurizar y arranca Airlock-In-2, que espera sus diez segundos y abre la puerta interior. El Panel de Botones de dentro lleva el Start de Airlock-Out-1; el panel de fuera lleva el Start de Airlock-In-1. Cuatro cubos baratos y dos paneles, sin condiciones en ninguna parte, y puedes tenerlo funcionando antes de terminar tu siguiente ronda de mineral. Pulsa un botón, cruza una cámara que se cicla sola y deja de cronometrar puertas a mano para siempre.
Construcción dos: las mismas puertas, avisadas por algo que sabe. Aquí el Open de la puerta lejana se sale del retardo por completo. La Ventilación de Aire tiene su propia barra de herramientas de disparo, y sus dos ranuras son que la sala se presurice y que la sala deje de estar despresurizada, una por cada dirección de un ciclo. Pon Trigger Now sobre un Temporizador llamado Airlock-In-Open en la ranura de presurizada, y deja que ese Temporizador abra la puerta interior y ponga en verde las luces de la cámara. El retardo de Airlock-In-2 desaparece de la construcción: la puerta ahora se abre con la presión misma. Añade un Controlador de Eventos en Door Opened vigilando la puerta interior y cierras la otra mitad: la ranura 2, el lado de totalmente cerrada, arranca la despresurización y pone la cámara en rojo, así que el bombeo nunca empieza hasta que la puerta ha terminado de recorrer su camino de verdad; la ranura 1, totalmente abierta, devuelve las luces. Si quieres un solo controlador vigilando las dos puertas, ahí es donde muerde la decisión de la AND Gate, y aquí la rama de la que te estás fiando es la falsa, así que la puerta va desactivada.
Construcción tres: deja de pulsar el botón. Pon un Sensor en la cámara, dale al campo la forma de la cámara y nada más allá, y ponlo a detectar jugadores. La ranura de entrada se lleva el Start del Temporizador del ciclo; la de salida se lleva el Start de un Temporizador de reinicio que devuelve las puertas y las luces a su estado de reposo. Fíjate en que esto es un añadido y no un reemplazo: el propio consejo de la wiki para esclusas es que un Temporizador puede ser arrancado por varias cosas, así que el Panel de Botones de dentro sigue funcionando junto al Sensor. Y lleva el punto ciego del Sensor al diseño de forma consciente. Un ingeniero que entra en la cámara sentado —en la cabina de un rover, en un asiento que soldaste ahí dentro, en una criocápsula— no es un jugador en lo que respecta al bloque. Siéntate a mitad de ciclo y el Sensor concluye que la cámara se vació y ejecuta tu reinicio. El Sensor elimina la pulsación del botón. No elimina la incertidumbre.
Ahora mete las tres en el fallo que las ordena, y no es un fallo exótico. Has estado fuera minando, el hielo se agotó mientras no estabas y el tanque de oxígeno que alimenta esa ventilación está vacío. Vuelves a casa y pulsas el botón de fuera.
En la construcción uno, Airlock-In-1 cierra la puerta exterior y le dice a la ventilación que presurice. La ventilación no tiene con qué. Diez segundos después —puntualmente, sin error, sin aviso y sin ningún cambio de color en ningún sitio donde estés mirando— Airlock-In-2 abre la puerta interior a una cámara que sigue en vacío. Nada funcionó mal. La cadena hizo exactamente lo que especificaste, y lo que especificaste fue una espera, no una comprobación. La wiki nombra este caso exacto en su propia lista de lo que una secuencia de Temporizadores no puede detectar: una sala que no se puede presurizar porque tus tanques están vacíos.
En la construcción dos, la puerta interior no se abre. Ni tarde ni a medias: no se abre en absoluto. La acción Open cuelga del evento de presurizada de la ventilación, y ese evento nunca se dispara, porque la presión nunca llega. El fallo sigue siendo un fallo; sigues estando de pie en una cámara de la que no puedes salir hacia tu base. Pero ahora es un fallo visible, en el lado seguro de la puerta, y te dice exactamente qué va mal: la sala nunca subió. La construcción tres, a cualquiera de las dos mitades que la atornilles, no cambia nada de esto. Sabe que hay alguien ahí. No sabe que la sala es segura.
Esa es toda la regla de decisión, y merece formularse en los términos más llanos posibles: la pregunta no es cuán ingeniosa es la tarea, es si la tarea necesita confirmación. Un ciclo que solo tiene que disparar un conjunto de interruptores a la vez no la necesita: constrúyelo con Temporizadores esta noche y disfrútalo. Un ciclo en el que el segundo paso es peligroso si el primero falló en silencio sí la necesita, y lo único que puede darte esa confirmación son eventos que informan de un estado real: la presión de la ventilación, el totalmente cerrada de la puerta, el bloqueado del conector, el porcentaje de llenado del tanque.
Así que construye la versión que tu modo de fallo merece, no la más impresionante que sepas cablear. Coge la tarea que nombraste al final de la sección anterior —la que más notarías si dejara de necesitarte— y pon la versión con Temporizadores en la pared esta sesión, en bloques con nombre, con holgura generosa. El día que te falle no estarás adivinando el arreglo: sabrás exactamente qué paso le mintió al siguiente, y ese paso es donde va el evento. Y deja el escalón de arriba donde lo deja la documentación. Subes a un script cuando la tarea necesita que se escriba un valor exacto o una programación que mantenga el propio juego, no porque la tarea te pareciera complicada en el momento en que estabas harto de hacerla a mano.
