Category Archives: Informática

Whatever happened to Anima: UNICO?

I updated Anima: UNICO for the last time three months ago, on 17th July. In that date I still hoped to be able torun a crowdfunding campaign to help me end the application with a big final push, to add the missing rules (monster powers, sheeles, gaïa 2…), support for gaming groups, houserules, random NPC generator, etc. Soon after that day, those hopes vanished and, although it was not my intention, that brought unto me a certain let down about Anima.

Since then, I have started a way in Patreon for anyone who wanted help me develop roleplaying software, and have started the first of such software: Workings of Fate, a set of tools for the Fate CORE system. The first tool is the Aspect Generator, to generate random aspects. It is still in development, as I want to add more variety and coherence to its results.

But the numbers are clear. Right now there are 163 users registered in Anima: UNICO, and 367 characters saved in its database (yes, many of them will be repeated, but still, there are a lot). During 2014, 3,521 users have started 7,823 sessions in Anima: UNICO.

(For comparision, Workings of Fate has received 198 sessions from 162 users in aproximately a month).

So it is time to start again looking for time to keep developing Anima: UNICO. These are the main points in my agenda:

  • Start the english and french translations. As there is now no impediment, I’ll get the help of anyone who wants to participate.
  • Debugging. There are several recurring bugs I have to eliminate. Mainly:
    • Ki section vanishes when buying certain abilities.
    • Ugly can crash the application.
    • MA and zeonic regeneration calculations are not ok.
    • Natural bonuses sometimes fail.
  • New functions. Main ones:
    • Monster powers.
    • Printable sheet (and PDF, if possible).
    • Rate of Fire and reach of projectile weapons.
    • Unarmed as a weapon.
    • Damage percetanges.
    • Sheeles.
    • Gaïa 2 content.
  • Comunity functions.
    • Gaming groups, with a DM to set the generation options to be used by the players.
    • Selection of books to appear in the application.
    • Houserules.
  • And derived applications:
    • Name, aspect, origin random generation.
    • Quick NPC random generation.

All of this will take me a lot of time, but it will slowly march forward.

And if the development of further software for roleplaying games seems interesting to you, remember supporting me in Patreon or streaight in Paypal (you can get the donation button in the Workings of Fate page)!

Making of Anima: UNICO – Localization

Here I am again. Today I am going to address a tricky issue: localization, this is, translating the application to other languages. Just from the start, there are several issues with the process.

I can’t just translate every game term to other language: I have to find and use the word used in the official translation. Luckily, I count with the great help of Vincent ‘Moklo’ Bouscarle, corrector of the French edition of the game, who is translating A:U to French, and Andre ‘Dynaes’ Reich, from the English forum, who is translating to English. I want to use this chance to, again, thank both for their help.

As I have explained before, Anima: UNICO is designed mostly in three layers. Model layer organizes information. Controller layer knows the models and the views and manages the generakl workflow of the application. The View layer gets data from the Controller and shows what the user sees in the screen. Only this layer has to be translated.

My solution

function setIdiomaUI() {
   var lang = navigator.language || navigator.userLanguage;
   
   if ((lang.lastIndexOf("es") != -1) || (lang.lastIndexOf("spa") != -1)) {
      IDIOMA_UI = SPA;
   } else {
      IDIOMA_UI = ENG;
   }
}
function L(id, spa, eng) {
   this.id = id;
   this[SPA] = spa;
   this[ENG] = eng;
   if (!diccionario["ANIMAUNICO_"+this.id]) {
      diccionario["ANIMAUNICO_"+this.id] = this;
   } else {
      console.log("Clave de diccionario repetida: [" + this.id + " / " + this[SPA] + " / " + this[ENG] + "]");
      console.log("--Clave previa: [" + diccionario["ANIMAUNICO_"+this.id].id + " / " + diccionario["ANIMAUNICO_"+this.id][SPA] + " / " + diccionario["ANIMAUNICO_"+this.id][ENG] + "]");
   }
}
L.prototype = {
   constructor: L,
   toString : function() {
      return this[IDIOMA_UI];
   },
   getId : function() {
      return this.id;
   }
};
function _l(clave) {
   if (diccionario["ANIMAUNICO_"+clave]) {
      return diccionario["ANIMAUNICO_"+clave].toString();
   } else {
      return clave;
   }
}

A bit of explanation: I have a class, L, that will be instantiated with every string to translate and its translations. I also have a function, _l, that gets the id of a string and returns the translation to the current user interface language. The Model and Controller layers work only with the id of the strings, which are unique. When the View layer shows any string in screen, it does so through the _l function.

The initialization of strings is like this:

var UI_DAÑO_FINAL = (new L("UI_DAÑO_FINAL","Daño final","Final Dmg.")).getId();
var UI_VELOCIDAD = (new L("UI_VELOCIDAD","Velocidad","Speed")).getId();
var UI_TURNO_FINAL = (new L("UI_TURNO_FINAL","Turno final","Final Init.")).getId();

As you can see, this is only for spanish and english. When the french localization starts, I’ll just have to add another field to the class L and another argument to every string.

Obviously, this solution still has several problems. For example, it is not specially good to form sentences with several variable parts, as it does not account for sintactic differences between languages. But for a character sheet, that will mostly show isolated terms, it is working well enough for me.

 

Making of Anima: UNICO – General structure

In my last post I went through the tools I’m using to develop Anima: UNICO. I have to add another one: SourceTree, a graphical UI for Git very useful and nice, and which makes easier following the GitFlow pattern. Obviously, I don’t need to use GitFlow (and actually I don’t follow it fully), but I like it, as a base over which organize me.

Now, let’s start with the meat. First, how to organice a javaScript application the size of Anima: UNICO? After my initial investigations, I arrived to the following workflow:

  1. I create as many Javascript files as I want/need, usually one per class.
  2. To publish them, I use Grunt to concatenate them and then to minify and uglify them. This way I get only one JavaScript file to publish on the web.

Regarding the organization of the javascript files, I’ve been following (more or less) Model-View-Controller patterns.

  • js/ – General folder for javascript files.
    • controller/ – Controllers.
    • data/ – Data.
    • view/ – Views.
    • model/ – Models.
    • locale/ – Localization.
    • libs/ – Third party libraries
    • vendor/ – Third party libraries
  • sass/ – SASS files.
  • img/ – Image files
  • fonts/ – Fonts
  • css/ –  CSS files.
  • index.html – Main web.
  • indexLocal.html – Main web for local debug.
  • Gruntfile.js – Grunt script.

Controllers

They control the communication between models, prepare data for the user, and receive the user actions and act on them.

Data

The concrete instance data for every class. This is, the data for every Advantage, Spell, Martial Art, etc.

There are several ways of storing data. As I wanted my application to work offline, I could not use a database. In the end, I stored them in their own initialization. This really is a bad idea. I should have stored them in JSON format from the start. In the future I will make the change.

An example:

addVentaja(new Ventaja( VENT_APRENDIZAJE_INNATO_EN_UN_CAMPO, “”, VENT_APRENDIZAJE_INNATO_EN_UN_CAMPO_DESC, REPETIBLE_OPCIONES, [2,3], [], true, [LISTA_TIPOS_SECUNDARIAS], [aprendizajeInnatoCampo], GRUPO_SECUNDARIAS ));

This line of code initialices the advantage “Natural Learner, Field”.

Views

Views generate the UI and interact with the user.

Models

Models are the base classes. Character, Race, MartialArt, etc…

Localization

Localization is everything related to showing the application in several languages. Right now, this means spanish and english, and french is in the works. For this, I have the inestimable help of Andrew “Dynaes” Reich and Vincent “Moklo” Bouscarle.

In another post I’ll detail how I do the localization.

 

Making of Anima: UNICO – Tools

Here I am again. As promised, I’m going to talk about the tools I use to create Anima: UNICO. Without further ado…

1. Language: HTML+CSS+JavaScript client-side, PHP server-side

This one is easy. The main development of Anima: UNICO is made in JavaScript. The web itself is done in HTML, but it is mainly created dynamically from the code using jQuery. The representation is almost totally controlled by CSS.

2. Frameworks and JavaScripts libraries: jQuery, jQuery UI, Modernizr, Gumby

One of the strong points of JavaScript is the great quantity of existing developments. Very probably jQuery is the most famous. It allows working with the webpage DOM without going crazy.

Beyond jQuery, I started using jQuery UI as base for the user interface. jQuery UI is a framework with functions to create buttons, dialogs, draggable components, etc.

Modernizr is a small library which easies the design among different web browsers.

Gumby is a framework to create adaptative webpages, ehich adjust themselves to the screen size. Is the base I use to format the page.

3. Frameworks and PHP libraries: CakePHP

For the server-side, I’m using, in a very basic way, CakePHP, which offers me just what I needed.

4. IDEs: Jetbrains WebStorm, JetBrains PHPStorm

I’ve fallen in love with the JetBrains IDEs. I loved WebStorm  to develop JavaScript, and when I started using PHP, I jumped to PHPStorm (which includes all WebStorm functionality). They are very powerful environments, and integrate everything I wanted them to integrare: version control, remote database, ftp, libraries…

Also, through them I discover the technologies from the next point.

5. More: Node.JS/NPM+Grunt, SASS+Compass, Mocha

JetBrains IDEs integrate with their own Node.JS server, which allows the use of lots of useful scripts. I discovered Grunt, which allows to automatize tasks (it is similar to Make), and used it to unify, minimify and uglify mi javascript files and get them ready to deploy to production.

6. Version control

I started using Subversion as version control, but some months ago I discovered and learned Git, and never looked back. It is a really great VCS.

7. Tasks, general management, online repository: Assembla

I found several online repository options. In the end, I chose Assembla, which offered me a very nice free plan. It integrates with svn and git and offers task and ticket management, that I can integrate with PHPStorm.

8. Reports and web analysis: Google Analytics

In my web I use Google Analytics to check daily views, language, browser… important details for a JavaScript project.

That’s all for today. Next day I’ll start with the code structure.

By the way, you can find the code in GitHub. Go ahead, fork it!

Configurar acceso remoto a una BBDD SQL Server

Este post va a ser tremendamente poco profesional, pero quizás a alguien le sirva de algo.

Se tiene una BBDD en un servidor SQL Server. Se quiere acceder remótamente, por ejemplo creando un acceso de datos ODBC desde otra máquina.

1) Ejecutar las herramientas de red de servidor en la máquina servidor. Habilitar el protocolo TCP/IP y fijar un puerto. Comprobar que dicho puerto está abierto en el firewall del servidor.

2) Ejecutar %windows%\system32\cliconfig.exe en el cliente. Habilitar el protocolo TCP/IP marcando detectar el puerto automáticamente. En la pestaña Alias, crear un alias para el servidor con un nombre distintivo. Marcar la opción TCP/IP, e indicar en acceso su IP.

3) En el cliente, crear el origen de datos ODBC indicando como servidor el alias creado.

EDITADO: Se me había olvidado que, evidentemente, hay que abrir también el puerto en el cliente.

Acceder a ficheros Excel desde C#

Se podría pensar que al ser ambos productos de Microsoft lo tendrían todo mejor integrado y preparado (a lo mejor lo tienen y me he complicado la vida. De ser así, por favor avisadme), pero acceder a los datos de un archivo Excel multihoja no es trivial.
Así he conseguido hacerlo yo:

public String[] getHojas() {
String[] listadoHojas;
DbConnection connection;
DbProviderFactory factory = DbProviderFactories.GetFactory(“System.Data.OleDb”);
try {
DataTable worksheets;
connection = factory.CreateConnection();
String connectionString = @”Provider=Microsoft.Jet.OLEDB.4.0;Data Source=” + ruta + “;Extended Properties=\”Excel 8.0;HDR=Yes\””;
connection.ConnectionString = connectionString;
connection.Open();
worksheets = connection.GetSchema(“Tables”);
listadoHojas = new String[worksheets.Rows.Count];
int i = 0;
foreach (DataRow dr in worksheets.Rows)
{
string hoja = dr[“TABLE_NAME”].ToString();

//las siguientes líneas “limpian” el nombre
hoja= hoja.Substring(0,hoja.LastIndexOf(“$”));
if (hoja.IndexOf(“‘”) == 0)
hoja = hoja.Remove(0, 1);

listadoHojas[i++] = hoja;
}
connection.Close();
return listadoHojas;
}
catch (Exception e) {
throw new Exception(e.Message, e);
}
}

Y luego, para acceder a los datos de una hoja concreta:

DataSet dsMsExcel = new DataSet();
DbConnection connection;
DbProviderFactory factory = DbProviderFactories.GetFactory(“System.Data.OleDb”);
try
{

if (hoja.Contains(” “) || hoja.Contains(“-“))
hoja= “[‘” + hoja+ “$’]”;
else
hoja= “[” + hoja+ “$]”;

DbDataAdapter adaptador = factory.CreateDataAdapter();
DbCommand selectCommand = factory.CreateCommand();

selectCommand.CommandText = “SELECT * FROM ” + hoja;

connection = factory.CreateConnection();
String connectionString = @”Provider=Microsoft.Jet.OLEDB.4.0;Data Source=” + ruta + “;Extended Properties=\”Excel 8.0;HDR=Yes\””;
connection.ConnectionString = connectionString;

selectCommand.Connection = connection;
adaptador.SelectCommand = selectCommand;
dsMsExcel.Tables.Clear();
adaptador.Fill(dsMsExcel);

return dsMsExcel;
}
catch (Exception e)
{
throw new Exception(e.Message, e);
}

Algo de tiempo… comentarios variados

He concluido mi curso de máster, con su bonita tesis y todo (“La Tecnología RFID: Estado Actual, Aplicaciones y Futuro”). Ahora me encuentro en una situación realmente excepcional: mi tiempo libre es realmente libre. ¡No tengo obligaciones fuera de las horas de trabajo! Así que a ver si dedico algo de ese tiempo al blog, al Helechal, y a algunos proyectos de rol en general.

Empecemos por algunas noticias…

Evidentemente, la noticia más relevante es el anuncio de la cuarta edición de Dungeons & Dragons. Los datos concretos sobre los cambios van apareciendo con cuentagotas. Algunos de los más interesantes:

  • Grandes cambios al sistema de magia: casi se elimina completamente la “magia vanciana” típica de D&D: se habla de magos lanzando conjuros de nivel 25, y magia que no se agota al lanzarla, por ejemplo.
  • Se agrupan las clases de personaje por “roles” en el grupo: los atacantes (guerrero, warlord), defensores (pícaro, explorador), líderes (clérigo, paladín) y controladores (mago, hechicero). Las clases concretas aún no se han dicho, pero esas ocho parecen las más probables, siendo el warlord una especie de bárbaro con gritos de guerra.
  • El juego básico va a ir de nivel 1 a nivel 30.
  • Los guerreros tendrán distintas habilidades según el arma en que se especialicen.

La sensación general que me da a mi esta cuarta edición es que va a tener cambios enormes, muchos de ellos en lo que se podría llamar “dirección juego de rol online de ordenador”, lo que no me hace mucha gracia. Sin embargo, hay muchas posibilidades de que el juego sea mucho más rápido que la tercera edición, y los personajes tengan habilidades más interesantes. Habrá que verlo, en mayo.

Por supuesto, estar tan ocupado no me ha impedido ir consiguiendo algunos juegos nuevos. Recientemente (en los últimos 3-4 meses, diría) he recibido Changeling: The Lost, Witch Hunter: The Invisible World, Wild Talents, Slang, The Burning Wheel, Burning Empires, Mythic Russia, Lesser Shades of Evil, Aces & Eights: Shattered Frontier y Godlike. A ver si comento un poco de cada uno.

  • Changeling: The Lost: El último juego del nuevo Mundo de Tinieblas. Un libro precioso, casi al nivel de Mage: The Awakening. Una nueva visión de las hadas, esta vez como los monstruos inhumanos que raptan a niños y los suplantan por changelings. El juego trata sobre las personas raptadas que consiguen huir de sus captores y vuelven al mundo, para descubrir que el tiempo ha pasado de modo distinto para ellos, y que su vida ha sido ocupada por una replica. Ellos han sido cambiados, y tienen que aferrarse a su humanidad perdida y huir del Hada que le busca. Tiene a priori mucho mejor aspecto que Changeling: The Dreaming. Al igual que Promethean, es una línea limitada: libro básico y cinco suplementos.
  • Witch Hunter: The Invisible World: Un juego muy reciente (de hecho, aún no ha bía sido distribuido por los canales normales: mi ejemplar lo compré en Noble Knights Games, que lo tuvo que conseguir en la GenCon). Ambientado en un siglo XVI alternativo, los personajes son cazadores de brujas que buscan y eliminan el mal (y se trata de brujas de verdad, así como demonios y otros males). Según lea informaré.
  • Godlike: El primer juego en emplear el sistema ORE de Greg Stolze. Trata de superhéroes en la Segunda Guerra Mundial, y de como ni la presencia de superhombres altera el mundo ni la guerra. La profunda ambientación y el genial sistema lo hacen un juego realmente bueno.
  • Wild Talents: Un juego de superhéroes más genérico que Godlike, del mismo creador, pero que también incluye como ambientación el futuro del mundo de Godlike. La sección con un estudio del género de superhéroes es excepcional.
  • Slang: Un juego español de Nosolorol para jugar partidas que parezcan sacadas de un guión de Tarantino (lo que se ve en muchas ilustraciones casi directamente cogidas de Pulp Fiction o Reservoir Dogs, por ejemplo). Presenta un análisis del género, y mucha información sobre Los Ángeles.
  • The Burning Wheel: Un curioso juego en formato A5 (libro pequeño), se presenta en tres manuales: Character Burner, Burning Wheel, y Monster Burner. Un juego de fantasía genérico, con un sistema muy interesante, en el que lo más importante son las creencias e instintos de los personajes.
  • Burning Empires: Un juego con el sistema de The Burning Wheel, basado en el mundo creado en los tebeos de Iron Empires. Presenta unas mecánicas de juego muy concretas que lo hacen casi parecer una mezcla entre juego de rol y juego de estrategia. Los jugadores se enfrentan al DJ, que no tiene el poder habitual en otros juegos, y tiene que seguir las reglas con tanto cuidado como el resto de jugadores. El conflicto general es relativamente simple: un planeta, creado en conjunto por todo el grupo de jugadores, se enfrenta a una invasión, primero oculta (como “La invasión de los ladrones de cuerpos”), luego abierta.
  • Mythic Russia: Un juego basado en el sistema de Heroquest y ambientado en la Rusia mítica de sus cuentos populares, con Baba Yaga, Koschei, y similares. Una ambientación que me resulta tremendamente evocativa, y un sistema que, aunque tiene problemas, dan ganas de conseguir que funcione.
  • Lesser Shades of Evil: Un juego de fantasía bastante original. La ambientación aparenta ser un mundo de espada y brujería más o menos típico, pero oculta una historia muy distinta, basada en alta tecnología y la capacidad de separar mente y cuerpo y permitir a una persona controlar distintos cuerpos.
  • Aces & Eights: Shattered Frontier: El juego del oeste definitivo. De los creadores de Hackmaster, usa un sistema derivado (el tono general de este juego es serio, eso sí), con subsistemas para guiar ganado, juegos de cartas, duelos, juicios, buscar oro, y todo tipo de acciones típicas del oeste.