Daños y resistencias

En Sticks & Stones hemos optado por un sistema de daños y resistencias, lo que significa que un arma que puede ser poderosa contra un enemigo pero débil contra otro. Lo mismo ocurre con los enemigos, que pueden ser vulnerables o resistentes a los diferentes tipos de daño.

Tipos de daño

Los objetos que causan daño, como las armas, definen uno o varios tipos de daño.

  • Perforante
  • Aplastante
  • Cortante
  • Hendidor
  • Fuego
  • Disparo
  • Virtual

En nuestro código, utilizamos un enum para catalogarlos.

public enum DamageType
{
    Piercing,
    Crushing,
    Slashing,
    Cleaving,
    Fire,
    Shoot,
    Virtual
}

Un arma podría combinar varios tipos de daño, por ejemplo un garrote con pinchos combinaría daño aplastante y perforante. Además para cada tipo de daño se define la cantidad de daño, pero eso lo veremos más adelante.

Armas

Las armas tienen varias propiedades en común. En nuestro código las agrupamos con 3 interfaces: IInventariable, IEquippable y IDamageDealer.

public abstract class Weapon : Wearable,
    IInventariable,
    IEquippable,
    IDamageDealer
{
    ...
}

Inventariable: indica que las armas pueden colocarse en un inventario, como por ejemplo la mochila.

public interface IInventariable
{
    InventariableType InventariableType { get; }
 
    float Weight { get; }
 
    bool Stackable { get; }
 
    short InventoryValue { get; }
}

Equipable: indica que las armas pueden equiparse en el cuerpo de un personaje.

public interface IEquippable
{
    List<BodyPart> AllowedEquippableAreas { get; }
 
    bool TwoHandsUse { get; }
}

Dañino: cualquier objeto que puede causar daños.

/// <summary>
/// Cualquier cosa susceptible de causar daño.
/// </summary>
public interface IDamageDealer
{
    /// <summary>
    /// Objeto con la configuración e información sobre el daño.
    /// </summary>
    DamageSource DamageSource { get; }
 
    /// <summary>
    /// Indica si puede ser lanzado o arrojado.
    /// </summary>
    bool CanBeHurled { get; }
}

La parte más interesante es IDamageDealer que es la interface que indica que un objeto puede causar daño mediante la propiedad DamageSource, que habla de la cantidad y tipos de daño.

DamageSource básicamente contiene un diccionario donde la clave es el tipo de daño y el valor es un entero que indica la cantidad de daño.

public class DamageSource
{
    public readonly Dictionary<DamageTypeint> DamageByType;
 
    #region Constructor
    public DamageSource(Dictionary<DamageTypeint> types)
    {
        DamageByType = types;
    }
    #endregion
}

Inicialmente DamageSource tenía propiedades adicionales relacionadas con efectos negativos (debuff) que se aplicaban al atacar. Pero es una mecánica que por ahora vamos a omitir del videojuego.

Estos son ejemplos de objetos dañinos (armas principalmente) que tenemos configurados en Sticks & Stones.

stone-axe-icon  Hacha de piedra
Hendidor = 13
wooden-bow-icon  Arco de madera
Disparo = 5
wooden-club-icon  Mazo de madera
Aplastante = 25
bone-knife  Cuchillo de hueso
Perforante = 4
Cortante = 2
*Daño potencial = 6
wooden-arrows  Flecha de madera
Perforante = 8

En el caso de las armas de proyectil, cómo los arcos, el daño que acaban causando depende también del proyectil que lanzan. Simplificando, se puede decir que un arma de proyectil causa un daño equivalente al suyo más el del proyectil que lanza. Según los ejemplos anteriores, un arco de madera que lanza flechas de madera, tendría un daño potencial de 13 (5 de disparo y 8 de perforante).

Resistencia y vulnerabilidad al daño

La resistencia o vulnerabilidad al daño es una propiedad que se configura en los personajes, pero también afecta al entorno, como por ejemplo un árbol.

Similar a cómo ocurre en las armas, en el código utilizamos una interface que indica si un objeto puede recibir daño.

Esta interface se llama IVulnerable.

public interface IVulnerable
    {
        uint BaseHitPoints { get; }
 
        int CurrentHitPoints { getset; }
 
        Dictionary<DamageTypeint> ResistencesByDamageType { get; }
 
        DamageInfo GettingDamage(
            CharacterBase owner,
            IDamageDealer damageDealer,
            ProjectileWeapon projectileWeapon,
            float damageMultiplier,
            AttackProperties attackProperties);
    }

La propiedad interesante es ResistencesByDamageType, que consiste en un diccionario donde la clave es el tipo de daño y el valor es el porcentaje de resistencia o vulnerabilidad a ese tipo de daño. Un valor negativo indica que es vulnerable y un valor positivo que es resistente. La omisión de un tipo de daño indica que no le afectará ni positivamente ni negativamente, es decir, un objeto que no tiene configuradas resistencias o vulnerabilidades recibirá el daño potencial del arma (13 siguiendo el ejemplo del arco y flecha u 6 del cuchillo de hueso).

Como dije, no solo los personajes son vulnerables al daño, hay objetos del entorno que también lo son, como por ejemplo los árboles.

forest-tree
Hendidor = -50%
Aplastante = 99%
Perforante = 80%
Disparo = 90%
Cortante = 80%
Fuego = -80%

Se puede observar que los árboles son especialmente vulnerables al daño hendidor (el que producen las hachas) y al fuego, y muy resistentes al resto de daños.

Los principales enemigos de Sticks & Stones, la míticas Holo-Balls, configuran sus propias resistencias y vulnerabilidades. La finalidad es crear estrategias y elecciones de armas específicas para cada enfrentamiento. No queremos que exista una sola arma poderosa, queremos que cualquier arma pueda ser útil.

En definitiva, en Sticks & Stones hay que experimentar para conocer y aprender sobre los enemigos y las armas.

¿Crees que este nivel de profundidad en el sistema de daños le sienta bien al videojuego?

El Concursante – III

¿Cuál es mi nombre?

Por si quieres refrescar la memoria, estos son los capítulos anteriores de la serie “El Concursante”: 

Mr. Palo, nuestro maniquí de pruebas, iba a dar el siguiente paso. Cuando tuvimos el primer prototipo listo y probamos como se sentía el videojuego, lo siguiente fue darle un lavado de cara para ver hacia donde encaminábamos el apartado artístico.

Este fue el primer cambio que sufrió después del prototipo inicial.

screenshot-2016-mayo-12-jpg

Durante la siguiente semana probamos juguetear con los colores y añadimos algunos elementos nuevos.

screenshot-2016-mayo-17

Y un mes después llegamos a esta versión.

screenshot-2016-junio-10

Como puedes ver, Mr. Palo se alimentó bien durante ese tiempo, pues ahora se ve más rellenito y parece un concursante.

Desde este momento, nuestro magnífico maniquí pasó a tener nombre propio.

Ferguson.

T O    B E    C O N T I N U E D . . .

Clarisse, un indie desarrollado por Not Human Games

Hace poco hemos conocido un videojuego que está desarrollando Not Human Games, llamado Clarisse. Como nosotros, están en proceso de aprobación en Greenlight.

clarisse-animated

Creo que el videojuego es bueno y merece tener éxito, y por eso, me he decidido a redactar este post, para ayudarles a que lo conozca más gente.

Me he sentido especialmente identificado con ellos, pues es su primer videojuego y le están poniendo todo el esfuerzo y cariño posible. Eso se nota.

Aquí puedes ver el trailer oficial.

Una pincelada sobre el juego, sacada de un extracto contado por ellos.

Clarisse es un juego de mecánicas point and click con un fuerte componente narrativo enfocado en la investigación y en las respuestas emocionales del jugador.

El jugador adquirirá el rol de una inteligencia artificial llamada Clarisse, que fue creada para ayudar a un importante científico (el Dr. Matt) en sus investigaciones.

Trabajarás en una avanzada instalación científica y aprenderás por medio de diferentes mecánicas y experiencias narrativas que te darán la oportunidad de saber más sobre el experimento, el Dr. Matt e incluso sobre tí.

Disponen de una demo que he tenido el placer de jugar. La verdades que la he disfrutando mucho y me he quedado con ganas de más.

Si quieres saber más, puedes visitar su página en Steam Greenlight.

¡Les deseo toda la suerte!

 

El diseño de los alijos de supervivencia

deathSticks & Stones es un Rogue-like, y como tal, la elevada dificultad y la permadeath (muerte permanente) forman parte de sus características principales. Vamos a tener que jugar una y otra vez para conseguir ganar este reality show.

A nivel de diseño esto nos pone en un aprieto, pues tenemos que conseguir que la experiencia de juego no se haga pesada o aburrida.

A grandes rasgos, la estructura del videojuego se puede resumir en planificación+combate. La parte de combate no es problema, es pura acción y la diversión está asegurada. Sin embargo, en la parte de planificación, que incluye: exploración, supervivencia, recolección y crafting, es donde debemos andar con más cuidado, porque son mecánicas lentas. Es aquí donde entran en juego los alijos de supervivencia.game-structure

Los alijos de supervivencia serán una de las mecánicas, entre otras tantas, que ayudarán a que la parte de planificación sea más entretenida. Lo que se pretende con los alijos, es potenciar la exploración añadiendo un pequeño componente aleatorio que otorgará ventajas al concursante entre partidas.

karmaA un nivel contextual, los alijos de supervivencia son creados por los mismos concursantes, como una forma para ayudarse entre ellos. Aquí jugamos un poco con el Karma, pues la idea es que si escondes algo bueno en un alijo para que otro se lo encuentre, tu Karma será positivo y es posible que alguien te devuelva ese favor. Aterrizando este concepto en el juego, la idea es que si en una partida escondes algo de valor, en tu siguiente partida encontrarás algo de valor equivalente.

Esta mecánica es una de las pocas que transciende entre partidas, ofreciendo al jugador una manera de comunicarse entre ellas y otorgandole ventajas que le permitan avanzar cada vez más lejos. Además está perfectamente integrada en el contexto, para que el jugador pueda sentir lo duro que es el reto que propone el reality show y decida si quiere ayudar a otros—o a sí mismo-—a obtener el premio.

Hasta aquí el concepto, pero ahora explico como resolvemos esta mecánica y que se va a encontrar el jugador durante la partida.

En la zona central, especialmente diseñada para planificarse y donde comienza la partida, el concursante tendrá que explorar, recolectar y construir cosas. En definitiva, preparase para la supervivencia y el combate. Durante la exploración, si se presta la suficiente atención al entorno, podremos encontrar el alijo, que se descubrirá por emitir un sutil brillo intermitente. Al situarnos en el origen del brillo se habilitará una opción para cavar en el suelo. No será necesario ninguna herramienta, el concursante cavará con sus propias manos poniendo al descubierto el botín, del que podremos coger todo lo que queramos y/o dejar cosas para que el próximo concursante las encuentre.

Internamente los objetos del juego tienen un valor, que se utiliza para calcular el valor total del alijo.

Por ejemplo, un alijo de valor 18 podría contener objetos que sumen hasta un total de 18:

1 × Lanza de madera (8) 1*8 = 8  wooden-spear
1 × Cuchillo de hueso (10)  1*10 = 10  bone-knife
wooden-spearbone-knife = 18

4 × Flecha de madera (3)  4*3 = 12  wooden-arrowswooden-arrowswooden-arrowswooden-arrows
1 × Cuerda (4) 1*4 = 4  rope
wooden-arrowswooden-arrowswooden-arrowswooden-arrows rope = 16

Este factor aleatorio, permitirá que el jugador pueda encontrar y utilizar objetos que no conoce, incentivando la experimentación con el crafting y añadiendo un punto de emoción al encontrar el alijo.

Esto es todo por ahora en cuanto los alijos de supervivencia, pero tenemos varios puntos abiertos, como por ejemplo si hay límite máximo en el valor de un alijo o si hay un número máximo de objetos que puede contener. También nos preguntamos: ¿se debe enterrar el alijo para considerase válido?

Te animo a que opines sobre está mecánica y nos ayudes a decidirnos por las dudas pendientes que nos quedan.

¡Muchas gracias!

 

Traje, hologramas y realidad aumentada

En Sticks & Stones eres un concursante en un show televisivo que mezcla supervivencia y acción. El concursante debe enfrentarse a enemigos un tanto especiales: las Holo-Balls, unas esferas que se desplazan por el suelo y proyectan hologramas.

gunslinger
Arte de juego – Gunslinger

gunslinger
Ilustración – Gunslinger

El concursante va equipado con un traje especial que le permite interactuar con las Holo-Balls, y unas lentillas de realidad aumentada que proporcionan una experiencia de combate segura.

El traje está conectado a un sistema de monitorización que controla las constantes vitales y la interacción con las Holo-Balls. Si durante el reto sufre algún desmayo o pérdida de conocimiento, el traje lo notifica al sistema y una unidad de emergencia viene a socorrerlo, provocando automáticamente su derrota. El traje también reconoce un impacto causado por algún objeto de realidad aumentada (proyectil) o Holo-Ball. Los impactos reducen los puntos de golpe de los que dispone el traje y si llegan a 0 el concursante también es derrotado.

ferguson-suit
Arte de juego – Concursante

Los proyectiles que lanzan algunas Holo-Balls son creados mediante la realidad aumentada, incapaces de causar daño físico al concursante. Existen varios tipos de proyectiles o balas y su aspecto determina sus características.

Cuando un holograma o artefacto de realidad aumentada se ve de color rojizo indica que está potenciado, mejorando sus propiedades normales.

super-bullet-normal Super bala
super-bullet-chargedSuper bala potenciada

 mega-bullet-normal  Mega bala
mega-bullet-charged Mega bala potenciada

 

Sticks & Stones te pone a prueba en un reto único y difícil, mezclando naturalezatecnología. ¿Podrás abrirte paso hasta el final partiendo de los palos y piedras que encuentres en el camino?

 

Nueva Holoball: Torpigdo

Hace unas semanas mostramos algunas de las Holoballs. Hoy te enseñamos a Torpigdo, un cerdo montado en un cañón que dispara balas muy poderosas.

Se dice que Torpigdo fue un aviador reconocido que acabó pilotando un cañón de tierra… que no te engañe su aspecto, detrás de sus gafas de aviador se esconde un poderoso enemigo al que respetar.

Su ataque es a distancia (range). Durante un breve periodo de tiempo cargará un poderoso disparo que lanzará a alta velocidad a través de su cañón. Su poder ofensivo es compensado con su falta de movilidad.


Test chamber: Torpigdo – Indie DB

Si quieres probar enfrentarte a Torpigdo, ¡descarga nuestra build y ponlo a prueba! Te retamos a derrotarlo devolviéndole sus disparos con el escudo holográfico.

Si te gusta, ¡compartelo!

 

 

More Foes

La comunidad indie es una comunidad sana y en constante crecimiento, por eso es habitual encontrar a un equipo indie hablando de otro.

Hace unas semanas hablábamos del videojuego Wizards of Legend, esta vez lo hacemos de More Foes, un pequeño estudio indie llevado por dos personas.

More Foes empezó desarrollando un videojuego llamado Chosen, muy prometedor y con un sello muy personal. Sobretodo para los fans de QuakeDoom, porque claramente hay muchas referencias y guiños que recuerdan a los títulos insignia de Id Software.

Por el momento, a fecha de 2017, han pausado el proyecto Chosen, aunque esperan continuarlo. En su lugar han empezado un nuevo desarrollo, Nazis Time. Un videojuego menos ambicioso, pero igualmente prometedor.

Nazis Time se presenta como un top-down shooter con generación procedural de mapas, donde manejamos a dos carismáticos personajes: Adam y Ricky.



Me encanta el diseño artístico y la puesta en escena que nos ofrece este estudio, por su sello explícito y visceral y por su propuesta Pixel Art bien cuidada.

Espero que sean capaces de terminarlos, porque estaré encantado de poderlos jugar.

Os dejo el enlace a su Blog y Twitter para que los podáis seguir.


More Foes: Twitter & Blog


¡Desde Sticks & Stones les deseamos mucha suerte!

 

Diseño y programación – Supervivencia y consumibles

En este post contaré cómo hemos diseñado y programado el sistema de supervivencia y consumibles, que afectan directamente a la mecánica de supervivencia.

El post se divide en 3 apartados:

  1. Supervivencia: la mecánica relacionada con los consumibles.
  2. Consumibles: los objetos que representan el concepto de consumibles.
  3. Colores: los colores que identifican los diferentes indicadores de supervivencia.

 

Supervivencia

Es una de las mecánicas del videojuego que sirve para hacer más difícil el reto al jugador. Durante la partida, sufrirá de hambre, deshidratación y sueño. Para lidiar con ello, tendrá que buscarse la vida, sobre todo utilizando el entorno natural en el que se encuentra. Podrá cazar animales, beber agua, dormir, recoger frutos silvestres, fruta, setas y otras tantas cosas.

Por tanto, la supervivencia mide tres factores:

  • Hambre hunger-icon
  • Deshidratación dehydration-icon
  • Sueño sleep-icon

Cada uno de estos factores tiene su indicador y se dividen en varias propiedades, que permite tener el control del estado de supervivencia de los personajes.

survival-status

Propiedades de supervivencia

La supervivencia está vinculada a los personajes orgánicos, como los concursantes, de manera que cada personaje define dos métricas importantes para cada uno de los factores de supervivencia (hambre, deshidratación y sueño):

  • El tiempo que tarda en desmayarse
  • La cantidad de puntos que necesita para quedar saciado

El código que verás a continuación, es parte del script de un personaje orgánico, donde definimos las propiedades de supervivencia.

  • Tiempo desmayo por hambre: indica el tiempo para desmayarse por hambre o desnutrición, expresado en segundos.
  • Tiempo desmayo por deshidratación: indica el tiempo para desmayarse por deshidratación, expresado en segundos.
  • Tiempo desmayo por sueño: indica el tiempo para desmayarse por sueño, expresado en segundos.
  • Puntos para saciar el hambre: puntos necesarios para saciar completamente el hambre.
  • Puntos para hidratarse: puntos necesarios para hidratarse completamente.
  • Puntos para aliviar sueño: puntos necesarios para aliviar el sueño completamente.
  • Tiempo durmiendo para recuperar sueño: tiempo necesario que se necesita dormir para recuperar completamente el sueño, expresado en segundos.
/// <summary>
/// Cualquier personaje del juego que sea orgánico, por ejemplo un concursante o un animal de la fauna.
/// </summary>
public abstract class OrganicCharacter : CharacterBase
{

...

  /// <summary>
  /// Tiempo para desmayarse por hambre o desnutrición (en segundos).
  /// </summary>
  public abstract float TimeToFaintFromHunger { get; protected set; }

  /// <summary>
  /// Tiempo para desmayarse por deshidratación (en segundos).
  /// </summary>
  public abstract float TimeToFaintFromDehydration { get; protected set; }

  /// <summary>
  /// Tiempo para desmayarse por sueño (en segundos).
  /// </summary>
  public abstract float TimeToFaintFromSleep { get; protected set; }

  /// <summary>
  /// Puntos necesarios para nutrirse al completo y saciar el hambre.
  /// </summary>
  public abstract ushort PointsToSatiateHunger { get; protected set; }

  /// <summary>
  /// Puntos necesarios para hidratarse al completo y saciar la sed.
  /// </summary>
  public abstract ushort PointsToHydrate { get; protected set; }

  /// <summary>
  /// Puntos necesarios para aliviar el sueño.
  /// </summary>
  public abstract ushort PointsToAlleviateSleep { get; protected set; }

  /// <summary>
  /// Tiempo necesario para recuperarse por completo del sueño,
  /// desde un estado completamente agotado o cansado por sueño (en segundos).
  /// </summary>
  public abstract float SleepTimeForFullRecovery { get; protected set; }

...

}

Métodos de consumo de los personajes

El código que añado a continuación, muestra algunos de los métodos de los personajes orgánicos, que permiten interactuar con los consumibles o consultar el estado de supervivencia.

  • Comprobar desmayo: indica si el personaje se ha desmayado por alguna de las propiedades de supervivencia.
  • Consumir: actualiza los indicadores de supervivencia del personaje para un consumible.
  • Beber una bebida: actualiza los indicadores de supervivencia de un personaje para una bebida.
  • Beber de un contenedor: da un sorbo a la bebida contenida en el contenedor de bebidas.
  • Dormir: actualiza el indicador de supervivencia que corresponde con el sueño aumentando los puntos correspondientes al tiempo dormido.
/// <summary>
/// Cualquier personaje del juego que sea orgánico, por ejemplo un concursante o un animal de la fauna.
/// </summary>
public abstract class OrganicCharacter : CharacterBase
{
 
...

 /// <summary>
 /// Indica si el personaje se ha desmayado por falta de comida, hidratación o cansancio.
 /// </summary>
 /// <returns>'Verdadero' si se ha desmayado, 'Falso' en caso contrario.</returns>
 public bool IsFaint()
 {
   return (CurrentFeedingPoints <= 0 || CurrentHydrationPoints <= 0 || CurrentStimulationPoints <= 0);
 }

 /// <summary>
 /// Consumir algún alimento, bebida o estimulante.
 /// Modificará el estado de supervivencia del individuo.
 /// </summary>
 /// <param name="consumable">Objeto a consumir.</param>
 public void Consume(Consumable consumable)
 {
   if (consumable != null)
   {
     // Alimentación
     float estimatedFeedingPoints = (consumable.FeedingPoints + CurrentFeedingPoints);

     if (estimatedFeedingPoints > PointsToSatiateHunger)
     {
       estimatedFeedingPoints = PointsToSatiateHunger;
     }

     CurrentFeedingPoints = estimatedFeedingPoints;

    // Hidratación
    float estimatedHydrationPoints = (consumable.HydrationPoints + CurrentHydrationPoints);

    if (estimatedHydrationPoints > PointsToHydrate)
    {
      estimatedHydrationPoints = PointsToHydrate;
    }

    CurrentHydrationPoints = estimatedHydrationPoints;

    // Estimulante
    float estimatedStimulationPoints = (consumable.StimulationPoints + CurrentStimulationPoints);

    if (estimatedStimulationPoints > PointsToAlleviateSleep)
    {
      estimatedStimulationPoints = PointsToAlleviateSleep;
    }

    CurrentStimulationPoints = estimatedStimulationPoints;
  }
 }

 /// <summary>
 /// Consumir una bebida.
 /// Modificará el estado de supervivencia del individuo, normalmente afectando a su hidratación.
 /// </summary>
 /// <param name="drinkSource">Fuente o surtidor de bebida.</param>
 public void Drink(IDrinkSource drinkSource)
 {
   if (drinkSource != null)
   {
     GameObject drinkCandidate = GameObjectFactory.GetSample(drinkSource.DrinkType);

     if (drinkCandidate is Drink)
     {
       Drink drink = (Drink)drinkCandidate;
       Consume(drink);
     }
   }
 }

 /// <summary>
 /// Beber o dar un sorbo de un contenedor de bedida, por ejemplo, una cantimplora.
 /// </summary>
 /// <param name="drinkContainer">Contenedor de bedida del que se va a dar un sorbo.</param>
 public void Drink(DrinkContainer drinkContainer)
 {
   if (drinkContainer != null)
   {
     if (!drinkContainer.IsEmpty())
     {
       drinkContainer.Use();
       Drink(drinkContainer as IDrinkSource);
     }
   }
 }

 /// <summary>
 /// Dormir un tiempo limitado.
 /// Modificará el indicador de sueño del individuo.
 /// </summary>
 /// <param name="sleepTime">Tiempo de descanso o sueño (en segundos).</param>
 public void Sleep(float sleepTime)
 {
   float calculatedPointsBySecond = sleepTime * SurvivalStatusEngine.GetRecoveryPointsWhenSleep(this);
   float estimatedStimulationPoints = (CurrentStimulationPoints + calculatedPointsBySecond);

   if (estimatedStimulationPoints > PointsToAlleviateSleep)
   {
     estimatedStimulationPoints = PointsToAlleviateSleep;
   }

   CurrentStimulationPoints = estimatedStimulationPoints;
 }

...

}

Los tres indicadores de supervivencia (hambre, deshidratación y sueño) tienen un valor que va disminuyendo con el tiempo, cuando cualquiera de estos llega a 0, el concursante se desmaya y pierde la partida. Para impedir que eso ocurra, el concursante debe consumir ciertas cosas para aumentar dicho valor. Estas cosas son las que antes he llamado consumibles.

 

Consumibles

En el videojuego, un elemento consumible es cualquier cosa que se puede consumir, como por ejemplo carne, agua, setas, fruta… Todos los consumibles tienen lo que llamamos puntos de supervivencia.

Puntos de supervivencia

Los consumibles otorgan puntos de supervivencia al consumirlos, aumentando el tiempo que el personaje puede aguantar sin desmayarse. Cuando hablamos de puntos usamos la siguiente nomenclatura:

  • Para saciar el hambre: puntos de alimento
  • Para hidratarse: puntos de hidratación
  • Para aliviar el sueño: puntos de estimulación

Por ejemplo, consumir moras añade 7 puntos de alimento a los indicadores de supervivencia del personaje. Esto aumentará el tiempo que tiene el concursante antes de desmayarse por hambre.

survival-stats-example

Es posible que un consumible pueda dar puntos a más de un indicador de supervivencia. Por ejemplo una naranja, otorga puntos de alimentación e hidratación.

Caducidad

Los consumibles pueden caducar, lo que significa que transcurrido su tiempo de caducidad se echan a perder y no se pueden consumir.

Actualmente tenemos deshabilitada esta opción por temas de jugabilidad. Creemos que es una mecánica más pesada que divertida y por el momento no la utilizamos.

Esto abre la puerta a otras mecánicas interesantes, como por ejemplo: si un consumible caducado se encuentra en un contenedor con otros consumibles, podría contagiar al resto y acelerar el tiempo que tardan en echarse a perder… Pero como he dicho, es una mecánica que de momento no vamos a utilizar 😛

El código de los consumibles

En nuestro código disponemos de una clase que representa este concepto de objeto consumible, a la que llamamos Consumable.

Las propiedades más relevantes son:

  • Puntos de alimentación: cantidad de puntos de alimentación que se obtiene al consumirlo.
  • Puntos de hidratación: cantidad de puntos de hidratación que se obtienen al consumirlo.
  • Puntos de estimulante: cantidad de puntos de estimulante que se obtienen al consumirlo.
  • Tiempo de caducidad: tiempo total que tarda en caducar.

Los métodos más relevantes son:

  • Comprobar estado de caducidad: indica si el consumible ha caducado.
  • Comprobar si caduca: indica si el consumible caduca. Hay consumibles a los que no aplica la caducidad en el videojuego, como por ejemplo el agua.
/// <summary>
/// Cualquier elemento que se puede consumir, como por ejemplo bebida, comida, estimulantes, etc.
/// </summary>
public abstract class Consumable : GameObject
{
 #region Constructor
 protected Consumable() : base()
 {
   if (BaseExpirationTime > 0)
   {
     float minExpirationTime = BaseExpirationTime * ((100f - ExpirationTimeMargin) / 100f);
     float maxExpirationTime = BaseExpirationTime * ((100f + ExpirationTimeMargin) / 100f);
     float expirationTime = CustomConstants.Random.Next((int)minExpirationTime, (int)maxExpirationTime);
     ExpirationTime = expirationTime;
     RemainingExpirationTime = expirationTime;
   }
 }
 #endregion

 #region Properties
 /// <summary>
 /// Margen en el que el tiempo de caducidad definido puede variar (en porcentaje).
 /// </summary>
 protected const float ExpirationTimeMargin = 10;

 /// <summary>
 /// Puntos de alimento que se obtienen al consumir esto.
 /// Sirven para saciar el hambre y mitigar la desnutrición.
 /// </summary>
 public abstract ushort FeedingPoints { get; }

 /// <summary>
 /// Puntos de hidratación que se obtienen al consumir esto.
 /// Sirven para saciar la sed y mitigar la deshidratación.
 /// </summary>
 public abstract ushort HydrationPoints { get; }

 /// <summary>
 /// Puntos de estimulación contra el sueño que se obtienen al consumir esto.
 /// Sirven para combatir el sueño, como la cafeína.
 /// </summary>
 public abstract ushort StimulationPoints { get; }

 /// <summary>
 /// <para>Tiempo base que tarda esto en echarse a perder, con el tiempo
 /// expirado no se puede consumir (en segundos).
 /// </para>
 /// <para>El tiempo real de caducidad queda definido por un margen pequeño
 /// que puede acortar o alargar la duración total.</para>
 /// <para>El valor 0 indica que no caduca.</para>
 /// </summary>
 public abstract float BaseExpirationTime { get; }

 /// <summary>
 /// Tiempo restante, que le queda al consumible para caducar o echarse a perder (en segundos).
 /// </summary>
 public float RemainingExpirationTime { get; set; } = 0;

 /// <summary>
 /// <para>Tiempo real que tarda esto en echarse a perder.</para>
 /// <para>Este tiempo no es constante, depende de un pequeño margen definido
 /// internamente que puede acortar o alargar la caducidad.</para>
 /// <para>Ver 'ExpirationTimeMargin'</para>
 /// </summary>
 public float ExpirationTime { get; protected set; } = 0;
 #endregion

 /// <summary>
 /// Obtiene el porcentaje actual de caducidad del consumible.
 /// Representa porcentualmente cuanto tiempo le queda para caducarse.
 /// </summary>
 /// <returns>Porcentaje restante antes de caducar.</returns>
 public float GeCurrentExpirationPercent()
 {
   return (RemainingExpirationTime / ExpirationTime) * 100f;
 }

 /// <summary>
 /// Indica si el consumible ha caducado.
 /// </summary>
 /// <returns>'Verdadero' si ha caducado, 'Falso' en caso contrario.</returns>
 public bool IsExpired()
 {
   return (IsExpirable() && RemainingExpirationTime <= 0);
 }

 /// <summary>
 /// <para>Indica si el consumible tiene tiempo de caducidad.</para>
 /// <para>Nota: Un consumible con una tiempo base de caducidad de 0 se considera no-caduco.</para>
 /// </summary>
 /// <returns>'Verdadero' si puede caducar, 'Falso' en caso contrario.</returns>
 public bool IsExpirable()
 {
   return (BaseExpirationTime > 0);
 }
}

La naranja sería un ejemplo de implementación de un consumible:

/// <summary>
/// <para>Naranja natural. Se obtiene del naranjo.</para>
/// <para>Datos orientativos del fruto: Calorías: 47; Agua: 87%</para>
/// </summary>
public class Orange : Consumable, IInventariable, IDamageDealer
{

...

 #region Inventariable
 public InventariableType InventariableType { get; } = InventariableType.Orange;

 public bool Stackable { get; } = true;

 public float Weight { get; } = 0.2f;
 #endregion

 #region Consumable
 public override float BaseExpirationTime { get; } = 0f;

 public override ushort FeedingPoints { get; } = 28;

 public override ushort HydrationPoints { get; } = 10;

 public override ushort StimulationPoints { get; } = 0;
 #endregion

 #region Damage Dealer
 public DamageSource DamageSource { get; } = new DamageSource(
 new Dictionary<DamageType, int>()
   {
     { DamageType.Crushing, 1 }
   },
   null);

 public bool CanBeHurled { get; } = true;
 #endregion
}

 

Colores

A cada factor de supervivencia le hemos asociado un color que permita identificarlo.

hunger-icon                        dehydration-icon                     sleep-icon
Hambre        
Deshidratación        Sueño

Utilizamos una clase que centraliza estos valores en forma de constantes, de manera que podamos cambiar estos valores de forma fácil si lo necesitamos.

Para elegir los colores hemos utilizado Adobe Kuler, una herramienta muy útil e interesante para buscar sintonía entre colores.

/// <summary>
/// Color base relacionado con el hambre.
/// </summary>
public static Color HungerColor new Color(139, 127, 89);
 
/// <summary>
/// Color base relacionado con la deshidratación.
/// </summary>
public static Color HydrationColor new Color(140, 190, 178);
 
/// <summary>
/// Color base relacionado con el sueño.
/// </summary>
public static Color SleepColor new Color(198, 168, 201);

Eso es todo (a alto nivel) en cuanto a diseño y programación sobre el sistema de supervivencia y los consumibles.

Si tienes dudas o curiosidad por saber el detalle de alguna cosa ¡espero tus comentarios!

 

 

Sistema de Crafting

En este artículo hablaré sobre el sistema de crafting que hemos diseñado para Sticks & Stones, pero antes de entrar al detalle, analizaré a alto nivel un par de videojuegos con modelos de crafting distintos.

 

minecraft-icon Minecraft

El rey del crafting, su nombre ya lleva escrita la mecánica que forma el pilar central del juego.

Su sistema consiste en combinar objetos en una cuadrícula de NxN, dónde la posición en la que se colocan los objetos dentro de la cuadrícula es importante. Además tiene cientos de combinaciones distintas.

minecraft-crafting

Para descubrir una receta –un ítem u objeto– debes imaginarte de que materiales está compuesto y que forma tiene.

El jugador puede llegar al resultado aplicando la lógica, así que podemos decir que todas las combinaciones que nos permite el juego son lógicas, pero no todas las combinaciones lógicas que se le ocurran al jugador tienen un resultado. Es decir, el jugador podría llegar a sentir frustración si cree haber encontrado una combinación razonable y no consigue nada, pero por otro lado, descubrir una nueva receta puede ser muy gratificante.

En definitiva, nos encontramos ante una original y difícil mecánica de crafting, con un catálogo de recetas muy amplio (más de 100) y con un alto grado de satisfacción y frustración.

 

how-to-survive-icon  How To Survive

En How To Survive el crafting no tiene tanto peso como en Minecraft. Ofrece un sistema de elaboración de recetas diferente, por lo que es un buen ejemplo para contrastar.

Nos encontramos ante una mecánica basada en combinaciones binarias, es decir, combinar objetos de dos en dos.

Durante el proceso de crafting, es posible crear recetas sin utilidad directa en el juego, pero que combinando con otros objetos puede llegar a obtenerse una receta útil.

howtosurvive-crafting-chainsaw

Una detalle particular de su sistema, es que una misma receta puede elaborarse con diferentes combinaciones. Por ejemplo, la cuchilla de hueso puede obtenerse de un hueso + cualquier cosa que sea cortante.

howtosurvive-crafting-bone-blade

Cuando se quiere combinar un objeto, el juego te marca en el inventario aquellos que son compatibles, por lo que reduce la frustración del jugador al crear combinaciones que no funcionan.

howtosurvive-craft-arrow

Además, conforme se avanza en el juego se van desbloqueando algunas recetas que quedan guardadas en un diario de supervivencia para poder consultarlas.

How To Survive tiene una mecánica de crafting sencilla, con tendencia a simular combinaciones reales de materiales y herramientas para elaborar las objetos. Dispone de un catálogo de recetas inferior a 100 elementos y tiene un equilibrado grado de satisfacción y frustración.

 

Comparativa: Minecraft vs How To Survive

Como resumen al análisis de ambos sistemas de crafting, añado una tabla comparativa de algunas de sus características:

minecraft-vs-howtosurvive

Esta comparativa no quiere indicar que un juego tiene mejor sistema que otro, simplemente pone sobre la mesa información para ver que existen diferentes modelos de crafting que pueden funcionar.

Lo importante es saber encajar el modelo adecuado con el tipo de juego.

 

Modelo de Sticks & Stones

Lo primero que hicimos fue analizar el sistema de crafting de otros juegos, como por ejemplo los explicados en el artículo. Y luego analizamos las características del nuestro, para ver qué modelos encajaban mejor.

Sticks & Stones, como buen Rogue-Like que es, necesita potenciar la dificultad así como alargar la curva de aprendizaje. El objetivo es que el jugador deba repetirlo varias veces y en cada partida aprenda algo nuevo.

Pero también es un juego de acción, lo que implica que el sistema de crafting debe ser ágil.

El enfoque

Para cubrir el aspecto de la dificultad, creemos que las recetas deben ser descubiertas por el jugador a medida que prueba combinaciones. Como no tendrá disponible el catálogo de todo lo que se puede hacer, hemos pensado en la posibilidad de que existan recetas básicas aprendidas desde el inicio. Esto ayudará a que el primer contacto con el videojuego sea más asequible.

Para hacer ágil el crafting, las recetas que se descubran quedarán guardadas. De esta forma, es el jugador el que va creando su propio catálogo.

Pero… ¡Basta ya de cháchara! ¡Vamos a ver algo!

sticksandstones-crafting

En nuestro modelo de crafting distinguimos entre dos elementos: ingredientes y herramientas. Lo mas importante es entender la diferencia:

  • Ingredientes: son los elementos que al combinarse producen el nuevo objeto. Desaparecerán del inventario del concursante tras la elaboración.
  • Herramienta: es el elemento necesario para poder elaborar la receta, pero no se consume tras la elaboración, y por tanto, permanecerá en el inventario del concursante.

Una receta puede elaborarse a partir de la combinación de 1, 2 o 3 ingredientes y 1 herramienta.

En algunos casos, con una misma combinación de ingredientes y herramienta pueden obtenerse hasta tres recetas distintas. Lo que distingue una de otra, es el proceso de elaboración. Por ejemplo, para hacer flechas de madera se requiere lo mismo que para hacer una lanza de madera: una rama dura y una herramienta cortante.

Queremos recetas intuitivas, para que el jugador pueda deducirlas, pero tenemos un espacio limitado, un máximo de cuatro elementos entre ingredientes y herramienta. Esta decisión la tomamos pensado en que fuera ágil, así que en ocasiones tenemos que diseñar recetas simplificadas.

 

Conclusiones

Diseñar un buen modelo de crafting es difícil. Si además hay que encajarlo con las características del videojuego, aún lo complica más… Y si aún así se quiere innovar, la tarea se vuelve titánica.

Para finalizar, comparto algunas de las preguntas más críticas que nos han ido acompañando a lo largo del proyecto:

  • ¿Es compatible unir acción y crafting?
  • ¿Es arriesgado innovar en un nuevo sistema de crafting?

Estaré encantado de recibir tus comentarios y discutir sobre el tema.

 

 

 

El Concursante – II

¿En qué me voy a convertir?

Por si quieres refrescar la memoria, éste es el capítulo anterior de la serie “El Concursante”: El Concursante – I.

Teníamos claro que queríamos tirar adelante el proyecto del videojuego, y una vez la idea caló en nosotros, teníamos que convencer a nuestro CEO para que creyera en ella, por que en definitiva, solo queríamos hacerla realidad si podíamos dedicar nuestro tiempo laboral a desarrollarla.

El proceso que vino después, lo explica mi compañero Valentín en el post “Cómo empezó todo“, así que sin entrar en ese detalle, voy a lo que fue el primer prototipo OFICIAL del videojuego.

El monigote sin nombre ya tenía un mote –que no un nombre–. Mr. Palo.

He aquí ¡Mr. Palo! El monigote que podía moverse y disparar flechas a globos azules.

mrpalo

Con este prototipo ya podíamos visualizar algunos aspectos que derivarían en importantes debates y discusiones, tanto técnicos como filosóficos. Como por ejemplo decidir el número de direcciones de las animaciones, ángulo de la perspectiva, sistema de combate

Mr. Palo iba a ser nuestro maniquí de pruebas, lo que aún no sabíamos es que iba a convertirse en EL MANIQUÍ, con nombre propio, personalidad… Es decir, el primer concursante.

T O    B E    C O N T I N U E D . . . 

 

Y a continuación una deuda pendiente…

La reliquia más sagrada

–Por último y porque sentía que al menos te debía una foto.–

En el capítulo anterior mencioné un prototipo no-oficial. Lo he recuperado para mostrarte lo que vieron nuestros ojos en aquel momento tan especial.

El monigote podía moverse, golpear con el palo, recolectar plantas y el mapa tenía algo de generación aleatoria. Todo, claro, en una versión muy simple. ¡Pero tenía vida!

unofficial-prototype-c

Y ahora sí, pongo fin al post con esta imagen tan épica e importante para nosotros, que marco el inicio de esta maravillosa y emocionante aventura.

unofficial-prototype-b