I am create a game engine in C# using OpenTK (OpenGL). My game's update system works off of an event queue, where when something happens, it is added to the event queue. Each event has a set of triggers and a set of actions.
Let's say the player walks. The 'PlayerWalked' trigger runs. Every event in the game with the 'PlayerWalked' trigger in their list gets added to the queue.
Now, the update function on the game is called several times a second. Every time it is called, the oldest event in the queue is run. Every action in the event's action list is run.
Now, I want to add a condition system. On the trigger 'PlayerWalked', rather than just adding it to the list, it checks the trigger, checks the conditions, and THEN adds it too the queue.
Example:
Event
Name: event1
Triggers: 'ChestOpened', 'PlayerDigs'
Conditions: Player Position is at 1, 1 (2D game).
Actions: Give player 10 gold.
Now, I have the trigger checking and actions working. Now all I need is to add the conditions. Here is my dilemma:
When I am storing the map, I need a way to store the conditions in the event's conditions file. I was thinking the file would contain this: 'playerPosition|(1,1)' But that is very broad, the variable 'playerPosition' might not exist, and I would have to parse it weird.
Question: How would I store conparisions (conditions, if statements) in a map file (string)?
More Information: The map is a directory stored in a map storage folder next to game's executable. In the map folder, there is a folder for events. In the events folder, there is a folder for each event. In each event folder there is a file for triggers, a file for conditions, and a file for actions. The triggers and actions are working now, but the conditions is what I am trying to add.
File Structure:
Maps (Directory)
Map1 (Directory)
Events (Directory)
Event1 (Directory)
Triggers (File)
Conditions (File)
Actions (File)
Event2 (Directory)
Triggers (File)
Conditions (File)
Actions (File)
Event3 (Directory)
Triggers (File)
Conditions (File)
Actions (File)
I am using OpenTK as a wrapper to OpenGL, but there is no sound engine yet. It is a 2D RPG game.
Edit: Someone has brought to my attention that it looks like i'm asking how to write to a file in C#. I know that.
What i'm asking is: How would
if (playerPosition == new Point(0, 0)) { }
translate into a text file that I would parse and store in a variable? How would I store an If statement in a variable, and how would I store that variable in a file?
Solve:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows.Forms;
namespace Entropy
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
a b = new a { s = ":D" };
string json = new JavaScriptSerializer().Serialize(b);
Dictionary<string, object> c = (Dictionary<string, object>)new JavaScriptSerializer().DeserializeObject(json);
MessageBox.Show(c["s"].ToString());
//Out: ':D'
}
}
public class a
{
public string s = string.Empty;
}
}
Storing comparisons in a string, and then turning them into code.... that is called writing a compiler! Computer science has your back on this!
So you're asking, what's the simplest compiler I can get away with, for my domain specific language?
You're mini-language is very mini: it only has predicates (possibly nested predicates)
You can look at C# compiler parser/generators. You've got some fun reading ahead of you.
Alternatively, you could create a class structure that holds these nested predicates, and then serialize them into json, and store the json.
so you might have
var condition = new Condition {
Object = Objects.Player,
Comparison = Comparisons.Equals,
Value = new Value { type = Position, innerValue = "2,1" }
};
And then you serialize it into a string you can save...
var json = new JavaScriptSerializer().Serialize(obj);
And then you can load it up again later, by deserializing the json back into an object.
There's some 'Evaluate' method you call on the comparison object and it rips through the object hierarchy, calculating an answer for you.
I've done this sort of thing in the past by instead referencing a scripting language, Lua is popular for this type of activity in games, but Python is good for interoperability as well.