How Can We Help?
Preface
While this documentation is for implementing New Triggers to Mugen 1.1a4, 1.1A4 and 1.0 mostly only differ by ASM addresses
Trigger Return Type FAQ
When you use a Trigger the game guarantees that it will return either an Integer or a Float when evaluated.
1. If you supply an Integer where a Float is expected, the engine automatically converts it to a float (1 > 1.00~)
2. If you supply a Float where an Integer is expected, the game will Truncate/Floor/Round Down the Float Value into an Integer.
3. The special case of FVar takes an Integer Argument (Float Variable Index) and returns a Float number.
2 Return Type and Free Type Writing
With this clarified, we need to be able to return an Integer for some (most) custom triggers, and a float for for the rest.
For Read Triggers, returning the Proper Type
For Write Triggers, write the Proper Type, and return the write value.
Normally, the type of number you write to an address must also be the type of number that is returned, however, this takes away user freedoms
Therefore conversions will be allowed
1. Supplying an Floating Number and writing to an Integer Address
This in effect will write a huge unpredictable value
And also return that value
Keep this in mind before you try to use floats for Integer Writing
2. Supplying an Integer Number and writing to Float Address
This will often Write and Return NaN/Invalid Float numbers
I do not personally see a reason to do so, but I will allow it.
Later on there will be official documentation about Return and Write Types
For each trigger though most are obvious.
4 Type Variants
For New Triggers, there are basically 4 types/variants
Read Only (Integer)
Read Only (Float)
Write (Integer)
Write (Float)
ParseTime Recognition and Building
Add New Triggers (strings) into custom game area
These triggers do not include the parentheses themselves due to how they are handled
Set the Trigger Code (ESI+0x0C) to the appropriate 4 type variant
However note that Reading floats is harder so it borrows the Writing function
That means the 4 type variants are implemented as 3 types of functions.
In Mugen 11A4
Var = 0x157 (Write Integer)
FVar = 0x158 (Read/Write Floats)
Life = 0x00F (Read Integer)
Afterwards, set custom identifier to differentiate these custom triggers from normal triggers
These areas have been observed to be unused across multiple tests
0x04 = Base
0x08 = Offset
0x0C = Borrowed Type
Base refers to the starting address
Player, GameArea, or Custom Handling
0x04 = 1 (Player > Read Int / Read Float)
0x04 = 2 (Player > Write Int / Write Float)
0x04 = 3 (Game > Read Int / Read Float)
0x04 = 4 (Game > Write Int / Write Float)
Note that Reading and Writing floats both use same function
That is why each Starting Address type needs 2 variants
So that in the middle of FVar() it can skip over writing or not.
(Reading Int is Life and Writing Int is Var())
(Reading Float is FVar() and Writing Float is FVar())
0x04 = 5+ (Custom)
There are unlimited values of 5 and above for custom handling
For special cases like Reading/Writing Sprite/Animation data.
However note each Custom Behaviour will still require 2 identifiers
Since any custom Read/Write area is considered its own Base.
Offset is Base+Difference that is used to Read from or Write to.
As shown previously, the Player Offset of 0x4 is their ID, and the Game Offset of 0x12754 is the RoundState
For custom types, Offset can actually be determined by the argument provided, this means that certain Read triggers are parenthesized
After this, we have a fake trigger with custom identifier that lets us differentiate them at RunTime
Runtime Borrowing Existing Functions
[Integer Player]
mugen.exe+56F3B mov ebp,[ebx+04]
mugen.exe+56F3E jmp mugen.exe+57CE2
[Integer Game]
mugen.exe+5704D mov ebp,[edx+00012754]
mugen.exe+57053 jmp mugen.exe+57CE2
So to return Integer Values
1.Set up a custom mov ebp[x+Offset]
2. JMP to 57CE2.
[Float Player]/[Float Game] is not as simple
So we will use the writing function (without writing) according to the special type
Int Writing and Float Read/Writing
In order to write to an address, we have to first enable a trigger to take arguments, this means a trigger followed by Parenthesis()
And this argument must also support max allowed recursion
(Custom triggers inside Custom triggers)
For this, we are going to borrow/customize the functionality of
Variable Reading (Var(x) and FVar(x))
Allowing Floats for Custom Triggers
- At floating value conversion, jump to 0x04 comparison area
- If 0x04 does not equal 0, do not Floor the number
- Otherwise if it does equal 0, floor the number if necessary.
mugen.exe+585C8 – 83 F9 01 – cmp ecx,01 { 1 }
mugen.exe+585CB – 75 64 – jne mugen.exe+58631
Second Identification
Just before the Var Range Limit Check
mugen.exe+569E2 – 83 F8 3B – cmp eax,3B { 59 }
mugen.exe+569E5 – 77 0C – ja mugen.exe+569F3
Jump to another 0x04 comparison area (not the same area)
If 0x04 does not equal 0, write the stored value to Base+Offset.
Otherwise, Run the bounds check and jump back to original function appropriately.