# 모듈 스크립트

## 개요

모듈 스크립트(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()
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.overdare.com/korean/manual/script-manual/advanced-gameplay-systems/modulescript.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
