PDA

View Full Version : Script in game, for quests



T-Bear
18-04-2011, 06:16 PM
Hi, i have one question:
I am making a simple game where you gather ressources, and build buildings. I have also made a mapeditor, and everything works well, but now i want to make som sort of script so you for example can give ressources or change the score if you build something (For quests and so on). Does anyone have an example how to do this?

BTW: I use
lazarus v. 0.9.30
freepascal v. 2.4.2

Thanks for any help! ;D

code_glitch
18-04-2011, 06:21 PM
I would start out by making some sort of line feed program that can find separate statements in one file, then break that down into words. Based on that you could get a command line structure where the first word is the command the script is running and the rest are parameters...

For easier access, I would use arrays to store game data so you do not have to write a command for every variable name ;) although it can be a pain to manage...

User137
18-04-2011, 07:15 PM
For resources on building stuff you can easily hardcode.

There is alternative to scripts, sort of quest objects or records. For example

pNPC = ^TNPC; // Pointer to record of non-player character.
// If it's class, use that direcly instead of pointer

TGameQuest = record
name: string;
reward: integer;
questStarter, questEnder: pNPC; // Careful with pointer, you have to save it in file as NPC name string or ID
collection: array[0..3] of integer;
collectionType: array[0..3] of TGameItemType;
collectionCount: integer;
// You can figure the rest :p
end;

quest: array of TGameQuest;
questCount: integer;
Point is, you can define quests as datatypes and add their editability to mapeditor.

code_glitch
19-04-2011, 11:27 AM
Just wondering, what map format are you using? TMX? If so I guess you'd have to come up with a system aside from the Map files to save a story... Working on that very problem now although I believe that if I make my engine a shell and control everything from scripts it might be a tad slow but very versatile ???

Bad Sector
02-05-2011, 04:50 AM
There are two ways to go with that. One is to write your own scripting language parser and the other is to use a pre-existing language.

Writing your own is an interesting project and something i've done many times for different projects. The complexity depends on the language's design and features and can be from something extremely simple (the simplest usable language could be something like Forth) to very complex (something like an interpreted Object Pascal). While it is tempting to shoot for the sky, in most cases all you need is very simple stuff. My LIL (https://github.com/badsector/lil) language has a very small implementation but it is very flexible and my Alithia 3D Engine (https://github.com/badsector/alithia/wiki/Screenshots) uses it for everything (note: these two projects are in C, not Pascal - i'm making a FreePascal implementation (https://github.com/badsector/fplil) of the scripting language but it still doesn't support all commands).

To learn how to make your own scripting languages/engines look on information about parsing, interpreters, etc.

The other option is to use a pre-existing one. I don't know much about the pure FreePascal solutions (i've only heard about some "PascalScript" or something like that but never used it). When i was making a 3D world editor a few years ago in Lazarus i wrote a scripting language for it called SimSAL. Recently i uploaded it to GitHub (http://badsector.github.com/simsal/) but the language is mostly untouched since ~2007. I wrote a readme file (https://github.com/badsector/simsal/raw/master/readme.txt) explaining the language, but feature-wise it is very poor - it doesn't even have subfunctions. If your scripts are very simple it could be usable (my C++ Nikwi game (http://www.youtube.com/watch?v=_RHmnUWih1A) used a much more primitive language than SimSAL so it is possible - just not for bigger scripts).

On how to use a scripting language (your own or existing), there are many ways. One of the simplest is to simply run some code for an entity's event. For example assume you have a TEntity class which amongs others has fields like



TEntity = class
private
FTouchCode: string;
protected
procedure DoTouch(OtherEntity: TEntity); virtual;
public
property TouchCode: string read FTouchCode write FTouchCode;
end;
The engine will call "DoTouch" when the entity touches (collides) some other entity. DoTouch's default implementation (it is a virtual so that a subclass can implement some other handling in native code) executes the "TouchCode" like



procedure TEntity.DoTouch(OtherEntity: TEntity);
begin
SetScriptVariable("OtherEntity", OtherEntity);
RunScriptCode(FTouchCode);
end;
Of course the "SetScriptVariable" and "RunScriptCode" parts depend on the language/engine you use. Also there might be some differences. For example SimSAL can be compiled so the runtime won't need to parse the code each time you execute it and instead of doing that, you can use a SetTouchCode for the write part of the TouchCode property that sets and compiles the code and have DoTouch execute the compiled code. Also SimSAL doesn't provide any functionality for setting variables (something common with scripting languages that use a compiled form) so you need to register a function that returns the OtherEntity value. LIL, on the other hand, doesn't compile the code but executes it by parsing it each time and does provide functionality for setting variables, however it is a bit slower. Although this shouldn't be a concern since scripts shouldn't do anything CPU intensive anyway - they're the game's "script" but the "actors" should always be in native code.

Anyway, i think that is enough to give you a few starting points. If you have any specific questions, ask :-)