¡Buenas! Como nunca antes se había hecho un post de Investigaciones sobre Otras Plataformas, aquí os dejo una lista de cositas que he ido descubriendo según he desarrollado fangames para Nintendo 3DS y New Nintendo 3DS, ampliable a futuros descubrimientos.
Con esto y un bizcocho, espero que os haya gustado hasta las ocho. Cualquier duda, podéis preguntar y así más gente se beneficia de ello.
¡Un abrazote!
- Hay 2 SDK: 1.3.0 y 2.1.0. La última versión de Unity que soporta el primer SDK, que es el más estable, es la 5.6.6f2; y la que soporta la otra es la 2017.2.5f1.
- La licencia que dio Nintendo a los desarrolladores que se registraron en el portal de Nintendo entre 2015 y 2019, sigue siendo válida para Nintendo Switch y Nintendo Switch 2 de forma oficial.
- La Old 3DS tiene un máximo teórico de 96MB de RAM para aplicaciones y la New 3DS 256MB. Sin embargo, estos límites no se pueden alcanzar, siendo el máximo posible 80MB en la Old 3DS y 178MB en la New 3DS.
- En Player Settings podemos definir cuanta RAM queremos que nuestra aplicación pueda usar. El problema es que Unity lo capa SIEMPRE a 64MB máximos en old 3DS y 124 MB en New 3DS. Cualquier número que pongamos por encima de 124MB en New 3DS o 64MB en old, se capará a 124MB o 64MB respectivamente pero activará el modo de memoria extendida de la consola. Este modo es utilizado por juegos como Monster Hunter o Super Smash Bros. Permite a la consola desactivar el Miiverse y el navegador que corre de fondo en la consola para darle más RAM al juego y así poder cargar más recursos.
- Aún así, podemos activar 80MB y 178MB en un CIA o CCI modificando el RSF dentro de la ROM. Este archivo es un XML con datos de configuración que permiten a la consola saber los metadatos y cómo debe ejecutarse dicho juego. Podemos desencriptar la ROM > modificarlo > encriptarla de nuevo o utilizar herramientas como RidTools o CiaForgeX que lo hacen todo en Unity mientras hacemos la build del CCI.
- Podemos ejecutar WebRequests en la 3DS a cualquier servidor si usamos la Internet Key. Ésta habitualmente se la pediríamos a Nintendo y depende del nombre de la aplicación y de la compañía. Sin embargo, se puede calcular de forma sencilla mediante la semilla que usa el SDK:
Código:
private uint Random1(uint seed)
{
seed = seed * 1103515245U + 12345U;
return seed;
}
private uint SdbmHash(string str)
{
uint num = 0U;
byte[] bytes = Encoding.UTF8.GetBytes(str);
foreach (byte b in bytes)
{
num = (uint)b + (num << 6) + (num << 16) - num;
}
return num;
}
public string Get3DSInternetKey()
{
string str = Application.companyName.Trim();
string str2 = Application.productName.Trim();
uint seed = this.SdbmHash(str + "::" + str2);
return "0x" + this.Random1(seed).ToString("X4");
}
- No se pueden utilizar texturas HD (1024x1024) ni resoluciones superiores. La máxima limitación es 512x512 y se debe usar exclusivamente para lo que tenga más detalle ya que se desborda enseguida.
- Aunque se puede exportar a ambos tipos de la familia 3DS, Unity aloca de forma extraña la memoria en el Heap. Sobretodo con Mono. Esto quiere decir que si tienes +150 scripts, seguramente desborden la memoria de old 3DS sin siquiera añadirlos a una escena. Estableciendo la memoria extendida de 72 u 80 MB en old 3DS se puede sortear parcialmente pero el SDK está principalmente hecho para New 3DS y eso se nota.
- Al tener tan poca memoria disponible, si queremos cargar recursos en tiempo real sean sprites, audio, prefabs... tenerlos en la escena de antemano ya referenciados puede ser contraproducente. Cuando Unity carga una escena aloca TODO lo referenciado por ella, incluyendo archivos no cargados aún. Esto facilita que se carguen muchísimo más rápido pero los deja ahí hasta que la escena se descarga. Por ello, lo mejor es usar carga dinámica Asset Bundles o Resources Load. Sin embargo, los Bundles son también contraindicados porque alocan todo lo que hay dentro, pudiendo desbordar la memoria RAM y fragmentando la alocación más de la cuenta. Por tanto, lo mejor es usar SIEMPRE resources load y descargarlo una vez se instancie o al descargar la escena.
- Para hacer el paso entre escenas lo mejor es siempre cargar una escena vacía, esperar 2, 3 frames, liberar los recursos no usados y cargados previamente, esperar uno o dos frames, liberar el colector de basura (Garbage Collector, aka GC), esperar un par de frames y ya cargar la siguiente escena. Así te aseguras de tener todo el espacio necesario para la nueva escena.
- Unity trabaja la pantalla táctil como input de ratón. Esto quiere decir que podemos implementar el toque en ella mediante UI o input de ratón como si fuera un móvil o un PC, facilitando muchísimo el desarrollo.
- Los Amiibo, funciones de la cámara entre otros, requieren que hagamos un plugin nativo en C++ mediante el CTR SDK y lo linkamos a nuestra aplicación.
- Se puede implementar multijugador local de forma "sencilla" mediante PIA (aunque solo es funcional en Unity 5.4.2) o mediante el protocolo propietario de Nintendo UDS. Así es como hice yo que funcionara el juego Pokémon Hitmonchan Boxing 3DS. Este mismo protocolo es usado por juegos como Monster Hunter o Smash Bros en el modo local multiplayer.
- Sin un devkit es complicado debuggear. Lo que suelo hacer yo es capturar los logs en un archivo de guardado y en Citra que me lo genere, ya que asi puedes devolverlo a unity y verlo desde ahí.
- La 3DS tiene unas limitaciones ENORMES de GPU ya que ésta solo permite shaders de Fixed Render Pipeline de Direct X9. Esto nos limita en unity a los shaders custom y a solo poder usar los Legacy Shaders que ya en 5.6.6 estaban deprecados. TextMeshPro funciona parcialmente ya que tendremos que hacer un shader propio que no use SDF, lo que nos elimina todo lo bueno que tiene. Sin embargo, se puede dar soporte para portear juegos que lo utilicen.
- A pesar de que seguimos usando Unity 5 para Nintendo 3DS, podemos usar bastantes herramientas modernas. Hay que tener en cuenta que solo podemos usar NET 3.5, pero si porteamos el código podemos hacer uso de Cinemachine, DoTween, Final IK, Animation Rigging, Odin Inspector...
Con esto y un bizcocho, espero que os haya gustado hasta las ocho. Cualquier duda, podéis preguntar y así más gente se beneficia de ello.
¡Un abrazote!