Un pequeño tutorial dedicado a escribir un simple Mutator para Unreal Tournament 3. Es un tutorial relativamente profundo y detallado, ideal para cualquiera que no sepa por donde empezar con el Unreal Script.Entonces, tienen su nueva y brillante copia de Unreal Tournament 3. Jugaron la campaña entera, y saciaron su sed de rockets en linea. Es hora de algo nuevo. Pero esperen! Seguramente a este juego le quede algo de vida.
Unreal Tournament 3 es un sistema muy flexible, es una plataforma ideal para ser modificada. Hay diferentes mods para Unreal Tournament 3, el modesto
Mutator, el
Custom Game Mode, el fabuloso
Total Conversion y el aun mas popular
Custom Content.
Aqui es donde entran ustedes, hoy nos enfocaremos en el Mutator, un pequeño pedazo de codigo que puede correr como un juego de nuevas reglas aplicables a cualquier GameType, en un servidor o en Instant Action.
Los Mutators solo hacen pequeñas modificaciones al juego (Y eso es lo que solamente deben hacer. Porque hacen esto, muchos Mutators pueden ser usados al mismo tiempo en diferentes combinaciones con locos y espectaculares resultados) ese es el beneficio y la flexibilidad del Mutator.
Preparacion:Antes de comenzar, tenemos que saber un poco mas sobre Unreal Tournament 3 y como funciona este (Si no aprendemos esto, nunca podremos hacer nada).
En Unreal Tournament 3 se guarda todo en paquetes (Esto incluye todo, desde modelos 3D, sonidos, etc) en nuestro caso, codigo. Los paquetes son colecciones de recursos, generalmente tienen la extension .upk. Los paquetes de codigo, sin embargo, tienen la extension .u, pero esto no significa que solamente tengan codigo. Tambien pueden contener cosas como sonidos o texturas del cual el codigo depende. Tener todo esto en un paquete mantiene las cosas organizadas y faciles de manejar.
Unreal Script en si mismo es un
lenguaje orientado a objetos, significa que cualquier cambio o adicion que queramos hacer, en lugar de escribir un monton de nuevo codigo o de cambiar codigo viejo, podremos anular y extender codigo existente para favorecer nuestras necesidades. De hecho,
NUNCA DEBEREMOS MODIFICAR EL CODIGO DE UNREAL TOURNAMENT 3 (Haciendo eso no podremos jugar en linea).
Pueden, convenientemente, descargar el script de
aqui.
Querran extraer los archivos de la carpeta
exported scripts en el directorio correcto (Por defecto, esto es en
C:\Documents and Settings\Usuario\My Documents\My Games\Unreal Tournament 3\UTGame\Src.
Quizas tengan que crear este directorio si no existe. No olviden que en
Usuario va el nombre de usuario de Windows que utilizan ustedes. Ahora querran crear una carpeta para guardar su propio codigo, para separarlo del codigo existente (Creen una carpeta en
Src llamada
FirstMutator, y una segunda carpeta dentro de ella llamada
Classes).
Quizas tambien quieran un editor de texto decente para poder empezar (Pueden utilizar el Notepad si desean, sin embargo recomendamos apliamente el
Notepad++ como el arma de eleccion. En proximos tutoriales discutiremos los beneficios y diferencias de utilizar Notepad++ en conjunto con el Unreal IDE (Ambiente de Desarrollo Integrado) para desarrollar en Unreal Tournament 3.
La carpeta de clases es donde mantendremos todo nuestro codigo escrito (Y estamos casi listos para empezar, pero antes debemos estar seguro de que el juego sepa donde encontrar nuestro codigo) asi que necesitaremos encontrar el archivo
UTEditor.ini en el directorio de Unreal Tournament 3 (Utilicen la busqueda de Windows, es una herramienta muy util para encontrar archivos en Unreal Tournament 3, asi que empiecen a utilizarlo!)) una vez en el, busquen la seccion
[ModPackages].
Justo al final de esta seccion, agreguen
ModPackages=FirstMutator (Esto le dice al compilador donde encontrar el codigo. Paren ! Donde esta el compilador ?
Si buscan en el Menu Inicio, se daran cuenta que tienen accesos directos al editor y al juego. Miren en sus propiedades, y notaran algo astuto (Ambos accesos directos apuntan al mismo programa). El editor se accede agregando el comando
editor al final de la ruta de destino. Podemos acceder al compilador del Unreal Script de la misma manera (Copiando el acceso directo del Unreal ED y cambiando el comando
editor a
make) cambiando al comando para compilar el codigo. Cambien el nombre del acceso directo a algo util, y coloquenlo en algun lugar accesible. Yo lo mantengo en la misma carpeta donde tengo el codigo con el que estoy trabajando.
Ahora, estamos listos para programar !
Escribiendo el Mutator:Necesitamos crear nuestro primer archivo de codigo.Creen un nuevo archivo de textoy llamenlo
FirstMutator.uc. La extension .uc es utilizada por el compilador para reconocerlo como un archivo de texto con codigo en Unreal Script. Esto significa que pueden mantfener pedacitos de codigo o codigo viejo cambiandole la extension a los archivos, ya que el compilador los ignorara. Me gusta utilizar .OLD y .SNIP para mantener las cosas organizadas, pero la eleccion es tuya.
Abran este archivo de texto, es hora de escribir nuestras primeras lineas de codigo. Las cosas finalmente estan llegando a algun lugar (?)
class FirstMutator extends Mutator;
DefaultProperties
{
}Bien, esto no dice mucho (Pero es importante!
class FirstMutator es la nueva clase que estas creando). Recuerda siempre darle al archivo de texto el mismo nombre que el de la clase (De otra manera el compilador te dira que hay una incompatibilidad entre la clase y el nombre del archivo y se reusara a compilar).
Default properties es donde se guardan los valores por defecto de las variables que utilice tu Mutator (No es necesario incluirlo si no tienes variables que agregar (una rareza) pero es una buena practica).
Ahora tenemos que decirle al Mutator que haga algo. La clase Mutator que estamos extendiendo contiene un monton de funciones utiles que nos permiten cambiar la manera de jugar. Encuentren el archivo y abranlo, mirenlo y veran un monton de codigo. Si programaron antes, tomense el tiempo para leerlo y entenderlo. Si nunca antes programaron, probablemente encuentren esto dificil de entender, pero no se preocupen por eso.
En este Mutator, vamos a hacer que el Enforcer haga mas daño. Enforcers+1!
La primer cosa que haremos es evitar que el jugador respawnee con una Enforcer normal, y en su lugar haremos que lo haga con una Enforcer+1. El jugador comienza con un
defaultinventory (Esto esta dictado por la clase
UTGame. Pueden hecharle un vistazo al archivo si les interesa.
Ahora crearemos una funcion para sobrepasar la funcion
InitMutator() en la clase
Mutator (Esto significa que utilizaremos la funcion creada en lugar de la que se encuentra en la clase
Mutator). Como tambien queremos que se haga el resto de lo se incluye en la clase
Mutator, agregaremos
Super.InitMutator() al final (La palabra
super le dice al compilador que busquen en la clase desde la que extendemos y utilice la funcion que le sigue) Elegante!
Si miraron en
UTGame, habras notado que el jugador respawnea con 2 armas en su
defaultinventory (La
Enforcer y el
ImpactHammer. Cambiando el primer elemento en el arreglo
defaultinventory, cambiamos lo que el jugador posee (En este caso cambiamos el
UTWeap_Enforcer por nuestro brillante y nuevo
UTWeap_EnforcerPlusOne.
Pero no tenemos ningun
EnforcerPlusOne! No nos preocupemos, todavia no lo tenemos, pero nos ocuparemos de ello en poco tiempo, asi que sigamos adelante!
class FirstMutator extends Mutator;
function InitMutator(string options, out string ErrorMessage)
{
if (UTGame(WorldInfo.Game) != None)
{
UTGame(WorldInfo.Game).DefaultInventory[0] = class'UTWeap_EnforcerPlusOne';
}
Super.InitMutator(Options, ErrorMessage);
}
DefaultProperties
{
}Es grandioso. El jugador ahora respawneara con el
Enforcer+1 en vez del
Enforcer. Idealmente, solamente basta esto y funciona, pero supongamos que alguien hace un mapa (porque ningun mapa por defecto lo trae) que tiene la Enforcer para tomar. Entonces el jugador podra tener las 2 armas a la vez (Y nosotros no queremos eso). Aca es donde la funcionc
CheckReplacement entra en accion, y probablemente sea la funcion que mas uses en Mutator futuros.
CheckReplacement literalmente va por todos los actores del juego (los que son efectivamente cada objeto del juego) nosotros podemos sobrepasar esta funcion para saber que actor es, y si es algo que no nos gusta, podemos hacernos cargo de el.
class FirstMutator extends Mutator;
function InitMutator(string options, out string ErrorMessage)
{
if (UTGame(WorldInfo.Game) != None)
{
UTGame(WorldInfo.Game).DefaultInventory[0] = class'UTWeap_EnforcerPlusOne';
}
Super.InitMutator(Options, ErrorMessage);
}
function bool CheckReplacement(Actor Other)
{
if (Other.IsA('UTWeap_Enforcer') && !Other.IsA('UTWeap_EnforcerPlusOne')
{
ReplaceWith(Other, "UTWeap_EnforcerPlusOne")
}
}
DefaultProperties
{
}Que paso aqui? Chequeamos si el objeto era un
Enforcer, y tambien si no era un
EnforcerPlusOne porque nuestro EnforcerPlusOne va a extender la clase Enforcer. Si no hacemos este chequeo y el objeto no es un
EnforcerPlusOne, la funcion
CheckReplacement continuara encontrando nuestra primer
EnforcerPlusOne (El cual es una Enforcer!), y lo reemplazara una y otra vez, llevando el juego a crashear cada vez que intentemos correr el Mutator. Mal!
Luego llamamos a la funcion
ReplaceWith, la cual reemplaza nuestras Enforcers por las nuevas. Puedes ver esta funcion en la clase Mutaror si te interesa ver como trabaja.
Ya casi estamos! Todo lo que necesitamos es crear un
EnforcerPlusOne para reemplazar las Enforcers.
Creen otro archivo de texto en la carpeta Classes, y llamenlo
itUTWeap_EnforcerPlusOne.uc. Por que no
Plus1? Bueno, no hay una razon tecnica para que no, pero el compilador piensa que terminar el nombre de una clase con un numero es una cosa muy mala. El codigo se compilara bien, pero recibiran una pequeña advertencia diciendoles que no lo hagan.
En ese archivo de texto, vamos a escribir un simple codigo. Es un buen momento para mirar el contenido de la clase
UTWeap_Enforcer. Ya que estamos extendiendolo y solo queremos que haga mas daño, no necesitamos nuevas funciones locas, solo un par de cambios a los valores por defecto de algunas variables.
class UTWeap_EnforcerPlusOne extends UTWeap_Enforcer;
DefaultProperties
{
InstantHitDamage(0) = 50
InstantHitDamage(1) = 50
}Eso es todo, modificar 2 variables. Noten que
InstantHitDamage(0) es el modo primario e
InstantHitDamage(1) es el secundario. Encontraran mas variables en
UTWeap_Enforcer para modificar (Por ejemplo, si solo quieren
Burst Fire, pueden cambiar ambos
FiringStatesArrays a
WeaponBursting.
Una ultima cosa queda por hacer, y eso es compilarlo.
Compilando el codigo:Recuerdan ese pequeño acceso directo que creamos para acceder al comando
make? Es hora de usarlo. Lo unico que necesitan hacer es correrlo, y el codigo se compilara sin errores ni advertencias. Si las tienes, quizas quieras dar un paso atras y ver que te esta diciendo. Hay posibilidades de haber cometido un pequeño error, y es facil de arreglar. Si realmente quedan trabados, intenten preguntando en los foros de Epic games, BeyondUnreal, o en los de ModDB o 3DBuzz.
Cuando compilan el codigo, el compilador automaticamente generara un paquete con el codigo compilado dentro y tambien generara un archivo
configuration.ini si es necesario. Encontraran el paquete en el directorio del UT3, que por defecto es
C:\Documents and Settings\My Documents\My Games\Unreal Tournament 3\UTGame\Unpublished\CookedPC\Script\FirstMutator.uQue es lo que falta?:Falta una pequeña cosa para que este Mutator este listo. Teoricamente puedes entrar al juego, seleccionar el
FirstMutator en el menu y jugar. Pero no tiene un nombre o descripcion, y tendras que correr el juego con otro comando switch (el '
-useunpublished') para que aparezca.
Aqui es donde el
configuration.ini hace su aparicion. Usen la busqueda de Windows para encontrarlo (Pista, busquen
FirstMutator). Abranlo y encuentren la seccion
[FirstMutator UIDataProvider_Mutator]. Debajo deberan agregar (o antes si es que ya esta ahi):
ClassName=FirstMutator.FirstMutator
FriendlyName=First Mutator
Description=My First Mutator!
GroupNames=
UIConfigScene=
bStandaloneOnly=False
bRemoveOn360=False
bRemoveOnPC=False
bRemoveOnPS3=FalseEsta seccion del ini controla como se muestra el Mutator en el menu.
Despues, necesitamos ver en la seccion
[UTWeap_EnforcerPlusOne UTUIDataProvider_Weapon], donde hay algunos datos que aparecen en el Weapon Browser. De nuevo, modifiquen la entrada para que se parezca a esto:
ClassName=FirstMutator.UTWeap_EnforcerPlusOne
AmmoClassPath=UTGame.UTAmmo_Enforcer
Flags=
FriendlyName=EnforcerPlusOne
Description=The Enforcer+1 is just plain better than the Enforcer.
MeshReference=UI_Weapons.Mesh.SK_UI_Weapons_Enforcer_3P
bRemoveOn360=False
bRemoveOnPC=False
bRemoveOnPS3=FalseAhora el Weapon Browser tiene una referencia a un modelo 3D y muestra correctamente el Enforcer, mas algun par de detalles. Ahora solo nos falta modificar una cosa, como sabemos que tenemos una Enforcer+1?
Necesitamos encontrar el archivo
localisation, que por defecto deberia haber sido creado en:
C:\Documents and Settings\My Documents\My Games\Unreal Tournament 3\UTGame\Unpublished\CookedPC\Localisation\FirstMutator.intModificaremos las siguientes lineas en la seccion [UTWeap_EnforcerPlusOne]:
ItemName="Enforcer+1"
PickupMessage="Enforcer+1"Ahora el juego nos dira que tenemos una Enforcer+1 o que tomamos una del mapa, excelente.
Listos para la accion! Podemos correr el juego creando un acceso directo de la misma manera que creamos uno para el compilador, añadiendo el comando '
-useunpublished', pero no es una buena manera si queremos distribuir el Mutator.
Lo ultimo que queda por hacer es mover nuestros archivos finalizados, cosa facil y rapida. Todos nuestros archivos estan en la carpeta
Unpublished, solo copien lo que hay ahi (Recuerden mantener la estructura del directorio!) y peguenlo en la carpeta
Published, listo.
Disfruten destruyendo con sus nuevas Enforcer+1s!
ModDB.com