Skip to content
/ DAWN Public

Term Project for Open Source Software of SeoulTech on 2024 fall semester

License

Notifications You must be signed in to change notification settings

YohanIm00/DAWN

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

248 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Banner

🐈‍⬛ DAWN

DAWN is a chaotic bakery tycoon adventure in Bakery Feliz.
If you wanna see a Korean README.md, CLICK HERE!


📋 Table of Contents

  1. Game PV
  2. Contributors
  3. Motivation
  4. Story
  5. Control Keys
  6. How to Play
  7. Implemented Features
  8. License
  9. References
  10. Development Status

🎥 Game PV

Game PV
▲ DAWN PV (95s): Click to visit the link.


👥 Contributors

Initial Development

  • Seonghyun Jeon - Original planner of DAWN, implemented game logic, and conducted overall development.
  • Jisub Shim - Implemented the chef and interaction systems, refactored the overall code.
  • Yohan Im - Designed artwork, implemented the player, and handled minor development tasks.

Game PV

Follow-up Development

  • Yohan Im - Reconstructed game scenes and implemented additional features.
  • PZJB - Redesigned the entire game artwork.

💡 Motivation

PLUM JAM
DAWN was created as part of the 2024 PLUM JAM, a summer program hosted by the PLUM game development club.
PLUM JAM is a game development hackathon where participants create games based on given keywords.
At the time, the keywords were 'Tiramisu Cake' and 'Balloon.'
After much deliberation on how to integrate these themes, the idea of "a cat selling tiramisu to ascend to great heights with a bundle of balloons" was born.
DAWN_ver0


📖 Story

Synopsis

Synopsis
There is Wand the black cat with an exceptional talent for making tiramisu cakes.
One day, he gotta be captivated by the sudden appearance of the colossal cat tower, MT.CATUS.
As Wand gazes at the tower in awe, a familiar meow echoes from the peak.
Realizing it’s his sibling, Wand starts pondering how to overcome this situation.
At that moment, a brilliant idea flashes through Wand’s mind:

"Trade tiramisu cakes for balloons, and use them to float to the top!"

The goal is 1,000 balloons! Will our Wand manage to gather enough balloons to reunite with their sibling?

Characters

Characters
▲ Character concept art: Wand on the left, Pu on the right.

  • Wand

    • A black domestic shorthair cat with striking amber eyes.
    • Known as "Tiramisu Hand" for their unique ability to turn any ingredient into a tiramisu cake.
    • Typically very quiet, often leaving others confused about what they want to say.
  • Pu

    • A gray-patterned Scottish Fold cat, usually seen with their eyes closed.
    • The head chef of Bakery Feliz, with great pride in their culinary skills.
    • For some unknown reason, Pu seems to understand Wand’s unspoken words perfectly.
  • (Future Characters)

    • Look forward to the next version for new additions!

Environment

  • The Village

    • A common hillside neighborhood that looks like it could exist anywhere, but it’s uniquely inhabited only by cats.
  • MT.CATUS
    MT.CATUS

    • An ultra-high "cat tower" that suddenly appeared in the center of the village.
    • The top of the tower features a prominent sign reading "MT.CATUS."
  • Bakery Feliz
    Bakery Feliz

    • A bakery run by Pu.
    • Due to the nocturnal nature of most cats, the number of customers increases as time goes on.
    • Interestingly, Pu runs the bakery based on their whims and often closes during peak hours.

🎮 Control Keys

Sorting Game

  • Arrow Keys
    • (Left Arrow): Serve tiramisu.
    • (Right Arrow): Serve milk.

Main Game

  • Arrow Keys
    Move the character up, down, left, and right.
  • Spacebar
    Interact during cutscenes and dialogues.
  • S : Serving
    • (Customers): Take orders, serve completed dishes.
    • (Chef): Place orders, collect prepared dishes.
  • E, R : lEft & Right
    • (E): Eat the food in the left hand.
    • (R): Eat the food in the right hand.

🕹️ How to Play

Sorting Game

SortingGame

  • A simple sorting game that can be played using only the right and left arrow keys.
  • If you correctly process 20 consecutive orders, FEVER mode will be activated.
    • During FEVER mode, pressing any arrow key will increase your score.
    • FEVER mode lasts for 3 seconds.
Sort1.mp4
  • If you press the wrong arrow key at any point, your score will decrease.
    • The higher your current score, the more points you will lose, so be careful!
Sort2.mp4
  • Aim for the highest score possible within the time limit!
    • The score is supposed to carry over as the initial value in the main game.
    • However, it was discovered that this functionality does not work as intended.
    • This issue will be addressed in the "Development Status" section later.

Main Game

MainGame

  • When a customer places an order, approach them and press the S key to take their order.
    • If you don’t take the order on time, the customer will leave angrily.
    • Angry cat customers will pop balloons as a consequence, so be careful!
Bake1.mp4
  • After taking an order, approach the chef Pu and, press the S key to start cooking.
    • You can take up to 10 orders at a time and cook up to 4 menu items simultaneously.
    • Cooking time depends on the menu item and is either 3 seconds or 5 seconds.
Bake2.mp4
  • Once the cooking is complete, you’ll hear the oven’s signature completion sound, and the dish will appear on the counter.
    • Similarly, press the S key at the counter to pick up the dishes in the order they were prepared.
    • You can carry up to two dishes at a time.
Bake3.mp4
  • Take the completed dishes to the customer and press the S key to serve them.
    • If the dish matches the customer’s order, they’ll eat it happily and reward you with balloons.
    • If the dish doesn’t match the order, there will be no reaction. Double-check the orders!
    • Additionally, you cannot take new orders while holding dishes. Serve the dishes first, then take the next order.
Bake5.mp4
  • If a mistake during serving leaves you with leftover food, you can press E or R to eat the food in your hands.
    • Eating food will increase your fullness level.
Bake7.mp4
  • However, if your fullness level maxes out, you’ll temporarily slow down, so watch out!
Bake6.mp4

Punishment_EN ▲ Oh dear, it seems Wand ended up getting scolded... Let’s be careful so that Pu doesn’t scold us too.


⚙️ Implemented Features

  • Engine: Unity

  • Programming Language: C#

  • Key Implementations:

    • Singleton Pattern: Used for components like AudioManager, GameManager, etc.

      • AudioManager:
      public class AudioManager : MonoBehaviour
      {
          public static AudioManager instance;
          public AudioClip[] bgmClips;
          public float bgmVolume;
          private AudioSource bgmPlayer;
          public enum BGM { MainMenu, Prologue }
      
          private void Awake()
          {
              instance = this;
              Init();
          }
      
          private void Start()
          {
              bgmPlayer.Stop();
      
              if (SceneManager.GetActiveScene().name == "MainMenu")
                  PlayBgm(BGM.MainMenu);
              else if (SceneManager.GetActiveScene().name == "Prologue")
                  PlayBgm(BGM.Prologue);
          }
      
          private void Init()
          {
              GameObject bgmObject = new GameObject("BGM Player");
              bgmObject.transform.parent = transform;
              bgmPlayer = new AudioSource();
          
              bgmPlayer = bgmObject.AddComponent<AudioSource>();
              bgmPlayer.playOnAwake = false;
              bgmPlayer.loop = true;
              bgmPlayer.volume = bgmVolume;
          }
      
          public void PlayBgm(BGM bgm)
          {
              bgmPlayer.clip = bgmClips[(int)bgm];
              bgmPlayer.Play();
          }
      
          public void VolumeController(float volume)
          {
              bgmVolume = volume;
              bgmPlayer.volume = bgmVolume;
          }
      }
      • Explanation:
        • Elements that need to remain active throughout the game were implemented using the Singleton pattern.
        • Background music is set for each scene and declared using the enum BGM type.
        • Since the class is implemented as a Singleton, its methods can be called anywhere using AudioManager.instance.VolumeController(0).
    • State Pattern: Used for Player and Customer.

      • CustomerStateMachine.cs
      public class CustomerStateMachine : MonoBehaviour
      {
          public CustomerState Order;
          public CustomerState Enjoy;
          public CustomerState currentState;
          
          private void Start()
          {
              Order = gameObject.AddComponent<OrderingState>();
              Enjoy = gameObject.AddComponent<EnjoyingState>();
      
              ChangeState(Order);
          }
      
          public void ChangeState(CustomerState newState)
          {
              currentState?.Exit();
              currentState = newState;
              currentState?.Enter(this);
          }
      }
      • CustomerState.cs
      public abstract class CustomerState : MonoBehaviour
      {
          protected CustomerStateMachine stateMachine;
          protected Customer customer;
      
          public virtual void Enter(CustomerStateMachine stateMachine)
          {
              this.stateMachine = stateMachine;
              customer = GetComponent<Customer>();
              customer.timer.fillAmount = 1;
          }
      
          public abstract void _Update();
          public abstract void Exit();
      }
      • EnjoyingState.cs
      public class EnjoyingState : CustomerState
      {
          private float maxTime;
      
          public override void Enter(CustomerStateMachine stateMachine)
          {
              base.Enter(stateMachine);
              customer.enjoyingTime += Random.Range(0, 2);
              maxTime = customer.enjoyingTime;
              GameManager.instance.GainBalloon(true, customer.menu.GetCookingTime());
          }
      
          public override void Exit() {}
      
          public override void _Update()
          {
              customer.enjoyingTime -= Time.deltaTime;
              customer.timer.fillAmount = customer.enjoyingTime / maxTime;
              
              if (customer.enjoyingTime < 0)
                  stateMachine.ChangeState(stateMachine.Leave);
          }
      }
      • Explanation:

        • Objects with behavior that changes based on interaction were implemented using the State Pattern.
        • The base for all states is an abstract class, which is inherited to create specific state implementations.
        • A state machine was designed to allow seamless transitions between states as needed, and this was integrated into the primary object, as shown below.
      • Customer.cs

      public class Customer : MonoBehaviour
      {
          public CustomerStateMachine stateMachine;
      
          private void Awake() { stateMachine = gameObject.AddComponent<CustomerStateMachine>();}
      
          public void Update() { stateMachine.currentState._Update();}
      
          public void OnDestroy() { GameManager.instance.customers.Remove(gameObject); }
      }
      • Summary:
        • The CustomerStateMachine manages state transitions for customers.
        • Abstract state (CustomerState) provides the structure, while specific behaviors are implemented in concrete states (EnjoyingState, OrderingState, etc.).
        • This approach ensures modular and maintainable code for varying customer behaviors.
    • DOTWEEN: Elements used in cutscenes

    • AbstractPart.cs

    using DG.Tweening;
    
    public abstract class AbstractParts : MonoBehaviour
    {
        protected Image image;
        protected Tween tween;
    
        void OnEnable()
        {
            image = gameObject.GetComponent<Image>();
            StartCoroutine(Alter());
        }
        protected abstract IEnumerator Alter();
    }
    • LetterTransform.cs
    using DG.Tweening;
    
    public class LetterTransform : AbstractParts
    {
        protected override IEnumerator Alter()
        {
            Transform transform = image.transform;
            yield return transform.DOPunchScale(new Vector3(0.5f, 0.5f, 0), 0.5f, 10, 1f);
        }
    }
    • Explanation:

      • Almost all supplementary effects in cutscenes, such as movement, scaling, fading, and shaking, were implemented using the DOTween library.
      • In Unity, most elements dealing with sprites are either SpriteRenderer or Image. This abstraction accommodates both cases by creating an abstract class (AbstractParts).
      • The actual functional behavior is handled using coroutines, with specific details provided in child classes like LetterTransform.
    • ScriptableObject: For managing game data

      • MenuSO
      public class MenuSO : ScriptableObject
      {
          protected float cookingDuration;
          protected Sprite foodSprite;
      
          public virtual float GetCookingTime() { return cookingDuration; }
          public virtual Sprite GetSprite() { return foodSprite; }
      }
      • BreadSO
      [CreateAssetMenu(menuName = "BreadSO")]
      public class BreadSO : MenuSO
      { }
      • DataManager
      public class DataManager : MonoBehaviour
      {
          public Dictionary<string, MenuSO> menus = new Dictionary<string, MenuSO>();
      
          private void Start() { LoadMenus(); }
      
          private void LoadMenus()
          {
              MenuSO[] loadData = Resources.LoadAll<MenuSO>("Cuisines");
      
              foreach (MenuSO menu in loadData)
                  menus.Add(menu.name, menu);
          }
      }
      • Explanation:
        • Most of the in-game data is managed using ScriptableObject assets.
        • Creating a MenuSO asset allows you to modify and manage its internal values directly within the Unity Editor.
        • The BreadSO class inherits from MenuSO to accommodate potential future menu additions.
        • The DataManager class loads pre-created ScriptableObject assets and integrates the data into the game.

📜 License

  • DAWN is licensed under CC BY-NC 4.0.
  • Modifications and redistribution of the code are allowed. As this project will continue to be developed, feedback on the code is highly encouraged and will be actively incorporated.
  • However, all artwork used in the game belongs to the original creators. Therefore, modification or redistribution of the artwork for commercial purposes is discouraged.

📚 References

PV

Games

[Inspirations]

[Development]

[Assets]


🛠️ Development Status

Completed

  • Main menu design
  • Player, NPC, and other elements
  • Sub sorting game
  • Main tycoon game
  • Dialogue system
  • Game over and scene transitions
  • Audio manager

Current Issues

  • Limitations of ScriptableObject

    • Values can be written and retrieved within the Unity Editor but are inaccessible after building the game.
    • In other words, after the build, only the last value modified in the Unity Editor can be retrieved.
    • While ScriptableObject is useful for loading pre-saved data, it seems unsuitable for modifying values during user's gameplay.
  • Internal Structure Problems

    • The initial game was developed within 20 hours, resulting in a somewhat chaotic structure.
    • Overuse of the Singleton pattern may lead to difficulties in memory management as the game expands.
  • Occasional Overlapping of Customers

    • Two customers sometimes occupy the same position.
  • Bugs Related to Player Eating Actions

    • Depending on timing, the player can move while eating or becomes unable to move after eating...
    • From a balance perspective, the Munch() action needs improvement: it should function as a useful option for the player.

Future Plans

  • Implement Data Management Using JSON

    • Separate and manage data beyond just the number of balloons, such as other necessary game variables.
    • Develop objects like DataManager or StageManager to load stage-specific data dynamically.
  • Refactor the Entire Game Structure

    • Minimize the use of Singleton patterns (limit to GameManager, AudioManager, etc.).
    • Apply and refine the state pattern for the chef.
    • Split overly attached functions in components like GameManager or CustomerSpawner.
    • Introduce a UIManager and improve DataManager functionalities using SOLID principles.
  • Fix Existing Bugs and Add New Features

    • For example, add an animation where the chef glares at the player when satiety is maxed out.
  • Add Settings Button to the Main Menu

    • Allow players to customize control keys to their preferences.
    • Implement standard features like adjusting BGM and SFX volume.
  • Enhance Main Game Features

    • Display a mini-game screen when customers order tiramisu cakes.
  • Expand the Overall Story and Add Characters

  • Complete and Integrate Pixel Art Graphics


DAWN by Yohan Im is licensed under CC BY-NC 4.0

About

Term Project for Open Source Software of SeoulTech on 2024 fall semester

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors