Thank you for your interest in contributing to Aesir! This document outlines the development workflow using Jujutsu (jj) version control system, coding standards, and best practices for contributing to this Ragnarok Online server emulator.
Aesir uses Jujutsu (jj) backed by Git for version control. Jujutsu provides a more intuitive and powerful version control experience compared to traditional Git workflows.
-
Install Jujutsu: Follow the installation instructions at https://jj-vcs.github.io/jj/latest/install/
-
Clone the repository:
jj git clone https://github.com/ygorcastor/aesir.git cd aesir -
Set up the development environment:
mix deps.get mix compile
Before starting work on a new feature or bug fix:
# Create a new change for your feature
jj new -m "feat: implement new feature description"
# Alternatively, create a bookmark for easier tracking
jj bookmark create feature/your-feature-nameJujutsu treats the working directory as a commit, making development more fluid:
# View current status
jj log
# Make your code changes...
# View what you've changed
jj diff
# Add a meaningful commit message to your change
jj describe -m "feat: detailed description of what you implemented
- Added new packet handler for login flow
- Implemented session validation
- Updated tests for edge cases"
# Continue making changes in the same commit or create a new one
jj new -m "fix: address review feedback"Use Jujutsu's powerful editing features to maintain clean history:
# Combine multiple commits into one
jj squash -r <commit-id>
# Edit a previous commit
jj edit <commit-id>
# Make changes, then return to working copy
jj edit @
# Rebase changes interactively
jj rebase -i -d master
# View operation history (useful for undoing mistakes)
jj op log
# Undo the last operation if needed
jj undoBefore submitting your changes, ensure code quality:
# Format code
mix format
# Run linting
mix credo --strict
# Run tests
mix test
# Run all quality checks
mix format && mix credo --strict && mix testWhen your feature is ready:
# Ensure your changes are on top of latest master
jj rebase -d master
# Create a clean, descriptive commit message
jj describe -m "feat: implement character movement validation
This commit adds comprehensive validation for character movement
packets to prevent cheating and ensure proper game mechanics:
- Added position validation against map boundaries
- Implemented speed checks to prevent teleporting
- Added unit tests with 95% coverage
- Updated documentation for packet handlers
Closes #123"
# Push to your fork
jj git push --remote origin --branch your-feature-name- Formatting: Always run
mix formatbefore committing. The project uses a.formatter.exsconfiguration. - Linting: Follow all Credo rules. Run
mix credo --strictto ensure compliance. - Documentation: Add
@moduledocand@docto all public modules and functions. - Typespecs: Add
@specannotations to all public functions. - Testing: Write comprehensive tests with good coverage for all new functionality.
- Use
snake_casefor variables, functions, and atoms - Use
CamelCasefor module names - Use descriptive names that clearly indicate purpose
- Prefix test modules with the module being tested plus
Test
- Use
{:ok, result}and{:error, reason}pattern for function returns - Prefer
withstatements for complex logic paths over nested case statements - Document all possible error conditions in function specs
- Avoid raising exceptions for normal control flow
When implementing new packet handlers:
- Create packet modules in the appropriate server app under
lib/packets/ - Follow the packet pattern:
defmodule MyServer.Packets.MyPacket do use Aesir.Commons.Network.Packet @packet_id 0x1234 @packet_size 24 defstruct [:field1, :field2] @impl true def packet_id, do: @packet_id @impl true def packet_size, do: @packet_size @impl true def parse(data), do: # implementation @impl true def build(packet), do: # implementation end
- Register packets in the appropriate packet registry
- Add comprehensive tests including malformed packet handling
- Use Ecto schemas with proper validations
- Add comprehensive changesets for data integrity
- Include database constraints where appropriate
- Write migration scripts for any schema changes
- Always validate sessions before processing authenticated requests
- Use the SessionManager module for all session operations
- Handle distributed session scenarios properly
- Clean up sessions on user disconnect
- Use the appropriate test case:
ExUnit.Case,Aesir.DataCase, orAesir.Commons.MementoTestHelper - Follow AAA pattern: Arrange, Act, Assert
- Use descriptive test names that explain the scenario being tested
- Group related tests using
describeblocks
- Aim for high test coverage, especially for critical paths
- Test both happy path and error conditions
- Include edge cases and boundary conditions
- Mock external dependencies appropriately using
Mimic
defmodule Aesir.AccountServer.PacketHandlerTest do
use ExUnit.Case, async: true
import Mimic
alias Aesir.AccountServer.PacketHandler
setup :verify_on_exit!
describe "handle_login_packet/1" do
test "successfully processes valid login packet" do
# Arrange
packet = %LoginPacket{username: "testuser", password: "password"}
stub(SessionManager, :create_session, fn _, _ -> {:ok, "session123"} end)
# Act
result = PacketHandler.handle_login_packet(packet)
# Assert
assert {:ok, %LoginResponsePacket{success: true}} = result
end
test "rejects login with invalid credentials" do
# Test implementation...
end
end
end- Use the
rathena.xmlfile as the primary reference for mechanics implementation - Focus on Renewal mechanics unless specifically implementing pre-Renewal features
- Verify formulas and calculations against rAthena source code
- Document any deviations or simplifications from official mechanics
- Correctness: Ensure mechanics work as intended in the official game
- Security: Validate all client input to prevent cheating
- Performance: Consider the impact on server performance, especially for frequently used systems
- Maintainability: Write clear, well-documented code that other developers can understand
Use conventional commit format:
type(scope): subject
body
footer
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Build process, tooling changes
feat(zone): implement player movement validation
Add comprehensive validation for character movement packets to prevent
speed hacking and teleportation exploits.
- Validate movement speed against character stats
- Check path validity on server side
- Add integration tests for movement system
Closes #123
- Documentation: Check the project's README and code documentation
- Issues: Search existing GitHub issues before creating new ones
- Discussions: Use GitHub Discussions for questions and general discussion
- Code Review: Be open to feedback and iterate on your changes
- Self-review: Review your own code before requesting review
- Quality checks: Ensure all tests pass and code is properly formatted
- Documentation: Update relevant documentation if needed
- Small changes: Keep pull requests focused and reasonably sized
- Responsiveness: Respond to review feedback promptly
Thank you for contributing to Aesir! 🎮