PDA

View Full Version : What's the name of the concept of scripting in a Sim/RTS type of game?



gcarreno
05-02-2017, 12:30 PM
Hey peeps,

I played an Amiga space exploration game in the mid 90' that frustrated me for not being able to finish it.

It wasn't that good and never got fandom, so I've never been able to find it on emulators. So I decided to redo-it myself.

I'm at the point where I've got about 70%-80% of the data objects done, but I'm now struggling with one thing:

How do I avoid having my code littered with IF/THEN blocks for the chain of events that I want the game to have.

The only word that comes to mind is a script, like in the movies. But there has to be some kind of other name for this kind of thing.

I'm thinking of something I can emulate with a linked list or a tree or some other nice data concept that avoids a bunch of IF/THEN or even CASE.

In this game I'll have to research some items. The basic ones will already have an entry to research, but others will depend on time played and planet scanned. On some planets, one can find literature, that once researched will give me new ships/weapons.

I'm asking here first, and not the Stack Exchange family, because I don't even know how to formulate the question, neither rationalize an effective query to search for it.

What do you guys suggest?

Thanks and cheers,
Gus

Ñuño Martínez
05-02-2017, 02:10 PM
Use an scripting language (https://en.wikipedia.org/wiki/Scripting_language) is a good choice. There are several ones that works on Free Pascal and Delphi as Pascal Script (http://wiki.freepascal.org/Pascal_Script) and Lua.

Create your own simple scripting language isn't as hard as most people think. I'm working in my very own one (http://www.burdjia.com/proyectos/bascript) right now (documented in Spanish only, at the moment). Anyway, here you have a simple (incomplete and untested) interpretor:


TYPE
(* A helper type. *)
TWordList = ARRAY OF STRING;



(* This splits a string in to words separated by spaces. *)
FUNCTION SplitWords (aText: STRING): TWordList;
VAR
CharNdx, WordNdx: INTEGER;
ResultList: TWordList;
BEGIN
{ First word. }
SetLength (Resultlist, 1); WordNdx := 0;
{ Extract... }
FOR CharNdx := 1 TO Length (aText) DO
BEGIN
{ If found space or comma (,), then another word starts. }
IF aText[CharNdx] IN [' ', ','] THEN
BEGIN
{ This is to avoid multiple spaces. }
IF ResultList[WordNdx] <> '' THEN
BEGIN
INC (WordNdx);
SetLength (ResultList, WordNdx + 1)
END
END
ELSE
{ Adds character to word. Does it uppercase. }
ResultList[WordNdx] := ResultList[WordNdx] + UpCase (aText[CharNdx])
END;
EXIT (ResultList)
END;



PROCEDURE MyScriptInterpretor (aScript: TStrings);
VAR
CurrentLine, Ndx: INTEGER;
LineWords: TWordList;
FullLine: STRING;
BEGIN
IF aScript.Count > 0 THEN
FOR CurrentLine := 0 TO aScript.Count - 1 DO
BEGIN
{ Extract words. }
LineWords := SplitWords (aScript.Lines[CurrentLine]);
{ Checks "commands" }
IF LineWords[0] = 'SAY' THEN
BEGIN
IF Length (LineWords) < 3 THEN
RAISE Exception.CreateFmt ('Not enough parameters on line %d.', [CurrentLine + 1]);
FullLine := '';
FOR Ndx := 2 TO HIGH (LineWords) DO
FullLine := FullLine + ' ' + LineWords[Ndx];
SomebodySays (LineWords[1], FullLine)
END
ELSE IF LineWords[0] = 'WARP' THEN
BEGIN
IF Length (LineWords) <> 3 THEN
RAISE Exception.CreateFmt ('Wrong parameters for WARP on line line %d.', [CurrentLine + 1]);
Player.SetPosition (StrToInt (LineWords[1]), StrToInt (LineWords[2]))
END
END
END;

Free Pascal's FCL includes an expression evaluator you can use to add maths to your interpretor too. See this link (http://wiki.freepascal.org/How_To_Use_TFPExpressionParser).

[edit]
I've just remembered that my PGD Challenge entry Momen3D includes it's own mission script system, much like the one you're asking for. Download it from here (http://www.pascalgamedevelopment.com/pgdchallenge02/final/momen3d-0.3.zip) and look at file src/mission.pas, function ParseFile, lines 191...650. It looks big and complex but it is actually quite simple, as it is divided in sub-routines for each task.

To see how the mission script files looks like, just see file bin/data/missions/default/tuto.md

gcarreno
05-02-2017, 02:23 PM
Use an scripting language (https://en.wikipedia.org/wiki/Scripting_language) is a good choice. There are several ones that works on Free Pascal and Delphi as Pascal Script (http://wiki.freepascal.org/Pascal_Script) and Lua.

Thanks Ñuño, anyway.

Well, I was afraid someone would answer something like this when I used the word script :) .

What I meant was a way to put this:

Once x time as passed, archaeologist finds, in some ruins, mention to advance space drive
Once you scanned planet Y and Z time passes, you find old space ship and can improve some other aspect
Once you have plan A and plan B on some research, you can discover FTL travel
etc...


into a data structure.

So more like a story kind of script, not a scripting language.

Is there a pattern or a type of data concept, like linked lists or AVL trees that game programmers regularly use to support this?

Cheers,
Gus

Rickmeister
05-02-2017, 05:48 PM
Hey peeps,

I played an Amiga space exploration game in the mid 90' that frustrated me for not being able to finish it.

Is that game perhaps Elite or Elite2?? Spent countless of hours playing both of them.. Now to the questions:

Sounds like using an embedded script language might overshoot the target, could you perhaps settle for some basic database instead? I used Json for something similar (not in pascal, but the principles are the same)

Json makes it easy to store key/value pairs, and it also has (limited) support for conditional branching.

A quickie:

{
"technology": [{
"id": "hyperdrive_1",
"name": "Basic FTL drive systems",
"prereq": ["playtime", 1],
"researched": true
}, {
"id": "wormhole_1",
"name": "Wormhole Navigation for Dummies",
"prereq": ["playtime", 2],
"reserached": false
}, {
"id": "wormhole_2",
"name": "Advanced Wormhole Navigation",
"prereq": ["wormhole_1", "hyperdrive_1"],
"researched": false
}]
}

Provided that you're using OPascal, you can then fairly easy map each Json-entry to an object, which you then can store away in an array or linked list.

I would parse the file like this (in pseudo-code)


Load Json-file
Get Json-object count
Make place for them (I've got a sweet spot for dynamic arrays)
For each Json object do
TechID:=id
TechName:=name
for each req in prereq
if prereq-field contains "playtime" then parse next field member as integer
else add TechID;s to list of prerequisits.
TechResearched:=researched


This would also make it easy to serialize all the data for saving and loading purposes, the memory footprint of the json-object isn't an issue as long as you're running on anything else then a C64, or a Casio pocket calculator. When you've researched a technology, change the "researched"-field of that object to true, and at the end of the game write the modified Json-file back to disk. Then the next time you load the game you will start from where you left instead of having to research all techs all over again.

gcarreno
06-02-2017, 11:14 AM
Is that game perhaps Elite or Elite2?? Spent countless of hours playing both of them..

When I was looking for the game name I had that one suggested and also Master of Orion.

MoO is turn based, the one I played was Real Time and Elite has a trading and mission aspects that the one I played did not have.

It was quite simply a Sim for resource mining and resource management. The game ended with a battle with the Martians. Either you won, by having a greater quantity of combat drones, or you loosed. I could never win the bloody thing and could not say if it was open ended or not...

I don't think the game ever got any recognition. It was very simple and didn't have any mission or trading in it, so probably a bit boring for the more hardcore gamers. But it quite appealed to my like. I don't really like the battle and trading aspect of Sims/RTS. What I really like is the calm, relaxed waiting of resource gathering, level updates and going through a tech tree.

Ok, in regards to your suggestion: It makes a lot of sense and I've already had some version of it in my mind. I asked here because more experienced programmers in the Sim/RTS genres might have already put something in stone.

From the looks of it, it seems that it's not something that has really cemented.

At the moment the Objects I've dished out are still "hook" free. I'll need to devise a way to connect the "scripting" objects to the data objects.

@Ñuño: I've downloaded your code and will have a look at it. Will report on it later. MANY THANKS!!

gcarreno
06-02-2017, 12:03 PM
Hey peeps,

After a little bit of searching on https://gamedev.stackexchange.com I found a mention to Finite State Machines (FSM) and it clicked immediately!!!

DUH!! Of course that's what I want. Why didn't it occurred to me initially is still a mystery :)

Now to learn a bit more in depth on the subject and then onto implementation.

Many thanks to all that gave me an answer.

Cheers,
Gus

Ñuño Martínez
06-02-2017, 12:59 PM
Then I recommend you to read this (http://gameprogrammingpatterns.com/state.html).

Anyway you can implement your state machine to use a scripting language. it will be more flexible and allow modding, which is always good. In that case the paper I linked may help you with this (http://gameprogrammingpatterns.com/bytecode.html) too.

gcarreno
06-02-2017, 04:17 PM
Then I recommend you to read this (http://gameprogrammingpatterns.com/state.html).

Thanks. I actually ended buying the book for my Kindle. The way it's explained connects very well into the game programming world.

Other stuff I read about the State pattern gave me more question marks in regards of how to make it work on the game, so this chapter is perfect to get the question marks gone.


Anyway you can implement your state machine to use a scripting language. it will be more flexible and allow modding, which is always good. In that case the paper I linked may help you with this (http://gameprogrammingpatterns.com/bytecode.html) too.

Thanks for this also. I'll probably implement some kind of modding in the very FAR future.

Keep in mind that this is a game I'm making for myself. I don't really think I'll ever publish it or anything. But, never say never, and all that, so I'll keep this handy just in case I do get it out from under "for my pleasure only".

Cheers,
Gus

gcarreno
06-02-2017, 04:45 PM
[edit]
I've just remembered that my PGD Challenge entry Momen3D includes it's own mission script system, much like the one you're asking for. Download it from here (http://www.pascalgamedevelopment.com/pgdchallenge02/final/momen3d-0.3.zip) and look at file src/mission.pas, function ParseFile, lines 191...650. It looks big and complex but it is actually quite simple, as it is divided in sub-routines for each task.

To see how the mission script files looks like, just see file bin/data/missions/default/tuto.md

I've downloaded your code and
sudo apt install liballegro5 but for some reason it's not able to initialise the allegro stuff.

Any hints on how to debug it?

Cheers,
Gus

SilverWarior
06-02-2017, 05:36 PM
but for some reason it's not able to initialise the allegro stuff.

Any hints on how to debug it?

Check the latest post in http://www.pascalgamedevelopment.com/showthread.php?13208-Momen-3d/page5 for possible solution.

SilverWarior
06-02-2017, 06:40 PM
After a little bit of searching on https://gamedev.stackexchange.com I found a mention to Finite State Machines (FSM) and it clicked immediately!!!

DUH!! Of course that's what I want. Why didn't it occurred to me initially is still a mystery :)

Hey don't be to hard on yourself. I also had to sleep over before I realized I should recommend you to use one of state machine designs. ;) But I see you already figured that out by yourself :)

Any way.
I also wanted to say that wile you are searching for state machine examples you should note that most of them are only showing the simplest state machine examples with very low complexity like general game state (whether you are in main menu, is game loading or is the game in progress for instance).
But the state machine that you will need for your game will probably need to have much higher complexity. But don't let that discourage you.

Also you might want to check Decision_tree (https://en.wikipedia.org/wiki/Decision_tree) and Behavior_tree (https://en.wikipedia.org/wiki/Behavior_tree_(artificial_intelligence,_robotics_a nd_control)) concepts.
Now while these two concepts are most often used for implementing AI they can also be used for controlling your game state.

Ñuño Martínez
06-02-2017, 06:55 PM
I've downloaded your code and
sudo apt install liballegro5 but for some reason it's not able to initialise the allegro stuff.

Any hints on how to debug it?

Cheers,
Gus
You need to install the dev versions too (liballegro5-dev) as well as the addons. Also see what SilverWarrior said.

Note that Momen3D use an old Allegro version (5.0, not 5.2).

gcarreno
06-02-2017, 07:01 PM
Check the latest post in http://www.pascalgamedevelopment.com/showthread.php?13208-Momen-3d/page5 for possible solution.


That page of the thread talks about new installs of XUbuntu and debug flag on the compile.

I'm on an Ubuntu 16.10, up to date and with open source video drivers. Hopefully it's not that.

Tried the debug -dDEBUGMODE but I still have a very non explanatory: Error initializing Allegro.

So I can't even tell you what specifically went wrong on the al_init call.

If I have time and patience, I'll probably fire up Lazarus to debug the thing.

Cheers,
Gus

gcarreno
06-02-2017, 09:24 PM
You need to install the dev versions too (liballegro5-dev) as well as the addons. Also see what SilverWarrior said.

Well, I thought as much and did install liballegro5-dev, dunno why I didn't use that in the prior post.
Ok, now about the addons? You thrown me on this since I've never used allegro for anything.


Note that Momen3D use an old Allegro version (5.0, not 5.2).

Ok, if the addons is not the thing, then the version might be an issue. Ubuntu 16.10 is installing 5.2 :(

Cheers,
Gus

gcarreno
06-02-2017, 09:32 PM
Hey don't be to hard on yourself. I also had to sleep over before I realized I should recommend you to use one of state machine designs. ;) But I see you already figured that out by yourself :)

Thanks !!!


Any way.
I also wanted to say that wile you are searching for state machine examples you should note that most of them are only showing the simplest state machine examples with very low complexity like general game state (whether you are in main menu, is game loading or is the game in progress for instance).
But the state machine that you will need for your game will probably need to have much higher complexity. But don't let that discourage you.

That's good advice. Thanks!

I usually don't do much copy/paste type of coding, mainly because if I don't understand what I'm pasting my hives flare up like a bad case of poison ivy ;)
If I don't understand it I can't master it, and if I don't master it it's gonna be deleted and replaced by something I do understand and can maintain, so why not just understand the damn thing before I get into bugs I can't squash cuz I just pasted some code like a script kiddy :)


Also you might want to check Decision_tree (https://en.wikipedia.org/wiki/Decision_tree) and Behavior_tree (https://en.wikipedia.org/wiki/Behavior_tree_(artificial_intelligence,_robotics_a nd_control)) concepts.
Now while these two concepts are most often used for implementing AI they can also be used for controlling your game state.

I've also stumbled on BT's and I still need to get e better grasp on that. I'll probably need it for some other game that has some resemblance of AI.
Decision trees is a subject that I think I grok, but will have to have a go at your link to see if my mental model coincides with it.

Cheers,
Gus

Ñuño Martínez
09-02-2017, 11:01 AM
Don't worry if you can't build it. Actually, IIRC, most people couldn't then.

[off-topic]
I'm thinking, since the PGD Engine project is dead (is it?) may be I should update the engine I created for that project to the latest Allegro, fix bugs and do some improvements and donate it. ::)