Group

  • Klaus Reche Riisom – klrii14@student.sdu.dk
  • Martin Slusarczyk Hubel – mahub14@student.sdu.dk
  • Niels Bonde Nielsen – nieni14@student.sdu.dk

BitBucket

The link to the bitbucket with the source code is: https://Cyberdane@bitbucket.org/iosprogrammingsdu/shakywords.git

Demo

The link to the demonstration of the app is: https://www.youtube.com/watch?v=8gXNQ0-n1EI

Introduction

Shaky Words is an offline multiplayer game that challenges competing teams in a series of questions from a particular subject area. The team with the fastest indication of an answer gets to answer first with the remaining teams in the next order that they indicated an answer. If a team answers correctly, they are rewarded with points. The team with the most points win.

A question presents the letters of the answer in a random order to provide teams with the necessary letters to provide some answer. In order to avoid teams being unable to answer, the device can be shook to reorder parts of the letters of the answer to show their correct order in the answer. Each time the letters are reordered, the amount of points to be rewarded are decreased. Questions are also timed to avoid unlimited time to answer a question to keep the tempo high. Once the first team has indicated that they have an answer, the time decreases to a small amount to force the other teams to find an answer quickly. This makes the game competitive and forces social interaction between teams to discuss potential answers.

Figure 1 showcases a conceptual model of the concepts present in the game, where the concepts and connections between concepts are shown.

Figure 1: Conceptual Model of Shaky Words.

The aim of this game is to increase knowledge and vocabulary on specific subject areas as well as increase the social contact between the participants. This may increase the participants curiosity in certain knowledge or interests, or create greater bonding between participants.

The game was created as part of the course iOS Programming, where the creation of an iOS app was a mandatory activity. The objectives of this app was to learn common concepts of iOS programming. These concepts include the platform of iOS, the language Swift, and using sensor interfaces, multiple screens, structural views, buttons, labels, data storage, graphics and audio.

Methods and Materials

The initial project work went into a brainstorm with inspiration from the inspirational projects presented in the slides in the lectures. The results from the brainstorm went into conceptual design with a conceptual model showcasing the overall concepts and connection between the concepts. Initial requirements were found from the conceptual model. A use-case diagram was created to document these requirements. Three simple prototypes were built based on the requirements using Marvel App. The simple prototype was evaluated by potential users, where the feedback was fed into the design for refinement, resulting in a new prototype.

A navigational prototype was built in XCode with storyboards and then evaluated by potential users. The feedback further refined the requirements and design. An object diagram was created to document the object model of the navigational prototype.

Next the logic was implemented in XCode with Swift incorporating the UIKit, CoreData, CoreMotion and AudioKit frameworks. The app was built using an MVVC pattern.

Results

This section describes the results from the applied methods materials.

Initial Brainstorm

The initial idea of the project focused on a party/trivia game with phone movement interactivity of graphics, where the person with the most points win. This covers a wide range of games, such as Yatzee, card games (e.g. Cards Against Humanity) or general trivia games like Trivia Pursuit, where you move pieces around. The focus was on the party aspect of the game, where the games need to be short, but also challenging. Therefore, the game needed to present something easily understood by anyone where the participants could compete on finding an answer. Games like the Jackbox Party Pack inspired the idea of a simple trivia, where everyone needs to be quick on the mark to signal that they are ready to answer. First one to indicate, first one to answer.

Another idea was that players could shake the screen to reveal random letters in the answer. This was found due to the requirement of sensors. The more letters were shown the less points the player could get. This is different from the final product, as the letters were supposed to be hidden completely here until shook free. The idea of shaking cards, where the player would then pick one, was also considered, but the mechanism behind this did not seem to inspire any interesting gameplay.

There are already existing games focusing on trivia and words, such as Trivia Crack [1], Quizzland [2], Word Guessing Games [3], Word Connect [4], Word Tricky [5], Wordfeud [6], Trivial Quiz Pursuit Knowledge [7]. This is a small selection, but the general element in most of these seems to be online multiplayer challenging friends or yourself, and improving your score everyday. They don’t seem to focus on the local multiplayer experience with social contact, which is something party games can benefit from, as it creates a lively social atmosphere. They also don’t have the shaking element to get hints, which makes the game physical.

Conceptual Design

The conceptual model can be seen in Figure 1, as previously shown. Teams answer questions to compete against each other. The overall requirements include being able to either play as teams or as individuals (single teams), get optional hints to the answer, competition with a final scoreboard on performance, and seeing the letters of the answer.

The overall purpose of the app is the ability to provide entertainment, increase vocabulary, train the brain and increase social interaction. Being in teams should help people to get talking with each other about potential answers. The target audience are all people above 11, where people play this in a social setting.

The shaking of letters to reveal the answer is an analogy to shaking physical Scrabble letters to potentially see new words.

Multiple questions arose during the conceptual design on how to deal with the design. These questions are addressed throughout the design of prototypes. The questions are as follows:

  • What if don’t know the answer?
  • What letters are available?
  • How to input the answer?
  • How many questions should be answered?
  • How do multiple people play?

Initial Requirements

This section describes the functional and non-functional requirements.

Functional Requirements

The functional requirements are based on the conceptual model, where a new game must be created for a certain amount of teams and their desired question area. The teams must be able to answer the question. If the device is shook, clues should be given on the answer. When all questions to be answered are processed, the teams must be able to see their final scores to compare how well they fared.

Name Description
Create Game As a user I would like to be able to create a new game with specific teams, a specific amount of questions to answer, the difficulty of the questions and the quiz pack to draw the questions from.
Shake for Clue As a user I would like to be able to shake the device to get a clue to the answer of the question.
Answer Question As a user I would like to be able to enter an answer to a question on behalf of my team to check if it is correct.
See Final Scores As a user I would like to see the final score of the game when it is over.

Table 1: List of initial functional requirements.

A use case diagram of these initial functional requirements is presented in Figure 2, showing the boundary of Shaky Words and how the user actor interacts with the use cases available within the system bounds.

Figure 2: Use case diagram of initial requirements

Non-functional Requirements

Table 2 presents the non-functional requirements of the project based on the initial project requirements from the course.

Name Description
Platform The application needs to be running on iOS.
Language The application needs to be implemented in Swift.
Sensor The application needs to integrate the accelerometer for shake gesture recognition.
Multiple Screens The application needs to have multiple screens.
Structural Views The application needs to have a structural view, such as a TableView.
Buttons The application needs buttons.
Labels The application needs labels.
Data Storage The application needs to store data on questions and answers.
Graphics The application needs graphics in the form of UIKit.
Audio The application needs to be play some audio.

Table 2: List of initial non-functional requirements.

Simple Prototypes

Three simple prototypes were created with the Marvel App. These can be found in [8], [9], [10]. Two of them were paper prototypes, and the third a mockup in Balsamiq Mockups 3 to try different approaches. The third mockup took more time to create, but also has a closer appearance to the actual design on iOS, which makes the prototype experience more familiar to existing iOS users than the paper prototypes.

Potential users tested the three prototypes. Overall, they did not have one favorite prototype, but prefered particular elements from each. They liked the idea of having teams instead of simply individuals, where they could compete with each other. They prefered to have the letters scrambled on the screen, and a time limit on how long games should take.

The fourth prototype (see [11] for a Marvel App link) was based on prototype 2, but drew elements from prototype 3 on indicating an answer, and prototype 1 on blocky letters for the answer. The time limits were introduced to the question screen. After the presentation of the fourth prototype one piece of feedback focused on the ability for users to be able to add their own question and answers.

Navigational Prototype

The navigational prototype was designed in XCode using storyboards with seques, allowing simple button interactions to move from one screen to another. A simple list for teams was created to showcase the UI for this.

Feedback on the navigation prototype focused on how users should be able to answer correctly. The answer written by a team may contain spelling mistakes, which would make the answer incorrect. One solution could be to have a list of options for the answer, similar to Who Wants To Be A Millionaire. Since the game is intended as a party game, making small mistakes when answering should not be too detrimental to the overall experience, as the focus is not on winning, but playing a game together with other people. Having a list of options for the answer would make the game easy for the first team to indicate an answer, since they simply have to pick the option that seems most likely. It would make the game a race to click first on the question screen instead of focusing on trying to figure out the answer. Other solutions would be to allow a certain amount of wrong letters in the answer, or subtract a point for each wrong letter.

Figure 3 presents an abstract object diagram of the MVVC structure in the game, showcasing the hierarchy of view controllers and the models used in each controller. The views are not included to avoid cluttering the diagram, and also avoid asynchronicity between the actual design and the diagram.

Figure 3: Object diagram for the navigational prototype.

New Requirements

The feedback from the navigational prototype led to a new requirement presented in table 3, where the user indicate if they have an answer, and they can create custom quiz packs with custom questions to be used in the game. Table 4 presents the new non-functional requirements focusing on answer time.

Name Description
Indicate Answer As a user I would like to be able to indicate that my team has the answer to the presented question.
Create Custom Quiz Pack As a user I would like to be able to create a new quiz pack with a new name. This quiz packs contains new questions that will be used by the application. The new questions must contain a difficulty for the question, the question text itself and an answer for the question.

Table 3: List of new functional requirements.

Name Description
Answer Indication Time The time to indicate an answer to a question is one minute. Once an answer has been indicated by one team, the remaining time changes to a maximum of 20 seconds, unless already below 20 seconds.
Answer Time The time to answer a question is one minute.

Table 4: List of new non-functional requirements.

Final Prototype

The design and selected implementation parts of the final prototype are presented in this section.

User Interface

The UI for the main menu can be seen in Figure 4, where the user can create a new game and create custom quiz packs.

Figure 4: Main Menu UI.

The UI for managing teams and selecting a quiz pack when creating a new game can be seen in Figure 5.

 

Figure 5: Left – Teams UI. Right – Quiz Pack Selection UI.  

The UI for managing custom quiz packs can be seen in Figure 6. The UI for managing questions can be seen in Figure 7.

 

Figure 6: Left – Custom Quiz Packs UI. Right – Custom Quiz Pack UI.  

Figure 7: Edit Question UI

The UI for seeing the current question of the game can be seen in Figure 8 (left). The UI for answering the question can also be seen in Figure 8 (right). The final scoreboard with the score for each team can be seen in Figure 9.

 

Figure 8: Left – Current question UI, Right – Question answer UI

Figure 9: Final Scoreboard UI

General Implementation

The game uses an MVVC structure to separate concerns for the domain-specific models, UI views and the view controllers communicating with the UI views. The object diagram in Figure 3 showcases the interaction between view controllers and the models they use. The view controllers represent the individual screens in the app with certain controllers for navigation of child controllers. The models cover the game used to store information about the currently played game, as well as the quiz packs stored persistently on the device. A few custom UIView elements were created to increase visual fidelity, such as the main menu letters shaking, but most custom UIView elements were created for table views as cells.

Shake Detection Implementation

Shake detection is implemented by reading the built-in accelerometer and comparing its values to a minimum acceleration constant. If one value is above the constant, the device is seen as shook. A repeating timer periodically checks the values for the aforementioned comparison.

Code Snippet 1 shows the Swift code to start the shake detection service given an update rate, sensitivity, activation interval and callback. The update rate specifies how often the accelerometer data should be checked. The sensitivity specifies the minimum acceleration constant to compare against the data. The activation interval specifies the delay until another shake can be detected. The callback is called when the shake is detected. This decouples the shake service from the view controller using it. The CMMotionManager from CoreMotion used to get the accelerometer is injected in the constructor.

func start(updateRate: Double, sensitivity: Double, activationInterval: Double, callback: @escaping () -> Void) {
   if !motionManager.isAccelerometerAvailable {
       print("No accelerometer available")
       return
   }
  
   motionManager.accelerometerUpdateInterval = updateRate
  
   if !motionManager.isAccelerometerActive {
       motionManager.startAccelerometerUpdates()
   }
  
   var activated = false
   var activatedCounter = 0.0
   let newTimer = Timer(fire: Date(), interval: updateRate, repeats: true) { (timer) in
       if activated {
           activatedCounter += timer.timeInterval
          
           if activatedCounter > activationInterval {
               activated = false
               activatedCounter = 0.0
           }
       }
       else {
           if let accelerometerData = self.motionManager.accelerometerData {
               let x = accelerometerData.acceleration.x
               let y = accelerometerData.acceleration.y
               let z = accelerometerData.acceleration.z
               if abs(x) > sensitivity || abs(y) > sensitivity || abs(z) > sensitivity {
                   activated = true
                   callback()
               }
           }
       }
   }
  
   RunLoop.current.add(newTimer, forMode: .default)
  
   timer?.invalidate()
   timer = newTimer
}

Code Snippet 1: Function to start shake detection. 

Hint Audio Playback Implementation

Shaking the device creates a sound to indicate that something occurred. Code Snippet 2 shows the setup of the hint audio playback using AudioKit. An audiofile is loaded and set as the file for an audio player. The shake detection service callback mentioned previously starts the hint audio player every time the shake detection is activated.

do {
  let hintAudioFile = try AKAudioFile(readFileName: "hint.mp3")
  hintAudioPlayer = try AKAudioPlayer(file: hintAudioFile)
  AudioKit.output = hintAudioPlayer
  try AudioKit.start()
}
catch let error {
  print("Could not initialize hint audio: \(error.localizedDescription)")
}

...

hintAudioPlayer.start()

Code Snippet 2: Playback of hint audio.

Persistence

The quiz packs and questions that are used for the game are persistently stored using a Core Data data model. A visualisation of the data model can be seen in Figure 10, where each model type has a collection of attributes and relationships. The quiz pack has a boolean value to indicate whether it is custom or built-in. Custom quiz packs can be added and modified using the custom quiz pack screens, whereas the built-in are created the first time the data is fetched, and remain immutable afterwards.

Figure 10: Data Model of QuizPacks and Questions.

Code Snippet 3 shows the factory class to create data model contexts. The data model context contains the persistence container for the data store of the game’s data model objects. The context also contains the managed object context to access and manipulate the data model instances.

class DataModelContextFactory {
  private let dataModelName = "ShakyWords"
 
  func createContext(success: @escaping (DataModelContext) -> (), failure: @escaping (Error) -> ()) {
      let persistentContainer = NSPersistentContainer(name: dataModelName)
      persistentContainer.loadPersistentStores { (description, error) in
          if let error = error {
              failure(error)
          }
          else {
              let dataModelContext = DataModelContext(persistentContainer)
              success(dataModelContext)
          }
      }
  }
}

Code Snippet 3: Class to create data model contexts.

Code Snippet 4 shows how to create a quiz pack data model object given the data model context in the DataModelController class. The data model context uses the managed object context to create a new quiz pack by inserting it into the managed object context. Fetching model objects requires creating an NSFetchRequest object, which the data model context is responsible for creating, and then executing this request for the managed object context.

func createQuizPack(name: String, custom: Bool) -> QuizPack? {
  let quizPack = context.create(QuizPack.self)
  quizPack?.name = name
  quizPack?.custom = custom
  return quizPack
}

Code Snippet 4: Function to create a quiz pack data model object.

Discussion

The app imagined in the introduction was realized, the goals mentioned in the introduction were all accomplished to some extend. The group has experience with Android development, as well as common desktop and web software development, which makes the development of this app familiar to other projects in the past.

The code, however, is not well tested or secured against common errors in all areas due to time constraints, lack of familiarity with the language and the lack of clear documentation of several problems that occured during development. Another limiter was the frustration of working with the IDE of XCode which has certain “quirks” which can be time consuming and create annoyances. The app was tested repeatedly by end users throughout the development cycle. Using the feedback from the users the app was changed in certain areas to better fit what the users wanted. The users pointed out that it would be nice to be able to add their own questions and quiz packs, so this feature was implemented in the app. The users also mentioned the wish for a shorter time span for answering questions than originally planned, and the addition of a timer to the answer screen as well as the question screen. All of the things that the users mentioned they would like in the app was incorporated into the app.

This app is still a prototype so the questions in the quiz packs are very limited. There are only a few so that the app could be tested with the repetition of question answer screens until the amount of questions runs out.  As mentioned, due to certain limiting factors not all of the app has been tested as thoroughly as it could have been. There are certain checks and limitations for the choices that the users can make that has not be addressed, such as selecting quiz packs with less questions than desired. These should be implemented before the app could be used as intended.

Conclusion

The goal of creating a game for iOS focused on a party/trivia with phone movement interactivity of graphics, where the person with the most points win was successful.While the app is not fully tested, a feature-complete prototype has been created. The game allows users to create teams to compete against each other with built-in or custom quiz packs. The device can be shook to provide a hint to the current question.

In the initial phase of the project the group looked at similar app that are already on the market, inorder to see what was already out there and how this app should differentiate itself. Based on these the initial idea for the app was developed and then a quick mockup was made. This mockup was then shown to potential users and they gave feedback, based on the repeated cycle of mockup and feedback the final app’s design and functionality was decided.

Perspective

The current game has a small sample of content for questions. Future iterations of the game would focus on providing more quiz packs and questions to ensure longevity and challenge of the game. Furthermore, more animations and background music could improve the user experience by making the UI less stiff and immerse the users in the game world, in that order.

Sources

[1] https://play.google.com/store/apps/details?id=com.etermax.preguntados.lite

[2] https://play.google.com/store/apps/details?id=com.xmonetize.quizzland

[3] https://play.google.com/store/apps/details?id=com.picsword.word.guessing.games

[4] https://play.google.com/store/apps/details?id=com.crossword.bible.cookies.find.english

[5] https://itunes.apple.com/us/app/word-tricky-fun-spelling-test/id637999962?mt=8

[6] https://itunes.apple.com/dk/app/wordfeud/id428312806?l=da&mt=8

[7] https://itunes.apple.com/us/app/trivial-quiz-pursuit-knowledge/id1175389256?mt=8

[8] https://marvelapp.com/36b8096/screen/48555705

[9] https://marvelapp.com/ei2g394/screen/48343578

[10] https://marvelapp.com/ei2fg89/screen/48343374

[11] https://marvelapp.com/9je556b/screen/48557043

Leave a Reply