@ agnasg

El bug que no lo es

30-08-2015 5:18 AM

En mi tarjeta de presentación soy un presidente corporativo.
En mi mente soy un desarrollador de juegos,
Pero en mi corazón soy un jugador de videojuegos.
Satoru Iwata 1995-2015

Este es un bug producido por desconocer (u olvidar) cómo es o cómo está estructurada la data. En realidad es un bug mental, no hay bug sino la apariencia de un bug que no lo es. Pero puede ser catalogado como bug porque huele a bug, luce como bug, sabe a bug. El detalle es que resulta ser otra cosa. Este tipo de bug quita tanto tiempo como los bugs reales, cuidado si no más tiempo. Me había pasado antes con clientes, y mi trabajo era convencerlos que el supuesto bug estaba solo en su cabeza. Estos son los bugs difíciles de explicar y los clientes adquieren un temor irracional hacia ellos, por lo que cada vez que aparece algo sospechosos gritan desaforados ¡bug! ¡bug! ¡bug! Inclusive llaman bug a cosas no implementadas. Un bug es algo que no funciona correctamente en algo implementado. Algo que no ha sido implementado no es un bug, es una omisión u olvido.

Pero el caso es que este bug aparente me pasó a mi. Un bug mental. Como ya he dicho estoy programando un parser para los dialogos de los npcs en psyblast. Yo tengo todo un tema con esto de los parsers y siempre prometo que no voy a hacer más nunca en mi vida uno más, pero al final termino enredado en uno nuevo. Volviendo al bug, el parser finalmente procesó y almacenó los dialogos correctamente en la base de datos del juego (sqlite por ahora) pero al final estaban apareciendo 7 registros (o rows en la base de datos) con el valor “Al terminar el hechizo…”, “Al terminar el hechizo…”, “Al terminar el hechizo…”. Por alguna razón el parser no estaba detectando el final del archivo de entrada. Dediqué 3 horas buscando, debugueando, sin ningún éxito. Al final se me ocurrió ver con detalle la base de datos. Estoy usando Sqlitebrowser, que es similar MySQL browser, y como los registros tienen varios campos y ocupan más del tamaño de la ventana, el campo relativo al “valor” queda truncado así que solamente se ve “Al terminar el hechizo…”… claro, al extender la ventana y ver el contenido del campo pude descubrir que el parser estaba funcionando, lo que pasaba es que casualmente los últimos registros corresponden a un npc que enseña hechizos y todos comienzan con la misma descripción “Al terminar el hechizo…”. Así pues, este era un bug que no es un bug. El parser estaba funcionando correctamente, el problema es que yo no recordaba los diálogos de este npc (los cuales escribí hace meses).

Enlaces que sí son enlaces

Parsers 2015

20-08-2015 3:33 AM

Estoy una vez más programando un parser de un archivo de dialogos de npcs intencionalmente simple, pero que ha resultado ser inadvertidamente complicado. Ya he dicho varias veces (1, 2, para la definición de parser ver aquí) que he tenido que hacer varios parsers en mi vida de programador de juegos inéditos. Si leemos aqui, veremos que mi opinión es que usar los viejos atlantes de la programación de compiladores (lex y yacc) es un trabajo de meses. Esa es una exageración, pero las cosas resultan algo como eso (esta librería de facebook usa bison y yacc para parsing de GraphQL, un lenguaje para describir requerimientos de datos). Pero ¿qué tal hacerlo a mano? Depende del lenguaje. Hace años hice un intérprete de un lenguaje similar a C y si mal no recuerdo no resultó complicado. Pero esta vez la complicación provino de la recursividad. Mi “simple” formato incluye un nombre de npc, que puede tener una o más palabras claves, que tienen asociado uno o más párrafos. Todo salpicado con formatos del tipo {[1]}, {[2d6]}, etc. que indican cuántas veces se debe decir el texto. Finalmente se pueden insertar %%comentarios%%, que abarcan una o más líneas. Simple ¿verdad?

No.

for (ilineno = 0; ilineno < MAX_LINES;ilineno++) {         if (dialog_id && variable_id) {        // variable_id not assigned yet to its dialog             update_dialog_variable (dialog_id, variable_id);             variable_id = 0;             dialog_id = 0;         }         bool    found = false;         // search a npc         while (parser->getline (line)) {
            lineno++;

            // handle comments
            if (handleComments (parser, line)) {
                continue;
            }

            begin = parser->after_pattern(line, CIS_TAG_NPC);

            if (begin == std::string::npos) {
                continue;
            }
            std::string s = line.substr (begin);
            end = parser->before_pattern(s, CIS_TAG_NPC);
            if (end != std::string::npos) {
                npcname = s.substr (0, end);
                found = true;
                break;
            }
        }
        if (!found) {
            break;    // finished... maybe
        }
        std::transform(npcname.begin(), npcname.end(), npcname.begin(), ::tolower);
        int id = npcs->getId (npcname);
        if (id == -1) {
            id = npcs->insert (npcname); // create instance
        }
        (id == -1) && panic ("CIntSystem::load: can't insert/update a new npc");
        // now a loop of ::keywords[,keywords]:: text,text...
        while (parser->peekline (line)) {    // give me the line but keep it in the input pipeline (so I can do a getline (line) after)
            begin = parser->after_pattern(line, CIS_TAG_NPC);
            if (begin != std::string::npos) { // we found a npc so we finished
                break;
            }
            dialog_id = insert_dialog ();    // create empty dialog
            while (parser->getline (line)) {
                lineno++;

                // handle comments
                if (handleComments (parser, line)) {
                    continue;
                }
                begin = parser->after_pattern(line, CIS_TAG_KEYW);
                if (begin == std::string::npos) {
                    continue;
                }
                int i;
                for (i = 0; i < MAX_KEYWORDS;i++) {                     std::string s = line.substr (begin);                     end = parser->before_pattern(s, CIS_TAG_SEP);
                    if (end != std::string::npos) {
                        keyword = s.substr (0, end);
                        insert_keyword (dialog_id, keyword);
                        begin = parser->after_pattern (s, CIS_TAG_SEP);
                    } else {
                        end = parser->before_pattern(s, CIS_TAG_KEYW);
                        value = missing + "'" + std::string(CIS_TAG_KEYW) + "' at line " + itos (lineno);
                        end == std::string::npos && panic (value);
                        keyword = s.substr (0, end);
                        insert_keyword (dialog_id, keyword);
                        break;
                    }
                }
                (i == MAX_KEYWORDS) && panic ("CIntSystem::load: Too much keywords or parsing error");
                break;
            }
            // now dialog's lines
            int    index = 0;
            while (parser->peekline (line)) {    // give me the line but keep it in the input pipeline (so I can do a getline (line) after)
                begin = parser->after_pattern(line, CIS_TAG_NPC);
                if (begin != std::string::npos) { // we found a npc so we finished
                    break;
                }
                begin = parser->after_pattern(line, CIS_TAG_KEYW);
                if (begin != std::string::npos) { // we found a another keyword so we finished current keyword
                    break;
                }
                while (true) {    // comments loop
                    parser->getline (line); // get the line
                    begin = parser->before_pattern(line, "::Lugar::");
                    if (begin != std::string::npos) {
                        int kk = 0;
                        kk++;
                    }
                    if (lineno == 28) {
                        int kk = 0;
                        kk++;
                    }
                    // handle comments
                    if (!handleComments (parser, line)) {
                        parser->getline (line); // eat the line
                        break;
                    }
                    // verify missing tag
                    begin = parser->before_pattern(line, CIS_TAG_NPC);
                    end = parser->before_pattern(line, CIS_TAG_KEYW);
                    (begin != std::string::npos || end != std::string::npos) && panic ("CIntSystem::load: Wrong comment in line " + line);
                }
                while (true) {    // this loop travel the line until its end... truly amazing
                    // as the documents is generated using Word, the text is in one line without newline (LF+CR)
                    // anyway this parser assume is possible to have several lines and each one is taken as a paragraph.
                    int initial_size = line.size ();
                    begin = parser->before_pattern(line, CIS_TAG_FMTBEG);
                    if (begin == std::string::npos) {
                        if (dialog_id == 0) {    // we found a line previously so lets create a new one
                            dialog_id = insert_dialog (line, 0, index);    // create empty dialog
                        }
                        // reset all
                        variable_id = 0;
                        dialog_id = 0;
                        trigger_id = 0;
                        // check next line
                        break; // exit the loop analizing this line so get a new line.
                    }
                    // begin != std::string::npos
                    // we found some formatting instructions
                    if (0 != begin) {
                        value = line.substr (0, begin); // <=:- value is here in case you're like me                          update_dialog (dialog_id, value, std::string(), variable_id);                         variable_id = 0; // this means that variable_id is assigned to his dialog                     }                     begin++;    // skip CIS_TAG_FMTBEG                     line = line.substr (begin);                     begin = line.find_last_not_of(whitespaces); // skip any white spaces
switch (line[begin]) {                     case CIS_TAG_CNTBEG:    // [                         // count                         ...
                        break;
                    case CIS_TAG_VARBEG:    // $
                        ...
                        break;
                    case CIS_TAG_VARACT:    // =
                        ...
                        break;

                    case CIS_TAG_VARDIS:    // ~
                        ...
                        break;
                    default:

                        ...
                        break;    // we don't reach this point.
                    }
                    ...
                }
            }
        }
    }
:

...

De enlaces

  • Una discusión sobre una patente de ascensor espacial sin que se mencione en lo absoluto a Arthur C. Clarke. Al parecer esta patente gira sobre conceptos que no encajan exactamente con la definición de ascensor espacial, es más bien una torre muy alta con un espaciopuerto en la azotea. Alguien hizo un post en 9gag sobre lo mismo.
  • Leyendo aquí descubrí Carrion Fields, un roleplaying mud, que inclusive está de 6to en topmuds. Raro que no lo vi hace meses cuando huía despavorido de batmud. En esa ocasión visité Aardwolf (suele estar de primero, me gustó hasta dónde llegué), landsofredemption.comabandonedrealms.com y Slothmud.
  • Tú necesitas un plan y un diseño. No. Tú necesitas ponerte a trabajar. Planear lo hacen los aviones :) Hablando en serio me gustaría hacer un inventario de cuántos posts como este he leído en los últimos 20 años. Pero si usted nunca ha leído uno así hágalo, la planificación es en mi opinión inútil pero siempre sirve como divertimento medieval cuando no tenemos nada mejor que hacer. Yo escribo ideas todo el tiempo, así que organizarlas en un plan no molesta en lo absoluto, así que sí, planifique, planifique, eso es bueno.

Oh Oracle

11-08-2015 10:31 AM

Solo enlaces

  • Me gustó este artículo por la forma extraña en que utiliza la expresión “No te repitas a ti mismo”. Esperaba una disertación sobre no caer de nuevo en errores que ya has cometido, pero en realidad se trata sobre no duplicar código. ¡¿No duplicar código?! ¡Como si pudiéramos evitarlo! No me refiero a las tonterías que hacemos cuando solemos ser novatos (somos novatos cada vez que comenzamos a trabajar con un sistema, api, lenguaje o herramienta nueva, lo cual debe suceder al menos una vez al año, es decir somos novatos anualmente), me refiero a las oportunidades en que tenemos que duplicar código. O cuando tenemos que hacer una y otra vez algo. Por ejemplo, he dicho que en mi vida de programador de juegos he tenido que hacer varios parsers, y metalenguajes para manejar el scripting, o los diálogos del juego. Lo hecho al menos 4 veces incluyendo cuando traté de hacer una imitación de Inform (reportado en alguna parte en el caad como un fracaso). Pues bien, aquí lo estoy haciendo otra vez con psyblast. ¿Repitiendome a mi mismo? La historia de mi vida. Y es que vivimos en la dicotomía de Ousterhout, entre un lenguaje formal y el lenguaje para scripting. Y en programación de juegos, esto es una norma obligada.
  • Journey of the light, un juego tan difícil que el desarrollador no se tomó la molestia de incluir los niveles 2-8 porque el 1 ya era lo suficientemente difícil. Evidencias. Steam de hecho decidió ofrecer la devolución total del dinero a quien lo solicite, sin importar el tiempo de juego ya consumido. El desarrollador se disculpó, dijo que fue un error, pero que el daño ya estaba hecho. Ouch.
  • ¿Quieren ver el blog post más arrogante del mes? Lean esto. ¿Oh un 404? Es porque es tan arrogante, es tan mala publicidad, que la gente de mercadeo de Oracle decidió eliminarlo. Pero no importa, aquí hay algunas copias: 1,2,3,4. Basicamente la Jefe de seguridad de Oracle dice que un cliente no puede investigar en busca de fallas (haciendo ingeniería inversa o cualquier otra cosa) porque eso sería violación de la licencia, y que eso es como ser infiel a la esposa/esposo. Y si un cliente descubre una falla tiene que mostrar suficientes evidencias como para que Oracle tome cartas en el asunto. Increíble. Reportado en reddit y Hacker news. Oh Oracle…

 

En otras noticias, India prohíbe la pornografía

03-08-2015 9:44 AM

India acaba de prohibir la pornografía al bloquear 857 sitios. No tengo idea qué va a pasar con los otros 857 millones de sitios web que tienen pornografía, ni qué sentido tiene dado que es imposible bloquear en realidad un sitio web. De la misma forma que la vida se abre camino en jurassic park, los sitios web tienen siempre un camino disponible para llegar a ellos. Además, freelancer como soy, y dado que en mi día a día tengo que lidiar con el 99% de los freelancers que existen, indios por supuesto (indios porque no se les puede llamar indúes porque eso es una religión y hay indios católicos, budistas, etc) sé por experiencia que ellos no aceptan un no por respuesta, ni permiten que los pisen no solamente por el legado de Ghandi sino por la experiencia que tienen  de ser pisados, con o sin razón. Así que imagino que la reacción va a ser interesante de ver, por decir lo menos, aunque supongo que se va a difuminar, como un argumento valido en 4chan/v

La nueva expansión de world of warcraft será presentada el 6 de agosto

29-07-2015 12:52 PM

Esto está raro. ¿Este anuncio está super adelantado por algún motivo que me estoy perdiendo? Tengo meses que no juego wow pero parece que el barco se está hundiendo, única explicación de adelantar el anuncio de la nueva expansión, cuando deberían estar corrigiendo los entuertos. Raro. Enlace.

The Battle for Wesnoth

27-07-2015 7:11 AM

Estuve varias horas revisando toda la historia alrededor de The Battle for Wesnoth, juego que se encuentra en desarrollo desde 2003, tiene una gigantesca comunidad, y la lista de desarrolladores excede el centenar. Llegó a mis manos debido a un llamamiento por ayuda, para continuar/reiniciar su desarrollo (mencionado en Hackers News y en Reddit). Es un juego de estrategia basado en turnos, del tipo Tribal Wars, donde tienes tu ejército, tienes fortalezas, y debes usar estrategia para conquistar territorio. Parecido también en cierta forma a Civilizacion. Está desarrollado en C++ y si bien es cierto que parece tener graves problemas de diseño,  particularmente en el sistema que maneja las conexiones, lo puedo recomendar como un buen ejemplo de un gigantesco juego que vale la pena examinar. También es interesante ver las imágenes, íconos, fonts y toda la media en general. Tiene un lenguaje propio WML para diseñar los mapas, e interfase con python y lua.

Enlaces (este es casi el resumen del mes porque creo que voy a estar muy ocupado de aquí al 31)

  • Defininitivamente estoy de acuerdo que esto está fuera de control. Este juego sobre diseño de puentes debe ser prohibido.
  • Hoy aprendí que puedes hacer function overloading en C.
  • Esto estuvo dando vueltas por las páginas de programación hace unas semanas: Los 10 mandamientos de la Nasa para programación. La última,Todo el código debe ser compilado desde el primer día de desarrollo con todos los warnings del compilador habilitados (All code must be compiled, from the first day of development, with all compiler warnings enabled at the compiler’s most pedantic setting) no puede ser más cierta. Curiosamente esto no puede ser más cierto: ayer entregué un sistema (bien bien complicado, del tipo NP), sin ningún warning pero, olvidé validarlo en 32 bits (coloqué una constante MAXCOST como 2147483648, el cual es un número que genera el warning: this decimal constant is unsigned only in ISO C90 (esta constante es unsigned solamente en ISOC90), por lo que ahora tengo que agregar pruebas en un sistema 32bits (mi máquina de desarrollo es 64 bits).
  • A mi no me gustan los juegos de cartas (me refiero a juegos tipo The Gathering o Yu Gi Oh), pero este juego Guild of Dungeoneering tiene un excelente diseño (y el video es super divertido). Estuvo entre los 10 juegos más vendidos hace unas semanas. Reportado aquí.
  • Por cierto que aquí esta la discusión sobre esta loquera de los 30fps. Por ejemplo: juegos con tag 30fps. Pues sí, algunos desarrolladores bloquean el frame rate a 30 para garantizar que el juego funcione bien sin importar el equipo y la tarjeta grafica. Interesante.
  • “La gente recomienda no programar juegos RPG por su gran alcance. ¿De dónde viene el gran alcance en los RPGs?. Hmm. No es una dolencia de los RPGs nada más, el mencionado juego The Battle for Wesnoth adolece del mismo problema por lo que desde el comienzo el desarrollador original alineó el desarrollo del juego con la filosofía KISS (mantenlo simple estúpido (keep it simple stupid)).
  • Lo cual me lleva a esta intesantisima historia sobre el desarrollo del juego The Age of Decadence. El cuento trata sobre las ??? en esta lista: 1) Anunciar un nuevo RPG. 2) ??? 3) Ganancias. En serio que esas son las ??? más angustiosas (angustiantes no parece existir como palabra) de mi vida.
  • Me quedé contemplando durante varios minutos este post en los clasificados de Reddit “Hi there. Im interested in starting a paid/rev share project. (“Hola, estoy interesado en comenzar un proyecto pagado/ganancia compartida”) Recordé horas, días, semanas, proyectos, discusiones, peleas en el chat (las peores y más violentas peleas), proyectos no pagados, frustración, etc, etc, etc. ¿Por qué? Porque hay personas que no saben nada de trabajar en un proyecto, no saben nada de trabajar/producir/llevar ideas a productos terminados, hay personas que no parecen personas. O al menos no parecen comportarse como tales. Porque decir en mi opinión “persona razonable” es una redundancia, toda persona debe ser razonable. Entonces, yo, como desarrollador, o como freelancer, o como programador de juegos decido colocar mis próximos días/semanas en manos de un ser (no consigo otra palabra no tan peyorativa) que tiene una idea y cree saber como llevarla a un producto terminado. Es la pesadilla de convertir el “???” del punto anterior a una realidad. Por ejemplo esta página sobre “Ideas propuestas frecuentemente”, es interesante por las respuestas de los desarrolladores. “Si esa es una interesante idea pero creemos que ese cambio va en contra de la filosofía del juego, es decir, va en contra de KISS, o va a cambiar el balance del juego, etc. Eso es inaceptable para un creador de proyectos que “tienen una idea”. Ellos son la persona de la idea y no se puede discutir razonablemente con ellos. Y el problema es que esta persona, la persona de la idea no hace nada, él solamente tiene su idea y nada más. A este tipo de proyectos yo les digo “no gracias” de entrada sin preguntar siquiera “qué”. Y sobretodo por lo de “ganancia compartida”. Como dice alguien en los comentarios “everything about your post tells me you’re an “idea guy” (“todo en su post me dice que usted es “la persona de la idea”). Y es que si no sabes que  “la persona de la idea” es lo más inútil e irrelevante de un proyecto, deberías estar lo más alejado posible de cualquier foro donde se publiquen anuncios para participar/desarrollar proyectos. ¡Gracias!

sourceforge have 24 hours down and nobody cares

19-07-2015 6:41 AM

sourceforge tiene ahora más de 48 horas caído, y a nadie le importa. Bueno mi post en reddit ha sido visitado por al menos 1000 vistantes continuamente desde entonces, así que si hay gente que todavía le importa. El punto es que con github y code.google.com sourceforge se ha vuelto irrelevante en los últimos años, como algunos comentadores han dicho. Sin embargo, por razones desconocidas todavía están alojados ahí importantes proyectos, incluyendo vim (el editor), unetbootin (una herramienta para bootear desde un pendrive) y, entre otros, irrlicht, el motor gráfico que uso diariamente para psyblast y otros proyectos personales. Como no es gran cosa lo que se puede hacer en este momento porque no hay acceso a los foros (hay 2-3 personas en el irc (#irrlicht:irc.freenode.net)) vamos a proponer la mudanza a github en lo que sourceforge vuelva a estar en línea. Mientras tanto hay un sitio no oficial con el repositorio:  https://github.com/osense/irrlicht-git

Sitio sourceforge de irrlicht (fuera de línea en este momento 19-07-2015 08:06)

Post en reddit reportando el problema (por agnas)

Viejas practicas

05-07-2015 10:22 AM

I-refuse-to-use-mallocLuego de muchos años y con el advenimiento de C++11 (y sus nuevas encarnaciones C++14 y C++17) me resultada realmente molesto ( o quizás hasta bochornoso) que mi vieja rutina strsave () continuara pululando dentro de mis aplicaciones y juegos. La primera versión la escribí en 1981 basado en el texto de K & R, y algo parecido se puede encontrar en casi cualquier aplicación desarrollada en C.

char *strsave (const char *id)
{
    char *str;

    if ((str = (char *) malloc (strlen (id) + 1)) == NULL) {
            g_write_debug ("strsave: out of memory");
            return NULL;
    }
    strcpy (str, id);
    return str;
}

La pregunta es ¿por qué? Con std:string esto dejó de ser necesario por lo menos hace 15 años. Viejas prácticas supongo, y que el programador C sigue escondido en alguna parte dentro de mí. std:string se puede encargar complemente del negocio de manejo de la memoria. La explicación clave es la siguiente: “std::string usa el allocator por defecto std::allocator, dado que std::allocator usa new y delete, la memoria heap es usada, así que el string es permanente hasta que el programa termina, o el programador hace algo al respecto.

Cuéntame uno de freelancing

03-07-2015 8:50 AM

… soy bailarina y traficante de armas.

Sofía Serrano

Leo con fruición la lección número 6 de este blogguer sobre freelancing: hacer crecer el negocio es más difícil de lo que usted piensa – Traté de comenzar un equipo de escritura  y por un tiempo funcionó.  Tenía 10 sub-contratistas (no todos trabajando al mismo tiempo) y estaba devorando negocio tras negocio como nadie. Pero se derrumbó. Rápidamente aprendí que el tiempo que dedicaba a entrenamiento, corregir sus errores y compensar las metas no cumplidas estaba excediendo la ganancia extra que estaba obteniendo. (Scaling is harder than you think it will be – “I tried to start a little writing team – and for awhile, it worked. I had 10 subcontractors (not all busy at once) and was passing off work like nobody’s business. But it fell apart.I quickly learned that the time I was spending trying to train them, fix their mistakes and compensate for their missed deadlines was easily offsetting the extra income I was making.“)

No sé cuántas veces tengo que explicar esto cada vez que alguien me pregunta por qué después de 10 años trabajando freelancing no me he expandido, por qué no he formado un equipo de trabajo. freelancing es diferente. No es obvia la estrategia para crecer y la razón está insinuada arriba: para crecer tienes que dejar de hacer freelancing y pasar a ser un gerente de proyectos, manejar recursos, etc., lo cual es exactamente lo que no queremos hacer cuando nos transformamos en freelancers. Yo formé o ayudé a formar variar compañías y mi rol fue básicamente ser el de líder de proyectos. Ya yo me sé ese capítulo. Ya vi esa película. Me transformé en freelancer justamente porque no quiero más reuniones con un equipo de trabajo los lunes o peor, los viernes por la tarde, para oír excusas y coartadas. Claro esto no está muy a la altura de las enseñanzas de Warren Buffett, y justamente  ahí está el punto, al decidirnos como freelancers le estamos diciendo see you later a Warren, y comenzamos a hacer nuestro propio camino.

Hay que ser coherente. O aprender a decir mentiras. Ejemplo: estoy trabajando un complicadísimo proyecto cuyo objetivo es una librería que sirva como wraper del api de una compañía que presta servicios de impresión de fotografías. Antes tenían un servicio basado en soap, ahora es REST. (hacer google SOAP vs. REST conduce a un montón de páginas con publicidad que no dicen nada útil, as usual, stackoverflow tiene una excelente respuesta). La primera pregunta que le hice a la persona que me está contratando fue “¿qué rol tiene usted en el equipo? ¿es usted el lider?”. La respuesta fue un “yes” tan poco creíble que no me sorprendió en lo absoluto cuando descubrí poco después que él no tenía idea de que C++ REST SDK no soporta SSL. Es decir, él no es el líder del proyecto, es un contratista que me está sub-contratando. De cuentos como este está lleno el ambiente de freelancing. Así que tenemos que desarrollar algo así como una caparazón para protegernos. Porque de nada sirve responder/corregir o entablar una discusión (¿cómo es que no sabes que C++ REST SDK no soporta SSL?). Es inútil. Sheldon no sobreviviría ni una semana como freelancer.

Se me olvidaba

30-06-2015 2:51 PM

En mi defensa entre más de 800 posts que hay en este blog, este es el primero llamado “Se me olvidaba”. Eso es algo.

Pues olvidaba mencionar ayer algunos puntos. Me acordé leyendo los links del mes de Emily Short, y  una nota en reddit esta tarde que me resultó interesante. Más de esto el próximo mes.

  • No tengo tiempo en este momento para escribir sobre el tema, porque voy saliendo a ver Jurasic World, pero un juego que debe aclarar que this is not a zombie story (esta no es una historia de zombies) me resulta verdaderamente perturbador.
  • Tampoco tengo mucho tiempo para hablar sobre el UI que estoy trabajando en  psyblast, y que ya no se cuántos de estos he hecho a lo largo de los años, ya perdí la cuenta. La regla aquí es reutilizar viejos componentes, de los cuales tengo toda una biblioteca. psyblast usa irrlicht así que no puedo sacar ventaja de lo que he hecho en Qt.
  • Lo que me lleva al cuasi-leit-motiv de este blog, reinventar la rueda etcétera. Pero esta vez lo voy a decir de una forma diferente. Resulta que en la serie de libros de Asimov, Fundación, se narra la historia de que toda la civilización va a colapsar (porque sí basicamente) y  como solución se debe plantar el germen para que la civilización renazca al otro lado del universo. El resto del primer libro y buena parte del segundo si recuerdo bien trata sobre cómo determinar qué significa eso, qué significa el otro lado del universo. Ciertamente puede ser el sitio más distante conocido (lo cual sería una solución bastante obvia) pero resulta que quienes determinaron lo de “el otro lado del universo” era algo así como socio-estadisticos, es decir, especialistas en el comportamiento estadístico de las masas sociales (o algo por el estilo). Así que “el otro lado del universo” tiene una connotación diferente. Por ejemplo, el planeta menos desarrollado socialmente. El cual resultó ser Terminus, un planeta poco avanzado, todo lo contrario de Trantor que era la capital del universo y consistía de una ciudad que abarcaba todo el planeta (algo así como Coruscant). Pues toda esta larga introducción es para mencionar que este desarrollador de juegos que desarrolló 340 juegos en 18 años debe estar al otro lado de mi universo. Lo digo no solamente por la cantidad sino por la calidad. Creo que el 95% es kk digital.