Asset - Project SLIDGE - A Visual Novel and Dialog Creation tool

Tsa05

Member
StormingLeech Interactive Dialog Game Engine
(Limited time, whole engine is $3 to give more people a chance to play)

DEMO*
VIDEO
(Zzzzz--a 17-minute long explanation of how to set up data and start building a game. Boring but thorough.)
How-To Wiki

*Some features in the demo are odd due to html5 export; eg, needing to click on the window to activate sound, game size not set to scale to browser size...


In-game visual editing



Style editors for creating/editing the global appearance of text and choice boxes



Character editor for layering and grouping character expressions and poses



What is SLIDGE?
It's HuniePop. There, I said it. The idea is simple: You want to use GameMaker to create some kind of game mechanics--platformer, match 3, hidden object, mmo, all the usual--but then, you have the twisted idea to attach a dating sim to it. Ok, maybe not a dating sim. A "Visual Novel." Or dating sim. Something with textboxes, choice boxes, characters who enter and exit and say stuff.

Of course, your text has to be wrapped and paginated and colored and typewritened and fonted and wiggle and shake and have emojis and sound effects and a fancy-looking box and bouncing icons and stuff.

RenPy, RPGMaker, Twine...they all make it so easy to create the dating--sorry, the visual novel part of the game, but then you've got to do the rest of the custom game mechanics you wanted without a handy Game-Making tool. Then there's GameMaker--the handy game making tool--that has...totally vanilla..text. SLIDGE does the fancy stuff, and more.

Why is SLIDGE?

There are dialog engines for GameMaker. All of the engines go straight to code. And there's absolutely no need. Visual Novels are visual.

If you use an engine that requires lines for each piece of text or action, how will you organize your game's innumerable dialog scenes and moments? How will you edit the appearance of scenes, insert new scenes, or adjust the positioning and timing of stuff on screen? Several thousand lines of engine calls and IF statements?

How are you going to localize your game in different languages?
With code-based solutions, you'd double all of the engine's text function calls. Or triple them. Or hand it to a language translator and ask them to program (correctly) for you?

Engines need code, sure, but why does the dev have to type all the code? That's not how these things work; the contents of a Visual Novel are data, not code. Why isn't it easy to set the data (the text, the character, etc) visually?

SLIDGE is a wysiwyg editor.
  • You pop an edit object into your game, and play.
    The editor is overlayed, you paste in text and design characters and scenes and stuff visually, and the data gets spat into %localappdata%.
  • You swap the edit object for the play object and add the data files as "included files" and your game is ready for the big-time.
There's your Dating...Visual Novel game, done, no code.

And if you *are* coding a game...
SLIDGE is a 1-object complete engine. Create an instance of SLIDGE anywhere, any time when you'd want dialog.

But wait, there's more.
SLIDGE integrates data with your game. Mmhm. Yours.
The player does stuff in-game, and when the dialog launches...it's changed because of stuff the player has done.

You've played games like this before. You get to the end of the adventure and the game has a series of "things" that happen.
"Johnny went on to become a doctor," "Sarah underwent robot transformation surgery," "Case never saw Molly again."
Non-linear dialog.
In a normal branching dialog system, you'd have to duplicate entire branches and make adjustments...or hijack the engine with custom code. In SLIDGE, the "end action" of any Scene, or the "target link" of any Choice Button can be the name of a scene.....OR a name of a room, OR a SLIDGE variable.

Somewhere along the way in your game, during some dialog or as a result of some other play elements, Johnny's fate is decided. Does he become a doctor? Will he successfully terraform his parents turnip farm into a replacement spleen farm??? You make the vital choice that determines Johnny's fate, and then go on with the game.

But your choice changed everything. Yep. The engine produces (or refers to, if already existing) a variable called global.register, which is a DS Map. You can invent variable names as you go along, tracking things you'll want later. Maybe you've decided that certain actions from the player change the value of "johnnyFate" in the Register. Within the engine, you'd attach that value to certain button choices. If you're coding? global.register[?"johnnyFate"]="farmerScene". Or anything you want.

What does that do for you? Well, when the game reaches it's final scene, you don't link to a specific scene name. Instead, set engine to go to the variable johnnyFate. You have altered fate itself! The chapter, the game, whatever, will re-route to whatever scene you name.

And yes, the engine has the ability to add and subtract numbers in the register, and also to perform setting, adding, or subtracting based upon conditions--eg, only set Johnny's fate to "becomesSquirrel" if he went nuts back in scene 3, else set his fate to "becomesDoctor".

And, of course, since it's all in a global ds_map....any other game mechanics you happen to be coding can use and modify that info. You could get a player's name and store it in the key: "playerName." The engine could print out "Hello [r=playerName]!" You get the idea. This engine, with visual editing, is sufficient for most visual novels or even point-and-click adventures. It could handle the dialog for your own RPG, or...anything. The data is all JSON, easy to use or edit in other tools as needed.

Point is, it's a very, very powerful system; It's in version 1. There will be updates. There will be bugs. There are, due to the complexities of the engine, and the fact that it uses practically everything in GameMaker, always going to be many ways to make it crash, break, or hiccup. Don't, and we'll both be happy. But I will also be evolving this as I create my own stuff.

As-is, you can go a very long way very easily, and I've created a full getting started video and a Wiki. And a demo. Check out everything, ask questions, and omit negativity (pls).

Where is SLIDGE
On the Marketplace. Eventually, it'll be on itch.io also. And, if people start using it--we'll call you pioneers--then there'll become a Patreon way of getting it via supporting ongoing dev/features. We shall see, the future is in your hands.[r=future]

One final thing about SLIDGE
For better and for worse, SLIDGE is written in 100% GML. That means it's as portable and cross-platformable as GML. As portable, not more. HTML5ers, you have been warned.
For example, as of this writing, an object's image index won't advance automatically in HTML5 the way it does in Windows when no sprite is set for an object. I had to assign a 1 pixel sprite to my engine object for the HTML5 demo, just to make things animate...

In the past 3 years, I have had more issues with annoying things not working in HTML the same way they did in Windows... Rawr. The Dec 5th 2018 patch with 115 bug fixes helped a lot :D Made the demo actually possible to put online~
 
Last edited:
O

ocimpean

Guest
I am a big fan of visual novels and RenPy. I found your idea to integrate it with another kind of gameplay in GM, quite interesting and I will keep an eye on your product. Unfortunately, do to the asked price and the fact is GM2 only, it is out of my reach. Good luck.
 

Tsa05

Member
Thanks for the interest, @ocimpean! It'll be half-priced in about a month; I've got a few little feature additions and some fancy things I want to add to it to extend its modular functionalities, and I'm planning to advertise it a bit more once that stuff is ready.
 
S

Session

Guest
Looks promising, sadly not available on Market with Trial accounts of GM2.

Any news on you putting it on itch?
 

Tsa05

Member
@Session Not on itch.io just yet; I've got a feature enhancement I want to finish first to make voice-over a little more intuitive to add (currently vo is possible but it's not obvious how to do it)
I should note, though, that I'm not sure that you'll be able to use it with trial GMS regardless... It's a really, really comprehensive asset, and while it's a simple single object you drop into your game to add dialog, it has a large library of essential scripts (139), which probably are more than the trial allows.

Once I've updated, I plan to offer the asset at a significant discount; I'd recommend checking it out then, with YYG's Creator Edition (It's like a paid trial that unlocks everything for a year, and gives you 12 months to decide whether to spend the rest to get the full GMS license).
 
S

Session

Guest
@Tsa05

Ah, good to hear.
Yea I'll be picking up GMS2 (Desktop) from Steam soon since the trial has worked out fairly well, I'll definitely keep an eye on Slidge though, it seems perfect for what I have in mind.

I do have a question though, is it quite easy to drop in and out of dialogue with Slidge?
For example, Take an RPG Game and imagine walking through a town, then each NPC you speak to would start up the Visual Novel style Dialogue from Slidge, once completed the conversation simply drops the player back to the 'normal screen' the player was at before engaging that conversation.

- Cheers :)
 

Tsa05

Member
@Session
Great to hear, and yes--that's what Slidge is designed to do.

When you want dialog to appear, like when the player talks to an NPC, you'd have something like this:
Code:
nnn = instance_create_layer( 0, 0, "Top_Layer", obj_showDialog);
nnn.sceneID = "townNPC1";
Those 2 lines of code would cause the dialog engine to start, and to load the "townNPC1" dialog scene.
Within a scene, you can set a background image, so basically, if you had a layer in your game room called "Top_Layer" and it was above all other layers, the dialog would appear on top of your game, and the background image you set in the scene would appear in front of your game.

Whenever any scene runs out of "moments" (which are like individual lines and character positions), it checks to see whether you linked an additional scene and plays that...or else the dialog cleans itself up and the instance is destroyed. Your game will be right where you left it.

The one thing you might need to do, though, is pause your game--this is something that depends upon how your own game works; there's many simple pausing scripts out there that simply deactivate other instances, or you might wish to make something more complex. Either way--your game can either be running continuously behind the dialog, or it can be paused.

There's a little spot in the engine reserved for this, too. Whenever the dialog engine starts, it looks for a script called "slidge_start" and whenever it cleans up, it looks for a script called "slidge_delete." These scripts don't exist by default. You can make them if you want the engine to always perform certain actions at the start or end--so you could create the slidge_start script and put in whatever code you need to pause your game, and then create the slidge_delete script and add the code you need to un-pause. (The scripts are intentionally not included--that way, when there's updates to the engine, customization you've made will not be overwritten).
 

Pfap

Member
I remember checking out your demo and just saw this again. Would it work for drawing user notifications and other user interface stuff? I've recently spent a lot of time building a script resource called create_popup() and I'm really not a huge fan of working with styling and how things appear. Is this something I could give to a designer and they could get it back to me with all nice ui stuff? Also, I'd be really interested in seeing a video of something being created with the editor. In the demo if you select the choices option it brings up the text box with buttons for "Show me more" and "with ice cream" ; which, are probably more in line with what I'd be looking for. Is it easy to customize and build pop ups and other ui elements that would be drawn over the game?


Edit:

Just saw the video link on the top of the page, I'll have to check it out.
 
S

Session

Guest
@Tsa05

Thanks for the detailed explanation, the system sounds perfectly set out. I'm looking forward to seeing what it can do soon when I pick it up!
 

Tsa05

Member
@Pfap Yea, there's a video! It's...a little dry, lol, because it's more of a full technical walkthrough of setting up styles and characters and then building a simple scene rather than a slick marketing demo :D Hopefully, it helps illustrate what you were asking though (or helps you sleep).
 
S

Sam (Deleted User)

Guest
This looks extremely well done. If i wasn't too lazy to make an actual game, I might actually need this for a project.
 
S

Session

Guest
@Tsa05

I'm really liking Slidge so far, picked it up today and have been toying around with it a little, I do have a question or a request If it's not already in the system;
Is there a way to take input from a player when prompted, during a dialogue?

An example would be;

Player is talking to a person and is asked if they want to Rename themselves, they select the choice (Yes or No) and then have a blank dialogue box show up waiting for the player to type in their new name, with the text appearing as they type ofcourse.

Not sure if this is already possible in Slidge.
 

Tsa05

Member
@Session Oh, it's entirely possible and in there already!
It's just...heh..complicated a little.

I made Slidge capable of doing basic add and subtract operations on data based upon choice buttons, and choice buttons are quite flexible, so... Yeppers!
Basically, you make a scene with a textbox. The textbox has no text in it, but uses the tag [r=name_input]. It actually doesn't have to be name_input--it's whatever variable name that you want. Slidge will check the stored data register and will see that there's no such value, so it'll draw nothing.

Then, you make a choice. Make its style a small box, and then put in a letter, like...Q. When the button is pressed, have the button set a Register value like this:
r[name_input]+=Q

Andddd....that's it? So, every time the Q choice is chosen, it adds a Q to the name_input variable. Since it doesn't exist at first and you're adding a string, it decides to add Q to empty string. And the result appears in the textbox because the [r=name_input] tag does that.

For delete, you make a choice that sets r[name_input]-=1
Since you're subtracting one from a string, it removes 1 from the string. Handy, right?
I'd mostly put those things in there so that you could manipulate the values of scene names in links (scene0 can become scene1, etc) but it works for keyboards, too! I'll make one for ya, because....it's a lot of buttons :D

ALSO! I'll have to get you an update of SLIDGE. After release, I discovered a fun little bug thanks to moving some link handling into a common function--basically, setting a key to activate a choice isn't working properly in most circumstances (including doing a keyboard). It's like 3 lines to fix, but I haven't pushed out the update yet.
 
S

Session

Guest
@Tsa05

Ah, well I'll keep an eye on the forum, I assume you'll post here when an update is pushed? - I haven't run into the bug just yet, I did have one issue but it may have entirely been my error;
I set a background for a scene, then tried to move the background image while holding Control and it would error and crash the Game. As I said though, it may have been something I did on my end, not entirely sure just yet!

Edit: I may be a little blind (Running on Coffee and it's late, hah!) but how do you rename the Choice text? I re-watched the video and took a look into the Docs but I can't seem to see it :oops:

I see how to assign variables and whatnot but editing the buttons choice text is escaping me currently, I suppose this is a sign that I need sleep soon!
 
Last edited by a moderator:

Tsa05

Member
@Session Ahhhhh--Backgrounds are currently not moveable; no fault of yours, but I left them as-is, with the idea that you either have an image you want to use as a bg (that fills the frame) or that you would use your game / pause screen as a bg. Hmmrm, adding to list. In the meanwhile, here's a fun workaround:
Make a new character named background, and set layer zero to be your background. If you'd like, you can set multiple "expressions" for multiple background images. Then, add the character and set its pose to whatever bg you'd like. Control+click *does* move characters, textboxes, and choices!!! (And characters appear behind text and choices)

Ohhh, heh, choice box text...you press Backspace to erase the initial text. Yes, I've got to add a clear button. Palm to face :D

ALSO. Your keyboard is done :D
So, I've pushed 1.0.7 to the Marketplace, which includes the little fix for the keyboard keys. They otherwise won't activate buttons on a keyboard screen/scene like this one.

As for how to actually do it... I've created a video, and a web page with the relevant style and scene data.
Instruction page: http://www.stormingleech.com/SLIDGE/Wiki/doku.php?id=slidge:making_an_on-screen_keyboard

I've actually got a script for batch-moving choices, but the UI for it isn't there yet (take a peek into the commented out line in the F1 key press event of obj_editDialog in the latest updated version to see how it's done in code). I used that to help me quickly reposition all 28 keys, to save time. :D
 
Last edited:
S

Session

Guest
@Tsa05
Haha it's no problem! I'm fiddling around with all the features to get used to it right now so I'll know what I can and can't do, so the background thing isn't an issue for me.
Thanks for the Video and Doc page! I really appreciate that, makes a lot more sense after I watched the demonstration video :)

Perhaps adding a Edit Text button just like the text box one on the choices page would be a nice little feature? Although I'm unsure how difficult that would be for you to create since it would have to know which Choice you're trying to edit the text of, hmm.

Again, thanks for all the help :)
 

Tsa05

Member
@Session Heya, my pleasure to help--I've a list of a thousand million little "things" that should be built on top of this framework for ease of game-creating, so having feedback is nice for focus. I had a bit of time this evening and added several features that you might find relevant to our recent conversation:

Update 1.0.8:
  • Added a button to batch-move ALL Choices in a moment in unison.
  • Added a button to edit the text in a choice button. The textarea is hilariously large compared to most buttons, feel free to giggle every time you see it.
  • Changed the backgrounds formatting a bit. When you load up any existing moment, it should smoooothly modify the format automatically. Zip through your various moments to update their metadata (non-updated metadata will always work, too--but it's always going to update next time a moment with non-updated bg data loads)
    • Modified formatting was last on my format punch-list, and brings background in line with other content types; background images were previously simply listed as a string data entry and are now a proper map, capable of containing additional metadata.
    • To that end, backgrounds can now be re-positioned but not within the visual editor yet. Still gotta add UI for that. For now, you can check any moment's data (after it's been converted to the new format) in the %localappdata% output folder, and modify the x and y of each background. Backgrounds are drawn relative to the top left corning, plus the x and y amount.
  • Choices can now be added vertically or horizontally, relative to the position of the last choice in the list. The default is vertical--hold the ALT key on the keyboard to add horizontally. This replaces the obscure method, which required flipping the behaviour manually in the create event of the editor object.
 
Last edited:

❤️×1

Member
Hey!
SLIDGE looks amazing and would advantageously replace the very limited dialog system in my project. Though, after reading this topic, I've a few questions:
_How hard would it be to replace the text rendering with scribble? I'm not afraid of forking your work and missing on future update, but is your code commented and/or readable?
_Can we use Spine animations as characters? Since I couldn't find any information about it, I expect it not do be supported, so the real question is would it be hard for me to implement?
 

Tsa05

Member
@❤️×1 Howdy!
With scribble? The Scheme/Racket module? It would depend on the implementation of the renderer, really.
Similarly with Spine, actually; I'm intending to support it someday but while I was developing this, GMS Spine support was all over the place (appears to be up-to-date as of these past couple months, though).

Let's see if I can cover both in one pass.

The Slidge engine uses JSON for all data storage; if you need to add data to supplement what is already collected, this is probably the trickiest part, because the data collection strides both the visual editor and the rendering. If you need a new type of data to be collected, it will likely require additions to the visual interface. Rendering, though, is quite flexible--in fact, I wrote and re-wrote the text renderer 3 times while producing SLIDGE, and I rewrote the character renderer twice. The choice box editor was rewritten several times during the textbox rewrite, and then rewritten again after that.

It might be helpful for me to go through the data flow to give you a sense of what is modular, and in what way--I did very specifically design Slidge to attempt to allow complete customization of any one aspect without having to touch the others.

When a "Moment from a "Scene" loads in the editor or the show mode:
  1. The Scene's JSON is loaded into a ds_map called convoMap. If all else fails, you can directly modify editDialog.convoMap or showDialog.convoMap.
  2. The moment's JSON is loaded, into a ds_map called entryMap. This is all of the data for the current moment on screen.
  3. For the current moment, individual sections of content are placed into arrays. These are:
    1. Characters. Each character in this moment is loaded into array myChars
    2. Choices. Each choice is loaded into an array called choices.
    3. Textboxes. Each textbox is loaded into an array called myText.
    4. Backgrounds. Each Backgrounds is loaded into an array called backgrounds.
  4. Pre-caching: The choices array is processed into a parsedChoices array. The myText array is processed into a myParsedText array.
So, at the end of all things, the relevant data are all in arrays. I basically just loop through each array and draw the contents.

Quick note on the caching thing:
Textboxes and Choices use the same text rendering method. I had previously found that the speed of rendering varied greatly depending upon how many tags needed to be interpreted, so I've included a function to pre-compute timing and position information for effects, etc.

Ok, so, the rendering part. Included below, the entire Draw event for the showDialog object. It's pretty short-looking :D


So, each of the arrays above has a corresponding draw function that accepts the data array and then draws. You could work at this level, completely replacing one of these functions with your own custom drawing function. If you replace in both the show and edit objects, then you'll retain all of the visual editing but with a different drawing method.

Commenting trails off with specificity, but every function has jsdoc stuff at the top, detailing the parameters and function description. For reference, here's draw_conversation_boxes in its entirety:
Code:
///    @description        draw_conversation_boxes(array, [amount], [whichBox], [ascend])
///    @arg    {array}        textboxes    An array of ds_maps with textbox info
//    @arg    {array}        pT            An array of parsed bits of text
/// @arg    {real}        [amount]    Amount of text to draw
///    @arg    {real}        [whichBox]    Want a specific box?
///    @arg    {bool}        [ascend]    Draw all up to whichBox
///    @arg    {array}        [status]    An array of status maps to update
/// @arg    {string}    [styleSet]    Which set of styles to pull from
/*
*    Part of SLIDGE Engine
*    Do not redistribute
*/
/*
*    Requires:
*        An instance variable styles
*            which is a ds_map containing textbox and choice styles
*        ds_map_lookup()
*        draw_styled_box()
*    Returns:
*        -1 or an array containing the results of drawing a box
*/
var a = argument[0];
var pT = argument[1];
if(!is_array(a)){
    return -1;
}
var c = get_center(1.5);
var retVal = -1;
var oCol = draw_get_color();
var amt = 0;
var whichBox = array_length_1d(a);
var    ascend = true;
var sset = "textbox";
var stats = -1;
if(argument_count>2){
    amt = argument[2];
}
if(argument_count>3){
    if(argument[3]>=0){
        whichBox = argument[3]+1;    // Loop goes up to <
    }
}
if(argument_count>4){
    ascend = argument[4];
}
if(argument_count>5){
    stats = argument[5];
}
if(argument_count>6){
    sset = argument[6];
}
for(var z=0; z<whichBox ;z+=1){
    if(!ascend && z!=whichBox){}else{
    var m = a[z];
    var xc = c[0]+real(ds_map_lookup(m,"x", "0"));
    var yc = c[1]+real(ds_map_lookup(m,"y", "0"));
    var avi = ds_map_lookup(m,"avi", "");
    var style = ds_map_lookup(m,"style", "");
    if(style=="") style = "Default";
    var text = ds_map_lookup(m, "text", undefined);
    //var parsedText = ds_map_lookup(m, "parsed", undefined);
    var sz = array_length_1d(pT);
    if(z>=sz){
        var parsedTextMap = undefined;
    }else{
        var parsedTextMap = pT[z];
    }
   
    if(ds_is_map(parsedTextMap)){
        var parsedNormal = ds_map_lookup(parsedTextMap, "normal", undefined);
        var parsedText = ds_map_lookup(parsedNormal, "textarea", undefined);
       
        var label = ds_map_lookup(parsedNormal, "label", -1);
    }else{
        var parsedText = undefined;
        var label = -1;
    }
   
    var align = ds_map_lookup(m, "textAlign", -1);
    var lalign = ds_map_lookup(label, "labelAlign", -1);
    var animate = real(ds_map_lookup(m, "animate", 1));
   
    var styleMap = ds_map_lookup(styles, sset, undefined);
    var myStyle = ds_map_lookup(styleMap, style, undefined);
   
   
    if(is_array(stats) && array_length_1d(stats)>z){
        var statsMap = stats[z];
    }else{
        var statsMap = -1;
    }
   
    if(z<whichBox-1){
        var amtToSend = -1;
    }else{
        var amtToSend = amt;
    }
   
    if(!animate){ 
        amtToSend = -1;
        if(whichBox-1==z){
            // Ending on a skip; skip ahead?
           
            if(!ds_is_map(statsMap)){
                statsMap = ds_map_create();   
            }
            var bList = ds_map_lookup(parsedText, "boxes", -1);
            var sz = ds_list_size(bList);
            statsMap[?"currentBox"] = sz-1;
           
        }
    }
   
    var result = -1;
    currentStyledBox = z;
   
    if(variable_instance_exists(id,"textSubimages")){
        if(is_array(textSubimages)&&array_length_1d(textSubimages)>z){
            var sub = textSubimages[z];
        }else{
            var sub = -1;
        }
    }else{
        var sub = -1;
    }

    result = draw_styled_box(xc, yc, myStyle, parsedText, amtToSend, avi, sub, label, align, lalign, statsMap);

    stats[z] = result;
}}
draw_set_color(oCol);

return stats;

The body isn't tremendously well commented because it's really just looping through the list of text boxes and pulling out specific bits of style metatada, then passing the whole thing along to draw_styled_box().

The render flow for drawing a textbox, by the way is this:
draw_conversation_boxes() > draw_styled_box() > draw_wrapped_colored_text()

So, if you wanted to change the text rendering, you could basically just replace draw_wrapped_colored_text().
The largest difficulty with replacing the text renderer, specifically, is probably that it's the deepest bit of integration, so it has several important return values. You'll also notice that the output is looped back through the input on mine...this way certain computations performed while drawing are maintained.

I've tried to keep these minimal, but text rendering had a special few. The draw_wrapped_colored_text() function returns a ds_map containing these values:
Code:
status[?"fxTime"] 
status[?"currentBox"] 
status[?"index"] 
status[?"hit"] 
status[?"truncated"]
status[?"done"]
fxTime: Irrelevant outside of my text drawing methods.
currentBox: keeps track of how much progress is made through the textbox, to assist with pagination. Pressing Continue in the engine increments this value.
index: The position of the current character of text that's been printed (seems silly, but all kinds of things like sound effects and emojis can manipulate the current index if they wish)
hit: true/false if the mouse happened to be positioned within the text. This goes up the chain and is taken into consideration for choice boxes.
truncated: true/false if the text stopped drawing before finished due to box size limitations (pagination)
done: All text for this textbox has been drawn

Some of these are fiddly and important, I fear, because of the desire to have the engine auto-paginate. My thought is that when you localize your game, text isn't going to fit in the box the same way that it did in your native language; with Slidge, I wanted everything to "just work" and it has caused me to need to track the currentBox, the truncated state, and the done state in order to determine whether a "continue" in the engine should skip typewriting, move to the next page of text, move to the next textbox on screen, or move to the next moment/scene. If ou skip pagination, a lot of that becomes simpler.

On the subject of simpler, draw_characters().
The draw_characters() function accepts a list of characters to draw, and then compares them to the most recently drawn set. If it finds a matching character ID number, it performs a position tween between the last and current version of the character, and then it calls the draw_character() function.

The draw_character() function accepts a ds_map containing character data and, if applicable, the linnear interpolation amount and character to interpolate from.
No return value is used.

So, you could replace draw_character with your own spine stuff and be good to go.

A few bits of UI won't work, though.
The Character "Designer" area wouldn't work--it lets the developer add sprites to layers and writes all of that info into a ds_map that gets sent into draw_character(). I'm not sure what that would be replaced with...it's possibly that you could just swap out the whole character designer with a list of your spine characters. Not sure. But at the least, you can easily go into the _characters.txt JSON and put whatever properties are needed to draw your Spine character into there. Slidge will see character entries and will pass them into the draw_characters function.

The expressions panel will also be a little wonky at first, since it is populated by the character designer. In like fashion, it's just holding data; you could totally edit the _characters.txt JSON file and put in whatever expression names you please. At present, Expressions in Slidge's JSON hold onto a list of layers to draw, but you could have them hold any data you like. When an expression is selected in the Slidge interface, it simply adds that field to the Scene JSON. How it's interpreted later is up to you.

For example, current Scene JSON character section:
Code:
"characters": [{
                    "moveSpd": "-1",
                    "flipped": "1",
                    "fadeSpd": "-1",
                    "marked": "1",
                    "scale": "1",
                    "x": "1002",
                    "rotSpd": "-1",
                    "darkened": "0",
                    "ID": "0",
                    "y": "413.60",
                    "expression": "Default"
                }
            ]
So, there's nothing at all in the Scene JSON that prohibits anything from being Spine. This is the data that gets passed into my draw_characters() function, and that function looks up the character ID over in _characters.txt in order to find out what to do with the info. In my case, that means looking up which sprites to draw, but it could certainly mean looking up which Spine JSON, etc.

Hope that helps! It's not trivial, but entirely workable :)
 

❤️×1

Member
Just wanted to report my experience after two weeks : SLIDGE is reaaaaaally easy to delve into : everything is simple to understand and if you have any doubt, everything is commented as well!
 

Tsa05

Member
Thank you, @❤×1! I'm really, really happy to hear that. I'm always worried about whether things will only make sense in my own mind--it's great to hear that the engine makes sense and is holding up to your needs!
 

Amon

Member
I just got back into this. I updated via the market place and it throws an error when I try adding a background.

Code:
############################################################################################
FATAL ERROR in
action number 1
of Mouse Event for Glob Left Pressed
for object obj_editDialog:

trying to index a variable which is not an array
 at gml_Object_obj_editDialog_Mouse_53 (line 154) -                      var bgM = backgrounds[currentBackground];
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Object_obj_editDialog_Mouse_53 (line 154)
 

Tsa05

Member
@Amon y..yeaaaaa. That's very typically...me. I've got a whole complex set of test suite files to make sure changes to the background format worked, and converted from the old format correctly, etc. Just...forgot the part where no background has ever, ever, ever been defined prior to the engine starting up. >_< Fixed the bug, uploaded to the marketplace, apologies for the terrible first impression.
 

Tsa05

Member
Update 1.0.12 is now available, and is a feature update. Voice-Over is now easier to do; the engine generally allows sounds to be layered in a kind of convoluted way, setting a background sound for moments, and then adding any number of "in-line" sounds. This is tedious for adding voice lines.

There is now a voice-over button on the editor for each textbox, permitting easy setting of a VO file that plays across pagination of any textbox, but stops automatically when a new textbox or moment plays.

Additionally, a method has been added for adding VO automatically, and in a way which permits voice files to be added to the game as downloadable content. Files must be named according to the scene, moment number, and textbox number they should accompany. The automatic feature is not compatible with HTML5 export because audio_create_stream is not available on that platform.

Full details on the Wiki, under the What's New section.
 

Tsa05

Member
I've been on other projects for a bit and haven't done much work with the engine lately, other than compile ideas for future additions.
Since I've let the engine sit for a bit, and there's only a small handful of people who've had a chance to pick it up and play, I've decided to reduce the price by 90% for a limited time. I'm planning to restore the price in a week.

Why the sale? Why 90%?
Well, after a lengthyyyy process of making the core and Interface (and discovering nearly a dozen confirmed GMS bugs along the way), I set the price in line with other Visual Novel creation tools out there. But it's been out for a while now, and I'd be gratified to have more people give it a try--and the price tag required more of a "commit" than a "try.

As for the steepness of the cut, I'm aiming for cheap enough that it's worth a shot to pick it up, regardless of immediate need. Hopefully then it may prove handy to some more people! (And, if it generates interest, bug reports, questions about use/features, then we all benefit)
 
Last edited:
Top