Física
Cómo se mueve un bot: su masa y su radio, las fuerzas que lo empujan o lo frenan, los choques, los bordes del mundo, el tope de velocidad y el giro.
Cada bot es un círculo que se desliza sobre un plano. Tiene una posición, una velocidad, una masa, un radio y un rumbo, y el mundo los actualiza en dos fases de cada ciclo (El ciclo y el orden de las acciones): en fuerzas y choques junta todo lo que lo empuja o lo frena y resuelve los choques; en movimiento aplica esas fuerzas de una vez, gira al bot y lo mueve. No hay tiempo continuo: todo pasa a saltos de un ciclo.
El estado físico de un bot
| Qué | Cómo lo lee tu ADN |
|---|---|
| Posición | .xpos y .depth (la profundidad crece hacia abajo) |
| Velocidad | .velup y .veldx respecto del rumbo; .velscalar, la rapidez |
| Rumbo | .aim (1256 es una vuelta) |
| Masa | .mass |
| Radio | no tiene sysvar |
| Clavado o libre | .fixed |
Todas llegan con un ciclo de atraso, como todos los sentidos (Ejecución y costos).
La masa sale del cuerpo, del caparazón y de los cloroplastos: 1 por cada 1000 de .body, 1 por cada 200 de .shell y casi 1 por cada cloroplasto. Nunca baja de 1 ni pasa de 32000. Un bot común pesa 1; uno con 500 cloroplastos pesa unos 500 (los detalles, en .mass).
El radio crece con el cuerpo, cada vez más despacio:
| Cuerpo | 100 | 1000 | 5000 | 10000 | 32000 |
|---|---|---|---|---|---|
| Radio | 46 | 114 | 210 | 271 | 415 |
Los cloroplastos acercan el radio a 415, el de un bot de 32000 de cuerpo: cuantos más tiene, más se acerca. Con la opción Radio fijo todos los bots miden 60, sea cual sea su cuerpo. El radio decide cuándo dos bots se tocan y cuánto los frena el fluido.
Fuerzas, inercia y tope
Las fuerzas no cambian la posición directamente. Durante fuerzas y choques se suman en un acumulado; en movimiento, la velocidad recibe ese acumulado dividido por la masa, se recorta al tope y recién entonces la posición avanza lo que diga la velocidad:
fuerzas y choques movimiento
rozamiento y fluido: frenan ya velocidad += acumulado ÷ masa
browniano, gravedad, empuje, velocidad, como mucho el tope
lazos: van al acumulado posición += velocidad
choques, paredes, formas: corrigen
la posición y frenan
Lo que no se frena sigue andando: sin rozamiento ni fluido, un bot que dejó de empujar conserva su velocidad para siempre. El tope es Velocidad máxima (40 por defecto; las reglas F1 lo suben a 180), que el bot lee en .maxvel. Con Sin inercia encendida, el mundo anula la velocidad al final de cada ciclo: el bot se mueve solo mientras empuja, aunque .velscalar sigue informando lo que avanzó en el último ciclo (.velup y .veldx, en cambio, leen 0).
El empuje voluntario
El bot se empuja escribiendo en .up, .dn, .sx y .dx (el grupo completo está en Movimiento). El mundo hace esta cuenta:
- Arma el empujón con
.up − .dnhacia adelante y.sx − .dxde costado, medido desde el rumbo. - Lo multiplica por la masa y, si el resultado pasa el tope de velocidad, lo recorta a ese tope.
- Le aplica la eficiencia Eficiencia del motor (0,66 por defecto) y lo suma al acumulado.
Como después se divide por la masa, para un bot liviano la masa se cancela: 10 .up store le suma unos 6,6 de velocidad por ciclo. Pero el recorte del paso 2 llega antes cuanto más pesa el bot, así que un bot pesado acelera muy poco aunque empuje fuerte.
El costo es el empujón ya recortado del paso 2 por Mover (y por el Multiplicador de costos). Con el costo de mover en 1, 10 .up store cuesta 10 y 100 .up store cuesta 40, lo mismo que 40, porque el tope ya lo recortó. Se cobra aunque el empujón no logre mover al bot (por el rozamiento, ver abajo), pero nunca más de la energía que le queda. Los cadáveres y los bots fijos no se empujan ni pagan.
Este bot compra 500 cloroplastos al nacer y después empuja a fondo:
' Compra 500 cloroplastos al nacer y, desde el ciclo 5, empuja a fondo
cond
*.robage 0 =
start
500 .mkchlr store
stop
cond
*.robage 4 >
start
40 .up store
stop
endPesa unos 490. Con el costo de mover en 1 paga 40 por ciclo y gana apenas 0,05 de velocidad: después de unos 75 ciclos empujando va a 4 y se queda sin energía. Un bot sin cloroplastos llega a 40 en dos ciclos por el mismo precio.
Rozamiento con el suelo
El rozamiento existe solo si Gravedad Z (contra el suelo) es distinta de 0: esa gravedad aprieta a los bots contra el suelo. Tiene dos partes:
- Dinámico (Rozamiento dinámico): en cada ciclo le resta a la rapidez masa × gravedad Z × coeficiente, sin pasarse de 0. Esa resta no se divide por la masa: a un bot pesado lo frena mucho más.
- Estático (Rozamiento estático): si el bot está quieto y la suma de lo que lo empuja en ese ciclo es menor que masa × gravedad Z × coeficiente, no se mueve. Si ya se mueve, solo frena los empujes de costado.
Las reglas F1 usan gravedad Z 2, estático 0,6 y dinámico 0,4. Un bot de masa 1 pierde entonces 0,8 de rapidez por ciclo, y para arrancar necesita un empuje efectivo mayor que 1,2: 1 .up store (0,66) no lo mueve y aun así se cobra, 2 .up store (1,32) sí. El mismo umbral crece con la masa: con el tope de 180 de F1, un bot de más de unos 100 de masa no puede arrancar con su propio empuje.
El fluido: densidad y viscosidad
Con Densidad del medio y Viscosidad distintas de 0, el mundo es un fluido. El arrastre resta de la velocidad una parte que crece con la rapidez y con el radio (como el rozamiento dinámico, no depende de la masa), y nunca más del 99 %. Si alguna de las dos vale 0, no hay arrastre. La densidad además suma la masa añadida, el fluido que el bot arrastra consigo: más inercia, sin más peso para la gravedad.
Este bot empuja tres ciclos y después se deja llevar:
' Empuja tres ciclos y después se deja llevar
cond
*.robage 3 <
start
40 .up store
stop
endSu .velscalar (cuerpo 1000, tope 40) en cuatro mundos distintos:
| Ciclo | Sin roce ni fluido | Rozamiento F1 | Fluido suave | «Agua» |
|---|---|---|---|---|
| 1 | 26 | 26 | 20 | 20 |
| 3 | 40 | 40 | 40 | 20 |
| 4 | 40 | 39 | 31 | 0 |
| 10 | 40 | 34 | 9 | 0 |
| 20 | 40 | 26 | 2 | 0 |
| 40 | 40 | 10 | 0 | 0 |
El rozamiento frena de a poco y parejo; el fluido, en proporción a la velocidad. Con los valores que la app sugiere para el agua, el bot no pasa de 20 mientras empuja y se clava apenas deja de hacerlo.
Gravedad, flotabilidad y mareas
Gravedad Y (hacia abajo) tira de todos hacia abajo: cada ciclo suma ese valor a la velocidad hacia abajo, pese lo que pese el bot y sin pasar por la eficiencia. Con 1, un bot quieto cae a 1, 2, 3… hasta el tope. En un mundo con paredes termina en el fondo; si arriba y abajo están conectados, cae para siempre y reaparece arriba.
En el modo estanque (Estanque (luz por profundidad)), con gravedad y sin conectar arriba con abajo, cada bot elige una altura con su flotabilidad (.setboy, que se lee en .rdboy). Si está más arriba de esa altura, la gravedad lo hunde; si está más abajo, lo empuja hacia arriba. Flotar cuesta energía en cada ciclo, en proporción a la flotabilidad, a la gravedad y a la masa (que cuenta hasta 192), con el precio de Mover.
B-Alpha, del Bestiario, es un bot de estanque: al nacer pide bajar su flotabilidad (con 0 se va al fondo) y, cuando llega a cierta profundidad, se clava y deja de pedir flotabilidad:
cond
*.depth 6500 >
*.fixed 0 =
start
1 .fixpos store
0 .setboy store
stopCon las mareas (Mareas (ciclos; 0 = no)) el mundo maneja la gravedad por su cuenta: la sube y la baja entre 0 y 4 a lo largo del período, corre las alturas de flotación, y mientras la gravedad está baja enciende el browniano.
Movimiento browniano
Con Movimiento browniano distinto de 0, cada bot recibe en cada ciclo un empujón al azar, en una dirección al azar y de hasta la mitad de ese valor, más un pequeño giro al azar. Como todo empujón, se divide por la masa: a los bots pesados apenas los sacude. Es la única fuerza que usa números al azar.
Choques entre bots
Dos bots chocan cuando sus círculos se superponen. El mundo lo revisa en fuerzas y choques, con las posiciones del final del ciclo anterior, una sola vez por par. Chocan todos: vivos, vegetales y cadáveres. Cada choque hace tres cosas:
Los separa. Si los dos están quietos (o los dos fijos), cada uno retrocede la mitad de lo que se superponen y quedan apenas tocándose. Si no, se corrigen solo una parte por ciclo, que depende de Elasticidad de los choques: con 0 se deshace cerca de un cuarto de la superposición, con 1 casi toda. El más liviano es el que más se corre.
Les cambia la velocidad. Solo cuenta la parte de la velocidad sobre la línea que une los centros; la de costado no cambia. Con elasticidad 0 (el valor por defecto, y el de F1) el choque es blando: los dos terminan con la misma velocidad en esa dirección, como si uno empujara al otro. Con 1 rebotan como bolas de billar. Un bot fijo cuenta como masa 32000 y no cambia su velocidad.
Les avisa. Los dos leen .hit en el ciclo siguiente, con el lado del golpe en .hitup, .hitdn, .hitdx o .hitsx, y sus sysvars ref* se llenan con los datos del otro aunque no lo estén viendo (ver Choques y golpes y Lo que se ve (ref*)).
Choques con formas
Las formas del mundo (El mundo) son rectángulos sólidos. Un bot que se mete en una vuelve a quedar afuera, apoyado en el lado más cercano. Si venía desde afuera, además pierde parte de su velocidad en ese eje (la mitad si pesa 1, menos cuanto más pesa) y lee .hit con el lado del golpe; si estaba metido de lleno, en cambio, recibe un empujón hacia afuera. Si en ese momento sus ojos no ven nada, .reftype vale 1. Si se superpone con tres formas a la vez, el mundo lo saca de un salto de 200 en cada eje para que no quede atrapado. Una forma no enciende .edge.
Los bordes del mundo
Cada par de bordes puede estar conectado o ser una pared: Arriba ↔ abajo conectados y Izquierda ↔ derecha conectados (si están los dos, el mundo es Toroidal (los dos ejes)).
- Conectados. El bot que sale por un lado entra por el opuesto. Si es un multicelular, el mundo traslada el organismo entero de una vez (Lazos y multicelulares).
- Pared. El bot que toca el borde queda acomodado contra él, lee
.edgeen 1 y pierde un 5 % de la velocidad en ese eje (dividido por su masa). No rebota y no se le borra la velocidad: si sigue yendo hacia afuera, queda pegado a la pared, y como la acomodación pasa antes del movimiento, puede asomar un poco más allá del borde.
Con gravedad 1 y paredes, un bot quieto cae al fondo y se queda ahí leyendo .velscalar 20 y .edge 1 en cada ciclo: la gravedad y el freno de la pared se empatan. Para saber si un bot está trabado, mirá .edge o compará su posición entre ciclos, no su velocidad.
El rumbo y el giro
El bot gira en movimiento, antes de moverse: .aimsx y .aimdx giran tanto, .setaim gira hasta un rumbo, y si escribís en .setaim un rumbo distinto del actual, manda ese. Un bot fijo también puede girar.
Girar cuesta Girar (multiplicado por el Multiplicador de costos) por cada 200 unidades de giro: un cuarto de vuelta (314) sale 1,57 y una vuelta entera, 6,28. Con .setaim el giro es el más corto hasta el rumbo pedido, pero el costo depende del número que escribís: si queda a más de media vuelta del rumbo actual, cuenta como número, se cobran además tantas vueltas enteras como entren en la diferencia, redondeando (1256 por vuelta).
' Mira a 0 al nacer; en el ciclo 3 gira a 1200 escribiendo -56
cond
*.robage 0 =
start
0 .setaim store
stop
cond
*.robage 2 =
start
-56 .setaim store
stop
endCon el costo de girar en 1, este bot paga 0,28 por pasar de 0 a 1200. Si escribe 1200 en lugar de -56, termina en el mismo rumbo pero paga 6,56. Para no pagar de más, calculá el rumbo nuevo a partir del actual (por ejemplo, *.aim 100 add) o girá con .aimsx y .aimdx.
El giro tiene inercia. El browniano y los lazos (Lazos y multicelulares) pueden dejarle al bot un giro propio que se suma al rumbo en cada ciclo, aunque el ADN no pida nada. El rozamiento lo frena, el fluido lo anula casi siempre, y un giro voluntario en sentido contrario lo descuenta. Un giro en el mismo sentido no lo aumenta.
Bots fijos
Un bot con .fixpos mayor que 0 queda clavado: no recibe ninguna fuerza (ni su empuje, ni la gravedad, ni el browniano), su velocidad es 0 y en los choques cuenta como un muro de masa 32000. Lo único que lo puede correr un poco es la separación de un choque o una forma que se le meta encima. Nadie se puede fijar desactiva la fijación para todos.
Los parámetros, de un vistazo
| Parámetro | Qué cambia | Por defecto | F1 |
|---|---|---|---|
| Velocidad máxima | Tope de velocidad y del empujón | 40 | 180 |
| Eficiencia del motor | Parte del empuje que se vuelve movimiento | 0,66 | no la cambia |
| Gravedad Z (contra el suelo), Rozamiento estático, Rozamiento dinámico | Rozamiento con el suelo | 0 | 2; 0,6; 0,4 |
| Densidad del medio, Viscosidad | Arrastre del fluido | 0 | 0 |
| Gravedad Y (hacia abajo) | Gravedad hacia abajo | 0 | 0 |
| Movimiento browniano | Empujones al azar | 0 | 0 |
| Elasticidad de los choques | Rebote de los choques | 0 | 0 |
| Sin inercia | Frenar en seco cada ciclo | no | no la cambia |
| Arriba ↔ abajo conectados, Izquierda ↔ derecha conectados | Bordes conectados | no | sí |
| Mover, Girar | Precio de empujar y de girar | 0 | 0,05; 0 |
Todos están en Parámetros: Física, salvo los bordes (Parámetros: Campo y bordes) y los costos (Parámetros: Costos).