tuts_gbc
Thread Id: 24221
Thread Name: [GBC] Consejos Utiles para Script GBC
#0
Chamber4315♪ 26330


ATENCION: Esta NO es una guía sobre scripts. Esta es una guía de consideraciones y consideraciones que ayuden a mejorar el rendimiento al momento de scriptear en GBC.
La presente guía está enfocada a los usuarios que inician el scripting pero que tienen conocimientos medio-avanzado de hacking GBC.

Recuerdo que cuando inicie en el RH lo primero que intente hacer fue un script, pero como todo novato lo único que logre fueron horas de no saber lo que hacía hasta que al fin termine arruinando una parte del juego.
Ahora que ya que comprendo mejor como funciona un juego de GBC vengo a compartirles mis experiencias que a más de uno les puede servir.

1.-Dominar el Repoint. Es necesario que antes de querer scriptear dominen el tema del Repunteo, ya que los comandos importantes requieren el uso de pointers. Hay facilidad al hablar de pointers en PKSV por que los bytes están invertidos, lo que ocasiona que en un pointer de 2-bytes los últimos 3 dígitos sean iguales que el del offset.

Ejemplo: el 2-byte pointer de $1AE345 es 0x6345

Como se determina entonces el primer digito del pointer (que esta en azul)? Fácil, lo determina el banco donde se encuentra el offset. Recuerden que cada banco se compone de 0x4000 bytes, por lo tanto, TODOS los bancos en el juego inician con 0x4000, 0x8000, 0xC000 y 0x0000. Lo único que hay que hacer es sacar la diferencia entre el inicio del banco y el 4 digito del offset de izquierda a derecha y al resultado le sumamos +4.

En nuestro ejemplo usamos el offset $1AE345, por lo tanto el inicio del banco es $1AC000. Entonces a 0xE le restamos 0xC y nos da como resultado 2.
A 2 le sumamos +4 = 6. De esta manera tenemos el inicio del pointer 0x6345.
Si en lugar de 0xE fuera 0xF entonces el pointer seria 0x7345.

2.-Las herramientas ideales del Scripting son PKSV + JohtoMap. Hay muchos hackers que hacen scripts directamente en Hex, pero siempre es más cómodo tener un entorno grafico. Recuerden que aunque JohtoMap y PKSV se integran, no son una misma herramienta, siempre que se haga el cambio de una herramienta a otra hay que re-abrir el ROM para evitar perder información.

3.-No compiles tu script hasta el final. Cuando trabajen en PKSV lo mejor es guardar el archivo en la PC y trabajarlo ahí. Eviten compilar (guardar) un script en el Rom hasta que no hayan revisado que los comandos, los pointers, los scripts secundarios y los textos sean los correctos, con esto evitan dañar la Rom por accidente.

4.-Sean ordenados. Un script de nivel medio se compone de scripts secundarios, que a su vez pueden tener también otros scripts. Lo mejor es seguir el orden que toma el PKSV, empezando por el script primario y siguiendo con los secundarios que vayas encontrando de arriba hacia abajo. En caso de usar el comando “applymovement” lo mejor es dejar las instrucciones de movimiento hasta el final.

5.- Hay que prever. Generalmente cuando uno cree que termino un script, pasa el tiempo y cuando lo vuelves a revisar vez algo que no te gusto o simplemente quieres seguir agregando más comandos, pero oh sorpresa, ya no tienes mas espacio. Para que esto no te pase hay que dejar cierta holgura en cada script. A que me refiero con esto? Veamos un script de ejemplo de lo que NO se debe hacer.

En este ejemplo (mirar spoiler) el script principal comienza en $15B700 y pesa 0x49 bytes.
El script secundario comienza en $15B749, ósea inmediatamente después de terminar el script principal. No aconsejo que hagan eso, porque en caso de querer expandir el script en un futuro, ya no tienen espacio y lo que tendrían que hacer es volver a programar los scripts secundarios junto con sus pointers, lo que se traduce en perdida de tiempo. En su lugar dejen unos cuantos bytes para poder estar modificando. Recomiendo de 0x10 a 0x20 bytes o lo que se les facilite para redondear.



6.-Bancos de texto. Agrupen el texto de un solo banco en un solo lugar. Si en una misma ciudad tienen múltiples scripts lo recomendable es que manden el texto de todos los scripts a un mismo lugar. Yo destino los últimos 0x1000 bytes de cada banco al texto, por ejemplo, si estoy en el banco 56 que abarca de $158000 a 15C000 (realmente hasta 0x15BFFF), dejo libre de $15B000 en adelante solo para texto.

Qué ventaja nos trae el agrupar el texto?
Al estar concentrados en que el script salga bien pocas veces prestamos atención a los diálogos, por esto es más fácil pensar en la historia del hack después y editarlos, pero para no estar lidiando los tediosos formatos de texto del PKSV podemos usar la herramienta POKETEXT que facilita el proceso de edición, de este modo no tenemos que preocuparnos por los gialogos de nuestros personajes. Recomiendo dejar entre 0x40 y 0x80 bytes para un dialogo normal de NPC.

Para que POKETEXT reconozca nuestro “banco de texto” solo hace falta editar el archivo “.ini” y agregar los datos con el siguiente formato:

[Nombre]
Start=$OFFSET + 1

Para nuestro ejemplo anterior quedaría algo como esto:


[Texto de Chamber]
Start=$$15B001

Para usar este método de edicion, el texto tiene que ir siempre pegado uno detrás del otro y restarle un byte, es decir, si el primer texto de nuestro banco comienza en $15B000 y el primer texto mide 0x65 bytes, el segundo debe empezar en $15B065 -1 = $15B064. Si no se aplica la regla del -1, POKETEXT no puede leer todos los textos que pongamos.

Otro consejo práctico es darle holgura. Aunque nuestro texto mida 0x65 rellenen con espacios en blanco para que mida 0x71 o 0x81, así tienen espacio de sobra por si quieren cambiar diálogos. Pero porque “0x81” en lugar de “0x80”??
Recuerden la regla del “-1” para que el POKETEXT lea nuestros bancos de texto, si agregamos 0x81 estamos redondeando automáticamente a 0x80 y nos quebramos la cabeza al momento de asignar pointers al texto y sabemos fácilmente que el texto esta ordenado. Ejemplo:


#ORG: data
-> 0x15B700 (0x81 bytes)
-> 0x15B780 (0x81 bytes)
-> 0x15B800 (0x81 bytes)
-> 0x15B880 (0x81 bytes)
-> …


7.- "3jump", nuestro major amigo. Se han preguntado qué pasa si disponemos de poco espacio en un banco y queremos hacer muchos scripts? Para esto hay dos soluciones, mudar toda la información a otro banco en blanco, pero esto conlleva mover gran cantidad de datos y repuntearlos, lo que es muy tardado y laborios… o pueden usar el comando "3jump".
Lo que hace "3jump" es enlazar un script con otro en cualquier lugar del Rom, asi como su nombre lo indica, hace un “salto” con un pointer de 3-bytes, por lo que podemos extender un script sin importar el espacio.

Si usan este método igual recomiendo que hagan un banco de puros scripts para que tengan todo mejor organizado.

"3jump" tiene su hermano malvado llamado “3call”, con la única diferencia de que al finalizar el script “con salto” se regresa al script principal y continua de manera normal. Esto es muy útil si quieres modificar un script existente en lugar de hacer un script de cero.

NOTA: El único inconveniente que he visto al usar "3jump" es que no es compatible con el comando "winlosstext" que se usa en las peleas contra Trainers. Parece que no son compatibles por que "winlosstext" no identifica que estas en un nuevo banco e intenta retomar el banco original para llamar el texto, por lo que se congela el juego, asi que eviten combinar estos dos comandos.

8.-Mejor un script nuevo. Recomiendo siempre trabajar sobre espacio en blanco y crear los acripts desde cero por si en un futuro quieren retomar algún script original sin que se vea afectado. Esta recomendación es muy personal, pero mas vale prevenir.

9.-“Como hago tal o cual cosa?”. La mejor manera de aprender es experimentar, así que si quieres hacer un script y no tienes ni idea de que comandos usar busca siempre en el juego original. Muchos me preguntan cómo pueden hacer encuentros con pokemon Shiny y la mejor respuesta es “mira el script del Red Gyarados”. Si después de intentar por tu cuenta las cosas no salen bien, ahora si no dudes en preguntar a otro usuario.

10.- Paciencia. Nadie nace sabiendo, todo es un proceso largo de aprendizaje. No se desesperen si las cosas no salen bien a la primera, al contrario, esmérense en encontrar el fallo para no volverlo a repetir. Si las cosas no fueran difíciles, entonces cual sería la satisfacción de hacerlo bien?


================================


Espero estos consejos sean útiles para los que quieren aprender Scripting, ya que el orden nos ayuda a tener menos fallos y hacer futuras ediciones con mas facilidad.

Por mi parte es todo, si alguien tiene alguna duda o quiere aportar de su experiencia personal los invito a comentar.

Hasta la próxima y suerte!
#1
javcdark 15833
interesante... comntemos
1.- todo esto es importante saberlo pero se puede optimizar a simple y sencillamente poner ":xxxx"
ejemplo


2.-...
3.-...
4.- como te menciono el primer punto, aqui tambien aplica la opcion ":xxxx" y lo hace automaticamente, en pocas palabras no importa la forma en que acomodes tus scripts, pksv los ordenara adecuadamente
5.- y de nuevo la solucion es ":xxxx", simpre y cuando tengas espacio disponible en el banco, no hay problema
6.-...
7.- a diferencia de lo que lo que describes, es muchisimo mejor usar el "2jump" que el "3jump", aunque la ventaja del "3jump" es que puedes utilizar cualquier espacio vacio en la rom
8.-...
9.-...tal parece que me estubiera escuhcando a mi mismo diciendote eso :)
10.-...

viendo esto me estoy animando a crear una escuela de script en gbc :awesome:
#2
Chamber4315♪ 26330
Iniciado por javcdark

4.- como te menciono el primer punto, aqui tambien aplica la opcion ":xxxx" y lo hace automaticamente, en pocas palabras no importa la forma en que acomodes tus scripts, pksv los ordenara adecuadamente


Gracias por tus comentarios, si deberia existir una escuela de scripting :D

Respecto a lo que dices del punto 4, PKSV MUESTRA los scripts secundarios de manera ordenada, aunque no lo esten... no se de a entender, si yo escribo:

1 >llama a 3
2 >llama a 5
3
4
5

.... quiero que al compilar aparezcan en ese orden y no como si PKSV los ordenara segun el orden de aparicion:


1 >llama a 3
3
2 >llama a 5
5
4


Es mas bien un obsesion por tenerlo todo ordenado XD
#3
G0LD_ZTHVARD0X! 27515
Hey posteas esto justo cuando hago mi primer script sin congelar el juego XD, antes de todo lo mejor seria conocer todos los comandos del pksv, mas sinceramente yo prefiero usar el editor hex y el comprendio de scripts, la razon...



Seguire estos importantes pasos para scriptear, gracias por xl tuto ^^
#4
Chamber4315♪ 26330
Iniciado por G0LD ZeroKuchiki!
Miksy91 una vez dijo que usar pksv era un 90% efectivo, mas no del todo, pues pksv fue hecho mas que todo para scriptear en r/z/e/fr/lg, por esa razon hay comandos que no reconoce o que los ejecuta con bugs


Eso es cierto y es bien importante, editare el post principal.

Uno de los fallos que comúnmente me suceden es que al tener megamapa abierto y compilar en PKSV el script se recorre un byte hacia atras. Si compilo un script en $1AC000 termina escribiéndose en $1ABFFF... Por tal motivo recomiendo solo tener abiertos PKSV y Johtomap al momento de trabajar.

Respecto a los comandos que no reconoce aun no me ha pasado, pero no lo dudo. Creo que los comandos mas "comunes" no tiene problema en reconocerlos. Lo unico que me he topado es que reconoce de manera automatica los objetos de r/z/e/fr/lg, por lo que si quieres poner un item "X", al decompilar de nuevo te aparece su equivalente en GBA, pero no pasa nada mientras tu sepas que es tu item.
#5
Crystal_ 28012
Gran aporte Chamber!

Debo ser de los pocos que hace scripts directamente en hex jaja, seguramente me deberia aplicar eso de ser mas ordenado yo, la verdad es que yo pongo el texto y los scripts un poco donde caen y luego cada vez que intento modificar algun script existente tengo que seguir todo desde el script pointer del header basicamente y descifrar algo te todo el desorden.

La verdad que yo nunca he utilizado el jump the 3-byte pointer asi que no puedo aclarar nada sobre eso, se me ocurre que puede ser que utilizaras el script de jump entre el winlosstest y el returnafterbattle,de forma que el winlosstext estuviese recibiendo el byte apuntado pero en la bank antugua, pero como digo no es mas que una idea que se me ocurre.

Por cierto por añadir algo simplemente como curiosidad si alguien se pregunta por que todos los pointers usados en scripts estan entre 0x4000 y 0x7fff es porque estos apuntan a la ram en donde la ram bank de 0x0 a 0x3fff es exactamente igual a la rom bank 0 mientras que la ram bank de 0x4000 a 0x7fff es la 'switchable bank' en la que se carga cualquier bank entre 01 y la ultima dependiendo de la cual necesitemos en cada momento. Simplemente por curiosidad aunque como ya he dicho, gran aporte Chamber, creo que me deberia aplicar alguna cosa yo jaja :)
#6
G0LD_ZTHVARD0X! 27515
Le agregare a la guia un par de consejos de yo (?)

1.Agregado a lo que [MENTION=26330]Chamber[/MENTION] ya dijo, Winlosstext es muy caprichoso, no se lleva bien con 2call,2jump, ni con dynamic, por lo que al usar ese comando debemos de hacerlo manualmente y aislado de estos comandos.

2. Para saber si no llevas algun error en el script, en pksv dale a "tools" e inmediatamente dale a "debug" esto hara una "falsa" compilacion, ya que te muestra la ventana de cuando compilamos, pero no esta compilando en verdad, si no sale nada al darle debug es porque casi todo el script esta malo.

3. Por experiencia propia limita el uso de 3jump a solo texto, a veces puedes liarte si pones casi todo el script en otro banco, para ello sustituye el 3jump por 3writetext, lo malo de 3writetext es que tampoco funciona con dynamic, teniendo que ingresar el offset manualmente.

4. Al igual que en GBA, las flags son limitadas, asi que cuidalas bien, ya que el rom carece de flags sin usar, por lo cual es limitada la cantidad de batallas, npc ocultos e items en el suelo.

Nada mas que agregar
#7
Chamber4315♪ 26330
Hablando de flags, por las "unused" te refieres a las que marca KBC en su tema de Pokeco?:

Table 2:
4C00 = Unused
F900 = Unused (Part of Celadon Diner's Scripts)
FA00 = Unused

Table 1:
003B - unused
003C - unused

Por que el compendio de Tauwasser marca las siguientes como "unused":

0000*= free for any usage
Table 1:

0001*= free for any usage
0002*= free for any usage
0003*=
0004*=
0005*=
0006*=
0007*= disables advanced calling dialogs when calling MOM

* - are reset to 0 on every map change

El problema de estas ultimas es que algunas se usan en la entrega de pokeballs por parte de Kurt y no se como funcione lo marcado con el asterisco (se resetean en cada cambio de mapa).

Igual me gustaria a invitar a que compartan de que modo han ahorrado Flags en sus respectivos hacks para ampliar el numero de eventos.Yo por ejemplo, uso un solo flag en con cada Lider de Gym (elimino el de la TM), aunque eso me obliga a que si no tienes espacio al momento de recibir la TM tengas que pelear de nuevo con el Lider.

Por ahi Crystal menciona que el usa flas de la Guarida Rocket para agregar mas Trainers.

Cual es su metodo de ahorro de flags??
#8
Crystal_ 28012
Una vez que has vencido a los rockets de la guarida estos ya no vuelven a aparecer, por lo que sus flags de peleado/no peleado pueden reutilizarse para eventos posteriores.

Tecnicamente cualquier direccion ram libre entre C000 y DFFF puede ser utilizada como flag mediante asm (sin estar necesariamente restringidas a scripts). Con el script 0E es posible llamar a asm en cualquier bank. Si por ejemplo se quisiera usar el bit menos significativo de $DEFF como flag, simplemente con:
ld a,(deff)
or a,%00000001
ld (deff),a
pone a 'true' (1) la flag, mientras que un and a,%11111110 en lugar del or la pone a 'false' (0).
Para comprobar su estado no hay mas que hacer, desde asm:
ld a,(deff)
and a,%00000001
Si la flag estaba en true (1), el and pondra la flag z (zero) a 0, mientras que si la flag estaba en false (0), la flag z se pondra a 1. De esta forma podremos manejarnos de forma diferente distinguiendo entre el contenido de la flag z.

Esto sin embargo es mas util de forma general (y en particular en asm) que en scripts, ya que por ejemplo la flag de las estructuras de los entrenadores o la flag de aparicion de los eventos estan limitadas a la tabla de bits 1.
#9
Chamber4315♪ 26330
Muy buena explicacion para una posible expansion de flags [MENTION=28012]Crystal_[/MENTION], pero como podemos hacer una rutina asi pero que funcione como tabla, me explico? hacer algo parecido a lo que hacen por defecto los comandos de script, crear nuestro pseduo "table 3" que reconosca los siguientes dos bytes depues del 0E ZZ XX YY para que asi lea un index y la flag?

U otra cosa, mas bien queria usarlo enfocado a la party para hacer un tutor, o quizas 8 tutores de movimiento, donde cada byte corresponda a un pokemon. Hay FF espacios en la ram libres consecutivos? Como puedo saber los espacios vacios?

Siempre con mi sarta de preguntas, pero me alegra acertelas en algun tema y no via perfil para que queden registradas.

Saludos!
#10
Crystal_ 28012
La unica que se con seguridad es DEFF porque KBM la uso para su rutina y aun asi creo que no esta libre en crystal.

Parece que hay una buena cantidad de direcciones libres alrededor de D500-D600 (hablando de crystal) pero puede que se usen para algo en particular.

Simplemente lo dije como idea, pero quizas no deberia haberlo enfocado a scripts. Por ejemplo yo uso un bit de DEFF a modo de flag utilizada por una rutina cuyo objetivo es limitar el numero de veces que un cierto item se puede usar como maximo en batalla. KBM utilizo la direccion DEFF para algo de la rutina que dividia entre fisico/especial. Lo que dices tu de los tutores si que podria guardarse en la ram (la compatibilidad de cada pokemon), siempre y cuando haya 100 direcciones ram libres, pero para que malgastarlas cuando puedes guardarlo tambien en la rom (ya que lo que tu dices son datos invariables)?
#11
Chamber4315♪ 26330
Cierto, se me fue la onda, no es necesario guardar eso el ram por que no hay variaciones. Si, lo mejor es usarlo para scripts.

Sobre la ram, como se puede saber cuales espacios estan vacios?

Por cierto, gracias por los flags del team rocket, es cierto que no se usan en nada. Ahora comprendo tambien lo de la guarida de los rocket, ahi hay muchos flas a utilizar tambien.
#12
Crystal_ 28012
puedes echar un vistazo a ver que ves en crystal aqui: https://github.com/yenatch/pokecrystal/blob/master/wram.asm

(y no, todas esas direcciones que dije parecian estar libres no lo estan e.e)
#13
G0LD_ZTHVARD0X! 27515
Quite el 10 del titulo porque ya estamos posteando varios consejos
-.-.-.-.-.-.-.-.-.-.
Agrago un consejillo mas.
Mientras se este ejecutando el comando FOLLOW recomiendo que NUNCA usen el comando SHOWEMOTE (comando que muestra emoticonos) ya que si lo hacen apareceran tiles basura en la pantalla, tengo un truco para poder hacer esto, pero no lo pondre porque me da paja :I

Y lo de la guarida rocket es cierto, hay un sinfin de flags y triggers disponibles, que curiosamente todas tienen un clearbit al final.
#14
G0LD_ZTHVARD0X! 27515
Experimentando he hallado una rareza en los scripts de mapa.

Es posible que un script de mapa se repita, lo descubri por medio del comando reloadmap, se lo puse a un script de un npc dentro del mismo mapa, cuando acabo el script inmediatamente se volvio a ejecutar el script de mapa.

Entonces el consejo es: No es aconsejable usar el comando reloadmap dentro de un mapa que si tiene un map script.
#15
Chamber4315♪ 26330
Iniciado por Sr.Dr.Prof. G0LD♪
Experimentando he hallado una rareza en los scripts de mapa.

Es posible que un script de mapa se repita, lo descubri por medio del comando reloadmap, se lo puse a un script de un npc dentro del mismo mapa, cuando acabo el script inmediatamente se volvio a ejecutar el script de mapa.

Entonces el consejo es: No es aconsejable usar el comando reloadmap dentro de un mapa que si tiene un map script.



Y de hecho no es la unica manera en que se repiten. El escript Header consta de dos partes, una dependiente de la ram y por lo tanto necesita estar en la tabla de x94000 (responsable de los triggers) y la otra es independiente de cualquier cosa.

Si tu haces un script que sea dependiente de la ram, mientas cierto flag no deje de coincidir (o ciincida) con el de la tabla el script se ejecuta indefinidamente.

Por eso es mejor usar la segunda parte del script header para no tener ese problema.