§
    O¼»j«  ã            
       óT  — d Z ddlZddlZddlZddlZej                             dej                             ej                             ej         	                    e
¦  «        d¦  «        ¦  «        ¦  «         ddlmZ ddlmZmZmZmZmZmZmZ ddlmZ ddlmZ  G d„ d	¦  «        ZdS )
zõ
Unit tests for FreeExile Savage Monster Ecosystem & Procedural Generation Engine.
Verifies 100-level scaling, 10,000 monster variants, ferocity & size distribution,
memory/hardware optimization, and server-authoritative Feral AI state machine.
é    Nz../../server)ÚFiveElements)ÚMonsterGenusÚMonsterRankÚMonsterAIStateÚProceduralMonsterÚAggressionProfileÚMonsterRuntimeStateÚMonsterAIAction)ÚMonsterProceduralEngine)ÚMonsterAIEnginec                   ó6   — e Zd Zdd„Zdd„Zdd„Zdd„Zdd„ZdS )	ÚTestMonsterSystemÚreturnNc                 ó´  — t          ¦   «         }|                     d¦  «        }|                     d¦  «        }|j        dk    sJ ‚|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j        j	        |j        j	        k    sJ ‚|j
        j        |j
        j        k    sJ ‚dS )zDGeneration of a monster with same ID must produce identical results.i9  N)r   Úgenerate_monsterÚ
monster_idÚnameÚgenusÚelementÚrankÚmax_hpÚvisualÚ
base_scaleÚ
aggressionÚferocity_index)ÚselfÚengineÚm1Úm2s       ú7C:\Projects\FreeExile\tests\unit\test_monster_system.pyÚ,test_single_monster_generation_deterministicz>TestMonsterSystem.test_single_monster_generation_deterministic   së   € å(Ñ*Ô*ˆØ×$Ò$ TÑ*Ô*ˆØ×$Ò$ TÑ*Ô*ˆàŒ} Ò$Ð$Ð$Ð$ØŒw˜"œ'Ò!Ð!Ð!Ð!ØŒx˜2œ8Ò#Ð#Ð#Ð#ØŒz˜RœZÒ'Ð'Ð'Ð'ØŒw˜"œ'Ò!Ð!Ð!Ð!ØŒy˜BœIÒ%Ð%Ð%Ð%ØŒyÔ# r¤yÔ';Ò;Ð;Ð;Ð;ØŒ}Ô+¨r¬}Ô/KÒKÐKÐKÐKÐKÐKó    c                 ó¸  — t          ¦   «         }|                     dd¬¦  «        }|                     dd¬¦  «        }|                     dd¬¦  «        }|j        j        |j        j        cxk     r|j        j        k     sn J ‚|j        j        |j        j        k     sJ ‚|j        j        |j        j        cxk     r|j        j        k     sn J ‚|j        j        |j        j        k     sJ ‚|j        j        |j        j        k     sJ ‚|j        j	        |j        j	        k    sJ ‚|j        j
        |j        j
        k    sJ ‚|j        j        |j        j        k    sJ ‚dS )zRLevel 100 monsters must have strictly greater ferocity, speed, aggro than Level 1.é
   é   ©Útarget_levelé2   éd   N)r   r   r   r   Úcollision_radiusr   r   Úaggro_radius_metersÚmovement_speedÚattack_windup_msÚattack_cooldown_msÚ
combo_hits)r   r   Úlow_lvlÚmid_lvlÚhigh_lvls        r    Ú-test_level_distribution_and_monotonic_scalingz?TestMonsterSystem.test_level_distribution_and_monotonic_scaling,   s{  € å(Ñ*Ô*ˆØ×)Ò)¨"¸1Ð)Ñ=Ô=ˆØ×)Ò)¨"¸2Ð)Ñ>Ô>ˆØ×*Ò*¨2¸CÐ*Ñ@Ô@ˆð Œ~Ô(¨7¬>Ô+DÐaÐaÒaÐaÀxÄÔGaÒaÐaÐaÐaÐaÐaØŒ~Ô.°´Ô1QÒQÐQÐQÐQð Ô!Ô0°7Ô3EÔ3TÐyÐyÒyÐyÐW_ÔWjÔWyÒyÐyÐyÐyÐyÐyØÔ!Ô5¸Ô8KÔ8_Ò_Ð_Ð_Ð_ØÔ!Ô0°8Ô3FÔ3UÒUÐUÐUÐUð Ô!Ô2°XÔ5HÔ5YÒYÐYÐYÐYØÔ!Ô4°xÔ7JÔ7]Ò]Ð]Ð]Ð]ð Ô"Ô-°Ô1CÔ1NÒNÐNÐNÐNÐNÐNr"   c                 ó.  — t          ¦   «         }t          j        ¦   «         }|                     dd¬¦  «        }t          j        ¦   «         |z
  dz  }t	          |¦  «        dk    sJ ‚|dk     sJ d|d›d�¦   «         ‚d	„ |D ¦   «         }t	          |¦  «        t	          t
          ¦  «        k    sJ ‚d
„ |D ¦   «         }t	          |¦  «        t	          t          ¦  «        k    sJ ‚d„ |D ¦   «         }t	          |¦  «        t	          t          ¦  «        k    sJ ‚dS )zVValidates that generating 10,000 distinct monsters completes in < 250ms with 0 errors.r%   i'  )Ústart_idÚcountiè  g     @@zProcedural generation took z.2fzms, exceeds 500ms limitc                 ó   — h | ]	}|j         ’Œ
S © )r   ©Ú.0Úms     r    ú	<setcomp>zXTestMonsterSystem.test_all_10_000_variants_generation_and_performance.<locals>.<setcomp>P   s   € Ð7Ð7Ð7¨˜QœWÐ7Ð7Ð7r"   c                 ó   — h | ]	}|j         ’Œ
S r8   )r   r9   s     r    r<   zXTestMonsterSystem.test_all_10_000_variants_generation_and_performance.<locals>.<setcomp>T   s   € Ð<Ð<Ð<¨a ¤	Ð<Ð<Ð<r"   c                 ó   — h | ]	}|j         ’Œ
S r8   )r   r9   s     r    r<   zXTestMonsterSystem.test_all_10_000_variants_generation_and_performance.<locals>.<setcomp>X   s   € Ð6Ð6Ð6¨˜QœVÐ6Ð6Ð6r"   N)r   ÚtimeÚperf_counterÚgenerate_batchÚlenr   r   r   )r   r   Ú
start_timeÚmonstersÚ
elapsed_msÚrepresented_genusÚrepresented_elementsÚrepresented_rankss           r    Ú3test_all_10_000_variants_generation_and_performancezETestMonsterSystem.test_all_10_000_variants_generation_and_performanceC   s8  € å(Ñ*Ô*ˆÝÔ&Ñ(Ô(ˆ
à×(Ò(°!¸5Ð(ÑAÔAˆÝÔ'Ñ)Ô)¨JÑ6¸$Ñ>ˆ
å�8‰}Œ} Ò%Ð%Ð%Ð%à˜EÒ!Ð!Ð!Ð#hÀÐ#hÐ#hÐ#hÐ#hÑ!Ô!Ð!ð 8Ð7¨hÐ7Ñ7Ô7ÐÝÐ$Ñ%Ô%­­\Ñ):Ô):Ò:Ð:Ð:Ð:ð  =Ð<°8Ð<Ñ<Ô<ÐÝÐ'Ñ(Ô(­CµÑ,=Ô,=Ò=Ð=Ð=Ð=ð 7Ð6¨XÐ6Ñ6Ô6ÐÝÐ$Ñ%Ô%­­[Ñ)9Ô)9Ò9Ð9Ð9Ð9Ð9Ð9r"   c                 ó<  — t          ¦   «         }|                     d¦  «        }d|j        j        cxk    rdk    sn J ‚|j        j                             d¦  «        sJ ‚t          |j        j        t          ¦  «        sJ ‚d|j        j	        cxk    rdk    sn J ‚dS )zcMonsters must contain valid shader palette LUT index and attachment keys for client GPU instancing.i+  r   é   ú#g        g       @N)
r   r   r   Úpalette_lut_indexÚelemental_tint_hexÚ
startswithÚ
isinstanceÚattachment_idsÚlistÚemissive_glow_intensity)r   r   r;   s      r    Ú/test_procedural_palette_and_modular_attachmentszATestMonsterSystem.test_procedural_palette_and_modular_attachments[   s´   € å(Ñ*Ô*ˆØ×#Ò# CÑ(Ô(ˆà�A”HÔ.Ð4Ð4Ò4Ð4°"Ò4Ð4Ð4Ð4Ð4Ð4ØŒxÔ*×5Ò5°cÑ:Ô:Ð:Ð:Ð:Ý˜!œ(Ô1µ4Ñ8Ô8Ð8Ð8Ð8Ø�a”hÔ6Ð=Ð=Ò=Ð=¸#Ò=Ð=Ð=Ð=Ð=Ð=Ð=Ð=r"   c           	      óø  — t          ¦   «         }t          ¦   «         }|                     dd¬¦  «        }t          |dddd|j        t
          j        ¬¦  «        }|                     |dd¬¦  «        }|j        t
          j        t
          j	        fv sJ ‚|j
        d	v sJ ‚d
}|                     ||d¬¦  «        }|j        t
          j        k    sJ ‚|j
        dk    sJ ‚d|_        d|_        |                     ||d¬¦  «        }|j        t
          j        k    sJ ‚|j
        dk    sJ ‚d|_        d|_        |                     |dd¬¦  «        }|j        t
          j        k    sJ ‚|j
        dk    sJ ‚|j        du sJ ‚dS )z^Verifies server-authoritative Feral AI transitions: IDLE -> PURSUIT -> ATTACK -> LEASH_RETURN.r)   é   r&   ç      $@)ÚmonsterÚ	current_xÚ	current_yÚspawn_xÚspawn_yÚ
current_hpÚai_state)ç      I@r_   gL7‰A`å ?)Ú
player_posÚdt)ÚSTANDÚPATROL)ç      (@rW   ÚMOVE_TOWARDSrd   ÚATTACKç      Y@)g     @Y@rg   ÚRETURN_TO_SPAWNTN)r   r   r   r	   r   r   ÚIDLEÚupdater^   rc   Úaction_typeÚPURSUITrY   rZ   rf   ÚLEASH_RETURNÚis_invulnerable)r   r   ÚairX   ÚstateÚactionÚplayer_nears          r    Ú%test_feral_ai_state_machine_and_leashz7TestMonsterSystem.test_feral_ai_state_machine_and_leashe   s¯  € å(Ñ*Ô*ˆÝÑÔˆØ×)Ò)¨#¸BÐ)Ñ?Ô?ˆå#ØØØØØØ”~Ý#Ô(ð
ñ 
ô 
ˆð —’˜5¨\¸e�ÑDÔDˆØŒ~¥.Ô"5µ~Ô7LÐ!MÐMÐMÐMÐMØÔ!Ð%8Ð8Ð8Ð8Ð8ð #ˆØ—’˜5¨[¸U�ÑCÔCˆØŒ~¥Ô!7Ò7Ð7Ð7Ð7ØÔ! ^Ò3Ð3Ð3Ð3ð ˆŒØˆŒØ—’˜5¨[¸U�ÑCÔCˆØŒ~¥Ô!6Ò6Ð6Ð6Ð6ØÔ! XÒ-Ð-Ð-Ð-ð  ˆŒØˆŒØ—’˜5¨^À�ÑFÔFˆØŒ~¥Ô!<Ò<Ð<Ð<Ð<ØÔ!Ð%6Ò6Ð6Ð6Ð6ØÔ$¨Ð,Ð,Ð,Ð,Ð,Ð,r"   )r   N)Ú__name__Ú
__module__Ú__qualname__r!   r3   rI   rT   rs   r8   r"   r    r   r      s€   € € € € € ðLð Lð Lð LðOð Oð Oð Oð.:ð :ð :ð :ð0>ð >ð >ð >ð(-ð (-ð (-ð (-ð (-ð (-r"   r   )Ú__doc__Úpytestr?   ÚsysÚosÚpathÚinsertÚabspathÚjoinÚdirnameÚ__file__Úworld.martial_matrixr   Úworld.monster_typesr   r   r   r   r   r	   r
   Úworld.monster_procedural_enginer   Úworld.monster_ai_enginer   r   r8   r"   r    ú<module>r…      sF  ððð ð €€€Ø €€€Ø 
€
€
€
Ø 	€	€	€	à „‡‚��2”7—?’? 2¤7§<¢<°´·²ÀÑ0IÔ0IÈ>Ñ#ZÔ#ZÑ[Ô[Ñ \Ô \Ð \à -Ð -Ð -Ð -Ð -Ð -ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð DÐ CÐ CÐ CÐ CÐ CØ 3Ð 3Ð 3Ð 3Ð 3Ð 3ðq-ð q-ð q-ð q-ð q-ñ q-ô q-ð q-ð q-ð q-r"   