Connect me!

About the game

At the beginning of 2018, I participated in the Global Game Jam once again. The theme of this years jam was transmission. Our 6-person team decided to try implementing a multiplayer game. The basic idea of our game was inspired by phone companies of the sixties. The main mechanic was that a player would be called by a random character. After hearing his voiceline the player had to draw his face which would then be send to the other players. The other players had to choose a character which was best fit to the drawn face. The whole game should take place in a local network and should be implemented in the Unity3D engine.

My tasks

During the first one and a half days of the project, I tried to implement network code with a teammate. Unfortunately we did not succeed in creating a working prototype. Since we only had little time left, we decided to change the gameplay into a singleplayer version. In this singleplayer the player had to match a random voiceline to a fitting character.

After changing the concept to a single player I had to implement the game logic.
First I wrote a class that represented a character. Within this ‚Caller‘ class a reference for a sound clip and a string was saved. The string served as a unique identification number for a character.

Show code
public class Caller {
   AudioClip m_SoundClip;
   string m_ImageID;
public Caller(AudioClip p_Clip, string p_ImageID) {
   m_SoundClip = p_Clip;
   m_ImageID = p_ImageID;
}

public AudioClip GetSound() {
   return m_SoundClip;
}

public string GetImageID() {
   return m_ImageID;
}

public override string ToString() {
   return "[Clip: " + m_SoundClip.name + " ImageID: " + m_ImageID +  "]";
}
}



The next step was the organisation of the characters as couples. I solved this issue by a creating a class called ‚Callerpair‘. Within this class 4 caller references were stored. The references ‚m_activeCaller‘ and ‚m_passiveCaller‘ were randomly set to one of the two characters on creation.

Show code
public class CallerPair {
   Caller m_Caller1;
   Caller m_Caller2;
   Caller m_ActiveCaller;
   Caller m_PassiveCaller;

public CallerPair(Caller p_Caller1, Caller p_Caller2) {
   m_Caller1 = p_Caller1;
   m_Caller2 = p_Caller2;
   ShuffleActivePassive();
}

public void ShuffleActivePassive() {
   if (Random.Range(0, 100) > 50) {
      m_ActiveCaller = m_Caller1;
      m_PassiveCaller = m_Caller2;
   } else {
      m_ActiveCaller = m_Caller2;
      m_PassiveCaller = m_Caller1;
   }
}

public Caller GetCaller1() {
   return m_Caller1;
}

public Caller GetCaller2() {
   return m_Caller2;
}

public Caller GetActiveCaller() {
   return m_ActiveCaller;
}

public Caller GetPassiveCaller() {
   return m_PassiveCaller;
}
}



After the game was started all resources were loaded and converted into callerpairs.

Show code
private void PrepareData() {
   m_CallerAudio = Resources.LoadAll("Sounds/");
   m_CallerSprites = Resources.LoadAll("Images/Characters/");
for (int count = 0; count < m_CallerAudio.Length; count += 2) {
   m_CallerPairs.Add(
      new CallerPair(
         new Caller(m_CallerAudio[count], m_CallerSprites[ 0 + count * 12].name.Substring(0,2)),
         new Caller(m_CallerAudio[count + 1], m_CallerSprites[ 12 + count * 12].name.Substring(0, 2))));
}
}



After that, prefabs were loaded and positioned. Each prefab was a button for a character. These buttons could be pressed to score points. If a wrong button was pressed the player lost time for his round.

Show code
private GameObject FindPrefabFromPrefix(string p_Prefix) {
   foreach(GameObject obj in m_ButtonPrefabs) {
      if (Equals(obj.name.Substring(0, 2), p_Prefix))
         return obj;
      }
   Debug.Log("No prefab found");
   return null;
}



Working out the logic of the game in one night was very challenging but fun. In retrospect, I would implement the callers and callerpairs as scriptable objects. That should make their organization easier.

Diese Diashow benötigt JavaScript.