Require points to print text

Share custom commands, script functions, actor implementations and other Naninovel plug-ins you've created.
Post Reply
Elringus
admin
Posts: 521
Joined: 11 May 2020 18:03

Require points to print text

Post by Elringus »

Apparently, a type of free-to-play mobile games, where player can spend points to continue reading a story are becoming popular.

This extension shows an example of a custom engine service, which tracks a global g_points custom variable, reducing it each time a print command is executed. When points are equal or below zero, a notification is shown to the player, game is saved and title menu is shown. When player has enough points (eg, via an in-app purchase or some other game mechanic), they'll be able to load from the last quick save and continue reading.

Code: Select all

using Naninovel;
using Naninovel.Commands;
using Naninovel.UI;
using UniRx.Async;

[InitializeAtRuntime]
public class PointsManager : IEngineService
{
    private IScriptPlayer scriptPlayer;
    private ICustomVariableManager variableManager;
    private IStateManager stateManager;
    private IUIManager uiManager;

    public UniTask InitializeServiceAsync ()
    {
        // Get references to the services we'll need later.
        scriptPlayer = Engine.GetService<IScriptPlayer>();
        variableManager = Engine.GetService<ICustomVariableManager>();
        stateManager = Engine.GetService<IStateManager>();
        uiManager = Engine.GetService<IUIManager>();
        
        // Register our monitoring method to be invoked before a command is executed.
        scriptPlayer.AddPreExecutionTask(HandleCommandExecuted);
        return UniTask.CompletedTask;
    }

    public void ResetService () { }

    public void DestroyService ()
    {
        // Un-register the monitoring method when the service is destroyed.
        scriptPlayer?.RemovePreExecutionTask(HandleCommandExecuted);
    }

    private async UniTask HandleCommandExecuted (Command command)
    {
        // We care only about the print commands.
        if (!(command is PrintText)) return;
        
        // Get custom global variable that tracks the points.
        // Don't forget to add it to the predefined variables configuration menu.
        variableManager.TryGetVariableValue<int>("g_points", out var points);
        
        if (points <= 0) // In case we're out of points:
        {
            // Notify the player and wait until they dismiss the notification.
            var confirmationUI = uiManager.GetUI<IConfirmationUI>();
            await confirmationUI.NotifyAsync("You're out of points and can't continue reading.");
            
            // Save the game and return to the title menu.
            await stateManager.QuickSaveAsync(); 
            await new ExitToTitle().ExecuteAsync();
        }
        else // In case we have enough points:
        {
            // Consume one point and save the variable.
            points -= 1;
            variableManager.TrySetVariableValue("g_points", points);
        }
    }
}

To test the above code, just copy-paste it to a new C# script.

Don't forget to add g_points to the predefined variables list and assign the initial value.

Image

To track current value of the variable while playing, use var console command:

Image

Post Reply