> For the complete documentation index, see [llms.txt](https://docs.overdare.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.overdare.com/korean/manual/script-manual/advanced-gameplay-systems/modulescript.md).

# 모듈 스크립트

## 개요

모듈 스크립트(ModuleScript)는 공통된 기능을 분리하여 재사용 가능하도록 구조화하기 위해 사용되는 스크립트입니다. 이를 통해 코드의 중복을 줄이고, 유지보수를 효율적으로 수행할 수 있습니다.

## 권장 실행 위치

* **서버와 클라이언트에서 모두** 사용해야 하는 모듈 스크립트는 **ReplicatedStorage**에 배치하는 것이 일반적입니다. (예 : Script와 LocalScript에서 VectorUtil 모듈 참조)
* **서버에서만** 사용하는 모듈 스크립트는 보안과 관리 측면에서 **ServerScriptService** 에 배치하는 것이 권장됩니다. (예 : Script에서 ServerGameConstValue 모듈 참조)
* **클라이언트에서만** 사용하는 모듈 스크립트는 용도에 따라 **StarterPlayerScripts**나 **StarterCharacterScripts**에 배치하는 것이 권장됩니다. (예 : LocalScript에서 Gui 모듈 참조)

## 동작 원리

모듈은 명시적으로 호출(`require`)될 때 실행되며, 첫 호출 시 초기화된 결과가 **캐싱**되므로 이후 호출 시에는 동일한 값을 반환합니다. 이를 통해 실행 효율을 높이고, 일관성을 유지할 수 있습니다.

### 1. 모듈 스크립트 구현

```lua
local UtilityModule = {}

function UtilityModule.PrintMessage(message)
    print("PrintMessage : " .. message)
end

return UtilityModule
```

### 2. 모듈 스크립트 참조 & 사용

```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UtilityModule = require(ReplicatedStorage.UtilityModule)

UtilityModule:PrintMessage("Hello World!")
```

## 모듈 스크립트 응용

### 유틸리티 클래스

**ModuleScript에서**

```lua
local MathUtil = {}

-- Example Function 1
function MathUtil:Sum(...)
    local numList = { ... }
    local result = 0
    
    for i = 1, #numList do
        result = result + numList[i]
    end
    
    return result 
end

-- Example Function 2
function MathUtil:SomeFunc()
    print("SomeFunc")
end

return MathUtil
```

**Script 또는 LocalScript에서**

```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MathUtil = require(ReplicatedStorage.MathUtil)

local sum = MathUtil:Sum(1, 5, 9, 10)
print(sum)
```

### 데이터 클래스

**ModuleScript에서**

```lua
local GameConstValue = {}

GameConstValue.RequirePlayerCount = 10
GameConstValue.MaxRound = 5
GameConstValue.RoundLimitTime = 180

return GameConstValue 
```

**Script 또는 LocalScript에서**

```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GameConstValue = require(ReplicatedStorage.GameConstValue)

local function CheckPlayerCount(playerCount)
    if playerCount >= GameConstValue.RequirePlayerCount then
        print("Ready to start the game")
    end
end
```

### 클래스 상속

**ModuleScript에서**

```lua
local MonsterClass = {}
MonsterClass.__index = MonsterClass

function MonsterClass:new(name, hp, dam, def)
    local self = setmetatable({}, MonsterClass)
    self._Name = name
    self._Hp = hp
    self._MaxHp = hp
    self._Dam = dam
    self._Def = def
    
    return self
end

function MonsterClass:Attack()
    print(self._Name, "Attack!")
end

function MonsterClass:Move()
    print(self._Name, "Move!")
end

function MonsterClass:Destroy()
    print(self._Name, "Destroy!")
end

return MonsterClass
```

**Script 또는 LocalScript에서**

```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MonsterClass = require(ReplicatedStorage.MonsterClass)

local Goblin = MonsterClass:new("Goblin", 100, 10, 5)
local Orc = MonsterClass:new("Orc", 200, 10, 5)

print(Goblin._Name)
print(Orc._Name)

Goblin:Attack()
Orc:Attack()
```
