New post, new project! Lolife is an old school action RPG.

It's very early days but there's quite a lot going on here already!
Multiple instances of a single sprite
The mice in the gif above are all instances of the same sprite. That might not sound like a big deal, but if you've tried to do similar in Pulp you might know it's surprisingly difficult!
 
 
As you can see, there's only one mouse sprite with four frames, one for each direction the mouse can face.
There are a handful of challenges to making this work in Pulp:
- All variables are global
- Variables can't be dynamically referenced (at least not directly)
- Sprites are tiles like any other - swapping them into a room will replace the tile at that location
Global variables make it difficult to separately track health for multiple instances of an enemy. They also make it difficult to keep track of the tile the enemy is "above", something you need to do given there's no record of the tiles swapped out of a room.
One (very reasonable!) solution is to duplicate a sprite and edit the variable names. That way you can easily place multiple enemies in a room as they are actually different sprites (even if they look and behave the same), but it's a bit messy and annoying to have so much duplication of tiles and code. I wanted to do better and find a way of avoiding this duplication!
My solution involves "registering" each enemy on entering a room. Take this "river" room as an example, which is empty of enemies in the editor:
The room script looks like this:
on enter do
	entity_1 = "mouse"
	entity_1_x = 8
	entity_1_y = 7
	
	entity_2 = "mouse"
	entity_2_x = 15
	entity_2_y = 3
	
	tell event.game to
		call "registerEntities"
	end
end
The game script handles tracking each enemy (I call them entities as they could just as easily be friendly NPCs) in a generic fashion. There's a bit of code duplication between each numbered entity, but it's a lot less (up to the number of entities that can be on screen at the same time) than having to duplicate every sprite to the same number.
The mouse sprite itself has a similarly simple-looking script:
on getMaxHP do
	max_hp = 3
end
on tick do
	tell "behaviour" to
		if aggro>0 then
			call "checkAdjacent"
			range = 3
			call "checkRange"
			if player_in_range==1 then
				call "flee"
			else
				call "randomWalk"
			end
		else
			call "checkAdjacent"
			call "randomWalk"
		end
	end
end
on attack do
	aggro = 1
	xy = "{event.x}x{event.y}y"
	tell event.game to
		call "damageEntity"
	end
end
The trick here is that the "behaviour" sprite contains all of the complex code to do with movement, but it's generic - checkAdjacent for example works out if the four adjacent tiles are able to be moved onto, assuming x and y variables have been set as the coordinates of the sprite. By separating out this complex but generic code, each enemy can have its unique behaviour easily constructed by stringing together the desired generic behaviours. As you can see here, a mouse will walk randomly or, if aggro'd (which happens on attacking any mouse on the same screen), will flee from the player if the player gets too close. You can see this behaviour in the gif.
The tick event is called from the game loop on each registered entity, and the game script then handles the actual swapping of tiles etc. based on variables changed by the sprite's script.
I've not shown that more complex code for handling entities or for behaviour, but the point is that now it is written I don't have to worry about it. If I want to create a new enemy, I just create one sprite and add a tick event with simple, strung together behaviour calls. If I want to create a new room with 3 enemies in it, I just register the three enemies in the room's enter event by name and starting coordinates. All the hard work is already done!
