1. Origen del lenguaje

Quick Basic Junior nació como parte de Reverse FAP (Frame Animation Program), un editor de animaciones cuadro a cuadro. Al incorporar soporte para prototipos de videojuegos, surgió la necesidad de un lenguaje propio para definir gráficos e interacciones sin depender de archivos de imagen externos. Ese pseudo-lenguaje creció y se formalizó hasta convertirse en QBJr.

El nombre rinde homenaje a QBasic, el entorno de MS-DOS que introdujo a una generación entera a la programación. El sufijo Junior indica su naturaleza simplificada y su vocación educativa.

📌 PROYECTO REVERSEQBJr. es parte de la suite Reverse: un ecosistema de herramientas de código abierto para la creación de videojuegos retro (8/16 bits), orientado a la experimentación, el aprendizaje y la expresión creativa en español.

2. Filosofía de diseño

Los siguientes principios guían cada decisión del lenguaje. Los primeros seis son del diseño original (v1.0). Los demás surgieron de la implementación real.

Simplicidad ante todo
Cada decisión prioriza la facilidad de aprendizaje sobre la potencia expresiva.
Vocabulario en español
Todas las palabras clave están en español, reduciendo la barrera del idioma para hispanoparlantes.
Una palabra, una función
Ninguna palabra clave comparte nombre con otra. Cada término es único e inequívoco.
Verbos y objetos
Las instrucciones son verbos de acción que operan sobre objetos. Los objetos se crean con CREAR.
Sin repetición de código
El sistema de subprogramas introduce abstracción sin la complejidad de funciones con parámetros.
Valores predeterminados sensatos
Un programa mínimo puede ignorar toda configuración y funcionar correctamente.
Capas de complejidad opcionales
El audio, el color y las capas pueden usarse de forma simple o explorados en profundidad. Nadie está obligado a conocer todo para empezar.
Operadores como palabras completas
AND OR XOR NOT MOD DIV — sin colisión con identificadores de una o dos letras. Solo son keywords en MAYÚSCULAS.
Archivos como datos declarativos
El formato .qdat permite definir mundos e ítems sin saber programar, abriendo el lenguaje a colaboradores no programadores.

3. Historial de versiones

VERSIÓNPERÍODOCAMBIOS PRINCIPALES
v1.02025Especificación inicial. Dibujo, variables globales, SI/MIENTRAS/REPETIR/PARA, subprogramas sin parámetros, paleta Retro y Moderna. Operadores lógicos: Y O OX NO.
v1.12025Reorganización estructural. Arreglos. SEGUN/CASO. Paleta predeterminada cambia de Moderna a Retro. Configuración global unificada.
v2.02025Cambio incompatible: Y/O/OX/NO → AND/OR/XOR/NOT. Identificadores de una letra habilitados. COLISIONA como operador infijo. FPS global. Precedencia documentada formalmente.
v2.12025Motor de tiles (CREAR TILESET/TILEMAP, PONER TILE, COLISIONA_TILE). Física (FISICA GRAVEDAD, VELOCIDAD, IMPULSO, EN_SUELO). Archivos y datos (ABRIR/LEER/ESCRIBIR, CARGAR DATOS, formato .qdat).
v2.22025Markdown extendido en canvas (TEXTO_MD, ALTURA_MD). IMPRIMIR para debugging. PAUSAR/REANUDAR. Consola del entorno con niveles de log.
v2.2+202610 funciones de cadena avanzadas (BUSCAR, EXTRAER, CORTAR_IZQ, etc.). TEXTO_MD con 5° argumento alturaMax. Incorporadas en implementación de referencia v0.9.8.
◈ NOTA HISTÓRICA — v2.0El cambio de Y/O/OX/NO a AND/OR/XOR/NOT fue el más significativo del lenguaje. Las letras Y y O colisionaban con variables de uso común (coordenada y, variable o). La solución: palabras completas en inglés que no colisionan con ningún identificador en español.

4. Estructura de un programa

Modelo de ejecución

Un programa en QBJr. se ejecuta de arriba hacia abajo, instrucción por instrucción. El game loop se implementa de forma explícita usando las estructuras de repetición del lenguaje — decisión pedagógica deliberada para que el alumno vea que un juego es literalmente un bucle.

' Estructura típica de un programa QBJr. PANTALLA 256 240 PALETA retro COLOR FONDO black DECLARAR x COMO ENTERO x = 128 REPETIR LIMPIAR SI TECLADO(FLECHA_DERECHA) ENTONCES x = x + 3 FIN SI CIRCULO x 120 12 RELLENO ESPERAR 16 HASTA TECLADO(TECLA_ESCAPE) FINALIZAR

Configuración global

INSTRUCCIÓNDESCRIPCIÓNDEFAULT
PANTALLA <w> <h> [COLORES <n>]Resolución del área de dibujo virtual.256×240, 16 colores
PALETA retro | modernaPaleta de 16 colores activa.retro
AUDIO MODO 4 | 8Canales de audio para síntesis.4
TEMPO <BPM>Velocidad musical. negra = 60000÷BPM ms.120
FPS <n>Velocidad de animación de sprites.60

Comentarios y coordenadas

La comilla simple ' inicia un comentario hasta el final de la línea. El sistema de coordenadas tiene el origen (0,0) en la esquina superior izquierda. X crece hacia la derecha, Y crece hacia abajo.

5. Variables y tipos

Todas las variables son globales. No existe scope local. Los nombres son case-insensitive: xJugador y xjugador son la misma variable. Las variables deben declararse antes de usarse.

TIPODESCRIPCIÓNEJEMPLO
ENTERONúmero sin parte decimal.42, -7, 0
FLOTANTENúmero con parte decimal.3.14, -0.5
TEXTOCadena de caracteres entre comillas dobles."hola mundo"
BOOLEANOSolo VERDADERO o FALSO.VERDADERO

Arreglos

Arreglos unidimensionales de tamaño fijo. El índice es base 1 (el primer elemento es [1]).

DECLARAR inventario[6] COMO TEXTO inventario[1] = "llave" inventario[2] = "linterna" ' Recorrer con PARA PARA i DE 1 A 6 IMPRIMIR inventario[i] FIN PARA

6. Operadores

OPERADORDESCRIPCIÓN
+ - * /Aritméticos. + también concatena TEXTO.
^Potencia. 2 ^ 8 = 256
\Raíz. 2 \ 9 = 3 (raíz cuadrada de 9).
MODResto. 10 MOD 3 = 1
DIVDivisión entera. 10 DIV 3 = 3
= <> < > <= >=Comparación. Devuelven VERDADERO/FALSO.
ANDConjunción lógica. Solo en MAYÚSCULAS.
ORDisyunción lógica. Solo en MAYÚSCULAS.
XORDisyunción exclusiva. Solo en MAYÚSCULAS.
NOTNegación lógica. Solo en MAYÚSCULAS.

Precedencia (de menor a mayor): OR · XOR → AND → NOT → = <> < > <= >= COLISIONA → + - → * / MOD DIV → ^ \ → - (unario).

⚠ MAYÚSCULASand or not xor en minúsculas son identificadores válidos para variables, no operadores. Un programa puede tener una variable llamada and.

7. Control de flujo

Condicional SI

SI vida <= 0 ENTONCES HACER game_over OTRO SI vida < 25 ENTONCES HACER advertencia SI NO HACER estado_normal FIN SI

Selección SEGUN

SEGUN direccion CASO "norte": HACER ir_norte CASO "sur": HACER ir_sur CASO OTRO: HACER detenerse FIN SEGUN

Ciclos

FORMACUÁNDO SE EVALÚAMÍNIMO DE EJECUCIONES
MIENTRAS cond … FIN MIENTRASAl inicio0 (puede no ejecutar)
REPETIR HASTA cond … FIN REPETIRAl inicio0
REPETIR … HASTA condAl final1 (siempre ejecuta)
REPETIR … MIENTRAS condAl final1
PARA i DE a A b [ENPASOSDE n]Al inicio0 si a > b

Control adicional

INSTRUCCIÓNDESCRIPCIÓN
ESCAPARInterrumpe el ciclo actual.
ESPERAR <ms>Pausa en milisegundos. Cede al game loop.
PAUSARSuspende hasta REANUDAR o START del Player.
REANUDARReanuda si estaba suspendido.
FINALIZARTermina el programa.
IMPRIMIR <expr…>Escribe en consola del Player sin afectar el canvas. Para debugging.

8. Subprogramas

Los subprogramas no reciben parámetros ni devuelven valores. Operan sobre las variables globales del programa. Se definen con DEFINIR y se invocan con HACER.

DECLARAR sx COMO ENTERO DECLARAR sy COMO ENTERO DEFINIR dibujar_estrella POLIGONO sx sy 30 5 RELLENO FIN DEFINIR sx = 64 sy = 80 HACER dibujar_estrella sx = 192 sy = 80 HACER dibujar_estrella

9. Paletas de colores

QBJr. incluye dos paletas de 16 colores. La paleta predeterminada es retro. Los colores se referencian siempre por nombre, nunca por número.

Paleta RETRO (predeterminada)

black
white
red
lime
blue
yellow
cyan
magenta
silver
gray
maroon
olive
green
purple
teal
navy

Paleta MODERNA

negro
blanco
rojo
verde
azul
amarillo
cian
magenta
gris
naranja
violeta
marrón
rosa
lima
celeste
dorado

HSL(h, s, l) genera colores dinámicos donde h=0-360 (matiz), s=0-100 (saturación), l=0-100 (luminosidad). Se usa donde se espera un nombre de color.

10. Geometría y dibujo

INSTRUCCIÓNDESCRIPCIÓN
TRAZO <px>Grosor del trazo en píxeles. Default: 1.
COLOR <c>Trazo y relleno al mismo color.
COLOR TRAZO <c> RELLENO <c>Trazo y relleno distintos en una instrucción.
COLOR FONDO <c>Color de fondo para LIMPIAR.
LIMPIARRellena la pantalla con COLOR FONDO.
PUNTO <x> <y>Punto de 1×1 px.
LINEA <x1> <y1> … [CERRAR] [RELLENO]Líneas contiguas. CERRAR cierra el path.
CIRCULO <x> <y> <r> [RELLENO]Círculo con centro y radio.
RECTANGULO <x> <y> <ancho> <alto> [RELLENO]Orden: ancho antes que alto.
POLIGONO <x> <y> <r> <lados> [RELLENO]Polígono regular inscrito.
TRIANGULO <variantes> [RELLENO]Por vértices, EQUILATERO, ISOSCELES o ESCALENO.
RELLENAR <x> <y>Flood fill desde el punto.

11. Texto en canvas

INSTRUCCIÓNDESCRIPCIÓN
TEXTO <x> <y> <expr> [SOMBREADO]Dibuja texto con fuente Press Start 2P. SOMBREADO pinta el fondo.
TEXTO_MD <x> <y> <ancho> <expr> [<alto>]Texto con markdown extendido y word-wrap. El 5° arg limita la altura.
ALTURA_MD(<ancho>, <expr>)Calcula la altura que ocuparía el texto sin dibujarlo.

12. Markdown extendido

Sintaxis disponible dentro de TEXTO_MD:

MARCADOEFECTO
# texto #Blanco brillante (título inline).
*texto*Rojo (alerta/peligro).
_texto_Verde (objetos/ítems).
**texto**Negrita.
//texto//Cursiva.
__texto__Subrayado.
~~texto~~Tachado.
^texto^Superíndice.
~texto~Subíndice.
[c=color]texto[/c]Color por nombre de paleta o valor hex.
# Título / ## h2 / ### h3Encabezados estructurales.
--- / ---===---Línea divisoria / decorada.

13. Sprites y animaciones

Un sprite define el tipo de entidad. Una instancia es la copia activa en pantalla con posición, rotación y estado propios. Múltiples instancias del mismo sprite son independientes.

INSTRUCCIÓNDESCRIPCIÓN
CREAR SPRITE <nombre> [<imagen>]Define tipo de sprite. Sin imagen: acepta animaciones.
MOSTRAR <sprite> <inst> [EN <x> <y>]Muestra o crea una instancia.
OCULTAR <sprite> [<inst>]Oculta una o todas las instancias.
BORRAR <sprite>Destruye sprite e instancias.
MOVER [HITBOX] <sprite> <inst> A <x> <y>Mueve la instancia o solo su hitbox.
ROTAR / ESCALAR [HITBOX] …Rota o escala instancia o hitbox.
VOLTEAR <sprite> <inst> HORIZONTAL | VERTICALEspeja la instancia.
CREAR ANIMACION <nom> DE <sprite> CON <imgs…>Define animación con fotogramas.
REPRODUCIR <anim> DE <sprite> <inst> [BUCLE] [POR <n>]Reproduce la animación.

14. Audio

Archivos externos

INSTRUCCIÓNDESCRIPCIÓN
CREAR SONIDO / MUSICA <nombre> <archivo>Define SFX o BGM desde archivo externo.
REPRODUCIR <n> [BUCLE] [VOLUMEN <v>] [PANEO <p>]Reproduce. Volumen 0-100, paneo -50 a 50.
DETENER <n> [FADE <ms>]Detiene con fundido opcional.

Síntesis por pistas

CREAR PISTA intro DINAMICA mf NOTA Do4:ne Re4:ne Mi4:ne Fa4:bl SILENCIO co FIN PISTA REPRODUCIR intro BUCLE

Figuras: cu (cuadrada) · re (redonda) · bl (blanca) · ne (negra) · co (corchea) · sc (semicorchea) · punto = ×1.5. Dinámicas: pp p mp mf f ff.

15. Capas y scroll

CAPACOMPORTAMIENTO
0, 1, 2Fondos con parallax. Factor configurable por capa.
3Capa principal. Responde a SCROLL.
4Capa frontal. Se mueve con la capa 3.
5HUD. Siempre al frente, independiente del scroll.
INSTRUCCIÓNDESCRIPCIÓN
FONDO <capa> <imagen> <factor>Carga imagen en la capa con factor de scroll.
SCROLL <dirección | ruta> <velocidad>Mueve la capa principal.
RUTA <nombre> DESDE <x> <y> EN <figura>Define ruta de scroll geométrica compleja.

16. Motor de tiles

INSTRUCCIÓNDESCRIPCIÓN
CREAR TILESET <n> <archivo> <tw> <th>Divide imagen en celdas tw×th. IDs base 1.
CREAR TILEMAP <n> <cols> <filas> [EN CAPA <c>]Grilla en la capa indicada. Default: capa 3.
PONER TILE <tilemap> <col> <fila> <id> [RIGIDO]Coloca tile. RIGIDO activa hitbox automática.
BORRAR TILE <tilemap> <col> <fila>Elimina el tile.
MOSTRAR / OCULTAR / BORRAR TILEMAP <n>Control de visibilidad y destrucción.
COLISIONA_TILE(<sprite> <inst>)VERDADERO si la hitbox colisiona con tile RIGIDO.

17. Física

INSTRUCCIÓNDESCRIPCIÓN
FISICA GRAVEDAD <v>Aceleración en px/s². Default: 500.
FISICA SPRITE <sprite> <inst> ACTIVA | INACTIVAActiva o desactiva física sobre la instancia.
VELOCIDAD <sprite> <inst> A <vx> <vy>Velocidad en px/s. Negativos: usar paréntesis.
IMPULSO <sprite> <inst> A <fx> <fy>Impulso instantáneo. Útil para saltos.
EN_SUELO(<sprite> <inst>)VERDADERO si está sobre tile rígido.
VEL_X(<sprite> <inst>)Velocidad horizontal actual en px/s.
VEL_Y(<sprite> <inst>)Velocidad vertical actual en px/s.
📌 NEGATIVOSVELOCIDAD p 1 A 100 (-200) — los valores negativos directos requieren paréntesis para evitar ambigüedad con el operador de resta.

18. Archivos y datos

INSTRUCCIÓNDESCRIPCIÓN
ABRIR <ruta> COMO <n> LECTURA | ESCRITURA | ANEXARLECTURA: fetch del servidor. ESCRITURA: localStorage.
LEER <archivo> <variable>Lee la siguiente línea.
ESCRIBIR <archivo> <texto>Escribe una línea.
CERRAR <archivo>Cierra y persiste.
FIN_ARCHIVO(<archivo>)VERDADERO si no hay más líneas.
CARGAR DATOS <ruta> COMO <n>Carga y parsea un archivo .qdat.
LEER_DATO(<datos> <sección> <clave>)Retorna el valor de la clave en la sección.
📌 FORMATO .qdatSecciones con [nombre], pares clave = valor, comentarios con #, valores multilínea con triple comilla """…""".

19. Teclado y mouse

INSTRUCCIÓNDESCRIPCIÓN
TECLADO(<tecla>)VERDADERO mientras la tecla está presionada.
TECLADO(<t1> + <t2>)Combinación simultánea AND.
BOTON_MOUSE(<acción>)"click izquierdo" · "mantiene derecho" · etc.
RUEDA_MOUSE(arriba | abajo)Giro de rueda en este frame.
MOUSE_ENCIMA(<sprite>)Hover sobre hitbox del sprite.
POSICION_MOUSE(x | y)Coordenada del cursor en espacio virtual.

Teclas de letra/número: usar el carácter entre comillas: TECLADO("W"), TECLADO("5"). Teclas especiales: FLECHA_ARRIBA/ABAJO/IZQUIERDA/DERECHA · BARRA_ESPACIADORA · TECLA_ESCAPE · TECLA_ENTER · TECLA_TAB · BLOQ_MAYUS · SHIFT_IZQUIERDO · CTRL_IZQUIERDO · ALT_IZQUIERDO · TECLA_F1…F12 · BACKSPACE · NUM_0…NUM_9.

20. Colisiones

FORMADESCRIPCIÓN
<spriteA> COLISIONA <spriteB>Operador infijo. VERDADERO si las hitboxes se solapan (AABB).
COLISIONA(<sprite>)VERDADERO si el sprite colisiona con cualquier otro.
COLISIONA_TILE(<sprite> <inst>)VERDADERO si colisiona con tile RIGIDO activo.

21. Funciones matemáticas

FUNCIÓNDESCRIPCIÓN
ABS(<n>)Valor absoluto.
RAIZ(<n>)Raíz cuadrada.
POTENCIA(<b>,<e>)Potencia.
SEN / COS / TAN (<grados>)Trigonométricas en grados (no radianes).
LOG / LOG10 / LOG2 (<n>)Logaritmos natural, base 10, base 2.
RND()Número aleatorio entre 0 y 1.
TRUNCAR(<n>)Elimina decimales sin redondear.
REDONDEAR(<n>)Redondea al entero más cercano.

22. Funciones de cadena

FUNCIÓNDESCRIPCIÓN
TEXTO(<n>) / NUMERO(<txt>)Conversión entre número y texto.
LARGO(<txt>)Cantidad de caracteres.
RECORTAR(<txt>)Elimina espacios al inicio y final.
MAYUSCULA / MINUSCULA (<txt>)Conversión de case.
BUSCAR(<txt>,<aguja>[,<desde>])Posición base-1 de la primera ocurrencia.
EXTRAER(<txt>,<desde>[,<largo>])Subcadena base-1.
CORTAR_IZQ / CORTAR_DER (<txt>,<n>)Primeros / últimos n caracteres.
REEMPLAZAR(<txt>,<viejo>,<nuevo>)Reemplaza todas las ocurrencias.
REPETIR(<txt>,<n>)Repite el texto n veces.
CARACTER(<n>)Carácter por código Unicode (CHR$).
CODIGO(<txt>)Código Unicode del primer carácter (ASC).