Skip to content

Releases: yhdgms1/novely

v0.54.0

02 Jul 11:29
03b8493

Choose a tag to compare

v0.54.0 Pre-release
Pre-release

Custom Actions Request

There is a way to override function used to fetch data in novely config.

const engine = novely({
  ...config,
  fetch: async (...args) => {
    console.log(args)
    return await window.fetch(...args);
  }
})

That function now is passed to custom actions.

const handler: CustomHandler = async ({ request }) => {
  await request('something.json')
};

Custom Actions Assets

Custom actions have .assets field, previously it could be only an array, but now it can also be a function.

const handler: CustomHandler = async () => {};

// handler.assets = [url];
handler.assets = async ({ request }) => {
  return await request('assets-for-my-action.json').then((r) => r.json())
}

When duration of assets function exceeds 250 ms empty array will be used instead of awaiting more. Function will be overwritten, always returning value from first run.

v0.52.0

28 Jun 16:56
ad13bcf

Choose a tag to compare

v0.52.0 Pre-release
Pre-release

Clean up

Custom actions provide clear function in which you can register cleanup handler. Previously you could register only one cleanup handler, now it is possible to register multiple. Cleanup handlers will be called in reverse order.

Code
const handler: CustomHandler = async ({ clear, paused }) => {
  const unsubscribe = paused.subscribe((paused) => {
    // do something there
  })

  // called last
  clear(unsubscribe);

  clear(() => console.log('I was called second'))
  clear(() => console.log('I was called first'))
}

Changed logic on how these cleanup handlers are stored. Now for every custom action there is created a spot in which cleanup handlers are saved. When back button is pressed, engine compares actions that are present now with actions that present then, and cleans up actions in the difference.

Explanation

Each number in array represents each custom action called

a: [1, 2, 3, 4]
b: [1, 2, 3, 4, 5]
c: [1, 2, 3, 4, 5, 6]

When I want to go back from c to b I take the difference between [1, 2, 3, 4, 5, 6] and [1, 2, 3, 4, 5] which is 6.
Same thing with b to a, difference is 5.

We try not to call actions 1, 2, 3 and 4 because they are running already.

When there is no left actions with same id and key we remove custom action's node from DOM.

Clean up is called when exit button is clicked.

Clean up is NOT called after custom action is called. In case it has requiresUserAction property and returns promise, cleanup should be done manually.

Here be dragons but I think that works.

Storage

The localStorageStorage was renamed to storageAdapterLocal.

v0.51.0

28 Feb 16:06
f10a7ce

Choose a tag to compare

v0.51.0 Pre-release
Pre-release

Pausing

Now it is possible to pause game. New methods are added to control pause states: engine.setPaused and engine.setFocused. It is required to pause the game when rewarded or fullscreen is shown. So this is an important thing. Also improves resources usage when tab is switched.

import { pauseOnBlur } from '@novely/core';

// consider to use SDK methods if available
// pauseOnBlur(engine);

// game is paused (e.g. ad is shown)
sdk.on('pause' () => engine.setPaused(true));
sdk.on('resume', () => engine.setPaused(false));

// game lost focus (e.g. tab was switched)
sdk.on('focus' () => engine.setFocused(true));
sdk.on('blur', () => engine.setFocused(false));

Custom Actions will receive new paused store to subscribe to.

const fn: CustomHandler = ({ clear, paused }) => {
	const unsubscribe = paused.subscribe((paused) => {
		if (paused) {
			// pause();
		} else {
			// resume();
		}
	});

	clear(() => {
		// do not forget to unsubscribe from updates
		unsubscribe();
	});
};

v0.50.0

23 Feb 14:32
b1a4dcf

Choose a tag to compare

v0.50.0 Pre-release
Pre-release

New engine.types property

Previously, engine.typeEssentials was added to simplify working with custom actions that require information about available languages, characters, state and data. However, the naming was not correct and the design was not the best. That's why engine.types comes in and replaces old engine.typeEssentials. For the convenience the new type utility is added — TypesFromEngine.

Before
type Characters = NonNullable<(typeof engine.typeEssintials)['c']>;
Now
import type { TypesFromEngine } from '@novely/core';

type Types = TypesFromEngine<typeof engine>;
type Characters = Types['c'];

IIFE is no more

Previously, build included iife build for CDN's with global Novely variable. I think it was not really used, also modern browsers support loading of ESM and CDN's ship ESM nowadays.

Languages

Languages that were translated using an online translator were removed. It has not enough quality.

v0.49.0

05 Feb 14:59
e5dea6a

Choose a tag to compare

v0.49.0 Pre-release
Pre-release

Dynamic Story Loading

Now it's possible to dynamically load story parts using new Story Options parameter. When the story is really huge, it can speed up initial loading time as less JavaScript is loaded.

It requires renderer to implement loading function for each context.

v0.47.2

03 Jan 14:54
f98c9ad

Choose a tag to compare

v0.47.2 Pre-release
Pre-release

Core

Function templateReplace is now passed into custom actions.

Click to expand
const handler: CustomHandler = ({ state, templateReplace }) => {
  const object = {
    ru: 'Текст по-русски',
    en: 'Text in English'
  }
  
  console.log(templateReplace(object, state()); // By default global data will be used instead of state, could be any object anyway
}

handler.id = 'my-custom-action';
handler.key = 'my-custom-action--1';

Each NovelyAsset get's id property. It's randomly generated at asset creation.

Click to expand

When NovelyAsset['source'] is accessed that asset will always use that value. NovelyAsset is typically used to get best supported image/audio format that will weight less. For the simplicity the new id property will help with asset determination.

const showSomething = (asset: NovelyAsset) => {
  const handler: CustomHandler = () => {
    // it's safe to access `source` now
    asset.source;
  }

  handler.id = 'show-something';
  handler.key = `show-something--${asset.id}`; // 

  return handler;
}

Added asset.image and asset.audio methods. Both accept always one argument, does not check for asset to be of certain type.

Click to expand

Sometimes we do not need to pick the best asset or get the resource type automatically. It just makes an asset with certain type.

import background_avif from './background.png?format=avif';
import background_webp from './background.png?format=webp';
import background_jpeg from './background.png?format=jpeg';

const background = import.meta.env.DEV ? asset.image(background_jpeg) : asset(background_avif, background_webp, background_jpeg);

Fixes playSound. Now when restoring a save, sound only be played if there are no blocking actions ahead of it.

@novely/solid-renderer@0.45.1

Characters and background now uses div with background-image property instead of canvas.
Custom showImage and hideImage actions were rewritten with some bugs fixed.

v0.46.0

10 Dec 04:47
4a5cf9f

Choose a tag to compare

v0.46.0 Pre-release
Pre-release
  • Dialog Overview implementation (disabled at current stage)
  • Icons in @novely/solid-renderer are moved into HTML template.

How to migrate

Only thing that should be migrated is @novely/solid-renderer's icons.

  1. Locate index.html
  2. Add inside the body tag the following:
Click to expand
<!-- Icons are taken from https://phosphoricons.com/ -->
<svg style="display: none;" width="24" height="24" viewBox="0 0 256 256">
	<path id="novely-save-icon" d="M219.31,72,184,36.69A15.86,15.86,0,0,0,172.69,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V83.31A15.86,15.86,0,0,0,219.31,72ZM168,208H88V152h80Zm40,0H184V152a16,16,0,0,0-16-16H88a16,16,0,0,0-16,16v56H48V48H172.69L208,83.31ZM160,72a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h56A8,8,0,0,1,160,72Z"></path>
	<path id="novely-settings-icon" d="M128,80a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Zm109.94-52.79a8,8,0,0,0-3.89-5.4l-29.83-17-.12-33.62a8,8,0,0,0-2.83-6.08,111.91,111.91,0,0,0-36.72-20.67,8,8,0,0,0-6.46.59L128,41.85,97.88,25a8,8,0,0,0-6.47-.6A112.1,112.1,0,0,0,54.73,45.15a8,8,0,0,0-2.83,6.07l-.15,33.65-29.83,17a8,8,0,0,0-3.89,5.4,106.47,106.47,0,0,0,0,41.56,8,8,0,0,0,3.89,5.4l29.83,17,.12,33.62a8,8,0,0,0,2.83,6.08,111.91,111.91,0,0,0,36.72,20.67,8,8,0,0,0,6.46-.59L128,214.15,158.12,231a7.91,7.91,0,0,0,3.9,1,8.09,8.09,0,0,0,2.57-.42,112.1,112.1,0,0,0,36.68-20.73,8,8,0,0,0,2.83-6.07l.15-33.65,29.83-17a8,8,0,0,0,3.89-5.4A106.47,106.47,0,0,0,237.94,107.21Zm-15,34.91-28.57,16.25a8,8,0,0,0-3,3c-.58,1-1.19,2.06-1.81,3.06a7.94,7.94,0,0,0-1.22,4.21l-.15,32.25a95.89,95.89,0,0,1-25.37,14.3L134,199.13a8,8,0,0,0-3.91-1h-.19c-1.21,0-2.43,0-3.64,0a8.08,8.08,0,0,0-4.1,1l-28.84,16.1A96,96,0,0,1,67.88,201l-.11-32.2a8,8,0,0,0-1.22-4.22c-.62-1-1.23-2-1.8-3.06a8.09,8.09,0,0,0-3-3.06l-28.6-16.29a90.49,90.49,0,0,1,0-28.26L61.67,97.63a8,8,0,0,0,3-3c.58-1,1.19-2.06,1.81-3.06a7.94,7.94,0,0,0,1.22-4.21l.15-32.25a95.89,95.89,0,0,1,25.37-14.3L122,56.87a8,8,0,0,0,4.1,1c1.21,0,2.43,0,3.64,0a8.08,8.08,0,0,0,4.1-1l28.84-16.1A96,96,0,0,1,188.12,55l.11,32.2a8,8,0,0,0,1.22,4.22c.62,1,1.23,2,1.8,3.06a8.09,8.09,0,0,0,3,3.06l28.6,16.29A90.49,90.49,0,0,1,222.9,142.12Z"></path>
	<path id="novely-back-icon" d="M199.81,34a16,16,0,0,0-16.24.43L64,109.23V40a8,8,0,0,0-16,0V216a8,8,0,0,0,16,0V146.77l119.57,74.78A15.95,15.95,0,0,0,208,208.12V47.88A15.86,15.86,0,0,0,199.81,34ZM192,208,64.16,128,192,48.07Z"></path>
	<path id="novely-book-open-icon" d="M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64Z"></path>
	<path id="novely-list-icon" d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM40,72H216a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16ZM216,184H40a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Z"></path>
	<path id="novely-x-icon" d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path>
	<path id="novely-play-icon" d="M232.4,114.49,88.32,26.35a16,16,0,0,0-16.2-.3A15.86,15.86,0,0,0,64,39.87V216.13A15.94,15.94,0,0,0,80,232a16.07,16.07,0,0,0,8.36-2.35L232.4,141.51a15.81,15.81,0,0,0,0-27ZM80,215.94V40l143.83,88Z"></path>
	<path id="novely-stop-icon" d="M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200V200Z"></path>
	<path id="novely-play-game-icon" d="M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32Zm0,176H48V48H208ZM80,128a8,8,0,0,1,8-8h60.69l-18.35-18.34a8,8,0,0,1,11.32-11.32l32,32a8,8,0,0,1,0,11.32l-32,32a8,8,0,0,1-11.32-11.32L148.69,136H88A8,8,0,0,1,80,128Z"></path>
	<path id="novely-file-plus-icon" d="M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Zm-40-64a8,8,0,0,1-8,8H136v16a8,8,0,0,1-16,0V160H104a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,160,152Z"></path>
	<path id="novely-files-icon" d="M213.66,66.34l-40-40A8,8,0,0,0,168,24H88A16,16,0,0,0,72,40V56H56A16,16,0,0,0,40,72V216a16,16,0,0,0,16,16H168a16,16,0,0,0,16-16V200h16a16,16,0,0,0,16-16V72A8,8,0,0,0,213.66,66.34ZM168,216H56V72h76.69L168,107.31v84.53c0,.06,0,.11,0,.16s0,.1,0,.16V216Zm32-32H184V104a8,8,0,0,0-2.34-5.66l-40-40A8,8,0,0,0,136,56H88V40h76.69L200,75.31Zm-56-32a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h48A8,8,0,0,1,144,152Zm0,32a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h48A8,8,0,0,1,144,184Z"></path>
	<path id="novely-caret-down-icon" d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z"></path>
	<path id="novely-globe-icon" d="M128 24a104 104 0 1 0 104 104A104.12 104.12 0 0 0 128 24Zm87.62 96h-39.83c-1.79-36.51-15.85-62.33-27.38-77.6a88.19 88.19 0 0 1 67.22 77.6ZM96.23 136h63.54c-2.31 41.61-22.23 67.11-31.77 77-9.55-9.9-29.46-35.4-31.77-77Zm0-16c2.31-41.61 22.23-67.11 31.77-77 9.55 9.93 29.46 35.43 31.77 77Zm11.36-77.6C96.06 57.67 82 83.49 80.21 120H40.37a88.19 88.19 0 0 1 67.22-77.6ZM40.37 136h39.84c1.82 36.51 15.85 62.33 27.38 77.6A88.19 88.19 0 0 1 40.37 136Zm108 77.6c11.53-15.27 25.56-41.09 27.38-77.6h39.84a88.19 88.19 0 0 1-67.18 77.6Z"/>
	<path id="novely-typewriter-speed-icon" d="M87.24 52.59a8 8 0 0 0-14.48 0l-64 136a8 8 0 1 0 14.48 6.81L39.9 160h80.2l16.66 35.4a8 8 0 1 0 14.48-6.81ZM47.43 144 80 74.79 112.57 144ZM200 96c-12.76 0-22.73 3.47-29.63 10.32a8 8 0 0 0 11.26 11.36c3.8-3.77 10-5.68 18.37-5.68 13.23 0 24 9 24 20v3.22a42.76 42.76 0 0 0-24-7.22c-22.06 0-40 16.15-40 36s17.94 36 40 36a42.73 42.73 0 0 0 24-7.25 8 8 0 0 0 16-.75v-60c0-19.85-17.94-36-40-36Zm0 88c-13.23 0-24-9-24-20s10.77-20 24-20 24 9 24 20-10.77 20-24 20Z"/>
	<path id="novely-music-volume-icon" d="M212.92 17.69a8 8 0 0 0-6.86-1.45l-128 32A8 8 0 0 0 72 56v110.08A36 36 0 1 0 88 196V62.25l112-28v99.83A36 36 0 1 0 216 164V24a8 8 0 0 0-3.08-6.31ZM52 216a20 20 0 1 1 20-20 20 20 0 0 1-20 20Zm128-32a20 20 0 1 1 20-20 20 20 0 0 1-20 20Z"/>
	<path id="novely-sound-volume-icon" d="M163.51 24.81a8 8 0 0 0-8.42.88L85.25 80H40a16 16 0 0 0-16 16v64a16 16 0 0 0 16 16h45.25l69.84 54.31A8 8 0 0 0 168 224V32a8 8 0 0 0-4.49-7.19ZM152 207.64l-59.09-45.95A7.94 7.94 0 0 0 88 160H40V96h48a7.94 7.94 0 0 0 4.91-1.69L152 48.36ZM208 104v48a8 8 0 0 1-16 0v-48a8 8 0 0 1 16 0Zm32-16v80a8 8 0 0 1-16 0V88a8 8 0 0 1 16 0Z"/>
	<path id="novely-voice-volume-icon" d="M144 165.68a68 68 0 1 0-71.9 0c-20.65 6.76-39.23 19.39-54.17 37.17a8 8 0 0 0 12.25 10.3C50.25 189.19 77.91 176 108 176s57.75 13.19 77.88 37.15a8 8 0 1 0 12.25-10.3c-14.95-17.78-33.53-30.41-54.13-37.17ZM56 108a52 52 0 1 1 52 52 52.06 52.06 0 0 1-52-52Zm151.36-42.4a108.36 108.36 0 0 1 0 84.8 8 8 0 0 1-7.36 4.86 8 8 0 0 1-7.36-11.15 92.26 92.26 0 0 0 0-72.22 8 8 0 0 1 14.72-6.29ZM248 108a139 139 0 0 1-11.29 55.15 8 8 0 0 1-14.7-6.3 124.43 124.43 0 0 0 0-97.7 8 8 0 1 1 14.7-6.3A139 139 0 0 1 248 108Z"/>
</svg>

How the final HTML template should look like: click

v0.38.0

07 Jul 09:59
8963524

Choose a tag to compare

v0.38.0 Pre-release
Pre-release

Core

  • getResourceType is passed to renderer

v0.37.0 — Untitled

07 Jul 09:53
3453654

Choose a tag to compare

v0.37.0 — Untitled Pre-release
Pre-release

Core

  • getResourseType function uses cache. Useful when http requests are made. By default file extension is used.
  • preview function that is passed to renderer now resolves object with assets array — array of resources that was used in that preview.
  • characterAssetSizes setting is added. It is used to gave canvas size before image are loaded
 const engine = novely({
   characters: {
     Peter: {
       name: 'Peter',
       color: '#c04931',
       emotions: {
         normal: peter_the_great
       }
     }
   },
   characterAssetSizes: {
     Peter: {
       width: 800,
       height: 1200
     }
   }
 })

v0.35.0

01 Jun 09:37
3c24c22

Choose a tag to compare

v0.35.0 Pre-release
Pre-release

Custom Actions Update

Some arguments were renamed and regroupped.

// previously
const custom: CustomHandler = ({ preview, get }) => {
  const { data, element } = get(true)
}
// now
const custom: CustomHandler = ({ data, flags: { preview }, getDomNodes }) => {
  const { element } = getDomNodes(true)
}

Custom Actions to Core!

Some internal code was moved into @novely/core package instead of being necessary to write in renderers.