Jump to content

Photo

Simple enemy script

script enemy editor eweapon

  • Please log in to reply
2 replies to this topic

#1 TLOZace5000

TLOZace5000

    Newbie

  • Members

Posted 28 February 2026 - 12:35 AM

I have this very simple script that makes an enemy just shoot two fireballs at Link per second, but I have a few questions. Version is 2.55.8.

 

This was done using Autoghost, but I've read there was supposed to be a new way to script custom enemy moves and attacks by using npc and eweapon scripts.

 

Is that necessarily easier than ghost.zh?

If I did it that way, does that mean I cannot use Ghost_X or Ghost_Y values that determine enemy positions (in the script code that is)? In other words, would the code look vastly different?
 

ffc script OctorockSpecial
{
	void run(int enemyID)
	{
		eweapon fireball;
		npc ghost = Ghost_InitAutoGhost(this, enemyID);
		
		while (true)
		{
			fireball = FireAimedEWeapon(EW_FIREBALL, Ghost_X, Ghost_Y, 0, 200, ghost->WeaponDamage, -1, -1, EWF_UNBLOCKABLE);
			Ghost_Waitframes(this, ghost, true, true, 30);
		}
	}
}


Edited by TLOZace5000, 28 February 2026 - 12:38 AM.


#2 Moosh

Moosh

    The Mush

  • Moderators

Posted 28 February 2026 - 06:15 AM

If you were using npc scripts, you'd use this->X, and this->Y instead of the ghost equivalents. In a ghost script, the this pointer represents an FFC that's linked to the enemy, which npc scripts do not need to use. Here's what your script would look like without ghost functions:

npc script OctorockSpecial
{
	void run()
	{
		eweapon fireball;
		
		while (true)
		{
			fireball = FireEWeaponAtHero(EW_FIREBALL, this->X, this->Y, true, 200, this->WeaponDamage);
			fireball->Unblockable = UNBLOCK_ALL;
			Waitframes(30);
		}
	}
}

FireEWeaponAtHero() is found in std_functions.zh.

 

Some pros and cons to ghost.zh in modern ZC:

Pros:

  • It has pretty much every feature you could want to script an enemy right out of the gate.
  • Animations are easy and (somewhat) intuitive to set up in the editor. Enemies use combos for graphics so you can easily change animation lengths without having to alter tile page layouts.
  • You can access some variables anywhere within your script (Ghost_X, Ghost_Y, ect) without needing to pass a pointer into a function. This can have some limited usage.
  • Ghost comes with some custom weapon movement styles built in. While these can all be reproduced with scripts, it takes some effort and nobody's yet submitted replacement scripts to the database.
  • If you're using regions, enemies can move while outside the viewport as FFC scripts are not suspended. This is currently a functional limitation of enemy scripts in 3.0. Conditionally this can be helpful.

 

Cons: 

  • Ghost's system for animations does not handle animations that don't loop or that need to restart to a certain frame gracefully. Since it uses FFCs, all animations are synced with a global timer.
  • Enemies are redrawn to the screen rather than using the in-engine sprites. This eats up a few draw commands and can cause draw order inconsistencies.
  • It adds a bit of global script overhead due to autoghost and weapon handling. This is not really noticeable or meaningful when playing but it is wasting instructions to loop over every enemy and weapon in situations where ghost isn't being used.
  • It uses a lot of sprite Misc[] indices for managing stuff in the global script. These are not as much of a high value commodity as they used to be, but by modern ZScript standards its usage is pretty wasteful.
  • Ghost's syncing of certain enemy stats with global variables and temporary arrays causes frequent timing issues. You have to jump through hoops to do simple things like changing the enemy's HP with another script and timing issues can cause enemy death animations to glitch out if you're not careful. This is the biggest pain point that drove me away from ghost.

 

If you switch from ghost.zh to npc scripts, my NPCAnim.zh header is able to patch up the animation features lost in the transition. It works a bit differently but ultimately gives more freedom to animate your enemies than ghost did. 

 

Overall I think which approach is better is somewhat of a bell curve. On the lower end where you're just writing simple addon scripts like you posted here, you should use npc scripts. In the middle where you want something quick, fast, and dirty, ghost.zh will be easier. When you want a finer degree of control, use npc scripts with NPCAnim. And at the highest level of enemy scripting where you're making a complex multi piece abomination with fully custom drawing routines...it doesn't matter which you use.



#3 TLOZace5000

TLOZace5000

    Newbie

  • Members

Posted 04 March 2026 - 10:57 AM

Okay. Thanks.

 

Would there be a way I could make this fireball projectile blockable or unblockable based on what shield Link has? Since adding fireball->Unblockable = UNBLOCK_ALL makes it unblockable no matter what shield Link has.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users