Jump to content
  • Advertisement

Journal

Sign in to follow this  
  • entries
    122
  • comments
    246
  • views
    90721

Entries in this blog

 

Observation 4

both the rate of growth and volatility of a thread (the probability that a thread topic will diverge and the rate of divergance) are directly proportional to its religiousity coefficient.

Daerax

Daerax

 

Google Notebook gone :(

Im not sure if it is a sign of the times (Microsoft layoffs & 2/3 loss in share price, Suns losing 98% of share price value etc) or just a coincidence but I'm pretty sure the job sections part of the site used to be alot busier.

In other news Google seems to be taking alot of heat and has increased ads, killed its least successful experiments like Google Notebook :( and uploads to google video while becoming stricter and more like a normal ole company with profitability not (or illusion of) creativity the primary focus*.

*I would not want to diagram that sentence muhahaha. Oh yeah google notebooks will still exist as a service to those who already use it. It just wont be maintained any longer.

Daerax

Daerax

 

C# Functional Programming

There is a screenie of the app at work



its proving fairly useful to me thus far. If I am further motivated in this direction I may add functionality to more easily track comments in other peoples journals since checking if the journal author has responded to your comment can get a bit bothersome if you have posted in multiple journals. Meh, maybe the new site will fix this better ... someday...

I spent a couple hours doing minor tweaks on Mike's Line Counting app last night. His app filled a gap I needed between useless and overpriced and too antiuseless to be useful. One thing I am happy about is I got it to output csv so I can have graphs like:

figure 2.

Yay :s.

Anyways this post is mostly to highlight the fact that functional programming in C# 3.0 is not so bad. I implemented a feature, which counts lines of source code in folder(s) instead of projects. I was able to do this hassle free both cause Mike had had already done all the hard work and cause I used functional programming paradigms. In functional programming the ultimate goal is in being able to come up with a *useful* mathematics for specifications (based on category theory) and being able to easily translate this back and forth to algorithims and final language. The less the distance between these concepts the more elegant logical and behaviourally correct code you can write. The programming paradigm which is so far closest to this ideal is the one called 'functional'. Where the word functional is used to emphasize that statements and assignments are replaced with functions and composition and that functions can be be passed around and bound to variables.

I like functional programming not because of some highbrow nonsense like lack 'o state but because humans are much worse at tending to details than automatrons. Every less line of code, every bit of irrelevant implementation detail I can leave off my hands and relegate to the computer is the probability of an error and mistake reduced and my productivity and efficiency increased. Also perhaps due to my training in maths I may be more inclined towards the paradigm since I just may be afflicted by 'Deformation professionnelle'.

The basic/core concepts of functional programming are fold, map and filter. In basic terms map is a function which applies a function of type (a -> b) to a Collection (often a list but may be a tree or other graph) of type a and returns a collection of type b. What good is this? In C# Select stands in for map.


var sourceFilesbyExtensions = new List();
//list of allowed extentions (e.g. cs, cpp, etc)
fileTypes.ForEach (ext => sourceFilesbyExtensions.Add(System.IO.Directory.GetFiles(folder, "*"+ext, searchOp )));

var statsOfNodes = sourceFilesbyExtensions.Select(
sourceFilesArray => sourceFilesArray.Select(sourceFile =>
{ var fn = new FileNode();
fn.Name = Path.GetFileName(sourceFile);
fn.Path = sourceFile; fn.ChildNodes.Add(fn);
CountFile(fn);
return Count(fn, (new StringBuilder()), (new StringBuilder()), (new FileNode()));
}).ToList()).ToList ();



With select I take a List and a function from string [] to List and get a List>. Fold is a an aggregating function. It takes a list/Collection of say type TypeA, an initial value for an accumulator of type TypeB and a function f(TypeB x, TypeA y) -> TypeB and so returns a value of type TypeB. It uses the function you passed to combine the accumulated value and an element from the collection till every element in the collection has been gone through and one arrives at its aggregate via your function. It expands out like this: f(..., f(x' ', f(x', f(x,y))) or f(x' ' ', f(x' ', f(x', f(...))).

A typical example of fold is how to sum a list of integers. C#'s fold is the Aggregate Function. IntList.Aggregate(0, (x,y)=>x + y); I use aggregate to Create a summary string from the individual summary strings held in each FileNode. I also use the Aggregate function to flatten a list of lists into one list. Google's mapreduce refers to the concept of Map and Flatten.


var undistinguishedNodeStats = statsOfNodes.Aggregate((p, q) => p.Concat(q).ToList());
Summary = undistinguishedNodeStats.Aggregate("", (s, n) => n.summary + s);








I will not go over filter because I have no example since I made no use of it here but it does what it sounds like it does. The whole source:


public void CalculateFromFolder(string folder, bool allDirectories)
{
var searchOp = (allDirectories) ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
var sourceFilesbyExtensions = new List();

fileTypes.ForEach (ext => sourceFilesbyExtensions.Add(System.IO.Directory.GetFiles(folder, "*"+ext, searchOp )));
var statsOfNodes = sourceFilesbyExtensions.Select(
sourceFilesArray => sourceFilesArray.Select(sourceFile =>
{ var fn = new FileNode();
fn.Name = Path.GetFileName(sourceFile);
fn.Path = sourceFile; fn.ChildNodes.Add(fn);
CountFile(fn);
return Count(fn, (new StringBuilder()), (new StringBuilder()), (new FileNode()));
}).ToList()).ToList ();
var ssb = new StringBuilder();

var undistinguishedNodeStats = statsOfNodes.Aggregate((p, q) => p.Concat(q).ToList());
CodeLines = undistinguishedNodeStats.Sum(n => n.CodeLines);
Comments = undistinguishedNodeStats.Sum(n => n.Comments );
BlankLines = undistinguishedNodeStats.Sum(n => n.BlankLines);
TotalLines = undistinguishedNodeStats.Sum(n => n.TotalLines);
Summary = undistinguishedNodeStats.Aggregate("", (s, n) => n.summary + s);
CsvOutput = undistinguishedNodeStats.Aggregate("", (s, n) => n.csvOut + s);

statsOfNodes.ForEach(fileNodes => {
if (fileNodes.Count > 0) {
var codeLines = fileNodes.Sum(n => n.CodeLines);
var totalLine = fileNodes.Sum(n => n.TotalLines);
ssb.AppendFormat("{0} files, Count {1}, Total Lines {2}, Code Lines {3} [Percentage: {4} %]",
Path.GetExtension(fileNodes[0].Path), fileNodes.Count,
totalLine, codeLines, Math.Round((double)codeLines/CodeLines * 100),1); ssb.AppendLine ("\r\n");}
});


Summary += ssb.ToString();
}



Daerax

Daerax

 

Journal Comment Eater

I found some free time hiding beneath my bed so I spent some 3 and a half hours making a little application which sits in your taskbar and tells you if you got new comments in your game dev journal. It was fun, Linq is my favourite part of the otherwise mediocre C#. It does this by html scraping the respective page. Every 20 minutes it checks if there have been new comments since the last check. If there has it tries to find out which posts got the comments and pops out a ballon telling you which. If there have been new entries since the last check it only checks the old entries. All this was done quite easily and not many lines of code thanks to the html agility pack and Xlinq.

Every 20 mins it checks if there was a new post at a url which is pasted in a textbox. If the textbox is empty it checks for a file located in the same directory as it for the url, if not it uses Gaiidens journal as the default.

if (textBoxUrl.Text == "")
{
if (File.Exists(infFilePath))
{
var urlFromFile = System.IO.File.ReadAllText(infFilePath); textBoxUrl.Text = urlFromFile;
return (urlFromFile == "") ? "https://www.gamedev.net/community/forums/mod/journal/journal.asp?jn=251283" : urlFromFile;
}
else
{
textBoxUrl.Text = "https://www.gamedev.net/community/forums/mod/journal/journal.asp?jn=251283";
return textBoxUrl.Text ;}
}
else
return textBoxUrl.Text;



It then checks if there have been any new comments since the last check.

var currentCheck = (currentCheckInit.Count > checkCompare.Count) && checkCompare.Count>0 ?
currentCheckInit.Skip(currentCheckInit.Count - checkCompare.Count).ToList()
: currentCheckInit;
var sb = new StringBuilder();
if (currentCheck.Sum(p => p.CommentCount) != checkCompare.Sum(p => p.CommentCount))
{
for (int i = 0; i {
if (currentCheck.IsComment && currentCheck.CommentCount != checkCompare.CommentCount)
{
var msg = "At " + DateTime.Now.ToShortTimeString() + " Found "
+ (currentCheck.CommentCount - checkCompare.CommentCount)
+ " New Comment(s) in thread, " + checkCompare[i - 1].Title;
listBoxLog.Items.Add(msg);
sb.AppendLine(msg);
newComment = true;
notifyIcon1.Text = "New Comment(s) found";
}
}
}







You can also save the last query results to disk. Then later on you may download from the site and check against disk so the program doesnt have to run continuosly to be useful.

private void buttonSaveState_Click(object sender, EventArgs e)
{
var sb = new StringBuilder();
oldCheck.ForEach(entry => sb.AppendLine (entry.CommentCount + "|"+entry.IsComment + "|" +entry.Title));
File.WriteAllText(statePath, sb.ToString());
}

private void buttonCompareStates_Click(object sender, EventArgs e)
{
var urlFromFile = System.IO.File.ReadAllText(infFilePath);
if ((urlFromFile != textBoxUrl.Text) && textBoxUrl.Text != "")
MessageBox.Show("Warning Url found in file and in textbox do not match. This *may* cause discrapncies.",
"Are you Sure you know what you are doing?",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
var tmpCheck = new List();
var dat = File.ReadAllLines(statePath).ToList ();
dat.ForEach(item => { var s = item.Split('|');
var newE = new JournalEntry();
newE.CommentCount = int.Parse(s[0]);
newE.IsComment = bool.Parse(s[1]);
newE.Title = s[2];
tmpCheck.Add(newE); });
var currentCheck = util.PollGDNEt(CheckUrlOptions());
inited = true;
DoComparison(currentCheck, tmpCheck);
}







The part that scrapes the page is here

public static List PollGDNEt(string url)
{
HtmlWeb page = new HtmlWeb();
HtmlDocument doc = page.Load(url);
var xdoc = doc.ToXDocument();

var queryResults = from element in xdoc.Descendants()
where element.HasAttributes
&& element.Name.LocalName == "span"
&& (element.FirstAttribute.Value == "regularfont" || (element.FirstAttribute.Value == "smallfont" && element.Value.Contains("Comments")))
select new {Title = element.Value,
IsComment = element.FirstAttribute.Value == "smallfont",
Count = element.FirstAttribute.Value == "smallfont" ?
int.Parse( Regex.Match( element.Value, @"\d+").Value ) : 0 };
var Entries = new List();
foreach (var result in queryResults)
{
var entry = new JournalEntry ();
entry.CommentCount = result.Count; entry.IsComment = result.IsComment ; entry.Title = result.Title ;
Entries.Add(entry);
}
return Entries;
}







Full Source is here (svn) or source rar'd. And app is here (requires .NET 3.5). Some stats in order of # comments found on page:

User | Total comments on Page | Avg Comments Per Post | Total Posts
-------------------------------------------------------------------------------------------------------
TrapperZoid 20 4 5
Drew 19 1.27 15
Talestyn 16 1.07 15
Ben 16 2 8
Ravuya 16 1.14 14
Me 6 1.2 5

Also Mike P if I you read this and I could get the source for your line counter project, would be cool.

Daerax

Daerax

 

RAE 2008 + Random

If (You are in the UK) And (Are Interested in Attending Graduate School Or (Are In Graduate School And are Interested in seeing how your School 'ranks' in your respective area of study) Then you may wish to check out the Reaserch Assesment Excersice 2008 results.

The goal of the exercise is to measure the quality of research output of universities across the UK. Of a course these results are just statistics and are just about as useful as using average height of people in City A to predict the height of the next person you see.

In Informatics + CS, top scorers are Edinburgh (towering over every one), Cambridge, Oxford, Manchester, Bristol, Imperial College London. In Pure Maths we have Cambridge, Oxford, Bristol, Leeds, Manchester, Warwick. An entry I was surprised to see there was the Open University. I wonder how it works if there is no real central location.

In other unrelated and random un-news I wonder what it says on the culture and views held of said people. If it shows cultural maturity or disdain of education and book learning amongst males.

Daerax

Daerax

 

Programming Related Quotes Taken from the 1960s

Below are a series of surprisingly relevant quotes taken from a book published in the 1970s. Some of the quotes are from the 60s.
Any Given Program, When Running, is obsolete.
Any given program costs more and takes longer
if a program is useful then it will have to be changed
if a program is useless, it will have to be documented
Program Complexity grows until it exceeds the capability of the programmer who must maintain it
Not until a program has been in production for at least six months will the most harmful error be discovered
If the input editor has been designed to reject all bad input, an ingenious idiot will discover a method to get bad data past it.
Profanity is the one language all programmers know best..
Investment in reliability will increase until it exceeds the probable cost of errors, or until someone insists on getting some useful work done
Adding manpower to a late software project makes it later
Fuzzy project objectives are used to avoid the embarrassment of estimating the corresponding costs
The effort required to correct course increases geometrically with time.
Build a system that even a fool can use, and only a fool will want to use it.

Daerax

Daerax

 

Ramblings on Recession effects on Indie Startups

There are some people here (not me) who are interested in starting up a small games business. They might be discouraged to do so due to the recent economic downturn, recession. But to me, this is good news for a start up indie games company and start ups in general. Here is why I think such is true.

Recessions hit those conglomerates and massive businesses (and those smaller ones dependent on them) hardest. During these times it is difficult to find jobs thus in terms of risk, striking out on your own is less and there is less harm and more opportunity in trying that idea of yours. Who knows, people may like it.
Economic recessions are a weeding out period, only the smart, lithe and agile companies survive. As a small developer you will be more situated to have quicker response times and better able to try unique approaches. Now your small size is your advantage.
Rates and offers from banks although harder to come by also tend to be more reasonable. Money is also more easily acquired from the government seeking to stimulate the economy. However loans should be avoided unless absolutely necessary - sometimes it pays to grow your business organically (and grow with it too), especially with deflation concerns in the forecast. This whole craze for Instant multi-million companies is to me quite childish and more importantly less sustainable.
Recession and specifically deflation means the value of money is increased, the cost of goods is generally less but also money is scarcer. There also tends to be less liquidity in the economy. What this means is that people are tending to save more. Due to having less expenses you can offer games at reduced prices. People will be more likely to thrifty spending and less to luxury spending and more likely to look elsewhere at less pricey items for leisure.
Finally and most morbidly, the job outlook for the future is apparently grim. Layoffs and hiring freezes at their highest rate in a long time. More people than ever claiming job benefits. More people at home with nothing to do and less money to spend. Making them more frugal and selective in their spending. Catch their attention and create balance in the universe by turning their losses to your gains.
And as a useless note that sounds like a quote out of a book by Captain Obvious but still worth pointing out: As an indie your chances are increased by making it so your game has mass appeal. The game should be non intimidating/have an intuitive friendly interface and also stand out by having great talking points - aspects which people want to talk about, argue on, comment on and share with their friends. Word of virtual mouth will be your friend there. Generally games which require less sustained time investment, with a brighter palette and 2D more cutesy graphics seem to have that universal appeal.

Another one is to be nice to people who took the time to use your stuff. Feedback is vital in Nature's Evolution and also for your game's. Responding to criticisms and complaints in a balanced manner will polish your product and make it compositionally more appealing further increasing your market base, developing your brand and building a company around it.

Daerax

Daerax

 

Python is kl but...

I just seen Washu's post on how he loves Python but do not find his argument very convincing. I would reply but the post is old so I decided to do it here. His main argument in *that* post is that Python has very little noise in its code. In my opinion that too ranks amongst the highest in criteria for a good language but is not a very distinguishing feature. In his post Washu anticipates people like myself who would "point to the many functional languages that have many of the same capabilities". Which is just what I am going to do.

The python code is items = [
{'name' : "Bronze Sword", 'value' : 50, 'diceCount' : 1, 'diceSides' : 4},
{'name' : "Steel Sword", 'value' : 100, 'diceCount' : 2, 'diceSides' : 4},
{'name' : "Adamantium Sword", 'value' : 200, 'diceCount' : 1, 'diceSides' : 10}
]

result = [item for item in items if item['value'] > 50]
print result






In F# the code is just as readable. As a personal opinion I find it more readable because the quotes around property names in the python code threw me a tiny bit and the list comprehension syntax is clearer IMHO.#light
type Item = {name : string; value : int; diceCount: int; diceSides : int}

let items = [
{name = "Bronze Sword"; value = 50; diceCount = 1; diceSides = 4};
{name ="Steel Sword"; value = 100; diceCount = 2; diceSides = 4};
{name = "Adamantium Sword"; value = 200; diceCount = 1 ;diceSides = 10}
]

let result = [for item in items when item.value > 50 -> item ]*
print_any result






F# also has a very lightweight whitespace based syntax and hassless integration with the .NET codebase. All without having to give up the benefits of static typing. The definition of the Item type also helps others (including the compiler) who might touch the code to know the relevant parts of Item in their entirety.

A final word is that the addition of the For Each extension method in the C# example is not fair since this is utility functionality that does not belong in the example. While it is useful it probably would be found in some other file while for a quick test, especially since it does not really reduce the amount of noise in the code (actually adds more) I do not think it belongs.

I guess my point is that python's clean syntax is more a yeh so, I can too feature. Not something particularly striking.

*The code is deprecated and his been replace with the slightly less (IMO) clear [for x in xs do if then yeild ]

Daerax

Daerax

 

Warning: This is a Short and Angry Thread

Why the Frock does Microsoft Solver Foundation (http://code.msdn.microsoft.com/solverfoundation) require Microsoft Office 2007 to be installed to use it? Do they not want anyone but those most loyal to their platform to use it? Arr. Argh. I am greatly annoyed by and hate idiotic limitations like these.

Hmm erm. Ah well it would seem that you just need to have Microsoft Visual Studio Tools for the Microsoft Office system (version 3.0 Runtime) installed. And Not Microsoft Visual Studio 2005 Tools for Office Second Edition Runtime like me. I am happier now I guess. Carry on then, nothing to see here.

[EDIT - Changed fire face to Ying Yang]

Daerax

Daerax

 

More on Generic RPG

After spending much of my time off completing Roger Zelazny's works, trapped in the wikipedia time sink whirlpool, gamedev and watching TV Shows and generally not doing anything I got back into the game, so to speak yesterday, just when my little vacation is over.

Some thing I have noticed is that OOP is better for creating abstracted and decoupled easily extensible code. That is I have so far found OOP methods are better for arranging the overarching design than Functional programming which excels in detailing the execution. Using Functional Programming as glue and the real meat has allowed me to progress in a more descriptive manner and have the level of data driven code I wish. Also, although I have used objects with mutable fields, I have designed the objects to interact with functions which are mathematical in the sense that although they will run sequenced computations within, they will with a few exceptions return the same output given the same input. Nonetheless I have taken advantage of reference semantics for a few fields with regards to updating although this is leveraged in only 2 places in the code last i counted.

The code layout is based around interfaces and to a minor extent composition. GameObject mostly represents the part of the object that is used by the computer. When the map is created GameObject contains a set of values which will control what files are loaded, where they are drawn etc. Each object is associated with an SDL surface via a Map for rendering purposes. The class which renders is separate from the concept of World which itself collects objects which act or do not act. All GameObjects contain a field called AbstractPart. Which Is a field which accepts any objects that implements the AbstractObject Interface (requiring a .Act() method).

To render the Narrator tells the World to build a VisibleObjects Tree. This is done by partitioning the map into visible and none visible objects. The visible objects are then partitioned into those that act and those that do not. All the objects that act (e.g. move) are run through and then placed back into the NonActors Tree. This tree is sent to the narrator.

def CheckFits( o, c, s, s2){
if ( (o + s2 - c > 0) && (o - c true
else
false
}

def partitioned_tree = Tree.Partition( visualization_tree ,
fun(o){
if ( CheckFits(o.Position.X, camera.Location.X,Nsdl.ScreenRes.Width, o.Size.Width ) &&
CheckFits(o.Position.Y, camera.Location.Y,Nsdl.ScreenRes.Height, o.Size.Height ))
true
else
false
});

def (visibleObjects, _) = partitioned_tree;
def (actors, nonActors) = Tree.Partition (visibleObjects,
fun(o) {
match(o.VisualType ) {
| VisualType.AnimatedAndActs => true
| _ => false }
});
seq [ (obj.Position, obj.CurrentAnimation) = (pos, dir.ToString ()) ,
obj in actors, obj.AbstractPart.Act(obj.Position, obj.Size) -> (pos, dir) ];

mutable FinalTree = nonActors;

seq [ FinalTree = Tree.Insert(FinalTree, actor, false), actor in actors];
FinalTree;





I enjoy being able to refactor sections of the code and not have to change any other bits and have it work. For example to update the system to use animations which have multiple differing I simply changed what I had left as a place holder - a string field to a list of tuples of type (string * string). Where the left string is the Animation name and the right is a filter expression that all animations which match it will be loaded. I suspect I will have to make significant changes to how I handle 'AbstractObjects' so I am glad of this ability to easily change sections without affecting other functionality.


The golden comet ball thing moves about like a fly while the tail animates. The blue flame does not move but animates
Source Snippet: Source

def objs = [GameObject(@".\Art\014.bmp", Drawing.Point(480,250), Drawing.Color.FromArgb (255,255,255), VisualType.Static() ),
GameObject(@".\Art\stand2.png", Drawing.Point(920,300),Drawing.Color.FromArgb (200,140,208), VisualType.Static(), 1.0f ),
GameObject(@".\Art\tavernx.bmp", Drawing.Point(420,260),Drawing.Color.FromArgb (200,140,208), VisualType.Static(), 1.0f )] ;

def o1 = GameObject(@".\Art\017.bmp",Drawing.Color.FromArgb (255,255,255), VisualType.Static() );
def ao = GameObject(@".\Art\Animations\BlueJet", Color.FromArgb (2, 9,124), VisualType.Animated(), 2.0f);

def ao2 = GameObject(@".\Art\Animations\earthmagic muni", Color.FromArgb (204, 173,97), VisualType.AnimatedAndActs(), 3.0f);

ao2.FilterAnims = [("North","earthmagic muni n "),("South","earthmagic muni s"),("East","earthmagic muni e"),
("West","earthmagic muni w"),("NorthEast","earthmagic muni ne"),("SouthEast","earthmagic muni se"),
("NorthWest","earthmagic muni nw"),("SouthWest","earthmagic muni sw") ];
ao2.AbstractPart = MovingAnimatedObject();



def w = World(@".\Art\012.bmp");

seq [ w.AddObject (o) , o in objs];

w.AddObject(ao);
w.AddObject(ao2);
w.AddObjectManyTimes(o1, World.RandomDistribution(95, 500));

_ = Narrator(w);






Another place where the focus on functional programming has paid off is in getting the AI up. The simple AI I rustled up uses Algebraic Types and Matching to create what I later found to be a Hierichal Finite State Machine. Within a functional paradigm it seemed pretty obvious and not worthy of a paper.. This is currently the stage where I am at. I wish the units to have fairly robust AI and am thinking of using Monads to implement something more robust than Behaviour Trees - that is if I understand it correctly, I am new to AI. My main texts on it are the book Mathematical Methods in Artificial Intelligence and AI Gamedev. My next post will detail my approach to this.

Daerax

Daerax

 

The Story of Gilan the Wise

So I did not do much programming this week. Actually, I dont think I did any. But I did think about what I want the Generic RPG to be. I wrote down some ideas and a genaral design and began work on characters, the first chapter and map and scripts for its characters.

First things I want the game to be small and completable. I also want to explore concepts related to nonlinear and emergent story. I want the game to be short but filling. I was able to think up a general design and retrofit a story to match this. I am using Reiner's Tiles sets which have a certain... style so the story is a bit quirky.

The game will be titled "The Story of Gilan the Wise". This is the synopsis:

You are Gilan, a retired but powerful mage who has been called by the Council of Seven because Max the Mad Mystic is at it again. He is seeking The Green Stone of Core Power to drive his device which will destroy the world. .

So you play an old male mage whose age is estimated to being anywhere from between 60 - 150. There are no elves or dwarves in this story. Except for hints here and legends there the back story for Gilan is never gone into.

There are Three Chapters with 2 main maps and one side map each. Every map with the exception of the first will have at least 1 but no more than 4 characters with involved conversations about philosophical issues, which tie into the game story. There will be any number of characters with generic conversations. The game though, is nonlinear in the sense that the chapters don't really exist; they are more an organizational tool for me.

There are no Levels, nor XP. You are already powerful so the need is not there. You can complete the game without killing anything. Though the power is there if you wish to flaunt it. There is HP and MP but no distinction is made between magery or priest magic. There is only the arcane arts. The game world assumes a level of development around 1700s and 1800s and develops a similar world view. The gameplay is centred around magic. The magic system is inspired by formal logic.

Since you are a powerful mage it seems right that you should be able to create your own spells. Gathering components and coming up with spells to defeat situations that will otherwise cause you to lose the game will be a focus. I have not yet thought about it but I want a powerful system that interacts with the world. I am thinking of a simple visual language that influences stats and has effects and alters rendering. I dont know, thats still a bit down the line. Regardless I have put a requirement on myself - to force my hand if you will - that all spells you come prebuilt with will have to be made in the game using this technique.

The other aspect is the story. I want to be able to play it and not know what is going on in some aspect. On that line I have thought about making the Council of Seven simple agents with motivations and attitudes. You start out knowing that there is a traitor amongst the seven. Then using simple decision theory and dice have the computer choose the culprit. After that use that as input in some algorithim that sorts of fills in the blank in areas in the story, levels and items etc. which I would have designed to be treated as free variables. Again I dont know the specifics of how I will implement this. But in my head the key words I am considering is recurrence relation. To make the story be sort of dynamic I am using variables and a set or relations to determine key outcomes.

Sort of a story where words and paragraphs are left out to be filled in and where each subsequent choice affects the set of choices that are possible in the future since for each choice the algorithm uses prior choices to calculate what to write display or generate. Choices made by both you and the traitor. So in a sense it will be you vs the computer - each member of the council will have a certain style and I think I will want two or three of the roadblocks to be randomly generated based on the set created from the actions taken on specific key turning points and agent originally chosen and dice.

In this sense the game does not have any story to be found out. There is a mystery and in playing the player solves it and develops their own story. Hence the title of the game.

Daerax

Daerax

 

Animated Collections

I have been distracted because someone on the forums mentioned Roger Zelazny's Amber Chronicles on Wednesday which meant that I had to look it up, become intrigued, buy the first 5 books and complete them yesterday.

One of my favourite series, up there with the Riftwar saga, deathgate cycle, belgariad/mallorien and farseer series. I still got 5 more books in the series to go. I see its influence on Planescape, Baldur's gate and the Game of Thrones.

Anyways I was able to integrate with the SDL animated collections. Now, Animated Sprites need not move nor must they change directions so it is silly to build in such assumptions into them. Thus I simply added two fields, another string and VisualType (static or animated) and now the set of all visual behaviour is closed. I was quite happy to see how trivial it was to extend the engine. I did not have to touch much, just add a couple of lines in two files.

I renamed what I once called objects to visual_aspect. This is because there will be two extensions to visual_aspect. Animated objects which change direction but exist only for a finite time (spells), animated objects which change direction and exist forever and can think. These will be NPCs. As well because I have decoupled actions from properties I can have arrows as Static Objects which exist for a finite time and change directions.

I am not using inheritance and instead using composition to create more complex behaviour to keep the functional way of composition as key.
-----------------
Changes:

ActOn ( v : VisualAspect ) : Sprites.Sprite
match(v.VisualType )
| VisualType.Animated => def animSprite = Sprites.AnimatedSprite(Nsdl.LoadBitmapAsAnimation(v.Key , v.FurtherFlags, v.Transcolor));
animSprite.Animate = true;
animSprite ;
| VisualType.Static => Sprites.Sprite(Nsdl.LoadBitmap(v.Key, v.Transcolor ));

....
seq[ { o.Size = bmp.Size ;

unless(surfacePool.Contains(o.Key))
surfacePool = surfacePool.Add(o.Key, bmp) } ,
o in TheWorld.VisualizationTree, ActOn(o) -> bmp




def objs = [VisualAspect(@".\Art\014.bmp", Drawing.Point(480,250), Drawing.Color.FromArgb (255,255,255), VisualType.Static() ),
VisualAspect(@".\Art\stand2.png", Drawing.Point(920,300),Drawing.Color.FromArgb (200,140,208), VisualType.Static() ),
VisualAspect(@".\Art\tavernx.bmp", Drawing.Point(420,260),Drawing.Color.FromArgb (200,140,208), VisualType.Static(), 2.0f )] ;

def o1 = VisualAspect(@".\Art\017.bmp",Drawing.Color.FromArgb (255,255,255), VisualType.Static() );
def ao = VisualAspect(@".\Art\Animations\BlueJet", Color.FromArgb (2, 9,124), VisualType.Animated(), 2.0f);

seq [ w.AddObject (o) , o in objs];

w.AddObject(ao);
w.AddObjectManyTimes(o1, World.RandomDistribution(95, 500));


Daerax

Daerax

 

Scrolling and Sorting

I was able to add a couple of things to the game tonight. Which was basically to enable defining a world and per pixel scrolling through it. This was done by essentially three things, using a Red Black Tree to hold the objects in the world. Adding the notion of layer to objects and adding a camera. One boon from the way I implemented things is that the world is in a sense infinite sized (technically int.Max sized) . You can place objects practically anywhere with negative or positive values and never be out of bounds. I could easily make it truly infinite but dont really have time to waste. As well you can keep on scolling the camera and also never be out of bounds. Youd just see endless stretches of the default tile.

Originally I was using a simple list to hold objects. Upon further thought I realized that I would like to be able to drop items, pick them up, kill npcs and summon cows. This meant using a data structure that allows quick insertion and deletion.

The red black tree (similar to C++ Multimap but does not allow multiple keys of same value) is a balanced and ordered tree. Objects implement the ICompare interface and are sorted upon insertion by first checking if the one of objects being compared is in a higher layer, if it is then it will automatically sink so as to be displayed on top, if not just compare Y values. For example, all objects which have a layer of 2 will always be above objects with a layer value of 0. This for example allows me to put an apple on a table or hang a picture on a wall. The default layer is zero. Layers can be negative, have decimal and are bound by float.Max. The Renderer asks the World for all visible objects, this is done by simply filtering out objects that are not in view. On a key down event the camera attaches a scrolling method to the tick events list and removes it on a key up.

Next will be to add NPCs which walk around and fight. Projectile and summoning spells. I will also be integrating the old Conversation scripting language I made some time ago.

--------------------
Snippets: full source here .

To display:

strip (z : option[Surface]) : Surface
match(z)
| Some(s) => s
| None => base_gfx

public Display() : void
seq [ _ = video.Blit(base_gfx,Drawing.Point(x,y)),
x in [0,base_gfx.Width..video.Width ], y in [0,base_gfx.Height..video.Height]];

seq[ _ = video.Blit (surface , Drawing.Point(p.X - camera.Location.X, p.Y - camera.Location.Y)),
o in TheWorld.BuildVisibleList(), strip(surfacePool.Find ( o.Key)) -> surface,
o.Position -> p ];
video.Update ();








Representing the World:

public AddObject(o : ObjectType ) : void {
objects = Tree.Insert(objects,o,false);
}

public BuildVisibleList () : list[ObjectType] {
def CheckFits( o, c, s, s2){
if ( (o + s2 - c > 0) && (o - c true
else
false }

objects.Filter( fun(o){
if ( CheckFits(o.Position.X, camera.Location.X,Nsdl.ScreenRes.Width, o.Size.Width ) &&
CheckFits(o.Position.Y, camera.Location.Y,Nsdl.ScreenRes.Height, o.Size.Height ))
true
else
false
}); }







Main() : void
def objs = [ObjectType(@".\Art\014.bmp", Drawing.Point(480,250), Drawing.Color.FromArgb (255,255,255)),
ObjectType(@".\Art\stand2.png", Drawing.Point(920,300),Drawing.Color.FromArgb (200,140,208)),
ObjectType(@".\Art\tavernx.bmp", Drawing.Point(420,260),Drawing.Color.FromArgb (200,140,208), 2.0f)] ;

def o1 = ObjectType(@".\Art\017.bmp",Drawing.Color.FromArgb (255,255,255));

def w = World(@".\Art\012.bmp");

seq [ w.AddObject (o) , o in objs];

w.AddObjectManyTimes(o1, World.RandomDistribution(95, 500));

_ = Narrator(w);









Objects all in same layer.

Moving the house to a higher layer.

Daerax

Daerax

 

Generic RPG

So Ive added another hobby project in addition to the development of the functional scripting language to rotate through. I've completed the logic tool and am working on packaging it for easy use and distribution - including a site where you can use it live.

The new project I'm working on is an open source game + game engine. Currently it is titled Generic RPG. It is a 2D Game using SDL.NET and Reiner's Tilesets. The core goal here is to first complete a small game. Second display the great efficacy with which a game can be completed when working with an expressive language. And why you should take all the help you can get when trying to complete a game since the odds are stacked against you. Instead of using a language because everyone else does.

I am also trying to the best as I can to write the game in an extensible way. Keeping in mind that in each stage of the development I want any one to be able to easily use the Engine in their own project to make any game that I could or better. I am also keeping a public SVN which will be an up to date collection of the source. Trac on assembla. The engine is simply the project compiled as a DLL no extra work. To run the game I simply change the output type to exe. The dll is not at all dependent on any of the resources I am using and independent from my own game which is data driven.

Finally I want to write a non trivial open source game using functional paradigms as the main driver and using objects as a packaging - something I have never really seen. People go on about how powerful functional programming is but never really give anything beyond abstract examples and those few practical are boring applications :p. Ofcourse I have made concessions. I have not gone dogmatically overboard by going overly pure.

Functional programming excels at writing code that is very data driven but fails at writing easily encapsulated extensible code. The various popular languages have solutions. On the .NET framework I have tried to write a balance of functional and .net compliant oop.


My initial design thoughts are:

------------------
The game is a story:

There is a story which must show the player things, and let them hear things. The story is also in charge of how these things are shown and heard.
This story takes place in a world. This world is big. But the world must be shown to the player. There must be a camera into our world that gives parts of the world to the story as we move.

Inside this world there are things. Everything can be seen. But some things can do. They can move Or make noise Or resist being moved. There are some things which move and change their form as they move.

Types of things:

. Narrator
. SDL
. Camera
. World
. Objects ------- Objects can have properties, some can:
- move
- change shape or form
- make sounds
- resist movement
- some combination of or all of the above
But we must also allow the player to do as he pleases. The player is an object which does all of the above but also takes instructions. For now he must take directions on where to go.
------------------------------------

I am also using a mind mapping software that someone in the forums recently mentioned. It fills in the final gap I needed I think - I already use whiteboards, paper notebooks, one note, PDA, ReminderFox. Freemind is not perfect though, it is good at organizing your thoughts but not as good as one note at organizing your organized thoughts.

Anyway this means that at any giving moment you can go to: here and see a graph of what my current thoughts are. These days I don't implement anything before first whacking it out on Freemind. The file is also there in the svn repository. So you can follow my development if you will.

Daerax

Daerax

 

Types and effects in FJ

One of the guiding principle for this language to have it be a lightweight language to learn functional programming in (I am learning alot from implementing it too =). So it was a difficult debate with myself whether or not to allow effects. In a later post I will talk about why I chose to implement effects into the language and go over the language. Nonetheless I chose to make the syntax such that it was clear that you were not manipulating variables but reference cells. The syntax for them is verbose compared to the rest of the language to discourage their use.

Some things Ive done is to add types - there is proper type checking - matching if branches, assignemnt, operations, while statements, functions etc. Which has actually aided in developing it. Also added let bindings. The guessing game in full:

guess = NextRandom 200.0;

Print "Guess a number between 0 and 200\n\n";

letrec game : float -> float -> unit =

function r : float | tries : float.

if r == guess then ( Print "Got It. Took: " ; Print tries; Print " tries.")
else (
if r > guess then
Print "Too High, Try again...\n"
else
Print "Too Low, Try again...\n" ;

game (Convert ReadInput To float) (tries + 1.0)
)

in game (Convert ReadInput To float) 0.0;




The pi calculator: Two versions. The top one is slower than the bottom one. One thing that I like about how I implemented the while statement is that it is like a function, it returns the value of the last term that was evaluated. So this:
z = while (@k) is whatever value k was at the end of the loop. The evaluation takes on average .5 seconds which is quite a bit slower than the other but alot more is going on as I will explain in a future post. However I am also counting the file loading and pretty printing which probable adds quite a bit.

val = mutable_cell 0.0;
den = mutable_cell 1.0;
isplus = mutable_cell true;
one = mutable_cell 1.0;

while (@den) 10000.0 do (
val 4.0 / (@den));
den 2.0;
one );

////////////////////////////////

- = function a : float | b : float . a + -b;
not b = fun a : bool . if a then false else true;

pi = while (@den) 10000.0 do (
if (@isplus) then
val 4.0 / (@den))
else
val 4.0 / (@den)) ;

den 2.0;
isplus @val
);

Print pi;




New targets

Add variants. and basic pattern matching on variants.

I suggest that the next program to try should be a Rock Paper Scissors game.

Accessing .net objects. Im thinking of the following syntax: handle = dotNetLoad "assembly"; then dotNetInvoke handle "methodnameasstring". As this is an interpreted language there will not be getting around using reflection to access libraries. when actually using the language as library I suspect having a way also to add objects to a heap that the script can access may be better. Will have to think about about the syntax and semantics of that. will probably need to support objects.

Daerax

Daerax

 

Some Programs

So the language is currently basically just the untyped lambda calculus with floats, strings, booleans, Console Input, abbreviation of lambdas (e.g. function a b vs. fun a. fun b) and +, - , *, / , , == operators. It is a simple language, getting most of its power as a side effect of the effectiveness of higher order functions.

The fact that the language I am implementing it in has tail recursion, pattern matching and garbage collection has made it quite easy to make an almost word for word conversion of the abstract descriptions and rules. I do not think Id have it so easy and move as quickly were that not the case. The F# parser and lexing tools really help, making it almost too easy.

So I wrote some of the first programs in the language:

pi = rec ( function pi den val one .
if den 1000.0 then
pi (den + 2.0) (val + one * (4.0 / den)) (neg one)
else
val );

pi 1.0 0.0 1.0 //3.13959265558979






The PI calculator. You will notice however that I stop at 1000. This is because recursion is done via the Y combinator, a function which fixes a function whose definition refers to itself, the implementation of recursion is done not in the VM but using the language itself. As such recursing too high causes a stack overflow. A guessing game:
r = "20";
game = rec (function game guess.
if r == guess then
"Got It"
else
game ReadInput));

"Guess the number: ";

guess = ReadInput;
game guess;





As you can see a number of deficiencies are highlighted here. As this is basically a direct translation of the lambda calculus there is no sequencing available. So I cannot tell the user that they have gotten the guess wrong. There is also no ability to get from strings to floats.

Some targets are to get the full version of these programs working. Some things I wish to add are: types, sequencing, let bindings, while loops and let rec recursion bindings that are more optimized by taking advantage of the host language.

Daerax

Daerax

 

User defined operators

factorial = rec ( fun fct . fun n .
if n == 0.0 then
1.0
else
n * (fct (n + -1.0)) );



A recursive function via Y combinator. Need to think of how to add letrec bindings. Looked it up in the simon peyton jones implementing functional languages book. seems straightforward enough.
------

Woohoo I got user defined operators. As I was going about implementing some infix operators I thought to myself that user defined operators is a staple of functional languages. I do not plan to have operator overloading so +, - , , & etc cannot be implemented. but you can still define your own infix operator by simply putting brackets around the function name. I cant figure how to drop the brackets without mucking up the parser.

So the following works:

% = fun a . fun b . a mod b;
5 [%] 3; // 2
(% 5 3) // or use it lisp style. :s

This works for all functions. so i can go:

mix = fun a . fun b . a * b + a;
2 [mix] 3 // 8




Daerax

Daerax

 

Looks like lisp :s

So Ive added strings, floats and booleans to the language. As well there is now named binding so programs can now be written. The language is still the pure lambda calculus, just with some sugar. its still abit sour though, kinda looks like lisp. Because it has higher order functions and the power of lambda abstractions im getting a lot of powerful behaviour almost for free. Including currying, being able to pass code about, tuple like structures. It is still useless though because there are no operators (to test some stuff implemented prefixed addition) so you cant do comparisons or complex math easily. Im currently targeting being able to run that pi example and The guessing game. :)


prod = fun x. fun y. addf x (mulf x y); /* x + y*x */

partapply = prod 4.0;
r = partapply 2.0; /* 12 */
k = prod 4.0 3.0; /* 16 */

zk = "BOO:";
ss = "lllp";
id = fun x.x;
id zk;

when = fun b . fun x . if b then x else false;

when true (
(fun x . x) ("Id is: " 5) );

p = 5 zk ss; /* */
"P is : " p; /*prints ("P is : " (5 "BOO:" ss))*/

p = 5 (zk ss); /*("P is : "(5("BOO:" "lllp")))*/




Daerax

Daerax

 

Functional Jargon

So this is an interim post. Although Ive added strings and "blocks" to the logic program this post is about a new project.

So implementing that last project I got bit by the language bug. It was fun comparing things with Epoch and Tangent although what I made was certainly not intended as a real language. But Ive decided to embark on writing a proper language from first principles. For me it is motivating to see what the others have done, every time I implement a feature I refresh the journal page to see if the others have made any new posts. Hopefully it is motivating and also provides friendly competition for the others so the languages dont simply die (e.g. Epochs current road block with lexical scoping might otherwise prove too daunting to be worth bothering about). Although each language is not related or part of the same domain since each addresses a different niche (Tangent: a beginner friendly OOP language that addresses much of the problems of OOP - collisons, dispatch , inheritance; Epoch a performant scripting language for games?).

So my language is called Functional Jargon. As its title implies it is intended to be a functional language. The language is written in F#. It is intended to fill the following niche

(1) Run on a PDA.
(2) A simple language to learn functional programming in
(3) A fairly efficient scripting functional language for games on the .NET platform.

(1) is by far the most important since it is often that I find myself wishing I had a language to test some algorithims on my PDA in a lightweight functional language. There is Scheme for PDAs but it is impossibly obtuse on a such a small screen. Thus the syntax will be fairly terse to enable quick scribbling. The PC version will have a more verbose pascal like script to make it friendlier.

Two and 3 imply that the language will be interpreted. Indeed the language will be exposed as a library with an eval method. Although it will be interpreted the abstract machine will be statically typed. I have no intention of making it a first class citizen on the .NET platform - the languages F# and Nemerle already fill this niche. Thus it will not produce IL. I will have to see how interop with say objects in a game will work. I may have to rely on reflection. I do not intend to support .NET classes since I intend to have a richer type system than it allows.
------

Because it is a functional language it makes sense to start out with the lambda calculus and then extend it. So rite now FJ is the untyped lambda calculus, it is already turing complete with support for recursion (via the fixed point combinator), higher order functions (everything is a function) and proper scoping (via nature of the calculus). But it is currently useless. Here are the kinda programs you can currently write in it:

x#; /*bind a variable to the context*/

y#;

x (y x); /* everything is a function */

fun z.z y; /* apply y to fun z -> z */

fun x.x; /* identity function */
fun t. fun f . f; /* boolean false */
(fun x.x) (fun x. x x) y;




Daerax

Daerax

 

Logic Language

So I went ahead and added those things. Pi takes ~0.09 seconds here so its between Tangent and Epoch... not that this is intended to be a real language heh. There is now a full multivalued lukasiewicz logic. Where 1 is true 0 is false and there is still mu. I have yet to add string and there is no boolean type. So the behaviour goes like: unbound variables default to mu. senseless operation result in mu. So for print 2
There are types. floats can be used as normal numbers or as values in a logic if they are between 0 and 1 and when used with normal logic operators. For example print 5 => 6 is mu. but print 0.005 => 0.006 is 1.0. you can still do logic like

truthtable P => Q (for L3 logic). you can also do thing like if tautology p & p print p else print mu.

Anyways here is the source for pi:

isPlus := true;
denominator := 1.0;
val := 0.0;

while denominator 10000.0 do
begin
if isPlus then
val := val + (4.0 / denominator)
else
val := val - (4.0 / denominator);

isPlus := Not isPlus;
denominator := denominator + 2.0
end;

print val

////////////////////////

Began at: 07/08/2008 20:36:58

: False
TFloat 3.141392654

Finished at: 07/08/2008 20:36:58 Interval: 00:00:00.1093750
run


Began at: 07/08/2008 20:36:59

: False
TFloat 3.141392654

Finished at: 07/08/2008 20:36:59 Interval: 00:00:00.0937500


raining := 0.4;
cloudy := 0.7;
shining := 0.2;

if raining Or shining => cloudy 1.0 then print 200;

print raining Or shining => cloudy
Began at: 07/08/2008 20:43:36
TInteger 200 TFloat 1.0

Finished at: 07/08/2008 20:43:36 Interval
print true ^ 20; print 2 ^ 20;
Error near line 0, character 30
Try one of: print ; quit; trycounter; t
ue | false; =>, ^, Or, Not,

TTriv False

Input: print true ^ 20; print 2 ^ 20

TTriv Mu TFloat 1048576.0

Input: print 2 true

TTriv Mu


Daerax

Daerax

 

Lukasiewicz logic 1

So instead of doing modal logic I decided to go ahead and skip that since it will prove to be too difficult and since it will not be useful in the context that this program is meant for.

Instead I went and built a 3 Valued Logic module. The logic system is Lukasiewiczian. So the type system has been made richer. By allowing ranging over one more value. Mu. The logic is still decidable and so one can still prove and verify and sentences in the language. The truth table is below. Interestingly when I was testing the language I was able to find an error in the reference text that I had never noticed before. The text stated a proposition evaluated to True when it in fact did to Mu.

The next act of business is to extend the system to allow full multivalued logic. This will require a fuller type system with floats required. I may then as well go ahead and add booleans back in, allow some basic flow control (loops, if then statements, input) and get a turing complete language in the package.

I will post my version of the PI calculator soon =).

let (===>) a b =
match (a, b) with
(True ,x) -> x
| (False , _) -> True
| (Mu , False) -> Mu
| (Mu, x) -> True

let (|||) a b =
match (a, b) with
(True , _ ) -> True
| (False , x) -> x
| (Mu , True) -> True
| (Mu , _ ) -> Mu

let (&&&) a b =
match (a, b) with
(True , x) -> x
| (False , _) -> False
| (Mu , False) -> False
| (Mu , _) -> Mu




Input: Raining := true ; Shining := mu;
Cloudy := true; dry := false;

print Raining ^ Cloudy Not Shining

Mu

Input: print Raining ^ Cloudy => Not Shining Or Cloudy

True

Input:

So what use is this? The main use of this is for pedagogical reasons. New students struggle alot with logic since it is often their first meet with anything so abstract. The idea is to have a friendly interactive online environment to hone your understanding and get used to the whole concept of why False Implies False needs to be true.

Daerax

Daerax

 

Propositional Logic

I decided to make a simple Proposition Logic Theorem Prover type thing last night. Something I have wanted to do since I first took logic some years ago. Since it is propositional logic all statements are decidable via truthtables so its nothing fancy.

I wrote the interpreter in F#. F# has Fslex and Fsyacc tools that make language building quite easy. For example the AST is represented as:

type expr =
| Val of string
| Bool of bool
| And of expr * expr
| Or of expr * expr
| Implies of expr * expr
| Not of expr
| Equiv of expr * expr

//with where a some rules have been given to lexer e.g.:

rule token = parse
| whitespace { token lexbuf }
| newline { (lexbuf: lexbuf).EndPos | "(" { LPAREN }
| ")" { RPAREN }
| "^" { AND }
| "Or" { OR }
| "=>" { IMPLIES }
....

//Or Parser :

Expr: ID { Val $1 }
| BOOL { Bool $1 }
| Expr AND Expr { And ($1, $3) }
| Expr OR Expr { Or ($1, $3) }
...

//And Interpreter in source via Match:

let rec evalE (env: Mapbool>) = function
| Val v -> if env.ContainsKey v then env.[v]
else System.Console.WriteLine("\nDefaulting to true for unbound variable: " + v); true
| Bool b -> b
| And (e1, e2) -> evalE env e1 && evalE env e2
....






The language is simple. It has only one type bool. Constants true and false which variable range over. There is assignment via sentences like: raining := true; Cloudy := true;
Shining := Not raining //You can then go something like
"print (raining Or (Cloudy ^ Shining)) => (Not Shining ^ raining) Or (raining ^ Shining)"// to get err let me check ... true

Another true prop:
print (Cloudy ^ Shining) => (raining ^ Shining ^ Not Cloudy)
Cloudy and shining implies raining and shining and not cloudy.

If variables are not bound then true is simply used in place of identifier.

Expressions are combined with : ^ (and), => (implies), (equivalence), Or, Not.

This is not useful. But it can print truthtables, check for tautologies, give counter examples, and list instances where a given formula hold. Variables here are need not bound since they are not searched for in the environment, they exist only to tell what to range over. tautology p => q p => q ^ q => p is given as true.. That is all for now after a few hours work.

I wish to add:

pretty printing, strings and operations on strings, an interactive environment, simplification. Expression assignments. So I can go Input: xorab = a Or Not b Or not b Or a; tautology a Or xorab ^ p Or xorab. "EStore in pq exp p => q as true"; p := true. VStore p; tryprove q in pq. Decided on simpler queries. e.g r := true. istrue q ^ p in p => q Or r. Simply breaks down expression after 'in' where searches for each in environment. else left alone. Then substitute each occurrence of bounded variables with values. Then for each variable after istrue extract table, if the union of all such vars is true then q ^ p is true. For example: in p ^ q Or r ^ q and defined r := true. Then it will tell you that q must also be true but p is unknown.


Modal logic would be fun to add although statements in modal logic are not decidable so it becomes a bit harder. But I can atleast do something like the raining example I gave but here it would be more helpful since it is more difficult to evaluate.

Daerax

Daerax

 

What Kind of Use

I asked earlier what Type Constructor Polymorphism is useful for. I feel they are really useful when programming in a typeful and functional way. They are useful for writing flexible, better abstracted code and reduce code duplication. Once you start in that style it is painful to drop back down to mere generics.

Usually though, the combined power of increased flexibility while allowing static checking is not necessary since usually one works in only a few instances of the types they abstract over.

However in an imperative framework with reflection and some dynamic features they are not so needed. At the cost of safety and clear abstraction power.

Daerax

Daerax

 

Types

So my last question was a bit of a lead in question.

A long time ago I tried to make an RPG in C with classes. I got burned terribly, stopped programming for 2 years and so am now paranoid. I am still on a quest to make a game but since I am only one programmer, I first require a language with a certain level of expressivity. Inspired by Tim Sweenies paper I set about a requirement list. Including standard closures, currying, partial application, higher ordered functions, algebraic types, tuples etc, I require:

Eased writing of parallel and concurrent code (simple - use the .NET Task Parallel library and F# async blocks), polymorphic variants, Generalized Algebraic data Types or similar (I think both can be approximated with abstract types , matching on types, views,extensible matching - active patterns in F#. perhaps some metaprogramming), dependentish types (using phantoms), higher kinded polymoprphism (though I can think of few reasons to have it,was just to allow), proper monads (useful I suspect for AI and other gameplay type code). I am still using my F# Nemerle combo for a language near enough to haskell on .NET. I solved i think - to my satisfaction at least - the prior things and shall be blogging on them as time comes my way:

Number Parameterized types and basic statically checked type level computations:

Sometime ago I was able to use phantom types and nemerle's metaprogramming capabilites to define dependent types like behaviour with type level arithmetic. This extends the type system with a bit more power while allowing the code to not become too dense. The downside is the added syntax and extra annotations.
def z = vec n //where the type of n is known at compile time and hence the size of z

[Enforce n method(n : Natural , m : Natural, o : int, v : vec 5 )
dtype n + 50 {}
/*Writing method[a,b,c,d] (n : Natural[a], ...) is cumbersome. All statically checked with phantoms.*/
{

} More on this later.

The other thing amongst others (haskell like monads with similar sugared notation) Ive done is again simulating the notion of higher kinded polymorphism using phantom types. This will be the subject of my next post.

Daerax

Daerax

 

Higher Kinded Types, Sorts and Birds

In regular programming, what use would the notion of kinds (generalization of generics, eg being able to write class[T[type]] ) be? On an OOP framework?

Note that T is a type constructor e.g. T = List in List. T is not and cannot be used as a type, List l is not allowed.

So it seems that again C++ templates come to the rescue, in addition to allowing dependent types and turing complete metaprogramming they are also higher kinded. So I suspect the Monad concept in C++ would be something like (note that I do not know or use C++ just musing again on the power of templates): template m> class Monad
{

virtual Monad Bind( m, ... ) = 0; //dont know how to write functions in C++ or if virtual is appropriate in a templated class>?
};

class Maybe : Monad {... }// ?

Daerax

Daerax

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!