Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Tamschi

51
Posts
4
Topics
42
Followers
78
Following
A member registered Oct 05, 2015 · View creator page →

Creator of

Recent community posts

(2 edits)

Please don’t stress out over it, but thank you, any amount really helps.

Battler Flipbooks Core can be used for free, so please first make sure it works for what you’d like to use it for. (There is an option to not pay anything after you use the “Download now” button on this page.)

If you’re satisfied, you can use the button again and enter the amount that feels right to you.
If you decide on an amount that would be enough to purchase one of my paid plugins, I recommend making that purchase instead, since that way you’ll get another useful plugin 🙂

(It really is fine to do this, since my compensation doesn’t depend at all on which one you choose if you enter the same amount.)


And just to make sure there’s no misunderstanding: You don’t need a GitHub account to use the template. First click on Battler_Flipbooks_LAYER.js, then on this button above the file content to download it to your computer:
Download raw file

You can then save it in your plugins/ folder and edit it with any plaintext editor if you need to make changes.

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

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.

(2 edits)

-whoops, self replied-

(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)

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 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.

(For anyone stopping by: This was out of genuine concern, but ultimately a non-issue.)

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.

(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.

I received confirmation (hours ago) that the detection has been removed, so if you get a malware alert from Microsoft Defender, please update its signatures to the newest version.

(5 edits)

Windows Defender may detect this (zipped) as Wacatac.B!ml.

This is an extremely common false positive. The !ml suffix stands for “machine learning”, so this is another case of unreliable AI being used 😮‍💨

I’ve already sent in a false-detection report to Microsoft for the file, but processing may take a while as higher priority support is paywalled and unavailable to single users. Update: They took about five hours, that’s okay in my book.

Here’s the (clean) VirusTotal scan of the archive: https://www.virustotal.com/gui/file/400037bcc0578f272a080e8baef5db6885200f561e7a0d728f3b07d8f58a1a95/detection

(2 edits)

I was able to publish the example plugin earlier than expected: https://tamschi.itch.io/battler-flipbooks-core/devlog/692886/layer-example-plugin

This is a small script that only shows damage animations, but it can be modified to play animations for other events.

(If this already solves your problem, I would greatly appreciate a small support payment, as creating polished plugins like Battler Flipbooks Core takes a lot of work. Only if you can spare it, of course.)

(10 edits)

Hello (and sorry for not replying earlier. I’m currently away from home, so I can’t check back quite as often)!

I’ll try explain it in a way that translates well. My answer also depends on whether you are able to write JavaScript plugins.

This “Core” here takes care of loading, running and displaying animations, but it doesn’t know when to start or shorten animations. At least one “Layer” is needed, which triggers animations based on the flow of battle.
(I broke this into multiple parts to make it more affordable, as for many games, just one or two Layers are needed.)

If you’d like to use a premade Layer (without writing JavaScript), I recommend Occasional Battler Flipbooks in most cases. This Layer allows you to have attack, damage, miss, evade and K.O. animations, among others. It can’t distinguish different attacks or damage types, however. It also can’t use contextual parameters like the damage amount. Please check the video on the page to see if this fits your use-case.

To also (or only) add frame-based entrance and idle animations, I recommend Battler Entrance Flipbooks. This Layer starts a single animation along with the battle and can also delay the start of battle until after the entrance animations.

Layers stack, so if you use both, then “occasional” animations can interrupt the idle animation, which then resumes once the “occasional” animation is over. You can see an example of this in the video for Battler Flipbook Sound Effect Events, which is an “Add-In” that adds sound effects to any Layer. You can keep using the default sound effect system too, of course.

I can’t offer translations for the help text, since I can’t afford a professional translation. Machine translation usually doesn’t work well with this kind of technical text.
However, if it would be helpful, I could try to machine-translate the parameters and their descriptions starting around the end of next week. I would be very thankful if you could point out errors, in that case.


If you know how to write your own plugins in JavaScript, you could also create your own Layer plugin instead of using one of mine.

Layers usually have one parameter where rules are entered, like this:

@base TS_Battler_Flipbooks_Core

@param rules
@text Rules...
@desc Animation rules for actors and enemies. The first full match is used.
@type struct<FlipbooksRule>[]
@default []

(The parameter definition of FlipbooksRule and nested structs is included in Battler Flipbooks Core’s source code and must be copied into each Layer.
Most Layers change it somewhat since they have additional conditions or effects.)

Then, in JavaScript, you can parse the parameters and instantiate the runtime like this:

'use strict';

const core = TS_Battler_Flipbooks_Core;

const parameters = PluginManager.parameters(NAME_OF_THE_LAYER_PLUGIN);
core.decodeParameters(parameters);

class MyRule extends core.FlipbooksRule {
    // Custom conditions can be added here.
}

// Hydrate rules from decoded parameter objects:
parameters.rules = parameters.rules.map(dpo => new MyRule(dpo));

// Using a derived runtime with its own name improves error messages:
class MyRuntime extends core.FlipbooksRuntime { }

// Create the runtime instance:
const runtime = new MyRuntime({
    rules: parameters.rules,

    // Other options. I normally have these in parameters, but this are okay defaults:
    enableHomeOverride: false, // Use `true` to use "Home override..." function!

    // These make the Layer work better with some other plugins:
    compatibilityTweaks: true,
    spriteSizeTweak: true,
    spriteSizeTweakUsePoseForPointer: true,
    spriteActorUpdateAppearTweak: true,
    spriteActorUpdateDisappearTweak: true,
});

Then, you can apply the rules at any time (normally in a hook) by calling runtime.apply(battler, {}), which will start applicable animations.

This here is (roughly) what runs the animations in Battler Entrance Flipbooks:

const api = window.MyPlugin = {
    ...core.makeHook(() => api, BattleManager, function setup() {
        const result = api.oldSetup.apply(this, arguments);

        for (const battler of BattleManager.allBattleMembers()) {
            runtime.applyRules(battler, {}); // <- You can pass named parameters here.
        }

        return result;
    }),
};

core.makeHook is a helper function I use to let other plugins easily change my hooks. You can hook an engine function plainly instead like this:

const oldSetup = BattleManager.setup;
BattleManager.setup = function () {
    const result = api.oldSetup.apply(this, arguments);

    for (const battler of BattleManager.allBattleMembers()) {
        runtime.applyRules(battler, {}); // <- You can pass named parameters here.
    }

    return result;
};

(This is quite minimal, but enough to run idle animations. I can make a starter project for layers around the end of next week and upload it here under a permissive license.)

(1 edit)

No, keep that. The code just stores the function from before it’s turned off.

This is a general JavaScript thing, if you replace a function you just replace it at that location (‘property’), but the function instance itself can still remain referenced elsewhere if the reference had been copied beforehand.

In this case, the backup reference is stored as PressTurnBattleSystem_removeStatesAuto and .call calls it as if it was a method of the first parameter, with the remaining parameter(s).

Yes, I wrote this so you can place it where you define CheckAllBattlersStates now and it will work. Just replace that entire assignment.

The reason I grabbed the original Game_Battler.prototype.removeStatesAuto there is so that if another plugin hooks that, its logic will still run if this one is applied later. That may avoid compatibility issues in some cases.

(1 edit)

The turn end function works perferctly now, thank you!

For the message, it works if you add these two lines (separately) to CheckAllBattlersStates:

BattleManager._logWindow.displayChangedStates($gameTroop.members()[i]);
BattleManager._logWindow.displayChangedStates($gameParty.members()[i]);

If you’d like to simplify CheckAllBattlersStates a bit, this version of it also works:

var PressTurnBattleSystem_removeStatesAuto = Game_Battler.prototype.removeStatesAuto;
function CheckAllBattlersStates() {
    for (const battler of $gameTroop.members().concat($gameParty.members())) {
        for (const state of battler.states()) {
            if (state.autoRemovalTiming === 2) {
                if (battler._stateTurns[state.id] > 0) {
                    battler._stateTurns[state.id]--;
                }
            }
        }
        PressTurnBattleSystem_removeStatesAuto.call(battler, 2);
        BattleManager._logWindow.displayChangedStates(battler);
    }
}

(Feel free to use this with or without giving credit, I really just refactored what you already had for the most part here.)

Right, please don’t overtax yourself on this. In any case: Thank you for fixing this so far!

The timing looks mostly correct now. The turn-end-removal states tick down only on the own teams turn end though.
Having it happen for all battlers on either turn end would be a lot more convenient, since it would allow me to time out the statuses just before the team acts again (like in Shin Megami Tensei: Liberation Dx2).

I can easily fix that on my own end, though, in case you prefer the current behaviour.


Since this is otherwise working now, I noticed another bug (maybe): The state removal message doesn’t appear for turn-end removals. I believe I can messily patch this on my end, but it may be worth looking into solving that more properly, too.

Ah, that was me probably! I’ll give it another spin.

(2 edits)

Auto-removal Timing: Action End appears to be working perfectly now (though I didn’t test interactions with restriction) 👍

However, Auto-removal Timing: Turn End is not. It seems to tick down once after each action by a battler on the same team, rather than when the team turn ends, likely because Game_BattlerBase.prototype.updateStateTurns is still called too frequently. Maybe I was mistaken and that one was the one to block.


Side-note: Since you (effectively) reimplemented Game_Battler.prototype.removeStatesAuto from scratch, there could be compatibility issues with some plugins now (though I’m not aware of any that hook that method, aside from one of my animation plugins in a very optional way).

If you want to block a function and still use it, it’s better to do it like this:

const oldRemoveStatesAuto = Game_Battler.prototype.removeStatesAuto;
Game_Battler.prototype.removeStatesAuto = function() {};

// and later to use it:
oldRemoveStatesAuto.call(battler, timing);

That way, your plugin will run other plugins’ hooks on that function correctly, if they were loaded earlier.

(3 edits)

I’m not sure. I haven’t checked very deeply how everything works with this plugin.

What I would try to do, personally, is to preserve more of the original turn infrastructure. I suspect this would require a relatively significant rework of this plugin, though, and I can’t tell you how feasible it is in general.

Edit: Alternatively, you could block Game_Battler.prototype.removeStatesAuto where it’s called with a timing that indicates turn-end, and call the original handler manually when control switches to the other team. I actually tried this, but I don’t understand your plugin well enough to make it work easily.

Thank you, glad to help 😊

I haven’t been able to test this, so unfortunately I still haven’t been able to include a Mac section yet, which is a little irksome. However, in case you are looking to publish for that platform too, the “64-bit” download of NW.js corresponds to “Intel” Macs and the “ARM64” version should work for any “M1”/“M2”/… Macs.

Thanks! It’s not super pressing currently, but would be really nice.

Only for states that have it set to “Turn End”. If Auto-removal Timing is set to “Action End”, it should happen after each time that specific battler would act.

Currently, what happens with this plugin is that all states with either auto-removal timing tick down each time an action ends (or something like that). This makes all states tick down very quickly (and unfortunately in a way that’s impossible to configure correctly for battles with various battler counts).

(2 edits)

Let’s say I have the Guard skill set up as follows (with Restriction to ensure the battler can’t act while that’s active): grafik.png

I also increased the Duration to 2 here since the parties take turns separately (and counting these “half-turns” would give more control). I expect the ‘Guard’ state to end reliably when the enemy team is done.

This is a somewhat special case, but in general I’m looking to use states that last a certain number of “team-turns” regardless of how many enemies are in the troop. In vanilla RPG Maker this is easily achieved with Auto-removal Timing: Turn End.

Edit: This should have “Remove by Restriction” disabled, so please disregard that. It’s not relevant to the issue, since I ran into it without that.

(2 edits)

The state duration decreases after each action of any battler, even though auto-removal timing is set to turn end.

I believe this happens because BattleManager.getNextSubject is changed to always return null (since then BattleManager.updateTurn will call BattleManager.endTurn).

Ideally, I would expect BattleManager.endTurn to be called each time a team uses up all their turns instead.

(4 edits)

The state duration issue still remains, unfortunately, which means I can’t really use this plugin.

Edit: <Don't skip turn> doesn’t seem to work for enemies, but fortunately I don’t need that function.


Side-note: Since one of the updates, this plugin creates more globals again, i.e. it’s not namespaced.

It’s not super likely they’ll collide going by their names, but there’s a potential compatibility risk there.

(1 edit)

(Still going to make the compatibility checker, just a bit out of commission right now because I caught a cold.)

Edit January 25th: The Compatiblity Tester plugin is now available as free “demo” above.

That’s a good idea, but I don’t think I’ll be able to do so before the holidays/new year. For what it’s worth, the risk of incompatibility should be very small:

This plugin installs only transparent hooks, so it doesn’t undo or hide any previous plugin’s features.

It also doesn’t extend any engine classes or instances with new properties, doesn’t call functions with additional arguments or new argument types, and creates no globals other than the TS_Dynamic_Pictures one, so there should be no risk of ‘hard’ collisions.
(I always use a WeakMap to manage instance-attached state.)

As far as interference with this plugin goes, check if the other plugins do any of the following:

  • change Sprite_Picture.prototype.updateBitmap (a lot)
  • change Sprite_Picture.prototype.loadBitmap (a lot)
  • change how Bitmap instances are constructed and loaded (a lot)

Dynamic Pictures doesn’t change these directly, but it needs the string from Game_Picture.prototype.name to flow into ImageManager.loadPicture relatively verbatim in cases where you use more than one layer.

It also needs to create a deferred Bitmap and manually put that into 'pending'/'loading' and then 'loaded' state. This should work unless the Bitmap logic is entirely rewritten by another plugin (which I haven’t seen so far).

For example the Yanfly series of plugins is compatible. I assume the VisuStella MZ series is structured somewhat similarly (though of course I can’t check due to the obfuscation there).

If you still notice an incompatibility or any kind of issue, please let me know so that I can fix that for everyone. I’ll keep an eye on my emails over the holidays.

If you don’t need pixel testing, picking, interaction ranges, mouse button choice, multiple entry points or mid-move accuracy, then also have a look at Tor Damian Design’s Mouse System Ex, which is free but tests only against the event’s occupied tile.

(2 edits)

Surprisingly this accepts colour names!

If you want to know what cornflowerblue is, just type that into the Hex box and press enter. (Spaces don’t matter.)

Remember to also enable each surrounding “Filter …?” group when you’d like to make use of parameters in it!

I forgot this once while testing. I’d prefer if this could be automatic, but I think it’s still more clear this way than detecting used categories invisibly.

Hm… please tell me if you figure out what exactly the issue was. I generally wouldn’t recommend using an older version, since hardware acceleration may be supported on fewer systems.

(3 edits)

This is an issue with the default package.json file I believe, which you have to edit in your game project folder. (I forgot about this step, thank you for pointing it out!)

Check if the start of the file looks like this:

{
	"name": "",
	"main": "index.html",
	"js-flags": "--expose-gc",

The updated runtime requires that the name value isn’t empty, so you can change it to something like

{
	"name": "my-game",
	"main": "index.html",
	"js-flags": "--expose-gc",

or such. (Edit: Please use a unique value! See above.) I don’t think it really matters beyond not being empty, since the title shown to the user is loaded from index.html instead.

(2 edits)

I wasn’t too sure which scopes to use as filter suggestions (for the not/in contexts: parameters), since literally any engine function technically works there, so that drop-down is relatively short. As with the occasions, you can specify custom targets just by typing them in in the same format as the suggestions, though.

If you use this feature (I imagine that in most cases you won’t, since I didn’t have to touch it at all to make the demo video.), please let me know what you found useful so that I can make it a bit more approachable.

(3 edits)

Thank you for the follow :)

Note that there will be a bit of overlap between the layers I make, since there’s a trade-off between how different the battle events that can trigger animations in a layer can be and how well the rules can react to specific context of an event.

For example, Battler Reaction Flipbooks will let you filter conveniently by how much damage an action did as percentage of the target’s max HP or its elemental effectivity, among many other action-related conditions, and can be used to make that damage-scaled fake knockback you saw in the video.

However, if you need only a simple general damage reaction per battler, then Occasional Battler Flipbooks will be enough, since it can be used to play an animation whenever the Game_Battler.prototype.performDamage engine function is called.
That one will come with a handy drop-down with suggestions for about 160 battler-related engine functions it can dynamically hook into, but without the additional filter conditions available in more specific layers.

Regarding map animations: The main reason this plugin is able to work efficiently and seamlessly at the same time is that it can predict which animations may be used based on the battlers that are present. Keeping all animations for all battlers in your game always in memory would likely cause issues due to memory use, especially on mobile/web, but they need to be in memory to play instantly when needed.

Map events also don’t (easily) have the meta data I use for flipbook rule conditions, and I can’t set up a nice object selector for them in the plugin parameters afaik, so animating them directly this way isn’t that feasible from a game content creation point of view.

The good news is that at least some map battle engines do in fact use battlers and Window_BattleLog internally, which makes them somewhat nearly compatible with this system already!
What’s needed to make it work is another plugin loaded after Battler Flipbooks Core that bridges it to the map battle system loaded earlier, and adjusts Sprite_Character to show bitmaps from a hidden Sprite_Battler-like instance animated this way during battles.

I’m close to certain that this is possible without changes to Battler Flipbooks Core, since all engine hooks are published as before/after properties and can be adjusted and called as needed without unintended side-effects due to that.

However, I currently don’t have plans to implement this myself. I am available for questions and code review towards this purpose though (and related to Battler Flipbooks in general, really).

It’s tricky because this is the kind of generic/subdued system that looks and behaves entirely differently depending on how it’s used. I have a very unpolished recording from about a month ago here with some features and fixes still missing at that point, as I had to make rough versions of some extensions to figure out and test the core, but this may not reflect well how someone else would use it in practice.

I’ll still try to make a better showcase once I have more of my code polished and published… but it will still feature those programmer art cubes or similar because I really can’t draw well enough for more than that.

In theory, you can also contact me via XMPP at tamme@schichler.dev, but I haven’t had the opportunity to test this yet, so for now I won’t include it in the list above.