Fractured: Paragon core hooks, mod-paragon, mod-ale, Docker build cap
- Track mod-paragon and mod-ale (un-ignore modules in .gitignore). - Ship docker-compose.override.yml with CMAKE_EXTRA_OPTIONS for LuaJIT (mod-ale). - Dockerfile: CBUILD_PARALLEL default to limit OOM under Docker/WSL2. - Core: CLASS_PARAGON sticky combo points (DetachComboTarget), selection rebind, Spell::CheckPower rune path for multi-resource Paragon. - spell_dk_death_rune: IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY) for Blood of the North / Reaping / DRM on Paragon. - Remove temporary Paragon CheckPower logging. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,437 @@
|
||||
<div align="center">
|
||||
|
||||
# 🤝 Contributing to ALE
|
||||
|
||||
*Help improve the AzerothCore Lua Engine*
|
||||
|
||||
[](https://discord.com/invite/ZKSVREE7)
|
||||
[](https://github.com/azerothcore/mod-ale/issues)
|
||||
|
||||
---
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> We welcome contributions from everyone! Whether you code or not, there are many ways to help improve ALE.
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Ways to Contribute](#-ways-to-contribute)
|
||||
- [Contributing Code](#-contributing-code)
|
||||
- [Reporting Issues](#-reporting-issues)
|
||||
- [Improving Documentation](#-improving-documentation)
|
||||
- [Creating Scripts](#-creating-scripts)
|
||||
- [Development Guidelines](#-development-guidelines)
|
||||
|
||||
## 🌟 Ways to Contribute
|
||||
|
||||
You don't need to be a developer to contribute to ALE! Here are various ways you can help:
|
||||
|
||||
### 💻 For Developers
|
||||
|
||||
- **Fix Bugs**: Browse open issues and submit fixes
|
||||
- **Add Features**: Implement new functionality
|
||||
- **Improve Performance**: Optimize existing code
|
||||
- **Write Tests**: Help ensure code quality
|
||||
- **Review Pull Requests**: Provide feedback on proposed changes
|
||||
|
||||
### 📚 For Writers
|
||||
|
||||
- **Improve Documentation**: Fix typos, clarify explanations, add examples
|
||||
- **Write Tutorials**: Create guides for common use cases
|
||||
- **Translate**: Help make documentation available in other languages
|
||||
- **API Documentation**: Document undocumented functions
|
||||
|
||||
### 🎮 For Scripters
|
||||
|
||||
- **Create Example Scripts**: Share useful script templates
|
||||
- **Report Script Issues**: Help identify API problems
|
||||
- **Share Best Practices**: Document scripting patterns
|
||||
- **Test New Features**: Verify new functionality works as expected
|
||||
|
||||
### 💬 For Community Members
|
||||
|
||||
- **Answer Questions**: Help others on Discord or GitHub
|
||||
- **Report Bugs**: Submit detailed issue reports
|
||||
- **Test Releases**: Try pre-release versions and provide feedback
|
||||
- **Spread the Word**: Share ALE with other server administrators
|
||||
|
||||
## 💻 Contributing Code
|
||||
|
||||
### Getting Started
|
||||
|
||||
1. **[Set up Git](https://help.github.com/articles/set-up-git/)** if you haven't already
|
||||
|
||||
2. **[Fork the repository](https://help.github.com/articles/fork-a-repo/)** to your GitHub account:
|
||||
- Main repository: [mod-ale](https://github.com/azerothcore/mod-ale)
|
||||
- Core engine: [ALE source in mod-ale](https://github.com/azerothcore/mod-ale/tree/master/src/LuaEngine)
|
||||
|
||||
3. **Clone your fork** to your local machine:
|
||||
```bash
|
||||
git clone https://github.com/YOUR_USERNAME/mod-ale.git
|
||||
cd mod-ale
|
||||
```
|
||||
|
||||
4. **Add the upstream repository**:
|
||||
```bash
|
||||
git remote add upstream https://github.com/azerothcore/mod-ale.git
|
||||
```
|
||||
|
||||
### Development Workflow
|
||||
|
||||
1. **Create a feature branch** from `master`:
|
||||
```bash
|
||||
git checkout master
|
||||
git pull upstream master
|
||||
git checkout -b feature/my-awesome-feature
|
||||
```
|
||||
|
||||
2. **Make your changes**:
|
||||
- Write clean, readable code
|
||||
- Follow existing code style
|
||||
- Add comments where necessary
|
||||
- Test your changes thoroughly
|
||||
|
||||
3. **Commit your changes**:
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Add feature: description of what you did"
|
||||
```
|
||||
|
||||
**Commit Message Guidelines:**
|
||||
- Use clear, descriptive messages
|
||||
- Start with a verb (Add, Fix, Update, Remove, etc.)
|
||||
- Keep the first line under 50 characters
|
||||
- Add detailed explanation in subsequent lines if needed
|
||||
|
||||
```
|
||||
Add new Player:GetQuestStatus method
|
||||
|
||||
This method allows scripts to check the status of a player's quest
|
||||
without needing to retrieve the full quest object. This improves
|
||||
performance for common quest-checking scenarios.
|
||||
```
|
||||
|
||||
4. **Push to your fork**:
|
||||
```bash
|
||||
git push origin feature/my-awesome-feature
|
||||
```
|
||||
|
||||
5. **[Open a Pull Request](https://help.github.com/articles/using-pull-requests/)**:
|
||||
- Go to your fork on GitHub
|
||||
- Click "New Pull Request"
|
||||
- Select your feature branch
|
||||
- Provide a clear description of your changes
|
||||
- Link any related issues
|
||||
|
||||
### Code Style Guidelines
|
||||
|
||||
#### C++ Code
|
||||
|
||||
```cpp
|
||||
// Use clear, descriptive names
|
||||
int GetPlayerLevel(Player* player)
|
||||
{
|
||||
if (!player)
|
||||
return 0;
|
||||
|
||||
return player->getLevel();
|
||||
}
|
||||
|
||||
// Prefer modern C++ features
|
||||
std::vector<uint32> GetPlayerQuests(Player* player)
|
||||
{
|
||||
std::vector<uint32> quests;
|
||||
// ... implementation
|
||||
return quests;
|
||||
}
|
||||
```
|
||||
|
||||
**Key Points:**
|
||||
- Use 4 spaces for indentation (no tabs)
|
||||
- Opening braces on the same line for functions
|
||||
- Use meaningful variable names
|
||||
- Add comments for complex logic
|
||||
- Follow existing patterns in the codebase
|
||||
|
||||
#### Lua Code (for examples/tests)
|
||||
|
||||
```lua
|
||||
-- Use local variables
|
||||
local QUEST_STATUS_COMPLETE = 1
|
||||
|
||||
-- Clear, descriptive function names
|
||||
local function OnQuestComplete(event, player, quest)
|
||||
if not player or not quest then
|
||||
return
|
||||
end
|
||||
|
||||
local questId = quest:GetId()
|
||||
print("Player", player:GetName(), "completed quest", questId)
|
||||
end
|
||||
|
||||
-- Register with clear event IDs
|
||||
RegisterPlayerEvent(8, OnQuestComplete) -- PLAYER_EVENT_ON_QUEST_COMPLETE
|
||||
```
|
||||
|
||||
### Testing Your Changes
|
||||
|
||||
Before submitting a PR:
|
||||
|
||||
1. **Compile the code** without errors
|
||||
2. **Test basic functionality** with your changes
|
||||
3. **Test edge cases** (nil values, invalid input, etc.)
|
||||
4. **Verify no regressions** (existing features still work)
|
||||
5. **Test on a real server** if possible
|
||||
|
||||
## 🐛 Reporting Issues
|
||||
|
||||
Good bug reports help us fix problems faster!
|
||||
|
||||
### Before Reporting
|
||||
|
||||
1. **Search existing issues** to avoid duplicates
|
||||
2. **Test on latest version** to ensure it's not already fixed
|
||||
3. **Gather information** about your setup and the problem
|
||||
|
||||
### Creating a Good Issue Report
|
||||
|
||||
Use this template:
|
||||
|
||||
```markdown
|
||||
**Describe the bug**
|
||||
A clear description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Load script '...'
|
||||
2. Trigger event '...'
|
||||
3. See error
|
||||
|
||||
**Expected behavior**
|
||||
What you expected to happen.
|
||||
|
||||
**Actual behavior**
|
||||
What actually happened.
|
||||
|
||||
**Environment:**
|
||||
- AzerothCore version: [e.g., commit hash]
|
||||
- ALE version: [e.g., commit hash]
|
||||
- Lua version: [e.g., LuaJIT, Lua 5.2]
|
||||
- OS: [e.g., Ubuntu 20.04]
|
||||
|
||||
**Script/Code:**
|
||||
```lua
|
||||
-- Minimal script that reproduces the issue
|
||||
local function OnLogin(event, player)
|
||||
-- problematic code
|
||||
end
|
||||
RegisterPlayerEvent(3, OnLogin)
|
||||
```
|
||||
|
||||
**Error messages:**
|
||||
```
|
||||
Paste any error messages from the log here
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
Any other information that might be helpful.
|
||||
```
|
||||
|
||||
## 📖 Improving Documentation
|
||||
|
||||
Documentation is crucial for helping users understand ALE.
|
||||
|
||||
### What to Document
|
||||
|
||||
- **API Functions**: Descriptions, parameters, return values, examples
|
||||
- **Events**: When they trigger, what parameters they pass
|
||||
- **Best Practices**: Common patterns and anti-patterns
|
||||
- **Examples**: Real-world use cases and complete scripts
|
||||
|
||||
### Documentation Workflow
|
||||
|
||||
1. Fork the repository
|
||||
2. Edit documentation files in the `docs/` folder
|
||||
3. Use clear, concise language
|
||||
4. Add code examples where helpful
|
||||
5. Test any code examples you include
|
||||
6. Submit a Pull Request
|
||||
|
||||
### Markdown Tips
|
||||
|
||||
```markdown
|
||||
# Use headers for structure
|
||||
|
||||
## Subsections help organize content
|
||||
|
||||
**Bold** for emphasis
|
||||
|
||||
`code` for inline code
|
||||
|
||||
```lua
|
||||
-- Code blocks for examples
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Use callouts for important information
|
||||
|
||||
- Lists
|
||||
- Keep
|
||||
- Things
|
||||
- Organized
|
||||
```
|
||||
|
||||
## 🎮 Creating Scripts
|
||||
|
||||
Share your scripts with the community!
|
||||
|
||||
### Where to Share
|
||||
|
||||
- **Discord**: [ALE Community](https://discord.com/invite/bx3y5Qmy)
|
||||
- **GitHub Discussions**: For detailed explanations
|
||||
- **Pull Requests**: Add example scripts to the repository
|
||||
|
||||
### Script Quality Guidelines
|
||||
|
||||
Good example scripts should:
|
||||
|
||||
1. **Be Well Commented**: Explain what the code does
|
||||
2. **Handle Edge Cases**: Check for nil values, validate input
|
||||
3. **Follow Best Practices**: Use local variables, cache data, etc.
|
||||
4. **Include Usage Instructions**: How to install and configure
|
||||
5. **Be Self-Contained**: Include all necessary code
|
||||
|
||||
### Example Template
|
||||
|
||||
```lua
|
||||
--[[
|
||||
Script Name: Player Welcome System
|
||||
Description: Sends customized welcome message based on player level
|
||||
Author: YourName
|
||||
Version: 1.0
|
||||
Date: 2025-01-09
|
||||
|
||||
Installation:
|
||||
1. Place this file in lua_scripts folder
|
||||
2. Configure MESSAGES table below
|
||||
3. Restart server
|
||||
|
||||
Features:
|
||||
- Different messages for different level ranges
|
||||
- Personalized with player name
|
||||
- Configurable message tiers
|
||||
]]
|
||||
|
||||
-- Configuration
|
||||
local MESSAGES = {
|
||||
[1] = "Welcome to the server, %s! Enjoy your adventure!",
|
||||
[10] = "Welcome back, %s! You've grown stronger!",
|
||||
[60] = "Greetings, veteran %s! The endgame awaits!",
|
||||
[80] = "Welcome, champion %s! You've mastered your class!"
|
||||
}
|
||||
|
||||
-- Get appropriate message for player level
|
||||
local function GetWelcomeMessage(player)
|
||||
local level = player:GetLevel()
|
||||
local message = MESSAGES[1] -- Default message
|
||||
|
||||
-- Find highest tier message player qualifies for
|
||||
for minLevel, msg in pairs(MESSAGES) do
|
||||
if level >= minLevel then
|
||||
message = msg
|
||||
end
|
||||
end
|
||||
|
||||
return string.format(message, player:GetName())
|
||||
end
|
||||
|
||||
-- Event handler
|
||||
local function OnLogin(event, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
local message = GetWelcomeMessage(player)
|
||||
player:SendBroadcastMessage(message)
|
||||
end
|
||||
|
||||
-- Register the event
|
||||
RegisterPlayerEvent(3, OnLogin) -- PLAYER_EVENT_ON_LOGIN
|
||||
```
|
||||
|
||||
## 🔨 Development Guidelines
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
mod-ale/
|
||||
├── src/
|
||||
│ └── LuaEngine/ # Core ALE source code
|
||||
│ ├── docs/ # Source documentation
|
||||
│ ├── methods/ # API method implementations
|
||||
│ └── hooks/ # Event hook implementations
|
||||
├── docs/ # User-facing documentation
|
||||
├── conf/ # Configuration file templates
|
||||
└── README.md # Project overview
|
||||
```
|
||||
|
||||
### Branch Strategy
|
||||
|
||||
- **master**: Stable, production-ready code
|
||||
- **feature/**: New features (e.g., `feature/add-new-hook`)
|
||||
- **fix/**: Bug fixes (e.g., `fix/player-null-check`)
|
||||
- **docs/**: Documentation updates (e.g., `docs/update-install-guide`)
|
||||
|
||||
### Pull Request Guidelines
|
||||
|
||||
**Good PR:**
|
||||
- Single, focused change
|
||||
- Clear title and description
|
||||
- Links related issues
|
||||
- Passes compilation
|
||||
- Includes documentation updates if needed
|
||||
|
||||
**PR Template:**
|
||||
|
||||
```markdown
|
||||
## Description
|
||||
Brief description of the changes
|
||||
|
||||
## Type of Change
|
||||
- [ ] Bug fix
|
||||
- [ ] New feature
|
||||
- [ ] Documentation update
|
||||
- [ ] Performance improvement
|
||||
|
||||
## Testing
|
||||
Describe how you tested your changes
|
||||
|
||||
## Related Issues
|
||||
Fixes #123
|
||||
Related to #456
|
||||
|
||||
## Checklist
|
||||
- [ ] Code compiles without errors
|
||||
- [ ] Tested on a running server
|
||||
- [ ] Updated documentation
|
||||
- [ ] Followed code style guidelines
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Acknowledgements
|
||||
|
||||
ALE is built upon the foundation of the [Eluna Lua Engine](https://github.com/ElunaLuaEngine/Eluna). We acknowledge and thank the Eluna team for their pioneering work in Lua scripting for World of Warcraft server emulators.
|
||||
|
||||
- **[Original Eluna Repository](https://github.com/ElunaLuaEngine/Eluna)**
|
||||
- **[Eluna Discord Community](https://discord.gg/bjkCVWqqfX)**
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<sub>Developed with ❤️ by the AzerothCore and ALE community</sub>
|
||||
|
||||
Thank you for contributing! 🎉
|
||||
|
||||
[⬆ Back to Top](#-contributing-to-ale)
|
||||
</div>
|
||||
@@ -0,0 +1,430 @@
|
||||
<div align="center">
|
||||
|
||||
# ⚙️ ALE Implementation Details
|
||||
|
||||
*Advanced features and technical documentation for ALE*
|
||||
|
||||
[](https://discord.com/invite/ZKSVREE7)
|
||||
[](http://www.azerothcore.org/)
|
||||
|
||||
---
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This document covers advanced implementation details and best practices for ALE (AzerothCore Lua Engine). For basic usage, see the [Usage Guide](USAGE.md).
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Configuration](#-configuration)
|
||||
- [Script Management](#-script-management)
|
||||
- [Advanced Features](#-advanced-features)
|
||||
- [Database Integration](#-database-integration)
|
||||
- [Performance Tips](#-performance-tips)
|
||||
- [Debugging](#-debugging)
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
### Server Configuration File
|
||||
|
||||
ALE settings are located in the AzerothCore server configuration file.
|
||||
|
||||
> [!WARNING]
|
||||
> **Important:** Always use the new configuration file generated after compiling with ALE. Without it, error logging and output may not function correctly.
|
||||
|
||||
### Available Settings
|
||||
|
||||
- **Enable/Disable ALE**: Toggle the Lua engine on or off
|
||||
- **Traceback Function**: Enable detailed debug information in error messages
|
||||
- **Script Folder Location**: Configure where ALE looks for script files
|
||||
- **Logging Settings**: Control log verbosity and output destinations
|
||||
|
||||
## 🔄 Script Management
|
||||
|
||||
### Script Reloading
|
||||
|
||||
Reload scripts during development with:
|
||||
|
||||
```
|
||||
.reload ale
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> **Development Only:** This command is for testing purposes only. For production use or troubleshooting, always restart the server.
|
||||
|
||||
**Limitations:**
|
||||
- Events are not re-triggered for existing entities (e.g., logged-in players)
|
||||
- Some state may persist from the previous load
|
||||
- Race conditions may occur with active scripts
|
||||
|
||||
### Script Loading
|
||||
|
||||
#### Default Behavior
|
||||
|
||||
- **Default Folder**: `lua_scripts` (configurable in server config)
|
||||
- **Hidden Folders**: Ignored during loading
|
||||
- **File Names**: Must be unique across all subdirectories
|
||||
- **Loading Order**: Not guaranteed to be alphabetical
|
||||
|
||||
#### Load Priority
|
||||
|
||||
Files with `.ext` extension load before standard `.lua` files:
|
||||
- `init.ext` loads before `script.lua`
|
||||
|
||||
> [!TIP]
|
||||
> Instead of using `.ext`, prefer the standard Lua `require()` function for better maintainability.
|
||||
|
||||
#### Using Require
|
||||
|
||||
The entire script folder structure is added to Lua's require path:
|
||||
|
||||
```lua
|
||||
-- Require file: lua_scripts/utilities/helpers.lua
|
||||
require("utilities/helpers")
|
||||
|
||||
-- Or simply (if in root)
|
||||
require("helpers")
|
||||
```
|
||||
|
||||
**Note:** Omit the `.lua` extension when using `require()`.
|
||||
|
||||
## 🎯 Advanced Features
|
||||
|
||||
### Automatic Type Conversion
|
||||
|
||||
In C++, you must explicitly cast between types:
|
||||
```cpp
|
||||
Unit* unit = ...;
|
||||
Player* player = unit->ToPlayer(); // Manual cast required
|
||||
```
|
||||
|
||||
In ALE, this happens automatically:
|
||||
```lua
|
||||
-- unit is automatically converted to the most specific type
|
||||
-- No manual casting needed!
|
||||
local name = unit:GetName() -- Works for Unit, Player, Creature, etc.
|
||||
```
|
||||
|
||||
All objects are automatically converted to their most specific type, giving you full access to all available methods.
|
||||
|
||||
### Storing Userdata Objects
|
||||
|
||||
> [!CAUTION]
|
||||
> **Critical:** Never store C++-managed userdata objects in global variables or across events!
|
||||
|
||||
#### The Problem
|
||||
|
||||
C++ manages object lifetimes. A stored pointer can become invalid when:
|
||||
- A player logs out
|
||||
- A creature despawns
|
||||
- An object is deleted by the core
|
||||
|
||||
Accessing invalid pointers causes crashes.
|
||||
|
||||
#### The Solution
|
||||
|
||||
Objects are automatically set to `nil` when they become unsafe (usually when the hook function ends).
|
||||
|
||||
**Instead of storing objects:**
|
||||
|
||||
```lua
|
||||
-- ❌ WRONG: Don't do this
|
||||
local savedPlayer = nil
|
||||
|
||||
local function OnLogin(event, player)
|
||||
savedPlayer = player -- Bad! Will be nil after function ends
|
||||
end
|
||||
|
||||
local function OnLogout(event, player)
|
||||
savedPlayer:SendMessage("Test") -- CRASH! savedPlayer is nil
|
||||
end
|
||||
```
|
||||
|
||||
**Store GUIDs instead:**
|
||||
|
||||
```lua
|
||||
-- ✅ CORRECT: Store GUID and retrieve object when needed
|
||||
local playerGUID = nil
|
||||
|
||||
local function OnLogin(event, player)
|
||||
playerGUID = player:GetGUID()
|
||||
end
|
||||
|
||||
local function SomeLaterEvent(event, ...)
|
||||
local player = GetPlayerByGUID(playerGUID)
|
||||
if player then
|
||||
player:SendMessage("Test") -- Safe!
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### Safe to Store
|
||||
|
||||
These userdata objects are Lua-managed and safe to store:
|
||||
- Query results (`ALEQuery`)
|
||||
- World packets (`WorldPacket`)
|
||||
- 64-bit numbers (`uint64`, `int64`)
|
||||
|
||||
### Userdata Metamethods
|
||||
|
||||
#### ToString Support
|
||||
|
||||
All userdata objects implement `tostring`:
|
||||
|
||||
```lua
|
||||
print(player) -- Outputs: Player (Name: "John", GUID: 123456)
|
||||
print(creature) -- Outputs: Creature (Entry: 1234, GUID: 789012)
|
||||
```
|
||||
|
||||
#### Global Metatables
|
||||
|
||||
Each class has a global table containing its methods:
|
||||
|
||||
```lua
|
||||
-- These global tables exist:
|
||||
Player = { GetName = function(...) end, ... }
|
||||
Creature = { GetEntry = function(...) end, ... }
|
||||
GameObject = { GetDisplayId = function(...) end, ... }
|
||||
```
|
||||
|
||||
#### Custom Methods
|
||||
|
||||
You can extend classes with custom methods:
|
||||
|
||||
```lua
|
||||
function Player:CustomGreeting()
|
||||
self:SendBroadcastMessage("Welcome, " .. self:GetName() .. "!")
|
||||
end
|
||||
|
||||
function GameObject:IsChest()
|
||||
return self:GetGoType() == 3
|
||||
end
|
||||
|
||||
-- Usage:
|
||||
player:CustomGreeting()
|
||||
if gameobject:IsChest() then
|
||||
print("Found a chest!")
|
||||
end
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Avoid modifying or deleting global class tables in normal code, as this can break other scripts.
|
||||
|
||||
## 🗄️ Database Integration
|
||||
|
||||
### Query Performance
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Database queries are slow! The entire server waits while data is fetched from disk.
|
||||
|
||||
#### Synchronous vs Asynchronous
|
||||
|
||||
**Use `Execute` for non-SELECT queries:**
|
||||
```lua
|
||||
-- Asynchronous - doesn't block server
|
||||
WorldDBExecute("UPDATE creature SET level = 80 WHERE entry = 1234")
|
||||
```
|
||||
|
||||
**Use `Query` only when you need results:**
|
||||
```lua
|
||||
-- Synchronous - blocks server until complete
|
||||
local result = WorldDBQuery("SELECT name FROM creature_template WHERE entry = 1234")
|
||||
```
|
||||
|
||||
#### Best Practices
|
||||
|
||||
1. **Cache at Startup**: Load data once during server start or script load
|
||||
2. **Use Tables**: Store frequently accessed data in Lua tables
|
||||
3. **Batch Operations**: Combine multiple queries when possible
|
||||
4. **Async When Possible**: Use `Execute` instead of `Query` if you don't need results
|
||||
|
||||
```lua
|
||||
-- ✅ Good: Cache data at startup
|
||||
local creatureNames = {}
|
||||
|
||||
local function LoadCreatureNames()
|
||||
local query = WorldDBQuery("SELECT entry, name FROM creature_template")
|
||||
if query then
|
||||
repeat
|
||||
local entry = query:GetUInt32(0)
|
||||
local name = query:GetString(1)
|
||||
creatureNames[entry] = name
|
||||
until not query:NextRow()
|
||||
end
|
||||
end
|
||||
|
||||
-- Call once at server start
|
||||
RegisterServerEvent(33, LoadCreatureNames) -- SERVER_EVENT_ON_CONFIG_LOAD
|
||||
|
||||
-- Now use cached data
|
||||
local function OnSpawn(event, creature)
|
||||
local name = creatureNames[creature:GetEntry()]
|
||||
print("Spawned:", name)
|
||||
end
|
||||
```
|
||||
|
||||
### Database Types
|
||||
|
||||
> [!CAUTION]
|
||||
> **Critical:** Use the correct getter function for each database type!
|
||||
|
||||
MySQL performs math in specific formats. Using the wrong getter can return incorrect values on different systems.
|
||||
|
||||
#### Type Mapping Table
|
||||
|
||||
| Base Type | Defined Type | Database Type | Query Getter |
|
||||
|---------------------------|--------------|-----------------------|-------------------|
|
||||
| char | int8 | tinyint(3) | `GetInt8()` |
|
||||
| short int | int16 | smallint(5) | `GetInt16()` |
|
||||
| (long int / int) | int32 | mediumint(8) | `GetInt32()` |
|
||||
| (long int / int) | int32 | int(10) | `GetInt32()` |
|
||||
| long long int | int64 | bigint(20) | `GetInt64()` |
|
||||
| unsigned char | uint8 | tinyint(3) unsigned | `GetUInt8()` |
|
||||
| unsigned short int | uint16 | smallint(5) unsigned | `GetUInt16()` |
|
||||
| unsigned (long int / int) | uint32 | mediumint(8) unsigned | `GetUInt32()` |
|
||||
| unsigned (long int / int) | uint32 | int(10) unsigned | `GetUInt32()` |
|
||||
| unsigned long long int | uint64 | bigint(20) unsigned | `GetUInt64()` |
|
||||
| float | float | float | `GetFloat()` |
|
||||
| double | double | double, decimal | `GetDouble()` |
|
||||
| std::string | std::string | varchar, text, etc. | `GetString()` |
|
||||
|
||||
#### Example
|
||||
|
||||
```lua
|
||||
-- ❌ WRONG: Can return 0 or 1 depending on system
|
||||
local result = WorldDBQuery("SELECT 1")
|
||||
local value = result:GetUInt32(0) -- Incorrect type!
|
||||
|
||||
-- ✅ CORRECT: Always returns 1
|
||||
local result = WorldDBQuery("SELECT 1")
|
||||
local value = result:GetInt64(0) -- Correct type for literal numbers
|
||||
```
|
||||
|
||||
## ⚡ Performance Tips
|
||||
|
||||
### Variable Scope
|
||||
|
||||
```lua
|
||||
-- ✅ Fast: Local variables
|
||||
local count = 0
|
||||
for i = 1, 1000 do
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
-- ❌ Slow: Global variables
|
||||
count = 0
|
||||
for i = 1, 1000 do
|
||||
count = count + 1
|
||||
end
|
||||
```
|
||||
|
||||
### Table Efficiency
|
||||
|
||||
```lua
|
||||
-- ❌ Avoid: Creating tables in loops
|
||||
for i = 1, 1000 do
|
||||
local data = {i, i*2, i*3} -- 1000 table allocations!
|
||||
end
|
||||
|
||||
-- ✅ Better: Reuse tables
|
||||
local data = {}
|
||||
for i = 1, 1000 do
|
||||
data[1], data[2], data[3] = i, i*2, i*3
|
||||
end
|
||||
```
|
||||
|
||||
### Cache Frequently Used Values
|
||||
|
||||
```lua
|
||||
-- ❌ Avoid: Repeated method calls
|
||||
for i = 1, 100 do
|
||||
player:GetName() -- Calls C++ function 100 times
|
||||
end
|
||||
|
||||
-- ✅ Better: Cache the value
|
||||
local playerName = player:GetName()
|
||||
for i = 1, 100 do
|
||||
-- Use playerName
|
||||
end
|
||||
```
|
||||
|
||||
### Minimize Database Access
|
||||
|
||||
```lua
|
||||
-- ❌ Bad: Query in a loop
|
||||
for entry = 1, 100 do
|
||||
local query = WorldDBQuery("SELECT name FROM creature_template WHERE entry = " .. entry)
|
||||
end
|
||||
|
||||
-- ✅ Good: Single query with IN clause
|
||||
local query = WorldDBQuery("SELECT entry, name FROM creature_template WHERE entry BETWEEN 1 AND 100")
|
||||
```
|
||||
|
||||
## 🐛 Debugging
|
||||
|
||||
### Print Debugging
|
||||
|
||||
```lua
|
||||
-- Basic output
|
||||
print("Debug: Function called")
|
||||
|
||||
-- With variables
|
||||
print("Player:", player:GetName(), "Level:", player:GetLevel())
|
||||
|
||||
-- Object inspection
|
||||
print(player) -- Uses tostring metamethod
|
||||
```
|
||||
|
||||
### Error Logs
|
||||
|
||||
Check these locations for errors:
|
||||
- **Server Console**: Real-time output
|
||||
- **Log File**: Persistent record in server folder
|
||||
|
||||
### Traceback
|
||||
|
||||
Enable traceback in the server config for detailed error information:
|
||||
```
|
||||
ALE.TraceBack = 1
|
||||
```
|
||||
|
||||
This adds call stack information to errors.
|
||||
|
||||
### Incremental Testing
|
||||
|
||||
1. **Start Small**: Test basic functionality first
|
||||
2. **Add Gradually**: Implement features one at a time
|
||||
3. **Test Each Step**: Verify each addition works before moving on
|
||||
4. **Use Reload**: Use `.reload ale` for quick iteration (dev only)
|
||||
5. **Full Restart**: Always do final testing with a server restart
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Objects becoming nil:**
|
||||
- You're storing userdata objects instead of GUIDs
|
||||
- See [Storing Userdata Objects](#storing-userdata-objects)
|
||||
|
||||
**Wrong database values:**
|
||||
- Using incorrect getter function for database type
|
||||
- See [Database Types](#database-types)
|
||||
|
||||
**Script not loading:**
|
||||
- Check for duplicate filenames
|
||||
- Check log for syntax errors
|
||||
- Verify script folder configuration
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Acknowledgements
|
||||
|
||||
ALE is built upon the foundation of the [Eluna Lua Engine](https://github.com/ElunaLuaEngine/Eluna). We acknowledge and thank the Eluna team for their pioneering work in Lua scripting for World of Warcraft server emulators.
|
||||
|
||||
- **[Original Eluna Repository](https://github.com/ElunaLuaEngine/Eluna)**
|
||||
- **[Eluna Discord Community](https://discord.gg/bjkCVWqqfX)**
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<sub>Developed with ❤️ by the AzerothCore and ALE community</sub>
|
||||
|
||||
[⬆ Back to Top](#-ale-implementation-details)
|
||||
</div>
|
||||
@@ -0,0 +1,308 @@
|
||||
<div align="center">
|
||||
|
||||
# 🔧 ALE Installation Guide
|
||||
|
||||
*Step-by-step instructions for installing ALE on AzerothCore*
|
||||
|
||||
[](https://discord.com/invite/ZKSVREE7)
|
||||
[](http://www.azerothcore.org/)
|
||||
|
||||
---
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> ALE is designed specifically for **AzerothCore**. If you're looking for compatibility with other emulators, check out [ElunaAzerothCore](https://github.com/Eluna-Ports/ElunaAzerothCore) for original Eluna compatibility.
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Requirements](#-requirements)
|
||||
- [Installation](#-installation)
|
||||
- [Configuration](#-configuration)
|
||||
- [Updating](#-updating)
|
||||
- [Troubleshooting](#-troubleshooting)
|
||||
- [Next Steps](#-next-steps)
|
||||
|
||||
## ⚡ Requirements
|
||||
|
||||
Before installing ALE, ensure you have:
|
||||
|
||||
### System Requirements
|
||||
|
||||
- **AzerothCore Server**: A working AzerothCore installation
|
||||
- **Git**: Version control system for cloning repositories
|
||||
- **CMake**: Build system (3.16 or higher recommended)
|
||||
- **Compiler with C++11 Support**:
|
||||
- Windows: Visual Studio 2019 or later
|
||||
- Linux: GCC 7+ or Clang 5+
|
||||
- macOS: Xcode 10+
|
||||
|
||||
### Build Dependencies
|
||||
|
||||
ALE can use either:
|
||||
- **ACE** (ADAPTIVE Communication Environment), or
|
||||
- **Boost** (for filesystem library)
|
||||
|
||||
These should already be available if you have AzerothCore set up.
|
||||
|
||||
## 🚀 Installation
|
||||
|
||||
### Step 1: Navigate to Modules Directory
|
||||
|
||||
Open your terminal (or Git Bash on Windows) and navigate to your AzerothCore modules directory:
|
||||
|
||||
```bash
|
||||
cd <azerothcore-path>/modules
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
cd /home/user/azerothcore/modules
|
||||
```
|
||||
|
||||
### Step 2: Clone the Repository
|
||||
|
||||
Clone the mod-ale repository into your modules folder:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/azerothcore/mod-ale.git
|
||||
```
|
||||
|
||||
This will create a `mod-ale` folder containing all necessary files.
|
||||
|
||||
### Step 3: Configure Build
|
||||
|
||||
Navigate to your AzerothCore build directory and configure with CMake:
|
||||
|
||||
```bash
|
||||
cd <azerothcore-build-directory>
|
||||
cmake ../ -DLUA_VERSION=luajit
|
||||
```
|
||||
|
||||
#### Lua Version Options
|
||||
|
||||
Choose your preferred Lua version with the `-DLUA_VERSION` flag:
|
||||
|
||||
| Version | Flag | Notes |
|
||||
|---------|------|-------|
|
||||
| **LuaJIT** | `luajit` | **Recommended** - Best performance via JIT compilation |
|
||||
| **Lua 5.2** | `lua52` | **Default** - Used if no version specified |
|
||||
| **Lua 5.3** | `lua53` | Newer features, compatible |
|
||||
| **Lua 5.4** | `lua54` | Latest version, all features |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Using LuaJIT (recommended for performance)
|
||||
cmake ../ -DLUA_VERSION=luajit
|
||||
|
||||
# Using Lua 5.3
|
||||
cmake ../ -DLUA_VERSION=lua53
|
||||
|
||||
# Using default (Lua 5.2)
|
||||
cmake ../
|
||||
```
|
||||
|
||||
### Step 4: Compile
|
||||
|
||||
Compile AzerothCore with the newly added module:
|
||||
|
||||
**Linux/macOS:**
|
||||
```bash
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```bash
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> The `-j$(nproc)` flag uses all available CPU cores for faster compilation.
|
||||
|
||||
### Step 5: Update Configuration
|
||||
|
||||
> [!CAUTION]
|
||||
> **Critical Step:** After compiling, you must use the newly generated configuration files!
|
||||
|
||||
The compilation process generates updated config files with ALE settings. Without these, ALE may not function correctly (no error messages, logging issues, etc.).
|
||||
|
||||
**Location of config files:**
|
||||
- Usually in your server's `etc/modules` or `configs/modules` directory
|
||||
- Look for files like `mod-ale.conf`
|
||||
|
||||
Copy the new `.conf.dist` files:
|
||||
|
||||
```bash
|
||||
# Example - adjust paths as needed
|
||||
cp mod-ale.conf.dist mod-ale.conf
|
||||
```
|
||||
|
||||
Then edit `worldserver.conf` and configure ALE settings (see [Configuration](#-configuration) below).
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
### ALE Settings in mod-ale.conf
|
||||
|
||||
After installation, configure ALE by editing your `mod-ale.conf` file:
|
||||
|
||||
```ini
|
||||
###################################################################################################
|
||||
# ALE (AZEROTHCORE LUA ENGINE)
|
||||
###################################################################################################
|
||||
|
||||
# Enable or disable ALE
|
||||
# Default: 1 (enabled)
|
||||
ALE.Enabled = 1
|
||||
|
||||
# Enable traceback for detailed error information
|
||||
# Useful for debugging but has performance overhead
|
||||
# Default: 1 (enabled)
|
||||
ALE.TraceBack = 1
|
||||
|
||||
# Script folder location (relative to server binary)
|
||||
# Default: "lua_scripts"
|
||||
ALE.ScriptPath = "lua_scripts"
|
||||
```
|
||||
|
||||
### Creating the Scripts Folder
|
||||
|
||||
Create the scripts folder next to your server executable:
|
||||
|
||||
```bash
|
||||
mkdir lua_scripts
|
||||
```
|
||||
|
||||
Place your `.lua` script files in this folder. ALE will automatically load them on server start.
|
||||
|
||||
## 🔄 Updating
|
||||
|
||||
Keep your ALE installation up to date with the latest features and bug fixes.
|
||||
|
||||
### Update Steps
|
||||
|
||||
1. **Navigate to the mod-ale directory:**
|
||||
|
||||
```bash
|
||||
cd <azerothcore-path>/modules/mod-ale
|
||||
```
|
||||
|
||||
2. **Pull the latest changes:**
|
||||
|
||||
```bash
|
||||
git pull
|
||||
```
|
||||
|
||||
3. **Navigate to your build directory:**
|
||||
|
||||
```bash
|
||||
cd <azerothcore-build-directory>
|
||||
```
|
||||
|
||||
4. **Reconfigure if needed (optional):**
|
||||
|
||||
```bash
|
||||
cmake ../ -DLUA_VERSION=luajit
|
||||
```
|
||||
|
||||
5. **Recompile:**
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
make -j$(nproc)
|
||||
|
||||
# Windows
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
6. **Restart your server** to load the updated version
|
||||
|
||||
> [!TIP]
|
||||
> Always backup your database and scripts before updating!
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### ALE Not Loading
|
||||
|
||||
**Check these things:**
|
||||
|
||||
1. **Config file**: Ensure you're using the new `worldserver.conf` generated after compilation
|
||||
2. **Enabled setting**: Verify `ALE.Enabled = 1` in config
|
||||
3. **Script path**: Ensure `lua_scripts` folder exists in the correct location
|
||||
4. **Logs**: Check server logs for error messages
|
||||
|
||||
### No Error Messages
|
||||
|
||||
If you're not seeing ALE errors:
|
||||
|
||||
- **Solution**: You're using an old config file. Copy the new `.conf.dist` file and reconfigure.
|
||||
|
||||
### Compilation Errors
|
||||
|
||||
**"Lua headers not found":**
|
||||
- ALE should automatically download Lua dependencies
|
||||
- Ensure you have internet connection during CMake configuration
|
||||
|
||||
**C++11 errors:**
|
||||
- Update your compiler to one that supports C++11 or later
|
||||
|
||||
**ACE/Boost errors:**
|
||||
- These should be installed with AzerothCore
|
||||
- Check your AzerothCore installation
|
||||
|
||||
### Scripts Not Loading
|
||||
|
||||
1. **Check file extension**: Must be `.lua`
|
||||
2. **Check file names**: Must be unique across all subdirectories
|
||||
3. **Check syntax**: Look for errors in the log file
|
||||
4. **Check location**: Scripts must be in the configured `ScriptPath` folder
|
||||
|
||||
### Getting Help
|
||||
|
||||
If you encounter issues:
|
||||
|
||||
- **GitHub Issues**: [Report problems](https://github.com/azerothcore/mod-ale/issues)
|
||||
- **Discord**: [Join our community](https://discord.com/invite/bx3y5Qmy)
|
||||
- **AzerothCore Discord**: [Get support](http://www.azerothcore.org/)
|
||||
|
||||
## 📚 Next Steps
|
||||
|
||||
Now that ALE is installed, you're ready to start scripting!
|
||||
|
||||
### Recommended Reading
|
||||
|
||||
1. **[Usage Guide](USAGE.md)** - Learn how to write your first script
|
||||
2. **[Implementation Details](IMPL_DETAILS.md)** - Advanced features and best practices
|
||||
3. **[API Documentation](https://www.azerothcore.org/eluna/)** - Complete API reference
|
||||
4. **[Hooks Reference](https://github.com/azerothcore/mod-ale/blob/master/src/LuaEngine/Hooks.h)** - Available event hooks
|
||||
|
||||
### Example Scripts
|
||||
|
||||
Create a test script to verify everything works:
|
||||
|
||||
**File:** `lua_scripts/test.lua`
|
||||
```lua
|
||||
local function OnServerStartup()
|
||||
print("ALE is working! Server started successfully.")
|
||||
end
|
||||
|
||||
RegisterServerEvent(33, OnServerStartup) -- SERVER_EVENT_ON_CONFIG_LOAD
|
||||
```
|
||||
|
||||
Restart your server and look for the message in the console.
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Acknowledgements
|
||||
|
||||
ALE is built upon the foundation of the [Eluna Lua Engine](https://github.com/ElunaLuaEngine/Eluna). We acknowledge and thank the Eluna team for their pioneering work in Lua scripting for World of Warcraft server emulators.
|
||||
|
||||
- **[Original Eluna Repository](https://github.com/ElunaLuaEngine/Eluna)**
|
||||
- **[Eluna Discord Community](https://discord.gg/bjkCVWqqfX)**
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<sub>Developed with ❤️ by the AzerothCore and ALE community</sub>
|
||||
|
||||
[⬆ Back to Top](#-ale-installation-guide)
|
||||
</div>
|
||||
@@ -0,0 +1,407 @@
|
||||
<div align="center">
|
||||
|
||||
# 🔀 Advanced ALE Integration
|
||||
|
||||
*Customizing and extending ALE for your specific needs*
|
||||
|
||||
[](https://discord.com/invite/ZKSVREE7)
|
||||
[](http://www.azerothcore.org/)
|
||||
|
||||
---
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> ALE is distributed as an AzerothCore module. Unlike traditional forks, you don't need to merge code. However, this guide covers advanced integration scenarios for custom AzerothCore builds.
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Standard Installation](#-standard-installation)
|
||||
- [Custom AzerothCore Builds](#-custom-azerothcore-builds)
|
||||
- [Maintaining Custom Changes](#-maintaining-custom-changes)
|
||||
- [Updating ALE](#-updating-ale)
|
||||
- [Contributing Back](#-contributing-back)
|
||||
- [Troubleshooting](#-troubleshooting)
|
||||
|
||||
## ✅ Standard Installation
|
||||
|
||||
For most users, installing ALE is straightforward:
|
||||
|
||||
```bash
|
||||
# Navigate to modules directory
|
||||
cd <azerothcore-path>/modules
|
||||
|
||||
# Clone ALE
|
||||
git clone https://github.com/azerothcore/mod-ale.git
|
||||
|
||||
# Rebuild AzerothCore
|
||||
cd <azerothcore-build-directory>
|
||||
cmake ../ -DLUA_VERSION=luajit
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> If you're using the standard AzerothCore setup, see the [Installation Guide](INSTALL.md) instead. This guide is for advanced scenarios only.
|
||||
|
||||
## 🔧 Custom AzerothCore Builds
|
||||
|
||||
### Working with Forked AzerothCore
|
||||
|
||||
If you maintain a fork of AzerothCore with custom modifications:
|
||||
|
||||
#### Step 1: Add ALE as a Submodule (Recommended)
|
||||
|
||||
```bash
|
||||
cd <your-azerothcore-fork>
|
||||
|
||||
# Add ALE as a submodule
|
||||
git submodule add https://github.com/azerothcore/mod-ale.git modules/mod-ale
|
||||
|
||||
# Initialize and update
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
# Commit the submodule addition
|
||||
git add .gitmodules modules/mod-ale
|
||||
git commit -m "Add mod-ale as submodule"
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Easy updates with `git submodule update`
|
||||
- Tracks specific ALE versions
|
||||
- Clean separation between your code and ALE
|
||||
|
||||
#### Step 2: Configure Build
|
||||
|
||||
Your CMake configuration should automatically detect the module:
|
||||
|
||||
```bash
|
||||
cd build
|
||||
cmake ../ -DLUA_VERSION=luajit
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
### Alternative: Clone Directly
|
||||
|
||||
If you prefer not to use submodules:
|
||||
|
||||
```bash
|
||||
cd <your-azerothcore-fork>/modules
|
||||
git clone https://github.com/azerothcore/mod-ale.git
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> **Not Recommended:** Avoid adding the `modules/mod-ale` directory to your fork's git repository. It makes updates more difficult.
|
||||
|
||||
Add to your `.gitignore`:
|
||||
```
|
||||
modules/mod-ale/
|
||||
```
|
||||
|
||||
## 🛠️ Maintaining Custom Changes
|
||||
|
||||
### Modifying ALE for Your Server
|
||||
|
||||
If you need to customize ALE:
|
||||
|
||||
#### Option 1: Fork ALE (Recommended)
|
||||
|
||||
1. **Fork the repository** on GitHub
|
||||
2. **Clone your fork** instead of the official repository:
|
||||
```bash
|
||||
cd modules
|
||||
git clone https://github.com/YOUR_USERNAME/mod-ale.git
|
||||
```
|
||||
3. **Make your changes** in a feature branch
|
||||
4. **Keep in sync** with upstream:
|
||||
```bash
|
||||
git remote add upstream https://github.com/azerothcore/mod-ale.git
|
||||
git fetch upstream
|
||||
git merge upstream/master
|
||||
```
|
||||
|
||||
#### Option 2: Patch Files
|
||||
|
||||
For small changes, create patch files:
|
||||
|
||||
```bash
|
||||
# Make your changes to ALE
|
||||
cd modules/mod-ale
|
||||
|
||||
# Create a patch
|
||||
git diff > ../../patches/ale-custom-changes.patch
|
||||
|
||||
# Apply the patch after updating
|
||||
git pull
|
||||
git apply ../../patches/ale-custom-changes.patch
|
||||
```
|
||||
|
||||
### Recommended Approach: Extension Scripts
|
||||
|
||||
Instead of modifying ALE core, create extension scripts:
|
||||
|
||||
**File:** `lua_scripts/extensions/custom_functions.lua`
|
||||
```lua
|
||||
-- Extend existing classes with custom methods
|
||||
function Player:CustomMethod()
|
||||
-- Your custom functionality
|
||||
end
|
||||
|
||||
function Creature:CustomBehavior()
|
||||
-- Your custom functionality
|
||||
end
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- No ALE core modifications needed
|
||||
- Easy to update ALE
|
||||
- Clean separation of custom code
|
||||
- Portable across ALE versions
|
||||
|
||||
## 🔄 Updating ALE
|
||||
|
||||
### Standard Update Process
|
||||
|
||||
For standard installations:
|
||||
|
||||
```bash
|
||||
cd modules/mod-ale
|
||||
git pull
|
||||
cd ../../build
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
### Updating with Submodules
|
||||
|
||||
If you added ALE as a submodule:
|
||||
|
||||
```bash
|
||||
# Update to latest ALE
|
||||
git submodule update --remote modules/mod-ale
|
||||
|
||||
# Or update all submodules
|
||||
git submodule update --remote
|
||||
|
||||
# Commit the update
|
||||
git add modules/mod-ale
|
||||
git commit -m "Update mod-ale to latest version"
|
||||
```
|
||||
|
||||
### Updating with Custom Changes
|
||||
|
||||
If you maintain a fork:
|
||||
|
||||
```bash
|
||||
cd modules/mod-ale
|
||||
|
||||
# Fetch upstream changes
|
||||
git fetch upstream
|
||||
|
||||
# Merge or rebase your changes
|
||||
git merge upstream/master
|
||||
# or
|
||||
git rebase upstream/master
|
||||
|
||||
# Resolve any conflicts
|
||||
# Then rebuild
|
||||
cd ../../build
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
### Version Pinning
|
||||
|
||||
To pin a specific ALE version:
|
||||
|
||||
```bash
|
||||
cd modules/mod-ale
|
||||
|
||||
# List available tags
|
||||
git tag
|
||||
|
||||
# Checkout specific version
|
||||
git checkout v1.2.3
|
||||
|
||||
# Or specific commit
|
||||
git checkout abc123def
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Pin versions in production environments for stability. Use latest in development for new features.
|
||||
|
||||
## 🤝 Contributing Back
|
||||
|
||||
If you've made improvements that could benefit others:
|
||||
|
||||
### Preparing a Contribution
|
||||
|
||||
1. **Ensure it's generic**: Your change should be useful for the broader community
|
||||
2. **Follow coding standards**: See [Contributing Guide](CONTRIBUTING.md)
|
||||
3. **Test thoroughly**: Verify your changes don't break existing functionality
|
||||
4. **Document changes**: Add comments and update documentation
|
||||
|
||||
### Submission Process
|
||||
|
||||
1. **Fork the official repository**
|
||||
2. **Create a feature branch**:
|
||||
```bash
|
||||
git checkout -b feature/my-improvement
|
||||
```
|
||||
3. **Make your changes**
|
||||
4. **Push to your fork**:
|
||||
```bash
|
||||
git push origin feature/my-improvement
|
||||
```
|
||||
5. **Open a Pull Request** on GitHub
|
||||
|
||||
See the [Contributing Guide](CONTRIBUTING.md) for detailed instructions.
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Merge Conflicts
|
||||
|
||||
If you encounter conflicts when updating:
|
||||
|
||||
```bash
|
||||
# Check which files have conflicts
|
||||
git status
|
||||
|
||||
# Edit conflicting files to resolve
|
||||
# Look for conflict markers: <<<<<<<, =======, >>>>>>>
|
||||
|
||||
# Mark as resolved
|
||||
git add <resolved-file>
|
||||
|
||||
# Complete the merge
|
||||
git merge --continue
|
||||
```
|
||||
|
||||
### Module Not Loading
|
||||
|
||||
**Check CMake configuration:**
|
||||
```bash
|
||||
cd build
|
||||
cmake ../ -DLUA_VERSION=luajit
|
||||
```
|
||||
|
||||
Look for output like:
|
||||
```
|
||||
-- ALE module found: /path/to/modules/mod-ale
|
||||
```
|
||||
|
||||
**Verify module directory structure:**
|
||||
```
|
||||
modules/
|
||||
└── mod-ale/
|
||||
├── CMakeLists.txt
|
||||
├── src/
|
||||
│ └── LuaEngine/
|
||||
└── conf/
|
||||
```
|
||||
|
||||
### Build Errors After Update
|
||||
|
||||
**Clean build recommended:**
|
||||
```bash
|
||||
cd build
|
||||
rm -rf *
|
||||
cmake ../ -DLUA_VERSION=luajit
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
### Submodule Issues
|
||||
|
||||
**Submodule not initialized:**
|
||||
```bash
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
**Submodule in detached HEAD state:**
|
||||
```bash
|
||||
cd modules/mod-ale
|
||||
git checkout master
|
||||
git pull
|
||||
```
|
||||
|
||||
## 🎯 Advanced Scenarios
|
||||
|
||||
### Multiple ALE Versions
|
||||
|
||||
Testing with different ALE versions:
|
||||
|
||||
```bash
|
||||
# Clone to different directories
|
||||
cd modules
|
||||
git clone https://github.com/azerothcore/mod-ale.git mod-ale-stable
|
||||
git clone https://github.com/azerothcore/mod-ale.git mod-ale-dev
|
||||
|
||||
# Switch between them
|
||||
ln -sf mod-ale-stable mod-ale # Use stable
|
||||
ln -sf mod-ale-dev mod-ale # Use dev
|
||||
```
|
||||
|
||||
### Custom Lua Version
|
||||
|
||||
Using a custom Lua installation:
|
||||
|
||||
```bash
|
||||
cmake ../ \
|
||||
-DLUA_VERSION=custom \
|
||||
-DLUA_INCLUDE_DIR=/path/to/lua/include \
|
||||
-DLUA_LIBRARIES=/path/to/lua/lib/liblua.a
|
||||
```
|
||||
|
||||
### Automated Updates
|
||||
|
||||
Create an update script:
|
||||
|
||||
**File:** `scripts/update-ale.sh`
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
cd modules/mod-ale || exit 1
|
||||
|
||||
echo "Fetching latest ALE..."
|
||||
git fetch upstream
|
||||
|
||||
echo "Current version: $(git rev-parse --short HEAD)"
|
||||
echo "Latest version: $(git rev-parse --short upstream/master)"
|
||||
|
||||
read -p "Update to latest? (y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
git merge upstream/master
|
||||
cd ../../build
|
||||
make -j$(nproc)
|
||||
echo "ALE updated successfully!"
|
||||
fi
|
||||
```
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- **[Installation Guide](INSTALL.md)** - Standard installation process
|
||||
- **[Contributing Guide](CONTRIBUTING.md)** - How to contribute changes
|
||||
- **[Usage Guide](USAGE.md)** - Getting started with scripting
|
||||
- **[AzerothCore Documentation](http://www.azerothcore.org/)** - Core documentation
|
||||
|
||||
### Getting Help
|
||||
|
||||
- **GitHub Issues**: [Report problems](https://github.com/azerothcore/mod-ale/issues)
|
||||
- **Discord**: [Join our community](https://discord.com/invite/bx3y5Qmy)
|
||||
- **AzerothCore Discord**: [Get support](http://www.azerothcore.org/)
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Acknowledgements
|
||||
|
||||
ALE is built upon the foundation of the [Eluna Lua Engine](https://github.com/ElunaLuaEngine/Eluna). We acknowledge and thank the Eluna team for their pioneering work in Lua scripting for World of Warcraft server emulators.
|
||||
|
||||
- **[Original Eluna Repository](https://github.com/ElunaLuaEngine/Eluna)**
|
||||
- **[Eluna Discord Community](https://discord.gg/bjkCVWqqfX)**
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<sub>Developed with ❤️ by the AzerothCore and ALE community</sub>
|
||||
|
||||
[⬆ Back to Top](#-advanced-ale-integration)
|
||||
</div>
|
||||
@@ -0,0 +1,279 @@
|
||||
<div align="center">
|
||||
|
||||
# 📖 ALE Usage Guide
|
||||
|
||||
*Learn how to create powerful Lua scripts for your AzerothCore server*
|
||||
|
||||
[](https://discord.com/invite/ZKSVREE7)
|
||||
[](http://www.lua.org/manual/5.2/)
|
||||
|
||||
---
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This guide is for **ALE (AzerothCore Lua Engine)**, which is specifically designed for AzerothCore. Scripts and APIs may differ from other Lua engines.
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Prerequisites](#-prerequisites)
|
||||
- [Your First Script](#-your-first-script)
|
||||
- [Lua Basics](#-lua-basics)
|
||||
- [ALE Basics](#-ale-basics)
|
||||
- [Script Reloading](#-script-reloading)
|
||||
- [Getting Help](#-getting-help)
|
||||
|
||||
## ✅ Prerequisites
|
||||
|
||||
This guide assumes you have already installed ALE successfully. If you have not, see the [Installation Guide](INSTALL.md) or the [Installation section](../README.md#-installation) in the README.
|
||||
|
||||
## 🚀 Your First Script
|
||||
|
||||
Let's create a simple "Hello World" script to get you started.
|
||||
|
||||
### Creating the Script File
|
||||
|
||||
Create a file named `hello_world.lua` in your scripts folder. By default, this folder is called `lua_scripts` and is located in your server folder (the folder containing server executables).
|
||||
|
||||
```lua
|
||||
local PLAYER_EVENT_ON_LOGIN = 3
|
||||
|
||||
local function OnLogin(event, player)
|
||||
player:SendBroadcastMessage("Hello world from ALE!")
|
||||
end
|
||||
|
||||
RegisterPlayerEvent(PLAYER_EVENT_ON_LOGIN, OnLogin)
|
||||
```
|
||||
|
||||
### Running the Script
|
||||
|
||||
1. Restart your AzerothCore server
|
||||
2. Log in to the game
|
||||
3. You should see "Hello world from ALE!" in your chat
|
||||
|
||||
### What Just Happened?
|
||||
|
||||
No core compiling was needed! Your script runs directly from the file you created.
|
||||
|
||||
Here's what the script does:
|
||||
- The file is compiled and run by the Lua engine when the server starts
|
||||
- The code registers a function to be executed when a player logs in
|
||||
- When the event triggers, the function sends a message to the player
|
||||
|
||||
## 📚 Lua Basics
|
||||
|
||||
Before diving deep into ALE scripting, it's helpful to understand some Lua fundamentals.
|
||||
|
||||
### Learning Resources
|
||||
|
||||
- **Lua Users Wiki**
|
||||
- [Lua Directory](http://lua-users.org/wiki/LuaDirectory)
|
||||
- [Tutorial Directory](http://lua-users.org/wiki/TutorialDirectory)
|
||||
- [Sample Code](http://lua-users.org/wiki/SampleCode)
|
||||
- **[Programming in Lua](http://www.lua.org/pil/1.html)** - Comprehensive guide
|
||||
- **[Lua 5.2 Reference Manual](http://www.lua.org/manual/5.2/)** - Official documentation
|
||||
|
||||
### Essential Concepts
|
||||
|
||||
#### Debugging with Print
|
||||
|
||||
The `print()` function outputs to the server console - perfect for debugging:
|
||||
|
||||
```lua
|
||||
print("Debug message here")
|
||||
print("Player name:", player:GetName())
|
||||
```
|
||||
|
||||
#### Control Structures
|
||||
|
||||
Learn about loops and conditionals:
|
||||
- [Control Structure Tutorial](http://lua-users.org/wiki/ControlStructureTutorial)
|
||||
- [Lua Manual - Control Structures](http://www.lua.org/manual/5.2/manual.html#3.3.5)
|
||||
|
||||
#### String Manipulation
|
||||
|
||||
Essential for text processing:
|
||||
- [String Library Tutorial](http://lua-users.org/wiki/StringLibraryTutorial)
|
||||
- [Pattern Matching](http://www.wowwiki.com/Pattern_matching)
|
||||
|
||||
#### Tables
|
||||
|
||||
Tables are Lua's only data structure (arrays and hash maps combined):
|
||||
- [Table Functions](http://www.lua.org/manual/5.2/manual.html#6.5)
|
||||
- [Table Semantics](http://www.lua.org/manual/5.2/manual.html#4.3)
|
||||
- [Tables Tutorial](http://lua-users.org/wiki/TablesTutorial)
|
||||
- [Programming in Lua - Tables](http://www.lua.org/pil/2.5.html)
|
||||
|
||||
#### Variable Scope
|
||||
|
||||
**Important:** Prefer local variables over global variables!
|
||||
|
||||
```lua
|
||||
-- Good: Local variable
|
||||
local playerName = "John"
|
||||
|
||||
-- Avoid: Global variable
|
||||
playerName = "John"
|
||||
```
|
||||
|
||||
Global variables can create conflicts with other scripts. Local variables outside functions are shared within the same script file (locally global).
|
||||
|
||||
## ⚡ ALE Basics
|
||||
|
||||
### Documentation Resources
|
||||
|
||||
- **[ALE API Documentation](https://www.azerothcore.org/eluna/)** - Complete API reference
|
||||
- **[Hooks Documentation](https://github.com/azerothcore/mod-ale/blob/master/src/LuaEngine/Hooks.h)** - Available event hooks
|
||||
- **[Implementation Details](IMPL_DETAILS.md)** - Advanced features and best practices
|
||||
|
||||
### Error Messages
|
||||
|
||||
ALE outputs errors to:
|
||||
- Server console (real-time)
|
||||
- Log file in the server folder (persistent)
|
||||
|
||||
If your script doesn't work, check the log file for errors. You can configure logging settings in the server configuration file.
|
||||
|
||||
### Global Functions
|
||||
|
||||
Global functions can be called from anywhere without requiring an object.
|
||||
|
||||
Besides standard Lua functions like `print()`, ALE provides its own global functions. Find them in the documentation under the `Global` class: [Global Functions](https://www.azerothcore.org/eluna/Global/index.html).
|
||||
|
||||
```lua
|
||||
-- Example: Get the Lua engine name
|
||||
print(GetLuaEngine())
|
||||
|
||||
-- Example: Get current game time
|
||||
local time = GetGameTime()
|
||||
```
|
||||
|
||||
### Member Functions (Methods)
|
||||
|
||||
Methods require a userdata object to run. Different object types (Player, Creature, GameObject, etc.) have different available methods.
|
||||
|
||||
#### Class Inheritance
|
||||
|
||||
Classes inherit from each other. For example:
|
||||
- `Player` and `Creature` both inherit from `Unit`
|
||||
- This means both players and creatures can use `Unit` methods
|
||||
|
||||
#### Calling Methods
|
||||
|
||||
Use the `:` notation to call methods on objects:
|
||||
|
||||
```lua
|
||||
-- Get player name
|
||||
local name = player:GetName()
|
||||
|
||||
-- Get creature level
|
||||
local level = creature:GetLevel()
|
||||
```
|
||||
|
||||
#### Example: Creature Combat Script
|
||||
|
||||
```lua
|
||||
local entry = 6 -- Creature entry ID
|
||||
local on_combat = 1 -- Event ID for combat start
|
||||
|
||||
local function OnCombat(event, creature, target)
|
||||
-- creature is of type Creature
|
||||
-- target is of type Creature or Player
|
||||
|
||||
print("Creature level:", creature:GetLevel())
|
||||
print("Target level:", target:GetLevel())
|
||||
|
||||
creature:SendUnitYell("You dare challenge me?!", 0)
|
||||
end
|
||||
|
||||
RegisterCreatureEvent(entry, on_combat, OnCombat)
|
||||
```
|
||||
|
||||
### Registering Event Handlers
|
||||
|
||||
Scripts work by registering functions to events. When the event occurs, your function executes.
|
||||
|
||||
#### Finding Register Functions
|
||||
|
||||
Search for "register" in the [ALE documentation](https://www.azerothcore.org/eluna/) to find all available register functions:
|
||||
- `RegisterPlayerEvent`
|
||||
- `RegisterCreatureEvent`
|
||||
- `RegisterServerEvent`
|
||||
- And many more...
|
||||
|
||||
#### Event IDs
|
||||
|
||||
Each register function requires an event ID. Find these IDs in the function's documentation page.
|
||||
|
||||
#### Function Parameters
|
||||
|
||||
ALE automatically passes parameters to your registered functions. The parameters are always in the same order, but you can name them anything you want.
|
||||
|
||||
Example: `PLAYER_EVENT_ON_LOGIN` passes:
|
||||
1. Event ID (number)
|
||||
2. Player object (Player)
|
||||
|
||||
```lua
|
||||
local function OnLogin(event, player)
|
||||
-- event = event ID number
|
||||
-- player = Player object
|
||||
end
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
Some events allow your function to return values to modify behavior. Check the event's documentation to see what can be returned.
|
||||
|
||||
```lua
|
||||
local function OnChat(event, player, msg, type, lang)
|
||||
if msg == "blocked" then
|
||||
return false -- Blocks the chat message
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## 🔄 Script Reloading
|
||||
|
||||
For quick testing during development, you can reload scripts without restarting:
|
||||
|
||||
```
|
||||
.reload ale
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> **Development Only:** Use `.reload ale` only for development. For production or if experiencing issues, always restart the server.
|
||||
|
||||
**Important Limitations:**
|
||||
- Reloading doesn't trigger events like login for already-connected players
|
||||
- Some state may not reset properly
|
||||
- Always do final testing with a full server restart
|
||||
|
||||
## 💬 Getting Help
|
||||
|
||||
### Support Channels
|
||||
|
||||
- **GitHub Issues**: [Report bugs or request features](https://github.com/azerothcore/mod-ale/issues)
|
||||
- **Discord Community**: [Join our Discord server](https://discord.com/invite/bx3y5Qmy)
|
||||
- **AzerothCore Discord**: [Official AzerothCore support](http://www.azerothcore.org/)
|
||||
|
||||
### Additional Resources
|
||||
|
||||
- [Lua Programming Guide](http://www.lua.org/)
|
||||
- [AzerothCore Documentation](http://www.azerothcore.org/)
|
||||
- [Implementation Details](IMPL_DETAILS.md) - Advanced ALE features
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Acknowledgements
|
||||
|
||||
ALE is built upon the foundation of the [Eluna Lua Engine](https://github.com/ElunaLuaEngine/Eluna). We acknowledge and thank the Eluna team for their pioneering work in Lua scripting for World of Warcraft server emulators.
|
||||
|
||||
- **[Original Eluna Repository](https://github.com/ElunaLuaEngine/Eluna)**
|
||||
- **[Eluna Discord Community](https://discord.gg/bjkCVWqqfX)**
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<sub>Developed with ❤️ by the AzerothCore and ALE community</sub>
|
||||
|
||||
[⬆ Back to Top](#-ale-usage-guide)
|
||||
</div>
|
||||
Reference in New Issue
Block a user