IMPORTANT UPDATES AND INCOMPATIBILITIES

Stopgap documentation until the real version is written.


MUGEN version 2000.01.01 introduces several powerful new features, at 
the cost of some incompatibilities with previous releases of the 
engine. The purpose of this document is to identify issues that will 
arise when upgrading to version 2000.01.01 of MUGEN, and to give a 
brief summary of its added capabilities.

Please read the section on major incompatibilities in its entirety.


============================================================
INCOMPATIBILITIES
============================================================

Major incompatibilities
-----------------------
- Intro/win pose changes
- LieDown action
- Pos X
- MakeExplod
- Common1.cns changes

Minor incompatibilities
-----------------------
- Rounding behavior
- Projectiles

Known bugs
----------
- Rounding behavior


============================================================
MAJOR INCOMPATIBILITIES
============================================================

The following are changes that may cause serious glitches in 
characters. It is recommended that character authors revise their files 
to comply with the new standards as soon as possible.


------------------------------------------------------------
Intro/win pose changes
------------------------------------------------------------

For intro and win poses (states 191 and 180) to work properly, the 
character must somehow inform the MUGEN engine when the pose is in 
progress and when it is finished, so that the game can go on. In 
releases of MUGEN prior to version 2000.01.01, this was accomplished by 
setting var9 to 1 at the start of the intro or win pose, and then 
setting var9 to 0 at the end of the pose. Typically, it would look 
something like this:

[Statedef 191] ; intro
type = S

[State 191, begin]
type = VarSet
trigger1 = time = 0
v = 9
value = 1   ; set v9 = 1 while intro is in progress.

... do stuff ...

[State 191, end]
type = VarSet
trigger1 = time = 205
v = 9
value = 0   ; set v9 = 0: OK to proceed with game


To free up var9 for normal use, this functionality has been subsumed 
into a new state controller, AssertSpecial. Intro and win poses will no 
longer work correctly without using AssertSpecial. Full documentation 
on AssertSpecial will be given below, but for the moment, let's see how 
the above example code would look using AssertSpecial:

[Statedef 191] ; new intro
type = S

[State 191, begin]
type = AssertSpecial
trigger1 = time = [0, 205]
flag = intro

... do stuff ...

Under the new scheme, the character must assert the "intro" flag using 
AssertSpecial for every tick during his intro pose. As soon as he stops 
asserting the intro flag, MUGEN will assume that it is OK to proceed 
with the game. So in the example above, the character finishes his 
intro and stops asserting the intro flag at time 206. MUGEN is then 
free to start the fight, assuming that the other character is not still 
asserting his intro flag. Make sure your character deasserts the intro 
flag, otherwise the round can never start!

To get a long win pose to work properly with AssertSpecial, use code 
like the following:

[Statedef 180] ; win pose
type = S

[State 180, begin]
type = AssertSpecial
trigger1 = time = [0, 142]
flag = roundnotover

... do stuff ...

Here, the character asserts the "roundnotover" flag for every tick 
during his win pose. This flag, when asserted, tells MUGEN that it is 
not yet OK to end this round and proceed to the next one. As soon as 
the character stops asserting the roundnotover flag, MUGEN is free to 
end the round.


------------------------------------------------------------
LieDown action (5110)
------------------------------------------------------------

Action 5110 must have finite looptime. That is, the last frame cannot 
have a time of -1. Otherwise, your character may not die properly if 
KOed.


------------------------------------------------------------
Pos X
------------------------------------------------------------

Pos X has been changed to report positions relative to the center of 
the screen, rather than the center of the stage. The new behavior seems 
to be more useful for most characters. This was a little-used trigger 
to start with, so its change may not affect most characters.


------------------------------------------------------------
MakeExplod
------------------------------------------------------------
The name of MakeExplod has been changed to the shorter Explod. MUGEN no 
longer recognizes the old controller name.


------------------------------------------------------------
Common1.cns changes
------------------------------------------------------------

As is usual, common1.cns has been revised to reflect changes in the 
engine. This may cause problems with characters that are overriding 
states in common1.cns. It is recommended that character authors using 
state overriding revise their states using the new states in 
common1.cns.


============================================================
MINOR INCOMPATIBILITIES
============================================================

------------------------------------------------------------
Rounding behavior
------------------------------------------------------------

The way in which MUGEN rounds floating-point numbers to integers has 
been changed. This should lead to less "sprite-hopping" and related 
problems. Unfortunately, this also means that offsets and velocities 
tuned by trial and error on old versions of MUGEN may end up slightly 
off in version 2000.01.01. The problems are most visible on 
backgrounds, where background layers may scroll too far, leaving 1-
pixel-wide "holes". Background authors are advised to recheck their 
backgrounds and adjust their delta values if necessary.


------------------------------------------------------------
Projectiles
------------------------------------------------------------

Projectiles are now capable of hitting when removed due to timeout 
(i.e., projremovetime expires). They are still not capable of hitting 
when cancelled by another projectile.


============================================================
BUGS
============================================================


------------------------------------------------------------
Rounding behavior
------------------------------------------------------------

There are still one or more sources of floating-point error in MUGEN 
that have not yet been corrected. This may cause mild inaccuracies in 
position binding (for instance, binding explods to a player).



============================================================
NEW FEATURES
============================================================

New/Revised controllers
-----------------------
- AssertSpecial
- Explod
- RemoveExplod

Major new features
------------------
- Helper characters
- Gethit overriding


============================================================
New/Revised controllers
============================================================

MUGEN version 2000.01.01 brings a complement of new triggers and 
controllers to the table. We have managed to finish documentation for 
all triggers; see the separate trigger documentation.


------------------------------------------------------------
AssertSpecial
------------------------------------------------------------

This controller allows you to assert up to three special flags 
simultaneously. MUGEN will automatically "deassert" each flag at every 
game tick, so you must assert a flag for each tick that you want it to 
be active.

Required parameters:
  flag = flag_name
    flag_name is a string specifying the flag to assert.

Optional parameters:
  flag2 = flag2_name
  flag3 = flag3_name
    You can assert up to three flags simultaneously.

Details:
  The flag name can be one of the following:
    - intro
      Tells MUGEN that the character is currently performing his intro
      pose. Must be asserted on every tick while the intro pose is 
      being performed.
    - roundnotover
      Tells MUGEN that the character is currently performing his win
      pose. Must be asserted on every tick while the win pose is being
      performed.
    - nostandguard
      While asserted, disables standing guard for the character.
    - nocrouchguard
      While asserted, disables crouching guard for the character.
    - noairguard
      While asserted, disables air guard for the character.
    - noautoturn
      While asserted, keeps the character from automatically turning
      to face the opponent.
    - nokosnd
      Suppresses playback of sound 11, 0 (the KO sound) for players
      who are knocked out. For players whose KO sound echoes, nokosnd
      must be asserted for 50 or more ticks after the player is KOed
      in order to suppress all echoes.
    - nokoslow
      While asserted, keeps MUGEN from showing the end of the round in
      slow motion.
    - noshadow
      While asserted, disables display of player shadows.
    - nomusic
      While asserted, disables playback of background music.


------------------------------------------------------------
Explod
------------------------------------------------------------

The Explod controller, formerly named MakeExplod, is a flexible tool 
for displaying animations such as sparks. Its functionality includes 
that of GameMakeAnim, which is now deprecated.


Required parameters:
  anim = [F]anim_no (int)
    anim_no specifies the number of the animation to play back. The 
    'F' prefix is optional: if included, then the animation is played
    back from fight.def.

Optional parameters:
  ID = id_no (int)
    id_no specifies an ID number for this explod. Useful mainly with
    the NumExplod trigger and the RemoveExplod controller.
  
  pos = xpos, ypos
    xpos and ypos specify the offset at which to create the explod.
    The exact behavior depends on the postype. If these parameters are
    omitted, they default to 0.

  postype = arg1 (string)
    arg1 specifies the postype -- how to interpret the pos parameters.
    In all cases, a positive y offset means a downward displacement.
    Valid values for postype are the following:
      - p1
        Interprets pos relative to p1's axis. A positive x offset is
        toward the front of p1. This is the default value for postype.
      - p2
        Interprets pos relative to p2's axis. A positive x offset is
        toward the front of p2.
      - front
        Interprets xpos relative to the edge of the screen that p1 is 
        facing toward, and ypos relative to p1's y axis. A positive x
        offset is away from the center of the screen, whereas a 
        negative x offset is toward the center.
      - back
        Interprets xpos relative to the edge of the screen that p1 is
        facing away from, and ypos relative to p1's y axis. A positive
        x offset is toward the center of the screen, whereas a 
        negative x offset is away from the center.
      - left
        Interprets xpos and ypos relative to the upper-left corner of
        the screen. A positive x offset is toward the right of the 
        screen.
      - right
        Interprets xpos and ypos relative to the upper-right corner of
        the screen. A positive x offset is toward the right of the 
        screen.

  facing = arg1 (int)
    Set facing to 1 to have the explod face in the same direction as 
    the positive x offset (as determined by postype), and -1 to have 
    the explod face in the opposite direction. Defaults to 1.
    
  vfacing = arg1 (int)
    Set vfacing to -1 to have the explod display vertically flipped,
    or 1 to have the explod display vertically unflipped. Defaults to
    1 if omitted.

  bindtime = arg1
    Specifies the number of game ticks to bind the explod to the bind 
    point specified by postype. For instance, if postype = p1, pos = 
    30, -40, and bindtime = 5, then the explod will be drawn at
    position 30, -40 relative to p1's axis for 5 ticks, no matter how
    p1 moves during this time. After the bindtime has expired, the 
    explod will no longer be bound to the bind point, and will 
    maintain its position (unless affected by the vel or accel 
    parameters). If bindtime = -1, then the explod will be bound 
    forever.

  vel = xvel, yvel (decimal)
    Specifies initial X and Y velocity components for the explod. 
    These are interpreted relative to the explod's "facing" direction.
    These default to 0 if omitted.

  accel = xaccel, yaccel (decimal)
    Specifies X and Y acceleration components for the explod. These 
    default to 0.
  
  random = arg1, arg2 (int)
    Causes the explod's bind point to be displaced by a random amount  
    when created. arg1 specifies the displacement range in the x
    direction, and arg2 specifies the displacement range in the y
    direction. For instance, if pos = 0,0 and random = 40,80, then the
    explod's x location will be a random number between -20 and 19, 
    and its y location will be a random number between -40 and 39.
    Both arg1 and arg2 default to 0 if omitted.

  removetime = arg1 (int)
    If removetime is positive, the explod will be removed after having 
    been displayed for that number of game ticks. If removetime is -1,
    the explod will be displayed indefinitely. If removetime is -2, 
    the explod will be removed when its animtime reaches 0. The 
    default for removetime is -2.

  supermove = bvalue (boolean)
    Set supermove = 1 to have the explod persist until the end of a
    super pause, regardless of the value of removetime. Defaults to 0.

  scale = xscale [,yscale] (decimal)
    xscale and yscale specify the scaling factors to apply to the 
    explod in the horizontal and vertical directions. Both default to 
    1 (no scaling) if omitted.

  sprpriority = arg1 (int)
    arg1 specifies the drawing priority for the explod. Animations 
    with higher priority get drawn over animations with lesser
    priority. For instances, setting sprpriority = -3 will cause the
    explod to be drawn under most characters and other explods, which
    usually have sprpriority >= -2.
    Defaults to 0 if omitted.

  ontop = bvalue (boolean)
    Set ontop = 1 to have the explod drawn over all other sprites and 
    background layers. This parameter has precedence over sprpriority.
    Defaults to 0.

  ownpal = bvalue (boolean)
    Set ownpal = 1 to give the explod its own copy of its palette.
    This is desirable if you want to keep temporary changes to the
    player's palette, such as recovering from a fall or using the
    PalFX controller, from affecting the color of the explod. Defaults 
    to 0 if omitted.


------------------------------------------------------------
RemoveExplod
------------------------------------------------------------

Removes all of a player's explods, or just the explods with a specified 
ID number.

Required parameters:
  none

Optional parameters:
  ID = remove_id (int)
    remove_id is the ID number of the explods to remove. If omitted,
    removes all explods.


============================================================
Major new features (a pseudo-tutorial)
============================================================

The following features are new to MUGEN version 2000.01.01. They are 
still subject to change, so we recommend that authors who use these 
features be prepared to revise their work for later versions of the 
engine if necessary.


------------------------------------------------------------
Helper Characters (a brief summary)
------------------------------------------------------------

It is now possible to create additional characters in the middle of a 
round. These characters use the main player's AIR, SFF, and CNS, but 
can be in different states than the main player. 

To keep this discussion intelligible, let's call a hypothetical player 
Kumquat. Suppose Kumquat has an attack where he calls Kiwi to run 
across the screen. This can be done by having Kumquat spawn Kiwi as a 
helper character. We then say Kumquat is Kiwi's parent, and Kiwi is 
Kumquat's child. Now, suppose Kiwi calls his friend Penguin to run 
across the screen behind him. This can be done by having Kiwi (the 
helper character) spawn Penguin (a sub-helper character). Then Kiwi is 
Penguin's parent, and Penguin is Kiwi's child. To describe the 
relationship between Kumquat and Penguin, we say that Kumquat is the 
root, and Penguin is a descendant. In general, Kumquat is the root for 
any helper characters he creates, or any sub-helper characters that his 
helper characters create, or any sub-sub-helper characters that his 
sub-helper characters create, etc. That is to say, the root is just the 
"real" player. The concept of the root, parents, children, and 
descendants is essential to the proper use of helpers.

To actually create this attack, we add Kiwi's running sprites to 
Kumquat's SFF, then create the corresponding action in Kumquat's AIR. 
It's usually a good idea to keep the action numbers and state numbers 
for helpers and the root separate, to avoid confusion. So we'll make 
Kiwi's running action 9000 or so.

Now we define a state in Kumquat's CNS for Kiwi to use.

; Kiwi's running state
[Statedef 9000]
type = S
movetype = I
velset = 6, 0   ; Kiwi's running speed
anim = 9000     ; Kiwi's running animation

[State 9000, 0]
type = PlaySnd
trigger1 = TimeMod = 10, 0
value = 0,0     ; Play a sound effect (footfall?) every 10 ticks

[State 9000, 1]
type = DestroySelf
trigger1 = time = 90

This is just a normal CNS state, except for the call to DestroySelf. 
This is a controller that removes a helper from the field of play (it 
doesn't work on the root). This is necessary to keep helpers from 
hanging around and littering up the game. It is also desirable from the 
standpoint of speed and memory, since helpers use just as many 
computational resources as full-fledged players.

Now, for the final step, Kumquat needs to create Kiwi so that the 
running "attack" can occur. This can be done by using the Helper state 
controller.

; Kiwi summon attack!
[Statedef 2000]
type = S
movetype = I

[State 2000, 0]
type = Helper
trigger1 = AnimElem = 2
ID = 9000    ; identification number
pos = 0, 0   ; offset for helper creation
postype = back  ; postype -- works same as Explod
stateno = 9000 ; specify initial state to start from (important!)
helpertype = normal  ; two types -- normal or player
keyctrl = 0
ownpal = 0

[State 2000, 1]
; do more stuff

The "ownpal", "pos", and "postype" parameters work exactly the same as 
in the Explod controller. If helpertype is normal, then the helper will 
not be constrained to the screen, and will not affect the camera. If 
helpertype is player, then the helper will be constrained to the screen 
and will affect the camera. In this example, setting the helpertype to 
normal allows Kiwi to run off the edge of the screen without scrolling 
the camera. Finally, "keyctrl" determines whether or not Kiwi should be 
able to respond to Kumquat's key input. keyctrl = 1 would be useful 
for, say, guided missile attacks, but not for Kiwi's running attack.

This is all that needs to be done. Kumquat can now summon Kiwi to run 
across the screen. Note that once Kiwi is created, Kiwi and Kumquat 
operate more or less independently. Kumquat can change out of state 
2000 to whatever state he likes, and Kiwi, in turn, could theoretically 
change from state 9000 to some other state. In short, helper characters 
act like independent, fully-fledged characters in almost all respects, 
and they have the full power of the state machine at their disposal. 
The above example barely scratches the surface. 

You may wish to achieve a greater degree of synchronization between the 
root and its descendants. This is possible using some new triggers (see 
the trigger documentation). We recommend that you not invest too much 
effort into this for the moment, as achieving good communication is 
currently a considerable programming challenge. Better methods of 
parent-child communication are likely to be added in the future.

The maximum total number of simultaneous players (roots and 
descendants) is 63. We recommend that you not use more than one or two 
helpers at a time, to maximize compatibility with low-memory setups.


------------------------------------------------------------
Gethit overriding
------------------------------------------------------------

If you added Clsn2 boxes for Kiwi in the example above, then tried him 
out, you would run into a nasty surprise. If you hit Kiwi, he'd turn 
into a clone of Kumquat!

The reason for this is the following: as far as MUGEN is concerned, 
Kiwi is exactly the same character as Kumquat; he just happens to be in 
a different state. Thus, when you hit Kiwi, he reverts back to 
Kumquat's main set of states.

The solution is to have Kiwi tell MUGEN to use a different set of hit 
states for him. This is called gethit overriding.

[State 9000, 2]
type = HitOverride
trigger1 = time = 0
time = -1    ; time to leave override active, -1 for forever
attr = SCA, AA, AT, AP   ; list of attributes to override
slot = 0   ; slot number to use for override (0-7)
stateno = 9005   ; state number to use when this override activates

You can have multiple gethit overrides active in different slots (so 
that different kinds of hits can send Kiwi to different states). Here, 
if Kiwi is hit by any attack, he is sent to state number 9005.

Note that if Kiwi can use gethit overrides, so can Kumquat, since 
they're not fundamentally different. Thus, you could have Kumquat react 
in a special manner to certain kinds of hits.

But there are some issues, as there always are; these primarily lie 
with attacks that put p2 in a custom state. For now, use gethit 
overriding sparingly, and test thoroughly.

To be finished.
