ZSS Language (IKEMEN Go Exclusive)
Overview
ZSS (Z State Script) is IKEMEN Go's modern state definition format. It replaces the classic .cns format with a cleaner, more readable syntax while adding powerful features like local variables, user-defined functions, and better scoping.
Key advantages over .cns:
- •Cleaner, more readable syntax (no brackets for sections)
- •Local variables (scoped to state or function)
- •User-defined functions (reusable logic blocks)
- •Inline expressions (no separate trigger lines)
- •Multi-line expressions
- •Comments with
#or// - •Import/include system
- •Better error messages
ZSS vs CNS Syntax Comparison
Statedef
CNS:
ini
[Statedef 200] type = S movetype = A physics = S anim = 200 ctrl = 0 velset = 0, 0 sprpriority = 2
ZSS:
zss
[Statedef 200; type: S; movetype: A; physics: S; anim: 200; ctrl: 0; velset: 0, 0; sprpriority: 2]
Or multi-line:
zss
[Statedef 200] type: S movetype: A physics: S anim: 200 ctrl: 0 velset: 0, 0 sprpriority: 2
State Controllers
CNS:
ini
[State 200, Light Punch Hit] type = HitDef trigger1 = time = 2 attr = S, NA damage = 25, 0 animtype = Light guardflag = MA hitflag = MAF pausetime = 8, 8 sparkno = 0 hitsound = 5, 0 ground.type = High ground.slidetime = 5 ground.hittime = 10 ground.velocity = -4, 0 air.velocity = -1.2, -3
ZSS:
zss
if time = 2 {
HitDef{
attr: S, NA;
damage: 25, 0;
animtype: Light;
guardflag: MA;
hitflag: MAF;
pausetime: 8, 8;
sparkno: 0;
hitsound: 5, 0;
ground.type: High;
ground.slidetime: 5;
ground.hittime: 10;
ground.velocity: -4, 0;
air.velocity: -1.2, -3;
}
}
ChangeState
CNS:
ini
[State 200, End] type = ChangeState trigger1 = animtime = 0 value = 0 ctrl = 1
ZSS:
zss
if animtime = 0 {
ChangeState{value: 0; ctrl: 1}
}
Multiple Triggers (OR logic)
CNS:
ini
[State -1, Fireball] type = ChangeState value = 1100 triggerall = command = "QCF_x" triggerall = statetype != A trigger1 = ctrl trigger2 = stateno = [200, 250] && movecontact
ZSS:
zss
if command = "QCF_x" && statetype != A && (ctrl || (stateno = [200, 250] && movecontact)) {
ChangeState{value: 1100}
}
Variables
CNS:
ini
[State 200, Set Counter] type = VarSet trigger1 = time = 0 var(0) = 1
ZSS:
zss
if time = 0 {
let counter = 1 # Local variable (ZSS exclusive!)
}
# Or traditional:
if time = 0 {
VarSet{var(0) = 1}
}
ZSS Exclusive Features
Local Variables
zss
[Statedef 1000]
type: S; movetype: A; physics: S; anim: 1000; ctrl: 0
# Local variables - exist only within this state
let hitCount = 0
let maxHits = 5
let damagePerHit = 30
if moveHit {
let hitCount = hitCount + 1
}
if hitCount >= maxHits {
ChangeState{value: 1001}
}
Local variables are:
- •Declared with
let - •Scoped to the current Statedef
- •Don't use up the global var(0)-var(59) pool
- •Reset when re-entering the state
- •Can be int or float
User-Defined Functions
zss
# Define a reusable function
function applyStandardHitDef(dmg, hitType) {
HitDef{
attr: S, NA;
damage: dmg, 0;
animtype: hitType;
guardflag: MA;
hitflag: MAF;
pausetime: 8, 8;
sparkno: 0;
hitsound: 5, 0;
ground.type: High;
ground.slidetime: 5;
ground.hittime: 10;
ground.velocity: -4, 0;
air.velocity: -1.2, -3;
}
}
# Use the function in states
[Statedef 200]
type: S; movetype: A; physics: S; anim: 200; ctrl: 0
if time = 2 {
call applyStandardHitDef(25, Light)
}
Inline Expressions
zss
# Complex expressions inline
VelSet{x: ifelse(facing = 1, 4.5, -4.5); y: -8.0}
# Ternary-style
ChangeAnim{value: cond(statetype = A, 600, 200)}
Import System
zss
# Import definitions from another file import "common_functions.zss" import "shared_hitdefs.zss" [Statedef 200] # Can now use functions defined in imported files
Comments
zss
# Single line comment // Also a single line comment /* Multi-line comment */
Multi-line Expressions
zss
if time = 2
&& statetype = S
&& ctrl
&& power >= 1000 {
ChangeState{value: 3000}
}
ZSS File Extension
ZSS files use the .zss extension. In the character .def file:
ini
[Files] cns = charname.zss ; Use .zss instead of .cns st1 = specials.zss ; Additional state files can also be .zss
You can mix .cns and .zss files in the same character -- the engine detects format by extension.
Migration Path: CNS to ZSS
- •Start with new characters: Write new characters in ZSS
- •Gradual conversion: Convert individual state files one at a time
- •Mixed mode: Reference both .cns and .zss files from the same .def
- •Test after each conversion: Verify behavior matches
When to Use ZSS vs CNS
| Scenario | Recommended |
|---|---|
| New IKEMEN Go project | ZSS |
| MUGEN backward compatibility needed | CNS |
| Complex character with many states | ZSS (cleaner, local vars) |
| Porting existing MUGEN character | Keep CNS |
| Learning the engine | CNS (more documentation) |
| Advanced programming features | ZSS |
Tips
- •ZSS uses semicolons (
;) to separate parameters within blocks - •Indentation is not required but improves readability
- •Local variables save you from running out of global var slots
- •Functions reduce copy-paste for common patterns (HitDefs, effects)
- •Use imports to share functions across multiple characters
- •The ZSS parser gives better error messages than CNS parser
- •All .cns state controllers and triggers work identically in ZSS