Skip to main content

Lost for easy making Construct 3 Addons.

This package works with DenoIt is unknown whether this package works with Cloudflare Workers, Node.js, Bun, Browsers
It is unknown whether this package works with Cloudflare Workers
It is unknown whether this package works with Node.js
This package works with Deno
It is unknown whether this package works with Bun
It is unknown whether this package works with Browsers
JSR Score
41%
Published
a week ago (3.0.2)

Lost by lostinmind.

Lost for easy making Construct 3 Addons.
v3.0.1

Lost is a framework for easy making Construct 3 addons using Deno (JavaScript runtime) that was created by lostinmind.

๐Ÿ’ช Advantages

Here I've compiled some of the benefits from standard addon creation for Construct 3.

  • โšก๏ธ Using the powerful JavaScript Runtime Deno.
  • โŒ Error detecting before installization of your Addon!
  • ๐Ÿ“ Only Typescript and no Javascript for your addon
  • E Typescript support for addon scripts!
  • ๐Ÿš€ Fast compilation to .c3addon format!
  • ๐Ÿงช Built-in addon testing using Developer Mode in Construct 3.
  • ๐Ÿ“‚ No need to configure separately aces.json and en-US.json files for addon. All necessary properties for aces.json and en-US.json are defined together with the function implementation.
  • ๐Ÿ” There is no need to configure addon .js scripts/files. Lost automatically detects the addon scripts/files!
  • ๐Ÿ“œ Structured categorization of all addon Actions, Conditions, Expressions. Categories are separated files like MyCategory.ts.
  • ๐Ÿšซ Possibility to mark all Actions, Conditions, Expressions in a category as Deprecated instead of having to configure each Action, Condition, Expression separately.
  • โœจ Additional tools to format the displayed text in Construct 3 itself by using built-in functions - formatting the text into a specific BBCode tag.

๐Ÿš€ Quickstart

  • Install Deno (JavaScript runtime)
  • Install Lost CLI by using deno install --name lost jsr:@lost-c3/lib/cli --global -f -A
  • Create empty folder which will be used as main folder for your addon.
deno install --name lost jsr:@lost-c3/lib/cli --global -f -A
lost create
  • Create a bare-bones project for addon by using one of the following commands:
lost create --plugin    # Creates a bare-bones project for 'plugin' addon
Check and install the latest version of Lost CLI!

deno install --name lost jsr:@lost-c3/lib@LAST_VERSION/cli --global -f -A

๐Ÿ“ Documentation

๐Ÿ”Œ Creating Plugin addon

lost create --plugin    # Creates a bare-bones project for 'plugin' addon

๐Ÿงฑ File structure

โ”œโ”€โ”€ Addon/                      # Addon folder
โ”‚   โ”œโ”€โ”€ Categories/             # Categories folder
โ”‚   โ”œโ”€โ”€ Files/                  # Addon files folder
โ”‚   โ”œโ”€โ”€ Scripts/                # Addon scripts folder
โ”‚   โ”œโ”€โ”€ Modules/                # Addon modules folder
โ”‚   โ”œโ”€โ”€ Types/                  # Addon scripts folder
โ”‚       โ””โ”€โ”€ global.d.ts         # Declaration file for your purposes
โ”‚   โ”œโ”€โ”€ icon.svg                # Your .svg OR .png addon icon
โ”‚   โ”œโ”€โ”€ Instance.ts             # Addon Instance class
โ”‚   โ”œโ”€โ”€ Plugin.ts               # Addon Plugin class
โ”‚   โ””โ”€โ”€ Type.ts                 # Addon Type class
โ”œโ”€โ”€ Builds/                     # Builds folder
โ”‚   โ”œโ”€โ”€ Source/                 # Final Construct 3 addon folder
โ”‚       โ””โ”€โ”€ ...
โ”‚   โ””โ”€โ”€ AddonId_Version.c3addon # Final .c3addon file
โ”œโ”€โ”€ deno.json                   # deno.json file for Deno enviroment
โ”œโ”€โ”€ addon.ts                    # Main addon file
โ”œโ”€โ”€ lost.config.ts              # Addon config file

โš™๏ธ Config setup

Let's setup lost.config.ts config file at first.

import type { LostConfig } from "jsr:@lost-c3/lib@";

const config: LostConfig = {
    /**
     * Set addon type
     */
    type: 'plugin',
    /**
     * Set a boolean of whether the addon is deprecated or not.
     */
    deprecated?: false,

    /**
     * A boolean indicating whether the addon supports Construct's worker mode, where the entire runtime is hosted in a Web Worker instead of the main thread.
     */
    supportsWorkerMode?: false,
    /**
     * The minimum Construct version required to load your addon, e.g. "r399".
     */
    minConstructVersion?: 'r416', 
    /**
     * Pass false to prevent the addon from being bundled via the Bundle addons project property.
     */
    canBeBundled?: false,
    /**
     * Pass true to set the plugin to be a single-global type.
     */
    isSingleGlobal?: true,

    /**
     * An object name that will applied after plugin was installed/added to project.
     */
    objectName: 'LostPluginName',

    addonId: 'Lost_MyAddon',
    addonName: 'Lost addon for Construct 3',
    addonDescription: 'Amazing addon made with Lost.',
    category: 'general',
    version: '1.0.0.0',
    author: 'lostinmind.',
    websiteUrl: `https://addon.com`,
    docsUrl: `https://docs.addon.com`,
    helpUrl: {
        EN: 'https://myaddon.com/help/en'
    }
}

export default config;

โš™๏ธ Addon setup

Let's setup addon.ts file at second.

import { Plugin, Property } from 'jsr:@lost-c3/lib@3.0.0';
import config from "./lost.config.ts";

const Addon = new Plugin(config)

Addon
    .addFilesToOutput()

    .setRuntimeScripts()

    .addRemoteScripts('https://cdn/index.js')

    /** @Properties  */
    .addPluginProperty('integer', 'Integer', { type: Property.Integer })
    .addPluginProperty('float', 'Float', { type: Property.Float })
    .addPluginProperty('percent', 'Percent', { type: Property.Percent })
    .addPluginProperty('text', 'Text', { type: Property.Text })
    .addPluginProperty('longText', 'Long Text', { type: Property.LongText })
    .addPluginProperty('check', 'Check', { type: Property.Checkbox })
    .addPluginProperty('font', 'Font', { type: Property.Font })
    .addPluginProperty('combo', 'Combo', {
        type: Property.Combo,
        items: [['item1', 'item2']]
    })
    .addPluginProperty('color', 'Color', { type: Property.Color, initialValue: [255, 210, 155] })
    .createGroup('group', 'Awesome Group')
        .addPluginProperty('info', 'Info', { type: Property.Info, info: 'Lost' })
        .addPluginProperty('link', 'Link', {
            type: Property.Link,
            callbackType: 'for-each-instance',
            callback: (inst) => {
                console.log('Link property for each instance');
            }
        })
        .addPluginProperty('link2', 'Link', {
            type: Property.Link,
            callbackType: 'once-for-type',
            callback: (type) => {
                console.log('Link property once for type');
            }
        })
;

export default Addon;

๐Ÿ“ Creating category

To create category you should create new CategoryName.ts file in path: ./Addon/Categories folder. Then you can use code snippet from bare-bones project !cc to create default Category structure or copy-paste below script.

import { Category, Action, Condition, Expression, addParam } from "jsr:@lost-c3/lib";
import type { Instance } from "../Instance.ts";

@Category('myCategory', 'Category Name', { isDeprecated: false, inDevelopment: false })
export default class MyCategory {
    /** @Actions */

    /** @Conditions */

    /** @Expressions */
}

[!INFO] isDeprecated property in options for category in @Category decorator deprecates all category Actions, Conditions, Expressions.

inDevelopment property in options for category in @Category decorator removes all category Actions, Conditions, Expressions from addon.

โšก๏ธ Create action

To create actions for your addon you should use @Action method decorator in your category class.

Example

import { Category, Action, Condition, Expression } from 'jsr:@lost-c3/lib';
import type { Instance } from '../Instance.ts';

/**
 * Setup your category settings here
 */
@Category('categoryId', 'Category Name')
export default class MyCategory {
    @Action(
        /**
         * A string specifying a unique ID for the ACE.
         */
        `doSomething`,
        /**
         * The name that appears in the action picker dialog.
         */
        `Do something`,
        /**
         * The text that appears in the event sheet. 
         * You can use simple BBCode tags like [b] and [i], and use {0}, {1} etc. as parameter placeholders.
         * For easy BBCode import functions from @lost-c3/lib --> Bold, Italic, Underline, Strikethrough, Code
         */
        `Do something`,
        /**
         * A description of the action or condition, which appears as a tip at the top of the condition/action picker dialog.
         */
        `Awesome description...`,
        {
            /**
             * Set to true to mark the action as asynchronous. 
             */
            isAsync: false,
            /**
             * Set to true to deprecate.
             */
            isDeprecated: false,
            /*
             * Set to true to highlight.
             */
            highlight: true,
            /**
             * Setup your parameters here.
             */
            params: []
        }
    )
    doSomething() {
        console.log('Do something');
    };    
}
Tip

You can use build-in BBCode functions for fast and beautiful development.

โ“ Create condition

To create conditions for your addon you should use @Condition method decorator in your category class.

Example

import { Category, Action, Condition, Expression } from 'jsr:@lost-c3/lib';
import type { Instance } from '../Instance.ts';

@Category('categoryId', 'Category Name')
export default class MyCategory {
    @Condition(
        `onEvent`,
        `On event`,
        `On event`,
        'Trigger when something done...',
        {
            /**
             * Specifies a trigger condition.
             */
            isTrigger: true,
            /**
             * Allow the condition to be used in the same branch as a trigger.
             */
            isCompatibleWithTriggers: false,
            /**
             * Specifies a fake trigger.
             */
            isFakeTrigger: false,
            /**
             * Allow the condition to be inverted in the event sheet.
             */
            isInvertible: false,
            /**
             * Display an icon in the event sheet to indicate the condition loops.
             */
            isLooping: false,
            /**
             * Normally, the condition runtime method is executed once per picked instance.
             */
            isStatic: false,
            isDeprecated: false,
            highlight: false,
            params: []
        }
    )
    onEvent(this: Instance) { return true };
}
Tip

You can use build-in BBCode functions for fast and beautiful development.

๐Ÿงฎ Create expression

To create expressions for your addon you should use @Expression decorator in your category class.

Example

import { Category, Action, Condition, Expression } from 'jsr:@lost-c3/lib';
import type { Instance } from '../Instance.ts';

@Category('categoryId', 'Category Name')
export default class MyCategory {
    @Expression(
        `getValue`,
        `GetValue`,
        `Returns some value`,
        {
            /**
             *  "number" OR "string" OR "any".
             */
            returnType: 'string',
            /**
             * Allow the user to enter any number of parameters beyond those defined.
             */
            isVariadicParameters: false,
            isDeprecated: false,
            highlight: false,
            params: []
        }
    )
    getValue(this: Instance) { return 'value' };
}
Tip

You can use build-in BBCode functions for fast and beautiful development.

๐Ÿ”ง Setting up Action/Condition/Expression parameters

To setup parameters in your Action/Condition/Expression you should use 'params' field when you creating on of the entity. Also you should use addParam() method AND Param enum that you can import from library.

List of available parameter types:

Type Description
"Number" A number parameter.
"String" A string parameter.
"Any" Either a number or a string.
"Boolean" A boolean parameter, displayed as a checkbox.
"Combo" A dropdown list.
"Cmp" A dropdown list with comparison options like "equal to", "less than" etc.
"Object" An object picker.
"ObjectName" A string parameter which is interpreted as an object name.
"Layer" A string parameter which is interpreted as a layer name.
"Layout" A dropdown list with every layout in the project.
"Keyb" A keyboard key picker.
"InstanceVar" A dropdown list with the non-boolean instance variables the object has.
"InstanceVarBool" A dropdown list with the boolean instance variables the object has.
"EventVar" A dropdown list with non-boolean event variables in scope.
"EventVarBool" A dropdown list with boolean event variables in scope.
"Animation" A string parameter which is interpreted as an animation name in the object.
"ObjInstanceVar" A dropdown list with non-boolean instance variables available in a prior "object" parameter.

Example

import { Category, Action, Condition, Expression, addParam, Param } from 'jsr:@lost-c3/lib';
import { bold } from 'jsr:@lost-c3/lib/misc';
import type { Instance } from '../Instance.ts';

@Category('categoryId', 'Category Name')
export default class MyCategory {
    @Action({
        `doActionWithParams`,
        `Do action`,
        `Do action with value: ${Bold('{0}')}`,
        {
            params: [
                addParam('value', 'Value', { type: Param.String, initialValue?: '' })
            ]
        }
    })
    doActionWithParams(this: Instance, value: string) {
        console.log('Do action with value', value);
    };
}

๐Ÿ’ข Deprecating Actions, Conditions, Expressions

Caution

Do not delete any actions, conditions, expressions from your category file. Because it can break projects that are using your addon inside.

Read more info: https://www.construct.net/en/make-games/manuals/addon-sdk/guide/defining-aces#internalH1Link0

How to mark any Action, Condition OR Expression as deprecated? Each Action, Condition OR Expression has isDeprecated property in decorator options property, so you can set it to true to deprecate.

Example

import { Action, Category, Condition, Expression } from 'jsr:@lost-c3/lib';
import type { Instance } from '../Instance.ts';

@Category('categoryId', 'Category Name')
export default class MyCategory {
    @Action(`doAction`, `Do action`, `Do action`, {
        /**
         * Default is False. Set to true to deprecate the ACE.
         */
        isDeprecated: true
    })
    doActionWithParams() { /* do something */ }
}

๐ŸŒณ Using Instance

Use Instance class to implement your custom logic to addon. Main instance file is available at path: ./Addon/Instance.ts.

Example of using Instance properties and functions inside any category entity (Action/Condition/Expression).

Instance.ts

const C3 = globalThis.C3;

class LostInstance extends globalThis.ISDKInstanceBase {
    readonly value: string = 'My property value';
    /**
     * Use this property to call any condition in your addon
     */
    readonly Conditions = C3.Plugins[Lost.addonId].Cnds;

    constructor() {
        super();
        const properties = this._getInitProperties();

        if (properties) {
            /**
             * Here you can find your plugin properties
             */
        }
    }

    _release() {
        super
            ._release();
    }

    /**
     * Here is our instance method
     */
    _getPropertyValue() {
        return this.value;
    }
}

C3.Plugins[Lost.addonId].Instance = LostInstance;
export type { LostInstance as Instance };

MyCategory.ts

import { Action, Category, Condition, Expression } from 'jsr:@lost-c3/lib';
/**
 * Import your instance type
 */
import type { Instance } from '../Instance.ts';

@Category('categoryId', 'Category Name')
export default class MyCategory {
    @Expression(`getValue`, `GetValue`)
    /**
     * Set the first argument of your method to: this: Instance
     */
    GetValue(this: Instance) {
        return this._getPropertyValue();
    }
}

๐Ÿ“š Using Scripts (Javascript / Typescript)

It's available to use custom Javascript OR Typescript script in your addon.

To use any script you should copy OR create script.js OR script.ts file at path: ./Addon/Scripts. Your script will automatically will be loaded with type: external-dom-script.

  • To use any file you should copy your file.css OR data.txt file to path: ./Addon/Files. If you added any .css file it will automatically loaded with type: external-css. If you added file with any other extension it will automatically loaded with type: copy-to-output.
Note

All Typescript files will be compiled into .js files after addon building.

Note

If you want to load your script with type external-runtime-script, you should call setRuntimeScripts(path) in your Addon object in addon.ts file.

Example

import { Plugin, Property } from 'jsr:@lost-c3/lib@3.0.0';
import config from "./lost.config.ts";

const Addon = new Plugin(config)

Addon
    .setRuntimeScripts('runtime-index.js')
;

export default Addon;

๐Ÿ“„ Using Files

It's available to use files in your addon.

To use any file you should copy OR create file.* file at path: ./Addon/Files. Your file will automatically will be loaded with auto-detected type.

Note

If you want to include your file in project build, you should call addFilesToOutput(path) in your Addon object in addon.ts file.

Example

import { Plugin, Property } from 'jsr:@lost-c3/lib@3.0.0';
import config from "./lost.config.ts";

const Addon = new Plugin(config)

Addon
    .addFilesToOutput('myfile.wasm')
;

export default Addon;

๐Ÿ“ฆ Using Modules

It's available to use custom Javascript OR Typescript module in your addon.

To use any module you should copy OR create mymodule.js file at path: ./Addon/Modules.

Example

import * as MyModule from './Modules/mymodule.ts';

const C3 = globalThis.C3;

class LostInstance extends globalThis.ISDKInstanceBase {

	readonly PluginConditions = C3.Plugins[Lost.addonId].Cnds;
	constructor() {
		super();
		const properties = this._getInitProperties();

		console.log(MyModule.VAR);

        if (properties) {

        }

	}

	_release() {
		super._release();
	}

};

C3.Plugins[Lost.addonId].Instance = LostInstance;
export type { LostInstance as Instance };
Note

All Typescript files will be compiled into .js files after addon building.

Note this is only supported from r401+.

[!INFO] ๐Ÿ“– For more info checkout official docs:

https://www.construct.net/en/make-games/manuals/addon-sdk/guide/runtime-scripts/sdk-v2

๐Ÿ”ค Fast BBCode features

For fast and beautiful development there is a few functions that can help you customize displaying text in your addon.

List of available BBCode functions:

Function Result
bold('Do action') Do action
italic('Do action') Do action
strikethrough('Do action') Do action
underline('Do action') Do action
code('Do action') Do action

Example

import { bold, code, italic, strikethrough, underline } from 'jsr:@lost-c3/lib/misc';
import { Action, Category } from 'jsr:@lost-c3/lib';
import type { Instance } from '../Instance.ts';

@Category('categoryId', 'Category Name')
export default class MyCategory {
    @Action(
        `doAction`,
        `${bold('Action name')}`,
        `${italic('Do something')} and ${strikethrough('NOT')}`,
        `${underline('Underlined description...')} with ${code('SOMETHING')}`
    )
    doAction(this: Instance) { /* do something */}
}

๐Ÿ—๏ธ Building addon

To build addon into .c3addon file you can use one of the following commands:

  • lost build

addon.c3addon file will be available at path: ./Builds/my_addon_1.0.0.0.c3addon

๐Ÿงช Testing addons in Developer Mode

To test your addon you can use one of the following commands:

  • lost serve
Important

๐Ÿชช License

MIT

Add Package

deno add jsr:@lost-c3/lib

Import symbol

import * as lib from "@lost-c3/lib";

---- OR ----

Import directly with a jsr specifier

import * as lib from "jsr:@lost-c3/lib";

Add Package

npx jsr add @lost-c3/lib

Import symbol

import * as lib from "@lost-c3/lib";

Add Package

yarn dlx jsr add @lost-c3/lib

Import symbol

import * as lib from "@lost-c3/lib";

Add Package

pnpm dlx jsr add @lost-c3/lib

Import symbol

import * as lib from "@lost-c3/lib";

Add Package

bunx jsr add @lost-c3/lib

Import symbol

import * as lib from "@lost-c3/lib";