Right now I'm programming a text engine for use in the ongoing game and others.
Basically I want all dialogue be stored in external .txt files, which are then parsed in-game.
That way the game can be easily translated, as well as modded in some ways, depending on the game (since in-game functions can also be parsed through the text).
In general, it's just easier to write something like this,
1
Looks like a trapdoor.
If I had the key, I might be able to open it.
It should be somewhere on this floor.As opposed to this
name[0] = "Girl"I'm still trying to figure out how I want everything to be formatted. For example, multiple scenes could be contained within one txt file, or different npcs and any branching dialogue could be separated into different files. Either way has situations were it might be difficult to keep track of, over time.
message[0] = "Looks like a trapdoor."+"\n"+"If I had the key, I might be able to open it."
name[1] = "Girl"
message[1] = "It should be somewhere on this floor."
I also have to decide how certain things will look when writing. For example I need to decide which symbols will be used to denote certain functions;
# denotes that a number can be entered.
# Use name associated with number until another name is used.
#> Put portrait image for corresponding name on the right.
#< Put portrait image for corresponding name on the left.
[d]# Dialogue number.
[d>]# Go to corresponding dialogue.
[f]# Set flag to true.
[f?]# Check if flag is true.
[e]# Call event.
An example of an interaction would look something like this, (Assuming you use portraits and stuff, otherwise it would look like the one above.)
///////////////////////////////////////////////////
1<
2>
[d]0
[f]0
1
[p]0
I'm here to buy something.
2
[p]20
Do you have a membership card?
If you don't have one then you can't shop here.
[f?]10///////////////////////////////////////////////////
[d>]1
[d>]2
[d]1
1
[p]1
Yes, I have it. It took a lot of work to get it.
2////////////////////////////////////////////////////////
[p]21
Then take a look around.
[e]10
[d]2
1
No I don't.
2That said, I haven't really decided for sure yet what all the functions should be.
That's a shame.
;
I won't be using all of them in every game.
Anyhow, that's all for now.
Something to think about maybe a little further in the future I'm sure, but maybe what you're wearing can change the dialogue too? I know it's nothing new but I always find it interesting when NPCs have different reactions/responses depending on your clothing or lack thereof.
ReplyDeleteThat would probably be done with [f]
DeleteClothing would then have a flag attribute etc.
Noakia still alive right ?
ReplyDeleteYup. It will never not be alive.
DeleteI don't know if the tool kit your using supports it, but I would seriously consider using .json instead of .txt files. It will save you a lot of time to use a system like that instead of making your own custom text format. Json is very intuitive, I think you'll find it more than adequate for what you need here.
ReplyDeleteFrom everything I've seen, it looks like it would take more work to write stuff.
DeleteI also need to be able to do things like parse actions mid sentence, so I think it's easier to just parse strings from txt in GM.
Whatever notation format you decide to use, I would recommend considering ease of typing so that creating new text doesn't become a chore. I've had something similar happen while working on something of my own.
ReplyDeleteOn of the reasons I want to parse stuff myself is so that the text files can be as simple as possible. I want it to feel as close as possible to just writing.
Deletenever worked with game maker, but there isn't custom user made dialogue systems integrated to ease that kind of issues? or some marketplace like unity where you can find one. Out of topic, which tools do you use to make pixel art and animations?
ReplyDeleteI don't use pre-made systems in GM. I prefer to learn how to do stuff myself when practical.
DeleteI use Aseprite.
It's not for GM, but this dialogue system for Unity seems pretty similar to what you're doing and might be worth referencing: https://github.com/exodrifter/unity-rumor
ReplyDeleteYeah, I'll take a look at some existing systems.
DeleteI would recommend adding a version string for the parser version to the beginning of the .txt files. If you make changes to the format (and you probably will), you don't have to worry about working with incompatible files that can cause hard-to-find bugs. It's just one line of text that can potentially save a lot of work.
ReplyDeleteHmm, that's something I hadn't thought of.
DeleteThat would be the most relevant in games with mod support, I think.
Another option would be to have a separate text file that controls which version or variation is used.
Writing your own parser is a fine thing to do. Idk what gml has, but I would highly recommend using some kind of dictionary structure to store everything, rather than using arrays. That way you can refer to everything by string rather than by index, and you could use this to organize loaded text files, cutscenes, character names and portraits, nodes in the dialogue tree, etc. You should research and see if gml has something like this: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=netframework-4.7.2
ReplyDeleteIt basically lets you map keys to values, and the key and value can be any type you want. EXTREMELY helpful when doing exactly what you're trying to do, and would make your text files far more readable if you could use string IDs for everything.
This looks like it might help: https://forum.yoyogames.com/index.php?threads/gmsugar-easy-constructor-scripts-for-gms-1-x-and-2-x.33933/
Probably won't come into play with the dialogue parsing. Once data is parsed it goes into the dialogue engine and I never touch it again in other code.
DeleteIf the dialogue engine I was making was more complex, I'd probably use it. I can think of other things I might use that for though.
This comment has been removed by a blog administrator.
ReplyDeletelmao what a legitimate comment
DeleteNow it's legitimately deleted.
DeleteQuestion Please! What Character is that? And where is she from?
ReplyDeletehttps://2.bp.blogspot.com/-LDCGxXFwOSc/V_IDHARLwrI/AAAAAAAACBY/pMUAF61wgRMS1vfv8sfyl7asTpGALTA3ACEw/s1600/taur_4.gif
https://3.bp.blogspot.com/-kVKOJnteWeU/WAhaJRzQB-I/AAAAAAAACBs/eoKu4JKMEnoPnx7Q9I2IIi-KxBCW8kHpACLcB/s1600/gape2.gif
Dark souls - Crossbreed Priscilla
DeleteAww, so it´s not a character you can play as = /
DeleteI wanna do cool stuff like you. Maybe in the next life I'll be talented.
ReplyDeleteWhy until your next life? Waiting around isn't gonna give you skill if you aren't practising for it.
DeleteTalent is generally just the willingness to work through initial stages of incompetence without giving up. If it takes you 5-10 years to get good enough to make games, then that's a lot more than 5-10 years of making games you have left over.
DeleteIt's a mixture of incompetence and mental illness. If I ever break out of this mental prison I'm going to make the world jizz itself to death.
DeleteSir, do you need any help with your work?
ReplyDeleteNah.
DeleteWell then. If you ever need an extra pair of programming hands, just leave the ad somewhere. Rohan will answer.
DeleteHey I have a random question so is there any chance we'll be able to see Aster get put on steam? I know you have Eroico on there which I have but it would be nice to play your other games on steam too.
ReplyDeleteJSON is easy to read and you won't have to write a parser to do what you want. Doesn't seem the gains of writing your own parser would outweigh the time saved.
ReplyDeleteIt is also extensible and can be used for non-string object types. You could use it for adjusting various game settings like health, damage, movespeeds, struggles etc. without doing a full game rebuild. You could bind settings reader to a key and just keep reloading in the middle of a level... The more things you cram into something like that, the more moddable your game gets beyond the translation bits. That kind of stuff seems more conducive to producing a game than re-inventing a de-serializer.
DeleteJson allows you to input data easily, but it doesn't make it any easier to derive advanced functions from simplified text. With a parser, all I have to do to create a multiple choice box during dialogue is write;
Delete[q]
[d1>]This is choice 1, it sends you to line 1
[d2>]This is choice 2, it sends you to line 2
[d3>][f1?]This is choice 3, but only appears if you have flag 1.
Everything the parser is doing for me is what I would have to write manually in a Json file.
That seems un-necessary. Example: https://pastebin.com/Txq5gfE1
DeleteIf you're talking about formatting the values further, then that is going to be a Templating language (kinda like Handlebars.JS) and not a Deserializer. Separate things, different uses, both useful.
The point of the parser is making it faster to add new dialogue without programming. If I have a sign that says;
DeleteWarning, landslides ahead.
That's all I need to write in a text file for it to work automatically. Depending on the type of dialogue I don't need any extra formatting or commands (I only need those for conditions, questions etc). Using a Json file would just be doing manually what my parser is doing automatically, which is assigning text and values.
The Json file would be faster performance-wise, but it would not be faster production-wise, which is what my goal here is.
I'll respectfully disagree and point to the pastebin I linked. That is precisely what JSON is used for. You are defining an object via a text format which is instantiated at runtime and used in code (for your in-game sign or whatever). It doesn't have to be JSON but learning how to use your favorite standard object storage notation and a publicly available serialization library instead of reinventing the wheel is a good milestone to reach as an engineer. It does just sound like you are not familiar with the concept of (de)serialization to be honest since they do exactly what you are talking about and more without you having to write code. GM does have public available serialization libraries that you can use btw.
DeleteTLDR and reiteration: JSON serializer library = .txt to GameMaker object. Somebody else already wrote that code for you.
I'm having difficulty understanding what you're trying to say I should be doing with a JSON file for dialogue because you keep saying I'm reinventing the wheel while presenting examples which require more input to get the same result.
DeleteWith a parser I can have a txt file say-
The door is opening. [s1]
And have it display the text, and then play a sound at the end. If a JSON file requires any more text than what I just wrote, then it is not accomplishing the same thing.
I talked to a programmer I know about JSON files, and he mentioned that they work well if you create a custom editor (for cutscenes for example) that writes JSON files automatically. That seems like the most convincing scenario that I would use them in place of a parser. However I think that's outside the scope of my current projects given the simplicity of what I need to do with dialogue. In my situation, I'll likely only look into JSON files for other kinds of data where inputting data manually is more viable.
DeleteFor your exact example, this is what it would look like in JSON:
Delete{message:"The door is opening.", endSound:"s1"}
It is more verbose than your example, yes. Not by much. YAML is less verbose, so maybe check that out since that is what you appear to be concerned about. The point is simple: you get input validation, countless format validation tools to find mistakes, stream reader, format parser and object intializer without writing any code when you use a standard free serialization library. They are often painfully optimized, robust, hugely extensible and hugely supported projects. Example: https://www.newtonsoft.com/json . Like I mentioned, there are other popular formats like YAML. And yes while they are more verbose than your example, they are good to learn how to use and will let you do much much more complex things with your scripting language when you are ready to tread that path.
Usage example lifted straight from newtonsoft's page:
Movie m = JsonConvert.DeserializeObject(json);
string name = m.Name;
// Bad Boys
Don't tell me your parser CODE is going to be more simple.
I mean, the parser was finished fairly quickly after this blog post, and already does precisely what I want. (which is speed up the process of creating dialogue by minimizing the amount of text)
DeleteThe only reason for me to use JSON files would be if it did something I need that my parser doesn't already do, which in this case it doesn't (If nothing else because the functions I want are few and very basic, in this project.)
Do what you do. At least you had a brush up, albeit brief, moment with it. Enterprise development wise, no blogpost would be made b/c this is just kinda a case in point classical example of where you would use a serialization library without thinking twice.
DeletePoint of the blog post was mostly just to show what I was doing, since people want to see updates.
DeleteAs for enterprise development, I'd still say it depends entirely on the context. If the goal was for something with,
1. Wider range of utility and options.
2. Better performance.
3. More extensive moddability for outside users.
Then I would use JSON files. However, my goals are,
1. Speed in adding new content by myself.
2. A small set of specific functions.
3. Simple modding for non programmers and translators.
JSON files are an enterprise solution for a reason. They work in whatever situation you throw at them, are reliable, and expandable. However, that doesn't mean they're going to be more efficient all the time, for every project. If I was making a game that only had 4 text boxes, I wouldn't bother with JSON or with a parser. I'd just do it internally in GM and call it a day.
In my case, 1. is my main priority, and so a parser just happens to be better for me.
The first thing I'll probably look into using with Json files is my sound editor, that I mentioned a few posts back.
DeleteSo it's just about to be able to make changes as easy and quickly as possible. I'd recomment using whatever file notation you like and on top of that provide a gui programm to quickly make such scenarios since they quickly can get unreadable and confusing. That's just my humble opinion on this topic though
DeleteWell, my main priority is that I can add content quickly, so I'm not going to get confused by what I chose. Modability is more of a pleasant side effect rather than my main goal.
DeleteThe idea technically was to see if you were interested in moving various monster, player and item values into an editable text file since that would allow you to make gameplay changes without having to re-compile the game. My experience with modding values beyond the original game design from the author is that only increasing/decreasing values tends to not be enough to make a good mod. Usually you need to be able to change some behaviors as well so I do think that even JSON would have its limits. Building support for that isn't trivial but I think that supporting code plug-ins is probably the best way to go (an example is MEF with Unity3D). The last piece would be enforcing the mods/plugins to be opensource for consumption sanity. Having a game that attracts modding in the first place is something different altogether :)
DeleteTo be honest I've more or less put modability aside. I think it's too much of a time sync for me to worry about in the beginning. At least for now, I'll only be working on editors or external file handling to the extent that it speed up my personal workflow.
DeleteEven outside of intentional focus on modding though, a few elements will probably be external regardless. There will be a lot of "lists of stuff" in general given the nature of the game.
This comment has been removed by a blog administrator.
ReplyDeleteYour games are like so awesome, i wonder why nobody makes gold stuff like this.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteWhen I wrote a message system for an RPG, I'd format it like this:
ReplyDelete[face:daisy disgusted]Boy, it sure is smelly in here.[z][clear]It makes me wanna . . .[wait:20] throw up.[z][clear][flagset:smelled:1]
With "actions" like flag checking, clearing the console, waiting, and pausing until the player presses Z, contained inside parentheses or brackets, like [action:arg0:arg1]. This allowed me to use strings for stuff like flag names, and made it a lot easier to write. Then again, it all boils down to what's easiest for you. For me, I'd rather have flags and faces accessed through descriptive names I won't forget, than through numbers.