Ritual Procedure Guide
Ritual scripts look like Spell scripts from the outside, but their resolution does several Summon-procedure jobs at once: find a Ritual Monster, check that materials can be used for that exact monster, make the material total legal, move the materials, Special Summon with SUMMON_TYPE_RITUAL, and mark the monster as properly Summoned.
Most ordinary Ritual Spells should start with the local helpers in procedure.lua. Manual Ritual scripts are still important, but they are for card text that changes the material source, Summons more than one monster, sends materials instead of releasing them, or applies extra behavior that does not fit the helper.
For a guided walkthrough of monster choice, material-selection cancellation, alternate locations, and optional follow-ups, read Ritual Summon Choices.
Helper Or Manual Script
| Need | Local pattern |
|---|---|
| A named Ritual Spell that can Ritual Summon one listed monster with equal-or-higher material Levels. | Use aux.AddRitualProcGreaterCode. |
| A Ritual Spell that can Ritual Summon a filtered group of Ritual Monsters with equal-or-higher material Levels. | Use aux.AddRitualProcGreater. |
| A Ritual Spell that needs the material total to exactly equal the Ritual Monster's Level. | Use aux.AddRitualProcEqual or aux.AddRitualProcEqualCode. |
| A Ritual Spell that checks the Ritual Monster's current Level instead of original Level. | Use the 2 variants, such as aux.AddRitualProcGreater2 or aux.AddRitualProcEqual2. |
| A Ritual Spell that needs Graveyard extras, material filters, delayed registration, or post-Summon work. | Use aux.AddRitualProcUltimate directly or through one of the wrappers. |
| A Ritual Spell that sends Extra Deck material, Summons multiple monsters, or uses a custom resource such as ATK instead of Level. | Write a manual target and operation, usually copying the shape of a close local script. |
The wrappers are thin. They choose a Level function, choose exact vs greater-or-equal checking, and pass the rest to Auxiliary.AddRitualProcUltimate.
Small Helper Examples
The simplest local Ritual Spell is a one-line procedure. Doriado's Blessing (c23965037.lua) registers an equal-or-higher Ritual Summon for one monster code:
function c23965037.initial_effect(c)
aux.AddRitualProcGreaterCode(c,99414168)
endThat one call creates the activation effect, checks hand material, checks field material, asks the player to choose a matching Ritual Monster, releases the selected materials, and Special Summons the monster as a Ritual Summon.
Super Soldier Ritual (c14094090.lua) uses a filter instead of a single listed code, and requires exact Levels:
function c14094090.initial_effect(c)
aux.AddRitualProcEqual(c,c14094090.ritual_filter)
end
function c14094090.ritual_filter(c)
return c:IsType(TYPE_RITUAL) and c:IsSetCard(0x10cf)
endRecette de Viande (c14166715.lua) shows a helper with post-Summon behavior. The local script uses AddRitualProcGreater2, checks the Ritual Monster's current Level, and passes an extra_operation callback:
aux.AddRitualProcGreater2(c,s.filter,LOCATION_HAND,nil,nil,false,s.extraop)Use that last style when the Ritual Summon itself is standard and the card has follow-up work. The callback can receive a missing tc or mat when no monster was selected, so keep the source callback's guards. Callback invocation alone does not report whether Duel.SpecialSummon succeeded.
What The Main Helper Builds
Auxiliary.AddRitualProcUltimate creates a normal Spell activation effect:
local e1=Effect.CreateEffect(c)
e1:SetCategory(CATEGORY_SPECIAL_SUMMON)
e1:SetType(EFFECT_TYPE_ACTIVATE)
e1:SetCode(EVENT_FREE_CHAIN)
e1:SetTarget(Auxiliary.RitualUltimateTarget(...))
e1:SetOperation(Auxiliary.RitualUltimateOperation(...))
c:RegisterEffect(e1)The local helper defaults summon_location to LOCATION_HAND. That means a plain helper Ritual Spell looks for the Ritual Monster in your hand unless a script passes another location.
The important arguments are:
| Argument | Meaning |
|---|---|
filter | Which Ritual Monsters this Spell can Summon. Code wrappers build this from Card.IsCode. |
level_function | Which value the material total is compared against, usually Card.GetOriginalLevel or Card.GetLevel. |
greater_or_equal | "Greater" for equal-or-higher material totals, "Equal" for exact totals. |
summon_location | Where the Ritual Monster may be selected from. Defaults to hand. |
grave_filter | Optional extra GY material group. The helper merges it into the material pool and later uses Ritual-material movement rules. |
mat_filter | Optional filter applied to the material pool before selection. |
pause | If true, the helper returns the effect without registering it. Scripts can adjust or clone it first. |
extra_target | Optional callback for activation-time announcements/bookkeeping, after chk==0 has returned; it cannot add a legality test to that branch. |
extra_operation | Optional callback after the main operation block; guard tc/mat because a selection may be missing. |
Target Branch
The target branch answers "can this Ritual Spell legally be activated now?"
The local helper follows this shape:
- Collect basic Ritual Materials with
Duel.GetRitualMaterial(tp). - Optionally filter that material group with
mat_filter. - Optionally collect extra GY materials with
grave_filter. - Search for a Ritual Monster that passes
Auxiliary.RitualUltimateFilter. - Set operation info for
CATEGORY_SPECIAL_SUMMON, andCATEGORY_REMOVEif GY material will be banished by the Ritual material flow. - Run
extra_targetif the script supplied one.
Auxiliary.RitualUltimateFilter checks more than the visible card name. It requires a Ritual Monster, applies the script's filter, checks Card.IsCanBeSpecialSummoned with SUMMON_TYPE_RITUAL, filters materials through Card.IsCanBeRitualMaterial, and then verifies that some subgroup can satisfy the required material total.
Because this is only the target branch, it should not move cards. It only proves that the action is currently possible and records public Chain information.
Material Checks
The material group from Duel.GetRitualMaterial is only the starting pool. After a Ritual Monster is chosen, the script must still filter by that monster:
mg=mg:Filter(Card.IsCanBeRitualMaterial,tc,tc)
if tc.mat_filter then
mg=mg:Filter(tc.mat_filter,tc,tp)
else
mg:RemoveCard(tc)
endThat local pattern prevents materials that are blocked for the chosen Ritual Monster from appearing in the final selection. The helper also respects a Ritual Monster's optional mat_filter and mat_group_check callbacks when scripts define them.
The material total is checked with Group helpers:
| Helper mode | Local check |
|---|---|
| Greater-or-equal | Group.CheckWithSumGreater over Card.GetRitualLevel. |
| Exact | Group.CheckWithSumEqual over Card.GetRitualLevel. |
| Player selection | Group.SelectSubGroup with Auxiliary.RitualCheck. |
Card.GetRitualLevel is used for the material cards. The helper's level_function is used for the Ritual Monster being Summoned. That is why AddRitualProcGreater and AddRitualProcEqual use the Ritual Monster's original Level, while the 2 variants use its current Level.
Local procedure.lua also handles cards with additional Ritual material Levels. Those extra Level values are stored in the high and low halves of the GetRitualLevel result. You usually do not unpack that value yourself; let the helper's RitualCheckAdditional logic do it unless you are writing a special manual procedure.
Operation Branch
The operation branch repeats the important checks because the game state may have changed while the Chain waited to resolve. The local helper re-collects materials, asks the player to choose the Ritual Monster, filters the material pool for that monster, lets the player choose a legal subgroup, and then performs the Summon:
tc:SetMaterial(mat)
Duel.ReleaseRitualMaterial(mat)
Duel.BreakEffect()
Duel.SpecialSummon(tc,SUMMON_TYPE_RITUAL,tp,tp,false,true,POS_FACEUP)
tc:CompleteProcedure()The order matters:
Card.SetMaterialrecords which cards were used as material.Duel.ReleaseRitualMaterialmoves standard Ritual Materials with Ritual-specific handling.Duel.BreakEffectseparates the material movement and summon in effect timing, rather than creating a cosmetic pause.Duel.SpecialSummonusesSUMMON_TYPE_RITUAL.Card.CompleteProceduremarks the Ritual Monster as properly Summoned.
For multi-Summon procedures, local scripts use Duel.SpecialSummonStep and Duel.SpecialSummonComplete instead of one direct Duel.SpecialSummon call.
Manual Ritual Scripts
Manual Ritual scripts should still look like the helper internally:
function s.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then
local mg=Duel.GetRitualMaterial(tp)
return Duel.IsExistingMatchingCard(aux.RitualUltimateFilter,tp,
LOCATION_HAND,0,1,nil,s.ritual_filter,e,tp,mg,nil,
Card.GetLevel,"Greater")
end
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,nil,1,tp,LOCATION_HAND)
end
function s.activate(e,tp,eg,ep,ev,re,r,rp)
::choose_again::
local mg=Duel.GetRitualMaterial(tp)
local tg=Duel.SelectMatchingCard(tp,aux.RitualUltimateFilter,tp,
LOCATION_HAND,0,1,1,nil,s.ritual_filter,e,tp,mg,nil,
Card.GetLevel,"Greater")
local tc=tg:GetFirst()
if not tc then return end
mg=mg:Filter(Card.IsCanBeRitualMaterial,tc,tc)
if tc.mat_filter then
mg=mg:Filter(tc.mat_filter,tc,tp)
end
local lv=tc:GetLevel()
aux.GCheckAdditional=aux.RitualCheckAdditional(tc,lv,"Greater")
local mat=mg:SelectSubGroup(tp,aux.RitualCheck,true,1,lv,tp,tc,lv,"Greater")
aux.GCheckAdditional=nil
if not mat then goto choose_again end
tc:SetMaterial(mat)
Duel.ReleaseRitualMaterial(mat)
Duel.BreakEffect()
if Duel.SpecialSummonStep(tc,SUMMON_TYPE_RITUAL,tp,tp,false,true,POS_FACEUP) then
tc:CompleteProcedure()
end
Duel.SpecialSummonComplete()
endThis is a bounded callback template using the local Sonic Tracker pattern; the surrounding script must define s.ritual_filter. Cancelling the material selection returns to monster choice instead of cancelling the resolving effect. It is useful when a card needs to change the Ritual Monster after selection, store material values, or apply a lasting effect to the Summoned monster.
When you write a manual procedure, keep the target branch and operation branch in sync. A common beginner mistake is to prove one material rule in target, then use a slightly different rule in activate.
Nonstandard Material Movement
Not every Ritual Spell releases every material. Nekroz Kaleidoscope (c51124303.lua) can use a monster from the Extra Deck as the full material. The local script checks the Extra Deck card as Ritual Material, records it with SetMaterial, then sends it to the GY with Ritual material reason flags instead of calling Duel.ReleaseRitualMaterial:
tc:SetMaterial(mat)
if not mc:IsLocation(LOCATION_EXTRA) then
Duel.ReleaseRitualMaterial(mat)
else
Duel.SendtoGrave(mat,REASON_EFFECT+REASON_MATERIAL+REASON_RITUAL)
end
Duel.BreakEffect()
Duel.SpecialSummon(tc,SUMMON_TYPE_RITUAL,tp,tp,false,true,POS_FACEUP)
tc:CompleteProcedure()That is a card-specific movement rule, not the default Ritual procedure. For a normal Ritual Spell, use Duel.ReleaseRitualMaterial.
Drytron-style scripts are another reason to go manual. The local scripts use Duel.GetRitualMaterialEx and an ATK based value helper so material adequacy is not only "sum Levels." Treat those as advanced templates and copy from a close local card when the printed text is similar.
Summon Type And Later Effects
The Summon call should use SUMMON_TYPE_RITUAL. Other effects can then check Card.IsSummonType to ask whether the monster was Ritual Summoned.
The local core also maps SUMMON_TYPE_RITUAL to REASON_RITUAL for material events. That matters for cards that care how they became material.
CompleteProcedure is separate from SUMMON_TYPE_RITUAL. The Summon type says what kind of Summon happened; CompleteProcedure marks the monster's proper Summon procedure as complete for later rule checks.
Common Pitfalls
| Mistake | Better habit |
|---|---|
Using Duel.GetRitualMaterial and immediately selecting from it. | Filter the group with Card.IsCanBeRitualMaterial after the Ritual Monster is known. |
Using Duel.Release for ordinary Ritual Materials. | Use Duel.ReleaseRitualMaterial so Ritual material movement rules apply. |
Forgetting SetMaterial. | Call tc:SetMaterial(mat) before moving the materials. |
Forgetting CompleteProcedure. | Call tc:CompleteProcedure() after the Ritual Summon succeeds. |
Checking only material Levels in target. | Also check a Summonable Ritual Monster, Monster Zone availability, and the chosen monster's material restrictions. |
| Mixing original-Level and current-Level helpers accidentally. | Use non-2 helpers for original Level, 2 helpers for current Level. |
| Copying a manual Ritual script without the operation recheck. | Rebuild the material group and confirm the chosen cards are still legal at resolution. |
| Letting the Ritual Monster become its own material by accident. | Follow the helper pattern: apply tc.mat_filter when present, otherwise remove tc from the material group. |
Useful API Pages
Auxiliary.AddRitualProcUltimateAuxiliary.AddRitualProcGreaterAuxiliary.AddRitualProcGreaterCodeAuxiliary.AddRitualProcEqualAuxiliary.AddRitualProcEqualCodeAuxiliary.RitualUltimateFilterDuel.GetRitualMaterialDuel.GetRitualMaterialExDuel.ReleaseRitualMaterialCard.IsCanBeRitualMaterialCard.GetRitualLevelCard.SetMaterialCard.CompleteProcedureDuel.SpecialSummonDuel.SpecialSummonStepDuel.SpecialSummonCompleteGroup.CheckWithSumEqualGroup.CheckWithSumGreaterGroup.SelectSubGroup