A downloadable RPG Maker Plugin

Buy Now$20.00 USD or more

šŸ“š This plugin is $5 off for owners of Dynamic Pictures, as they have some parts in common. Use Dynamic Actors (free) to control both at once.

With this plugin, you can use rules to apply bitmap replacements and additional bitmap layers to Characters, that is Actors, Events and Vehicles shown on Maps. Shown Characters continue to update live according to the defined rules, and this is guaranteed to not flicker even if the bitmap isn't loaded yet.

Rules are applied in order, top to bottom, so that each rule can react to the tags added by previous rules. You can also make use of the AddCharacterTags (MV), RemoveCharacterTags (MV), Change Character Tags (MZ) and ClearCharacterTags (MV) / Clear Character Tags (MZ) plugin commands to modify preset tags for Characters. These presets can be erased all at once for all Events in a Map with the ClearMapCharacterTags (MV) / Clear Map (Event) Character Tags (MZ) command.

You can use the Z-Index parameter to change the order in which the layers appear, though the default of showing them front-to-back above the original base layer(s) should work unmodified in many cases.

Note that tile Events' bitmaps and characters drawn on windows (i.e. in the save file list) are not affected by this plugin!

Before deploying for Linux on Windows, you must update MV's NW.js runtime.

Ideas

  • If you draw equipment into an image separate from your base character sprite images, you can use this plugin with character conditions to have your character sprites wear it.
    • For easy setup, it's possible to layer a single-character layer where the file name starts with '$' over a multi-character sheet - the layer will be visible in each slot automatically.
  • This plugin can also be used as part of a character customisation system, where for example an Actor's or Event's appearance is controlled by Switches, Variables or Character Tags.
    • Character Generator parts are already in the correct format for this.
    • Please note that this plugin only works with Sprite_Characters (on Maps) and images in the /img/characters folder. This means it can't be used to compose side view battler images like those found in /img/sv_actors.
  • By combining a shorthand condition like isOnBush && !isJumping && isMoving (without backticks) with terrain tags, you could add ripples or dust motes that appear around Characters' legs when they move through water or sand.
    • To make this effect reliably responsive in web deployments, you may want to enable preloading for that layer, but this isn't strictly required.
    • You can also use isDashing in the shorthand to add variations for faster movement to the above (though this is limited to the player by default).

Hints

  • Space your z-indices a bit so that it's easier to insert something in-between layers later on.
    • In case you didn't, you can also use text mode to set a rule's z-index to a number with more decimal places.
  • Layers are deduplicated automatically. The topmost copy of each remains.
  • You can use the target name placeholder %1 in added layers to show different images depending on the target.
    • This way, you can for example use just one rule for a piece of armour, even if different characters are involved, even if those variants wouldn't fit on a single multi-character spritesheet.
  • This plugin works both with single-character spritesheets (whose file name starts with $ or !$) and with multi-character/multi-form sheets. The mode of the base image is used, and single-character layers are tiled over multi-character base images while multi-character layers are cropped if necessary.
    • However, please avoid mixing furniture (!) and other (non-!) images.

Caution

  • Actors drawn to windows using Window_Base.prototype.drawActorCharacter (that is: characters shown on save files) are not affected by this plugin.
    • For this reason, please use a suitable default when setting up your actors (or an alternate specifically for UI, like a close-up of their face).
    • You can easily replace this default for on-map sprites with an always-applicable rule that hides the default and adds the actual base layer at z-index 0.
  • "Targets:" and "Hide Layers:" don't automatically require files for the purpose of "Exclude unused files". You can make a rule without targets to mark files as used.
  • The "Preload?" flag is quite aggressive and loads/reserves layers along with any of the rule's targets, so it shouldn't be used if a target image is used in unrelated situations or the precise timing isn't as important.
    • Layers do not desync just because some aren't loaded yet.
  • This plugin does not prevent flickering where a tile Event is involved or when the base image switches between a "big" (single-form, with '$' in the file name sign) character image and a multi-form spritesheet!

Load Order

Dynamic Characters should be loaded relatively late, in order to have priority when splitting and merging Character image file names. It may have to be loaded before some other plugins that manage Character images more coarsely.

Plugin Parameters

AddCharacterTags Command,
RemoveCharactersTags Command,
ClearCharacterTags Command
and
ClearMapCharacterTags Command

You can use these parameters to rename the MV-style plugin commands in this plugin, in case there's a collision. MZ-style commands are unaffected.

Character rules...

Rules to add and/or hide layers for certain targets (initial layers), based on conditions checked every frame.

Rules are indexed by target and conditions are precompiled when the game starts, so this should stay fast even with hundreds or thousands of rules overall.

See the parameter help and the JavaScript- and Shorthand Conditions sections below for more information.

Layer Separator

A character or sequence of characters used to separate layers in character file names. This shouldn't appear in the names of character image files you want to display.

You can erase this parameter, in which case the text TS_Dynamic_Characters__Separator will be used.

Compatibility tweaks?

Tweaks for compatibility with certain other plugins.

These are generally enabled by default, as they should have either no or unnoticeable impact when the other plugin isn't present, but are optional.

JavaScript Conditions

Rules and their embedded character conditions ("for…") can contain JavaScript conditions, which should be boolean expressions.

In these expressions, target refers to the file name (without extension) that the rule is being applied to, tags is an array of symbols and strings containing the currently applicable tags and character is the Game_CharacterBase instance currently being examined.

In actor and enemy conditions, battler refers to the Game_Actor or Game_Enemy that the condition is examining.

This means you can for example write (battler.hp / battler.mhp) <= 0.5 in an Actor condition to only apply the character rule while the examined Actor is at or below 50% of their maximum HP. (See the next section for a shorter way to write this rule!)

End-of-line comments (with //) are allowed in JS and shorthand conditions.

Shorthand Conditions

Rules and character conditions can contain "shorthand conditions", which are a convenient way to write JavaScript conditions more concisely. For example, here (in an Actor condition) you can even write (hp / mhp) <= 0.5 for the same effect as above!

This is because, inside shorthand conditions, the following identifiers are available, in addition to the target, tags, character and, in Actor conditions, battler parameters also present in JavaScript conditions:

Sw… and Var…, not following ., where is a series of digits

These identifiers are expanded into getting the state of the numbered Switch or value of a Variable.

character location

  • regionId and terrainTag: These evaluate to the respective number value.
  • isOnBush and isOnLadder: true or false depending on location.

character properties and state

isThrough, isDashing, isMoving, isStopping, isJumping, isNormalPriority, isObjectCharacter (i.e. no "!" in the filename sign), isDirectionFixed, isAnimationPlaying, isBalloonPlaying, hasWalkAnime and hasStepAnime evaluate to true or false depending on the character's current state and configuration.

checkStop(threshold: number)

You can call the checkStop method without prefixing it with character. in shorthand conditions. Pass a number and it will return true or false, so for example checkStop(10) returns true iff the character has been stopped for more than 10 frames.

volatile character properties

moveSpeed, moveFrequency, opacity, blendMode, jumpHeight, realMoveSpeed, distancePerFrame, direction and bushDepth are number-returning methods on character that may change frequently during characters' movement on the map.

In shorthand conditions, you can use them as free-standing identifiers that evaluate to the respective return value directly.

battler state

Similarly to Sw… and Var… above, St… can be use to check whether the battler is affected by the specified state.

Additionally, the following boolean identifiers can be used directly (and are expanded into method calls):

isDeathStateAffected, isDualWield, isAutoBattle, isGuard, isSubstitute, isPreserveTp, isHidden, isAppeared, isDead, isAlive, isDying, isRestricted, isConfused, isActor, isEnemy

battler buffs & debuffs

The following evaluate to the respective buff level as number, where level 0 is neutral:

mhpBuff, mmpBuff, atkBuff, defBuff, matBuff, mdfBuff, agiBuff, lukBuff, anyBuff (= the sum of all other buff levels)

You can also get booleans according to the following pattern:

mhpIs…, mmpIs…, atkIs…, defIs…, matIs…, mdfIs…, agiIs…, lukIs…, anyIs…
…MaxBuffAffected, …BuffAffected, …DebuffAffected, …MaxDebuffAffected, …BuffOrDebuffAffected, …BuffExpired

battler options

Use these booleans to check a battler's options in combat:

canInput, canMove, canAttack, canGuard

battler properties

The following properties of battler can be used as if they were local variables (without backticks):

  • hp: Hit Points
  • mp: Magic Points
  • tp: Tactical Points
  • mhp: Maximum Hit Points
  • mmp: Maximum Magic Points
  • atk: ATtacK power
  • def: DEFense power
  • mat: Magic ATack power
  • mdf: Magic DeFense power
  • agi: AGIlity
  • luk: LUcK
  • hit: HIT rate
  • eva: EVAsion rate
  • cri: CRItical rate
  • cev: Critical EVasion rate
  • mev: Magic EVasion rate
  • mrf: Magic ReFlection rate
  • cnt: CouNTer attack rate
  • hrg: Hp ReGeneration rate
  • mrg: Mp ReGeneration rate
  • trg: Tp ReGeneration rate
  • tgr: TarGet Rate
  • grd: GuaRD effect rate
  • rec: RECovery effect rate
  • pha: PHArmacology
  • mcr: Mp Cost Rate
  • tcr: Tp Charge Rate
  • pdr: Physical Damage Rate
  • mdr: Magical Damage Rate
  • fdr: Floor Damage Rate
  • exr: EXperience Rate

battler phase

These battle-flow related shorthands are likely not useful for choosing a Character sprite on the map, but they are still available in this plugin:

isSelected, isUndecided, isInputting, isWaiting, isActing, isChanting, isGuardWaiting

isChanting and isGuardWaiting are true while the battler isWaiting to perform a magic or guard skill, respectively.

event state

In Event conditions, the following additional shorthands are available instead of battler ones:

SSwA, SSwB, SSwC and SSwD retrieve the value of the Event's Self-Switches 'A', 'B', 'C' or 'D', respectively.

vehicle state

In Vehicle conditions, the following additional shorthands are available instead of battler or event ones:

isBoat, isShip, isAirshipWhether the vehicle is the given type.
isLowest, isHighestAirship state.
isTakeoffOkSeemingly unused. Checks whether followers are gathered at the player's position.
canMoveWhether the vehicle is allowed to move.
By default always true except for airships not at highest altitude.
isLandOkWhether the party may exit the vehicle at this location/direction, by landing the airship or disembarking a boat or ship.

Plugin Commands

AddCharacterTags kind id ...tags (MV),
RemoveCharacterTags kind id ...tags
(MV),
ClearCharacterTags kind id
(MV),
ClearMapCharacterTags id (MV)

kindactor, event or vehicle (without backticks, case-insensitive)
idfor actors and eventsID numbers
for vehiclesboat, ship or airship, case-SENSITIVE
For "ClearMapCharacterTags"The Map ID of the Map on which to remove all Events' Character Tags.

These commands add and/or remove preset tags on Characters. These tags can be checked by rules, and unlike tags added by rules are persistent for the given Character.

Change Character Tags (MZ),
Clear Character Tags (MZ),
Clear Map (Event) Character Tags (MZ)

The MZ-style Plugin Commands provide the same functionality as the MV-style commands, but grouped somewhat differently due to the richer Plugin Command interface available there.

JavaScript API

This plugin unconditionally sets the global variable TS_Dynamic_Characters when first loaded.

There, the following properties and functions are available:

version

Semantic Version-compatible featureLevel and patchLevel information.

I don't reset the patchLevel to 0 when incrementing featureLevel, so that patchLevel alone is enough to determine whether a certain fix is available in each version.

This property is frozen and the object is frozen.

parameters

Parsed plugin parameters, with trailing _, __ and _files stripped from property names. The shorthand and JS conditions are present as functions, here, and missing arrays and strings are added as empty. Boolean properties are normalised to true or false.

This property is frozen, but the object is mutable.

CharacterRule, BattlerCondition, ActorCondition, EventCondition and VehicleCondition

Classes that validate and evaluate rules. It's possible for other plugins to extend these to create more advanced rules programmatically.

These properties are frozen, but the classes are mutable.

mvAddCharacterTags, mvRemoveCharacterTags, mvClearCharacterTags, mvClearMapCharacterTags, mzChangeCharacterTags, mzClearCharacterTags, mzClearMapCharacterTags

Plugin command handler functions, called with a Game_Interpreter instance as this-argument and arguments in their parameters.

changeActorTags(actorId, addTags, removeTags),
clearActorTags(actorId),
changeEventTags(eventId, addTags, removeTags),
clearEventTags(eventId),
clearAllEventTagsForMap(mapId),
changeVehicleTags(vehicleId, addTags, removeTags),
clearVehicleTags(vehicleId)

Used by the "…CharacterTags" command handlers above.

actorId, eventId and mapId are numbers, vehicleId a string and addTags and removeTags are a (string | symbol)[] each.

signRegExp: RegExp

A non(!)-global RegExp to grab the sign of an img/character/ filename.

You may have to adjust this if you change ImageManager.isBigCharacter.

applyRules(indexedRules, index, characterName, tags, character): string

The function that transforms Character file names each frame.

indexedRules is a (frozen) readonly CharacterRule[],
index is a Map<string, number[]> containing indices into indexedRules,
characterName is a string (returned by Game_CharacterBase.prototype.characterName),
tags is a (string | symbol)[], copied from the Character's preset tags and
character is a Game_CharacterBase to test the relevant rules on.

gatherSavedInstances(): Generator<{} | null | undefined, void, void>

A generator function that returns all instances for which preset tags should be saved at that time. For simplicity, this function is also allowed to yield null and undefined, which are ignored.

oldPluginCommand, oldLoadCharacter, oldReserveCharacter (MV-only), newPluginCommand, newLoadCharacter, newReserveCharacter (MV-only), oldCreateGameObjects, oldMakeSaveContents, oldExtractSaveContents, newCreateGameObjects, newMakeSaveContents, newExtractSaveContents

Functions associated with engine hooks installed by this plugin, where old… has the original implementation and new… this plugin's.

The hooks are installed with a small trampoline, which means that changes to these properties are effective at the respective position in the call chain.

Save Contents

This plugin creates an additional top-level key TS_Dynamic_Characters in each normal save file. There, the following properties are stored:

instanceTags: [Game_CharacterBase, string[]][]

Tag settings for Actors and Vehicles, attached to their instance identities.
Note that only string tags are preserved.

See also *gatherSavedInstances() in the API for how to save this information for custom uses of Game_CharacterBase.

eventTags: (((string | symbol)[] |undefined|null)[] |undefined|null)[]

Per Event tag settings for Map Events. As their instances are not persisted, keyed storage is used here instead (also at runtime).

Like with the instanceTags, only string tags are preserved across saving and loading.

Compatibility Notes

This plugin was tested on RPG Maker MV 1.6.3 and RPG Maker MZ 1.7.0, uses only the public RPG Maker API as far as possible, and does not use any platform-specific APIs.

This plugin should be compatible with any deployment target available for RPG Maker MV and MZ, including web and most custom ones.

If you notice issues or glitches in combination with other plugins, please tell me about them, and I'll check if a compatibility tweak is feasible.

This plugin is compatible with YEP_ItemCore (independent items).

Copy of License Grant

(as included in the plugin file, aside from line wrapping)

A license for this plugin can be purchased at https://tamschi.itch.io/dynamic-characters .

Once you have purchased it, you may redistribute and sublicense this plugin file as part of games you create. You may not redistribute nor sublicense it separately or as part of an asset- or resource-collection.

You may modify this plugin when including it with your games, as long as the attribution above and this license grant stay intact. If you do so, you must add comments to indicate which changes you made from the original.

Social Media

If you'd like to help me out a bit, I'd hugely appreciate if you could share this page with others who may be interested in this plugin. To make that more convenient, I've created a few social media accounts for updates and announcements:

Announcement on Mastodon (via Elk), Announcement on Bluesky

I'll continue to post all important updates here on itch.io, of course, and the comments below remain the easiest way to reach me if you have any questions or bug reports.

Purchase

Buy Now$20.00 USD or more

In order to download this RPG Maker Plugin you must purchase it at or above the minimum price of $20 USD. You will get access to the following files:

TS_Dynamic_Characters.js (MV+MZ) 107 kB
Version 1.1.0

Development log

Comments

Log in with itch.io to leave a comment.

Hi there! Just found your page. This plugin and dynamic pictures looks awesome! I took a look at the DLC you mentioned, but your plugins frankly look more robust and useful and I would rather support our community of talented people.

I just saw your comment below about tying the two plugins together via the API? Any chance you might do that sometime soon-ish? That would be icing on the already very tempting cake.

Imma going to buy them either way of course :) They are just what I have been looking for.


(2 edits)

Thank you for the praise and consideration ā˜ŗļø

I hadnā€™t really thought fully through the combinationā€¦ but yes, this is feasible, if not quite as flexible as each plugin separately. (You could combine these approaches, of course, also on the same sprite(s).)

I assume you use Pictures for example as Actor talk sprites in cutscenes, and may also have Actors that appear as Events while not in the party?
The latter isnā€™t supported all that well by Dynamic Characters directly, but a controller that combines them can use the broader Actor condition implementation from Dynamic Pictures and apply them to bothā€¦
I should be able to give you a choice on whether to apply a rule to all Characters or only the specified Actors in the party, so that you can still use combined Actor character spritesheets if your Actors donā€™t appear as Events.

I wonā€™t have to do much testing or new UX design (for the plugin parameters) for this, so I can give you a rough ETA of two weeks. I canā€™t fully guarantee this estimate due to some life stuff I have going on, but at least from a technical point of view, I donā€™t expect any obstacles.

(+1)

Hey! Wow, thanks for the thorough response. There's no rush! I'm just waiting for payday to roll around. My game likely wont be finished this year or next, so take your time :D life comes first.

I am no coder yet (I can do a bit of JS when I need to, but large scripts still make my head spin, very much a novice tutorial-follower). The reason the combination sounded appealing to me is this: I have decided to try to drive myself insane by making a single-player life-simulator game. Only 1 main actor, the rest of the cast will be NPC Events that (with a handful of possible exceptions) don't need to change an awful lot through the game. I can do most of that within the vanilla engine. 

But for the main player, nearly every choice you make will change your character in some way, for good or bad.  Much will be subtle, but some consequences will be major and need visually representing. Mood/status, clothing, scars, tattoos, fat/thin, etc. So I was looking for a way to represent as many of these changes as possible both in the player map sprite and character portrait (which would be visible when talking and when you open the skills and stats menus). And that is how I stumbled upon your plugins =)

The idea is the game plays out over a set timespan of 10-20 in game years, but it can be replayed many times for many different outcomes. I want the gameplay to be as non-linear as possible. But obviously, keeping up with the sheer number of sprites needed for that amount of player choice without plugins is a path to madness. lol

I have no idea if I can achieve everything I want with your plugins, nor of course would I expect that, but it seemed the combination of the two would be the best "starting block" currently available for me to study and (try to) build off. 

(1 edit)

I think what you describe is fully supported. Iā€™m still making it a little more versatile than that so itā€™s useful for many kinds of games, though. (Itā€™s really not much effort at all.)

Rules can influence later rules through the tag system, so itā€™s pretty easy to set up variations of a rule. You likely will have to use one rule per variation, though, unless you extend the plugins, and if something is at once in front of and behind something else that will need two rules too.
Itā€™s possible to hide the base layer and replace it with a different one, so weight changes and different poses shouldnā€™t be a problem.

The default character portrait drawn onto the message box and menu unfortunately isnā€™t affected by my plugins. (Itā€™s not really a Sprite normally, which makes it difficult to work with.)
If you add a (modified) Sprite_Picture sourced from a Game_Picture to the Scene_Status, or to the window directly, that will be affected though! Hereā€™s the one I use in Live Menu and Pause (for the pause screen Picture):

class Sprite_Pause extends Sprite_Picture {
	/** @override */
	initialize() {
		super.initialize(0);
	}

	/** @override */
	picture() {
		return pausePicture;
	}

	/** @override */
	updatePosition() {
		super.updatePosition();
		// Because I don't use the standard Picture container.
		// (See `Spriteset_Base.prototype.createPictures`.)
		this.x += Math.floor((Graphics.width - Graphics.boxWidth) / 2);
		this.y += Math.floor((Graphics.height - Graphics.boxHeight) / 2);
	}
}

pausePicture is just a standard new Game_Picture() that I called .show(ā€¦) on to set it up. In theory you can make that a constant in a plugin if there are no changing parameters. The load order doesnā€™t matter vs. mine, since I hook into the Sprite_Picture and Game_Picture prototypes without changing the instances.

(2 edits)

-whoops, self replied-

The combined-rules plugin is now available: Dynamic Actors

I admittedly gave you a safe estimate on when Iā€™d get this done, but it also just turned out to be much less work than expected. I guess I can thank past-me for good API design šŸ˜…

Enjoy, and let me know if there are any problems or features youā€™d like to see added.

(+1)

Hey man! Thank you so much :). I picked everything up just now. Looking forward to having a play with it this week. 

Thank you for your purchase! Please let me know how it works for you, especially if thereā€™s anything you think could be improved.

I see that this states it only works for top down sprites, not sideview battlers. Would Dynamic Pictures be what I use to have dynamic SV sprites and what would be the best method to tie them together?

(2 edits)

I currently donā€™t have a plugin that adds bitmap composition to side-view battlers. (Dynamic Pictures only works on Sprite_Pictures showing Game_Pictures, usually shown with the ā€œShow Pictureā€¦ā€ command.)

The main reason is that the games Iā€™m contributing to donā€™t use the side-view battle mode. If your game uses a Picture to represent the player character(s) and/or enemy, then Dynamic Pictures would work for that. Otherwise, a plugin layering battler bitmaps is needed.

The cleanest way to tie my plugins together is through their JavaScript APIs. I could make a plugin (at no extra charge) that specifically targets Actors and sets up those rules in both Dynamic Pictures and Dynamic Characters at once. It doesnā€™t sound like that would fit your use-case, though.

(+1)

Thank you for the reply. While sideview bitmaps would be nice (saves a lot of on asset compatibility), I understand why it isn't an option. I'll keep looking around for such then.

I do think, even if it wouldn't fit it, the Dynamic Actor/Picture tie-in rules would be a good idea.

I agree. For now Iā€™ve created it as placeholder file in my project repository, though Iā€™m probably too busy with other things to work on it soon.

(1 edit)

I should probably mention that here even if it costs me half the sales: Since one week after I published this plugin, there is now official DLC for RPG Maker MZ that has a lot of feature overlap and also covers other actor appearances like side-view sprites.

I havenā€™t used it and the Steam page doesnā€™t show the plugin settings, though, so I canā€™t comment on how easy it is to make use of.