Photoshop Plugins With UXP: Scripting

Clock icon 3 Min. read

The previous post in the series provided a general overview of UXP, Adobe’s new extensibility platform for Creative Clouds apps. Let’s now look at a simple script, how to run and debug it, as well as how scripts can be used to show simple UI to the user.

A simple script

UXP scripts are written using modern JavaScript, powered by the V8 engine. Here’s an example of a script that creates a new document and adds a text layer to it:

const { app } = require("photoshop");
 
const doc = await app.createDocument({ width: 600, height: 600 });
const layer = await doc.createTextLayer({ contents: "Hello world!", fontSize: 32, position: { x: 100, y: 100 }});

I’m really a fan of how expressive modern JavaScript can be. Most commands triggered on the Photoshop side, like app.createDocument above, are asynchronous and should be awaited for completion. Because scripts run in a modal context, await can be used freely throughout the script.

To run the script, just save it with the .psjs extension and double click the file. This should yield the following mind-blowing result:

A screenshot of the Photoshop document created by the script, with the "Hello world!" layer visible

Read more...


Photoshop Plugins With UXP: Introduction

Clock icon 5 Min. read

This is the first in what I think is going to be a series of posts about UXP — Adobe’s newest framework for writing plugins and scripts for Photoshop and other Creative Cloud apps.

A screenshot of some JavaScript code

This post provides a general introduction to the framework alongside some personal thoughts. Future posts will probably be shorter and cover specific development topics as I work on migrating my Expresso Exporter plugin from CEP to UXP.

A little bit of history

If you’ve ever attempted to write a Photoshop script or plugin you know that it can be quite a challenge. As far as I know of, there have been three main ways to extend Photoshop until now:

  • ExtendScript: a JavaScript-like scripting language available in Photoshop and other Adobe apps since forever. It can be used to write scripts with simple UI. It’s very old and slow and haven’t received any significant update in a long time.
  • CEP (Common Extensibility Platform): can be used to create custom panels and dialogs in Photoshop and other apps. Every CEP plugin runs in a hybrid browser (CEF) / NodeJS environment with support for fairly modern web technologies. Unfortunately, any interaction with the underlying app still needs to happen via ExtendScript, making plugins this weird monster made of different technology stacks.
Tech stack layers of a CEP extension, including HTML, CSS, JavaScript and ExtendScript
Tech stack of a CEP extension. Source: Adobe.
  • C++ Plugins (CSDK): native C++ plugins, also available in Photoshop since forever, are the go-to way to implement filters, file importer/exporters and generally everything that involve computation-heavy logic. Native plugins can also be included in CEP plugins, creating so called “hybrid” plugins.

(The list above doesn’t include the Generator framework or the Kevlar-based API for brevity.)

All these solutions are either old, slow, complex, scarcely documented or buggy and, generally, a pain to work with. There are tools — including some written by yours truly — that try to improve things, but maintaining rather complex plugins have always proven problematic.

Read more...


How to Deal Damage to World Actors With GAS

Clock icon 2 Min. read

While working on The Bug Squad I run into a situation where I needed to apply damage to world actors — in my case explosive barrels — using the Gameplay Ability System.

Early explosive barrel implementation using GAS.

The standard way to do this in UE is to set bCanBeDamaged to true on the actor and override the TakeDamage function and/or related events. This, however, doesn’t work with GAS where damage is applied via gameplay effects.

A quick search in the Unreal Slackers Discord showed the common practice is to give an AbilitySystemComponent to these actors. Apparently, this is also the approach Epic uses in Fortnite for world objects that can be destroyed such as rocks, trees, walls, etc.

Read more...


How to Customize the UE5 Place Actors Panel

Clock icon 1 Min. read

While working on a project or a custom plugin in Unreal Engine it can be useful to add custom actor classes to the Place Actors panel. This is my custom panel for The Bug Squad, which I’ll be using as an example for this post:

A screenshot of the custom category in the UE5 editor

First, the PlacementMode module should be added as a dependency in the editor module’s build.cs file. Here’s mine:

BugSquadEditor.build.cs
using UnrealBuildTool;
 
public class BugSquadEditor : ModuleRules
{
    public BugSquadEditor(ReadOnlyTargetRules Target)
        : base(Target)
    {
        // [...]
 
        PrivateDependencyModuleNames.AddRange(new[]
        {
            "BugSquad",
            "Core",
            "CoreUObject",
            "Engine",
            "PlacementMode",
            "SlateCore",
        });
    }
}

Read more...


The Bug Squad: An Update

Clock icon 2 Min. read

A lot has happened on The Bug Squad over the past few months and I’m quite happy about the progress so far. Here’s how things look:

Progress!

My original plan was to aim for an arcade gameplay built on top of procedural levels and hordes of monsters, but I gradually pivoted to a more story-driven experience. This gave me the perfect excuse to go back doing level design work (which I haven’t done in ages) and also allowed me to code a quest system (which I’ve never done before).

Procedural generation tests

I still made some quick tests with procedural generation and with Poisson Disk Sampling in particular. The algorithm is effective at procedurally placing objects such as monsters, objectives, decorations, etc. I’ve tried to use it to generate lumps of terrain as well.

My implementation is based on this one and could be expanded to use disks of different sizes to make the object distribution more interesting. I have to say Unity is really good to make quick tests thanks to C# and the OnDrawGizmos event for debug visualization.

Read more...