Construct 3 icon

Construct 3

Documentation

Subclassing instances

Ashley's avatar
Medal
Construct Team Founder
Published 3 Jun, 2019
713 words
~3-5 mins

Construct uses the IInstance and IWorldInstance interfaces to provide access to instances. Many plugins provide derivatives of these to provide plugin-specific APIs. For example the Text plugin adds a text property with an ITextInstance class that derives from IWorldInstance. The Plugin interfaces section covers these.

However in your projects it is often desirable to have a further customised class to represent instances. For example all your Sprite instances will provide an ISpriteInstance interface, but this is still a fairly generic class to represent many different aspects of your project, such as both the player and enemies. Subclassing allows you to use your own custom classes like PlayerInstance or EnemyInstance to represent different objects in your game. Then any time you ask Construct for instances, such as with getAllInstances(), you'll get references to your custom classes instead of a generic ISpriteInstance or IWorldInstance class.

To use subclassing, follow the steps provided here. The Ghost shooter code scripting example also demonstrates how to use this, with a custom MonsterInstance class to represent the enemy monsters in the game.

Step 1: create your class

First write a class that extends from the class normally used by the instance. For example when extending a Sprite instance, extend from ISpriteInstance. The class names for all plugin types can be found in the Plugin interfaces section. If the plugin does not have its own class, derive from IWorldInstance if the instance appears in a layout, else IInstance. If you extend the wrong class, a message will appear in the console indicating which class you should extend from instead.

In this example we'll extend a Sprite instance for the player, so the class extends from ISpriteInstance.

class PlayerInstance extends ISpriteInstance
{
	constructor()
	{
		super();
	}
}

Often it is sensible to organise code by using a separate script file for the class.

Step 2: set the instance class

Next, use the IObjectClass.setInstanceClass() method to set your custom class. This must be done before any instances in the project are created, to make sure they all use the right class. Therefore this must be called in runOnStartup, which runs before the runtime has finished loading, so no instances exist yet.

runOnStartup(async runtime =>
{
	runtime.objects.Player.setInstanceClass(PlayerInstance);
}

Step 3: customise the class

Now you can add custom properties and methods to your class. For example the Player class may need to use an ammo counter, and a shoot method to fire one of their bullets. You can write these as you would with a normal JavaScript class.

class PlayerInstance extends ISpriteInstance
{
	constructor()
	{
		super();
		
		// Start with 5 bullets
		this.ammo = 5;
	}

	shoot()
	{
		// Decrement ammo count
		this.ammo--;
		
		// create a bullet instance, etc.
	}
}

Note that here ammo is not an instance variable or anything else associated with Construct's event system: it's just a normal JavaScript object property.

Since IInstance has a runtime property, within your class you can always use this.runtime to refer to the runtime script interface.

Step 4: use your custom features

Now whenever you retrieve instances of the player from the existing APIs, you'll get PlayerInstance classes instead of the default ISpriteInstance. Then you can read your custom properties and call custom methods.

// Assume called in "beforelayoutstart" event
function OnBeforeLayoutStart(runtime)
{
	// Get player instance from Construct
	const playerInstance = runtime.objects.Player.getFirstInstance();
	
	// Example uses of custom class
	console.log("Ammo = " + playerInstance.ammo);
	playerInstance.shoot();
}

Conclusion

Subclassing is straightforward to set up, and lets you use custom classes for different objects in your project. This can make your code a lot clearer, and helps you to use the full power of JavaScript classes with instances in Construct's runtime.