Skip to content

Releases: BenMakesGames/PlayPlayMini

8.2.0

14 Jun 17:23

Choose a tag to compare

PlayPlayMini 8.2.0

Breaking changes

(Does semver mean nothing anymore?)

  • SetPostProcessingPixelShader and PostProcessingShader have been removed. They are replaced by a new scoped API, WithSceneShader (see below). To replicate the old "post-process the whole frame" behavior, wrap your entire Draw body in using (Graphics.WithSceneShader(...)).

New features

Scene shaders - GraphicsManager.WithSceneShader(...)

  • New scoped API mirroring WithShader, with two overloads:
    • WithSceneShader(Effect? pixelShader, Action<Effect>? configure = null)
    • WithSceneShader(string pixelShaderName, Action<Effect>? configure = null)
  • Renders its body into a layer-sized render target, then composites that layer to the previous target through the supplied effect. Unlike WithShader (per-draw-call), this runs once at composite time against the assembled layer, so shaders that sample neighboring scene content (ripples, blurs, refraction, chromatic aberration) work correctly.
  • Lets you shade part of a frame (e.g. shade the world, leave UI/HUD/cursor unshaded by placing them after the using block).
  • WithSceneShader(null) is a no-shader variant useful for blend isolation; nesting is supported.
using (Graphics.WithSceneShader("Warble"))
{
    // background, world, etc.
}
// banner, HUD, mouse - drawn unshaded over the warbled layer

Mouse: disable on gamepad input - MouseManager.DisableOnGamepadInput

Mirrors existing DisableOnKeyPress, but for gamepad input instead of keyboard.

After setting MouseManager.DisableOnGamepadInput = true, the cursor will be hidden when any gamepad button, trigger, or thumbstick (past a circular dead-zone) is engaged, across all four player slots.

Performance

  • KeyboardManager: PressedAnyKey, AnyKeyDown, and AnyKeyUp now take params ReadOnlySpan<Keys> instead of IList<Keys> + LINQ - no allocations, no LINQ.
  • GameStateManager.Draw: drawn-services loop converted from foreach to indexed for to avoid enumerator allocation.
  • Pooled render targets and shader scopes in GraphicsManager.

Templates

The PlayPlayMini templates project - github.com/BenMakesGames/PlayPlayMiniTemplates - has been merged into this one, and had its templates updated to work with PlayPlayMini 8.2.0.

8.0.0

16 Apr 00:46

Choose a tag to compare

Breaking Changes

MouseManager.Draw now takes an AbstractGameState instead of a GameTime

(If you're not using custom cursors, this doesn't affect you.)

When using a custom cursor, if the passed game state is not the current state, the cursor will not be drawn.

// ❌ don't do this anymore:
if(GSM.CurrentState == this)
    Mouse.Draw(gameTime);

// ✔ do this now:
Mouse.Draw(this);

If for some reason you DO want to always draw the custom cursor, pass null (for example: Mouse.Draw(null);).

Fixes

  1. One of the DrawWavyText overloads was not correctly computing the width of the text, resulting in it being off-center when the font had any horizontal spacing. This has been fixed.
  2. FixedUpdate calls are no longer fired in rapid succession after leaving the game in the background for a while.
  3. FixedUpdate calls always receive a delta time of 16.6666...ms
  4. FixedUpdate is now called every 1000.0 / 60.0 ms instead of every 16.6667ms.

Other Changes

  1. Games no longer slow down to 1 frame per 20ms when focus is lost.
    • If prefer the old behavior, set GSM.InactiveSleepTime = TimeSpan.FromMilliseconds(20); in your game's startup class.
  2. GameStateManagerBuilder.AddAssets now accepts an IEnumerable<IAsset> (instead of an IList<IAsset>).

New Stuff

  1. Added GetCenter() method to IRectangle<int> and IRectangle<float>
  2. Added Gravity property to TumblingSprite
    • it defaults to 0.2, which is the value that previous versions of the library were using internally
  3. As always: a few more docblocks

7.2.0

09 Jan 21:30

Choose a tag to compare

Big changes

PlayPlayMini.UI is formally abandoned

  • I haven't worked on this library, or even tested it, in forever
  • I have no desire to use it in any of the games I'm working on
  • if you liked this library, please feel free to fork it - take ownership, and start publishing your own NuGet packages! (it's fun!)
  • a slimmer replacement library may come in the future, based on PlayPlayMini's IRectangle<T> interface and its various extension methods

Added new PlayPlayMini.VN

  • I have used this code, or an earlier version of it, in a few games which have been published on Steam
  • ^ that said, I have published it as a release candidate (you will not see it in NuGet unless you check the box to see prerelease packages) because I have not extensively tested it in this new form

Small changes

  • added a few more docblocks throughout PlayPlayMini and PlayPlayMini.GraphicsExtensions
  • migrated many more extension methods to .NET 10's new extension block syntax
  • added extension methods to PlayPlayMini.GraphicsExtensions for drawing text with outlines when using spans

Known issues

7.1.0

21 Dec 15:21

Choose a tag to compare

  • upgraded third-party dependencies, including Autofac
  • added a few more docblocks
  • migrated a few more extension methods to .NET 10's new extension block syntax
  • added a new particle effect (ShrinkingCircle) to GraphicsExtensions

6.3.0

27 Sep 21:21

Choose a tag to compare

  • Added method overloads related to MonoGame's Rectangle class (for rectangle-drawing and .Contains checks)
  • Added an API for applying shaders to groups of .Draw* calls (see below)

Shader API

As an example, suppose you have loaded a shader called "subtractive_plasma", which uses a time-based plasma effect (via a gameTime parameter) to omit parts of drawn objects:

public void DrawLayeredMonochromePlasma(GraphicsManager graphics, GameTime gameTime)
{
    graphics.Clear(Color.Black);

    // draw a blue rectangle, with plasma "holes" (via the subtractive_plasma shader)
    using (graphics.WithShader("subtractive_plasma", s => {
        s.Parameters["gameTime"].SetValue((float)gameTime.TotalGameTime.TotalSeconds);
    }))
    {
        graphics.DrawFilledRectangle(0, 0, graphics.Width, graphics.Height, Color.DarkBlue);
    }

    // draw a dark gray rectangle, with plasma "holes" (via the subtractive_plasma shader)
    using (graphics.WithShader("subtractive_plasma", s => {
        s.Parameters["gameTime"].SetValue((float)gameTime.TotalGameTime.TotalSeconds * 1.5f);
    }))
    {
        graphics.DrawFilledRectangle(0, 0, graphics.Width, graphics.Height, Color.DarkGray);
    }
}

of course, any number of .Draw* calls may be inside a using-.WithShader block; all will have the shader applied.

6.2.0

06 Jun 20:05

Choose a tag to compare

  • Added alternative constructors for *Meta records, to support use-cases where keys and file paths are identical
  • AssetCollection.GetAll<T>() now explicitly requires T to be an IAsset
  • Added more docblocks

Alternate constructors for *Meta records

Suppose you load assets as follows:

.AddAssets([
    new PictureMeta("Map", "Backgrounds/Map"),
    new SpriteSheetMeta("SpellIcons", "Icons/Spells", 24, 24),
])

The asset keys - "Map" and "SpellIcons" in this example - make it easier for devs to refer to pictures and other assets by name, rather than memorizing a path (a path which could change!) However, to help prevent dev mistakes, you may want to use consts, anyway, in which case the key and path may as well be the same since file paths are guaranteed unique:

.AddAssets([
    new PictureMeta(Pictures.Map, Pictures.Map),
    new SpriteSheetMeta(SpriteSheets.SpellIcons, SpriteSheets.SpellIcons, 24, 24),
])

When taking this approach, repeating the same value/const for every asset is annoying. This update provides convenience constructors for when your key and path are the same:

.AddAssets([
    new PictureMeta(Pictures.Map),
    new SpriteSheetMeta(SpriteSheets.SpellIcons, 24, 24),
])

6.1.0

02 Jun 15:46

Choose a tag to compare

  • Upgraded to MonoGame 3.8.4
  • Upgraded third-party dependencies (MS, Autofac, and others)
  • Added a particle effect system to BenMakesGames.PlayPlayMini.GraphicsExtensions

Particle Effect System

The particle effect system is one I've used in a few of my Steam games so far, including Word x Word. The particle effects that come bundled with BenMakesGames.PlayPlayMini.GraphicsExtensions were copy-pasted straight out of those games, with slight modifications to make them more general-purpose.

Here's an example of a game state that creates a tumbling "glass shard" particle when the mouse is clicked.

public sealed class MyGameState: GameState
{
    private GraphicsManager Graphics { get; }
    private MouseManager Mouse { get; }

    private List<IParticle> Particles { get; } = new();

    public MyGameState(GraphicsManager graphics, MouseManager mouse)
    {
        Graphics = graphics;
        Mouse = mouse;
    }

    public override void Update(GameTime gameTime)
    {
        Particles.Update(gameTime);

        if(Mouse.LeftClicked)
            Particles.Add(new GlassShard(Mouse.X, Mouse.Y, Graphics.Height, Color.SkyBlue));
    }

    public override void Draw(GameTime gameTime)
    {
        Graphics.DrawParticles(Particles);
        Mouse.Draw(gameTime);
    }
}

6.0.0

14 Apr 03:54

Choose a tag to compare

  • Upgraded to MonoGame 3.8.3
  • Upgraded to .NET 9.0
  • Replaced FluentAssertions with Shouldly in automated tests
  • Added GraphicsManager.Clear() method (parameterless version of GraphicsManager.Clear(Color c)
  • Added more docblocks

5.6.0

31 Mar 22:52

Choose a tag to compare

Added bool GameStateManager.ContainsAsset<T>(Func<T, bool> predicate) where T: IAsset, intended to facilitate automated testing.

5.5.0

06 Mar 00:04

Choose a tag to compare

  • Can now call AddServices & AddConfiguration on the GameStateManagerBuilder multiple times