GMS2でプロジェクトをバージョン管理したい

# [これはGameMaker日本語コミュニティ主催の「GameMaker Advent Calendar 2024」 DAY16の記事です](https://adventar.org/calendars/10686)


こんにちは、いちたくさんです。普段インターネットではゲーム実況したりゲーム実況見りたゲーム開発したりしてます。表社会ではエンジニアやっているので、今回はテックな話を書こうと思います。

## 目次
1. [Game Maker Studio2本体にはバージョン管理機能がないという話](#game-maker-studio2本体にはバージョン管理機能がないという話)
2. [Gitを導入しよう](#gitを導入しよう)
2.1 [Gitとは](#gitとは)
2.2 [Gitの導入方法](#gitの導入方法)
2.3 [GMS2上でプロジェクトをGitと紐付けする](#gms2上でプロジェクトをgitと紐付けする)
3. [バージョン管理をしてみる](#バージョン管理をしてみる)
3.1 [バージョン管理の基本](#バージョン管理の基本)
3.2. [作業をやりなおす](#作業をやりなおす)
3.3. [バージョンを切り分ける](#バージョンを切り分ける)
4. [おわりに](#おわりに)

## Game Maker Studio2本体にはバージョン管理機能がないという話
カタカタとプログラミングしてるとこんなことを感じることがあると思います。

- 様々な機能を平行して実装するとどこまで何を作ったのかわからなくなりがち
- 機能追加の際にコードの追記箇所と既存箇所の区別がつかなくなりがち
- 最新版・デモ版・デバック用等の完成品を別フォルダで管理するのが手間かかりがち

__これらの悩みはバージョン管理ツール=Gitを導入すると解決できます__

## Gitを導入しよう
### Gitとは

https://ja.wikipedia.org/wiki/Git

Gitはかなり一般的なバージョン管理システムです。主に複数人で１つのプロジェクトを管理する際に使われたりするのですが、個人での開発でも重宝するパワーのあるツールです。

特に、GMS2ではオフィシャルにGitによるソースコードの管理を推奨？しており、以下の通りにマニュアルページも存在しています。

https://manual.gamemaker.io/monthly/ja/#t=IDE_Tools%2FSource_Control.htm

一方で、上記のマニュアルページは~~Gamemaker Manualじゃいつものことですが~~あまりマニュアルしていません。
また、GMS2上ではGitとしてできる操作が限られているため、今回は導入したGit上でバージョン管理の操作を実施する方法を書いていきます。

### Gitの導入方法

<font color="red">**Gitのインストール方法はググれば沢山出てくるためそちらを参照してください。**</font>

:::note info
インフォメーション
書くのがめんどいというわけではありません
:::

参考としては以下のリンクあたりがわかりやすいかなと思います

https://qiita.com/T-H9703EnAc/items/4fbe6593d42f9a844b1c

https://note.com/oonotakashireal/n/n31214938aa69

### GMS2上でプロジェクトをGitと紐付けする

インストールをしたGitをGMS2側でも使えるようにするためいくつか設定を行ないます。

#### 今回使用する環境は以下の通り
- OS
    - Windows 10 Pro(22H2)
- GameMaker Studio 2
    - IDEバージョン:2023.11.1.129 Steam
    - ランタイム:2023.11.1.160
- Git for Windows
    - git version 2.28.0.windows.1

コマンドライン操作はGit Bashを使用します。また、私は昔にインストールしたGitをあんまりアップデートしないまま使用し続けていますが、最新の者でも基本的な操作は変りません。

#### 共通設定の変更

まずはGMS2内でインストールしたGitを紐付けます。手順としては以下の通り。

1. [ファイル]タブをクリック
2. [環境設定]の項目をクリック
3. [プラグイン]>[ソース管理(Git)]をクリック
4. インストールしたGitの`git.exe`があるフォルダを指定する
5. [適用]をクリックして設定を反映させる

![pic001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/b8adf371-4d68-5e34-00b4-f0807b652ceb.png)

#### プロジェクト内の設定

次にプロジェクト内でバージョン管理の使用を有効化させます。

1. [ゲームオプション]をクリック
2. [メインオプション]>[全般]をクリック
3. 「ソース管理を有効にする」のチェックボックスをクリックして有効化する
4. [適用]をクリックして設定を反映させる

![pic002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/c273e282-1ce2-e8a1-ee4b-13e3c288fd7c.png)

#### バージョン管理の有効化

最後にプロジェクトのバージョン管理を有効化させます。これにより、Gitでのバージョン管理の操作が可能になります。

1. [ソース管理]>[プロジェクトリポジトリを作成]をクリック

![pic003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/10b4686b-c55e-58f7-c2a9-430222e793cb.png)
2. アセットブラウザの各項目の右側に緑色のチェックマークが付いていたら有効化されている
![pic004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/034c167b-9ea7-5f5f-e8b3-5dac5d3cb7b7.png)

## バージョン管理をしてみる
上記の設定によりバージョンの使用が可能になったため、ここからは実際にバージョン管理を使った簡単な操作を説明します。
バージョン管理のある開発では、プロジェクト内で各機能を追加するごとに`commit`を実行することで定期的にプロジェクトを保存しながら作業を進めていきます。

```mermaid
graph LR
    start(["commitして保存<br>(タイムスタンプ1)"])-->|機能Aを追加|B(["commitして保存<br>(タイムスタンプ2)"])
    B-->|機能Bを追加|C(["commitして保存<br>(タイムスタンプ3)"])
```

#### バージョン管理の基本

1. GMS2上で作業を進める（変更を加えた項目には赤色のビックリマークが付く）
![pic005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/18cff22c-216d-8f0f-cbea-624df6bea96d.png)

2. Git Bashを開きプロジェクトを保存しているフォルダに移動する
![pic006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/046f1cc8-793b-11f2-02b0-c484b2df96ff.png)

3. `git status`で保存するファイルを確認して`git commit -am "◯◯"`で保存を実行する
    （◯◯には加えた変更の内容の詳細を簡単に記載できる）
![pic007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/f83f82e6-130f-b501-8e63-b4f680f49bc4.png)

4. GMS2上の[ソース管理]>[変更をコミット]をクリックするとGMS2内でコミットが反映され赤色のビックリマークが緑色のチェックマークに変わる
![pic008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/14dfc856-e8f4-61c2-c252-584d1389ff9b.png)

:::note info
3にて`git commit -am "◯◯"`を実行した時点でcommit自体は完了しており、4におけるGMS2上の操作は画面における表示の同期を取るための操作になるため実施しなくても影響ありません。Git Bash上にてcommitした時点でGMS2上の画面にコミット結果が同期的に反映されない（緑色のチェックマークに変わらない）のが仕様なのかどうか私にもよくわかりません...
:::

### 作業をやりなおす
色々と機能を追加していくとこれまで正常に動いていた箇所が動かなくなったり、実装したは良いものの気に入らない挙動をしてしまったり、結果としてやっぱり追加をとりやめて元に戻したくなることがあると思います。

```mermaid
graph LR
    start(["ある程度動いている状態"])-->|機能Aを追加中|B(("よくわかんなく<br>なってきた"))
    B-->|作業をなかったことにして元に戻したい|start
```

バージョン管理を導入していると元に戻す作業がとても楽になります。簡単な流れとしては以下の通り。

1. よくわかんなくなってしまった状態
![pic009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/7d7b3046-39ea-f85c-8336-1b061bfb81db.png)

2. Git Bash上で以下のコマンドを順に実行する

```
$ git reset HEAD .
$ git checkout .
$ git clean -df .
```

`git reset HEAD .`は新規に作成したファイルのgit上の登録解除。`git checkout .`は修正したファイルの修正内容のリセット。`git clean -df .`は新規作成したファイルの削除になります。
3. GMS2上でプロジェクトのリロード画面が表示されるためリロードを実施する
![pic010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/c3433247-6fd2-8bda-8984-87831e5137ad.png)

### バージョンを切り分ける

バージョン管理をすると１つのフォルダ内で完成版及び開発版の種類別切り分け管理ができます。

```mermaid
graph LR
    start(["開発版1.0"])-->|機能Aを追加|B(["開発版1.1"])-->|機能Bを追加|C(["開発版1.2"])-->|機能Cを追加|D(["開発版1.3"])
    B-->|デバッグ版に編集|BA(["デバッグ版1.0"])
    BA-->|デバッグ版の修正|BB(["デバッグ版1.1"])
    C-->|デモ用に調整|CA(["デモ版1.0"])
    CA-->|デモ版の修正|CB(["デモ版1.1"])
```

例として、上記のフローの通りに開発版・デバッグ版・デモ版の3種類を用意した場合、それぞれをコマンド１つで切り替えをすることができます。切り分けた各フローを`ブランチ`と言います。

以下に簡単なブランチ切り替えの例を書きます。

1. コミットをする
![pic021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/3fe0bc8d-cf9a-6be5-87f3-029670e223b8.png)

2. Git Bash上で以下のコマンドを順に実行する
```
$git branch ◯◯
$git checkout ◯◯
```
※◯◯は任意の名前。今回は`dev_demo`とします

![pic011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/c26b06c4-0351-5e51-6ee7-987e00946a4c.png)
　青文字の箇所が◯◯と一致していれば問題なしです。
3. 変更後GMS2上で修正を加え、commitを実行する（今回は`isDemo`を変更する）
![pic012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/09bbb710-472f-5792-8d99-574d628fbf1f.png)

![pic013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/7069f83e-7f44-41e2-290f-47135fbe9c95.png)
4. Git Bash上で`git checkout ◯◯`を実行してブランチを切り替える（最初のmasterブランチに切り変える）
![pic014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/e5291059-ba08-a61c-b6d1-8087097d31b0.png)
5. GMS2上でプロジェクトのリロード画面が表示されるためリロードを実施する
![pic015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/74b5f3ee-7fbd-12d6-dddb-803706b82c30.png)
6. GMS2上だと`isDemo`がfalseの状態(1の状態)に戻っている
![pic016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/44cdfa39-2a01-095b-a7a5-244a407fb23f.png)
7. 現状のフロー(master)を修正してコミットする（ここではisDevelop変数を追加する）
![pic017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/1016f26a-92c2-c515-c466-bb18f30de705.png)
![pic018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/6df4d676-3641-3643-791e-789fc070dba6.png)
8. `is_demo`ブランチに戻ると`isDevelop`変数がない状態になります
![pic019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/610d1297-6cec-7e2f-2f3f-d543e00d9d01.png)
![pic020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961121/245c925d-f4d1-a7c7-ab6b-9a72e4091f75.png)

上記の流れをフロー図にするとこんな感じ

```mermaid
graph LR
    start(["master(isDemo = false)"])-->B(["master(isDevelop = true）"])
    start-->BA(["dev_demo(isDemo = true)"])
```

上記のように分岐した場合、commit完了後の状態であれば好きなタイミングで`master`と`dev_demo`の切り替えができます。


## おわりに
今回はgitの導入と簡単な操作を記載しました。そもそもgitベースの開発を導入すると定期的なcommitにより作成する領域を明確にしながら作業を進めることができます。加えてgitのブランチ分けを上手く使うと開発版・デモ版等をわざわざ別フォルダで管理する必要がなくなり楽になる他、開発中の「やっぱなし！やりなおし！」ができて開発作業が非常に楽になります。

拙い文章ではありましたが皆さんのゲームdevの糧になっていただければ幸いです。不明点やよくわからん点、誤字等がある場合はコメントください。