Open shawncplus opened 5 years ago
This is kind of opinionated but I think that logging back into a destroyed instance should emit an event so the developer can decide what to do. An example implementation might involve recreating the instance, then dropping the player back in to a starting room.
What I wanted to make for it was the ability to pass in a config object that you can utilize for npcs and objects. I would have to make my own custom helpers, but if you did area.clone(config) and had something like config = { health: 1.4, ...} and have that that health percent be applied to all the npcs being loaded.
Essentially be able to scale the attributes on items or npcs being loaded in the zone.
How are area instances indexed?
I'm not understanding what you mean...like added to RoomManager / AreaManager type of thing?
What happens to players who log out in an instance and log back in after the instance has been destroyed?
I agree with Sean, just emit an event.
Items from instanced/non-instanced versions of an area should save/load correctly
I suspect that we should also approach mobs in a similarly careful way. It wouldn't be out of the ordinary for games to incorporate features that might reference a mob. Such as taming, or npc memory. We'd want any references to mobs from previously existing instances to be handled well.
For general modes of operation, I feel like there are two distinct ways games tend to use instances.
I wonder how this would interact with quests? They have an area in their id.
Here's an odd thought, when cloning an area as a new instance, perhaps you leave the area part of the entityReference the same, and add an instance id onto each of the id's for mobs, rooms, items...I don't know, maybe that would be terrible implications, maybe not, haven't looked into it versus changing the area part of the entityReference. Or maybe there's an elegant way to go underneath all of that anyway, I'm not sure.
Essentially be able to scale the attributes on items or npcs being loaded in the zone.
I LOVE THIS IDEA BRIAN!!! SO GOOD!
Can instanced zones be saved for next reboot?
Well considering Ranvier engine at the moment doesn't serialize rooms, probably not.
I don't see why there couldn't be event hooks in place that, with a custom DataSource, would enable saving instanced zones. But you are correct that it does not serialize rooms by default.
Basic instancing functionality is now testable on the instancing
branch of core. You'll also need to update your example bundles to the most recent code. For bundle-example-player-events
you'll need to be on the instancing
branch as well.
instanced
property:title: Test Area
instanced: player
Non-falsey values of instanced
are arbitrary and used purely for bundle developers to change how a given area should be instanced.
Areas which have a non-falsey value for instanced
will not be created/hydrated at server startup. Instead, creation of these areas is left entirely to bundle developers.
An example implementation can be seen here https://github.com/RanvierMUD/bundle-example-player-events/tree/instancing
The gist being:
AreaFactory.createInstance(gameState, areaName, instanceId)
which handles the work of creating an area, assigning the given instance id, then hydrating the area. This happens synchronouslyLike creating an instance, how an instance gets removed and cleaned up is entirely up to the bundle developer. The removeArea(area, instanceId)
will dereference the area and allow for creation with the same key but it's the responsibility of the caller of removeArea()
to do things like halt combat, make sure players don't get stuck in a dereferenced area, cancel any effects, etc.
As to @nelsonsbrian 's idea I've added events for an area when an NPC is added/removed. This currently happens when an NPC is spawned by room.spawnNpc
.
To accomplish something like that you would create 2 effects. The first being an Area
effect which listens for npcAdded
and based on its configuration would create an NPC
effect and attach it to the new NPC.
It would look something like:
Somewhere a configuration exists that says { health: 1.4, ...
, an instanced area is generated, you initialize the new area-bonuses
effect passing in that config, then attach it to the area.
Whenever an NPC gets spawned in that area your effect will be listening for it and when it does will be able to create a new effect like area-npc-bonus
, and attach it to said NPC.
I've found some an unexpected thing come up with using the instancing branch. Largely it works awesome! Basically, if you try and use state.RoomManager#getRoom to fetch a room from an instance that isn't loaded, it can't find it. Maybe this makes since as the rooms don't technically exist yet. I've run into it using the teleport command, as well as the starting room.
I've been using this function, which comes from someplace else. Just figured I'd share in case anyone else runs into this.
RoomUtil.getRoom = function(state, player, nextRoomId) {
const nextAreaName = state.AreaFactory.getNameByEntityReference(nextRoomId)
let nextRoom = null
if (state.AreaFactory.isInstanced(nextAreaName)) {
const instanceId = player.name
if (player.area != nextAreaName ){
B.sayAt(player, `W]Entering instanced area: w]${nextAreaName}`)
if (!state.AreaManager.getArea(nextAreaName, instanceId)) {
B.sayAt(player, "W]No instance exists, creating...")
state.AreaFactory.createInstance(state, nextAreaName, instanceId)
}
B.prompt(player)
}
nextRoom = state.RoomManager.getRoom(nextRoomId, instanceId)
} else {
nextRoom = state.RoomManager.getRoom(nextRoomId)
}
return nextRoom
}
There are currently a few architectural road blocks preventing multiple instances of a single area.
There are other questions but I think the answers to these are in the responsibility of bundle developers: