Page 1 of 4

[Library] - GrimQ - v1.4.3

Posted: Mon Nov 19, 2012 8:03 pm
by Xanathar
Update 05-Apr-2013: Released 1.4.3 - minor revision for those using jkos framework: viewtopic.php?f=14&t=4256&p=57922#p57922

----------------------------------------------------


Update 25-mar-2013: Released 1.4 - see here for the changelog and download link:

viewtopic.php?f=14&t=4256&start=30#p57075

Check it even if you don't plan to use queries, as it might be useful for generic use too.
-------------------------------------------------------------------------------


Update 23-jan-2013: Released 1.3.2 - see here for the changelog: viewtopic.php?f=14&t=4256&p=52035#p52035

Download at: http://code.google.com/p/lualinq/downlo ... -1.3.2.zip

Check it even if you don't plan to use queries, as it might be useful for generic use too.
-------------------------------------------------------------------------------

Update 05-dec-2012: Released 1.2 - see here for the changelog: viewtopic.php?f=14&t=4256&start=10#p46454
Check it even if you don't plan to use queries, as it might be useful for generic use too.
-------------------------------------------------------------------------------

Update 27-nov-2012: Released 1.1 - see here for the changelog: viewtopic.php?f=14&t=4256&p=45021#p45021
Check it even if you don't plan to use queries, as it might be useful for generic use too.
-------------------------------------------------------------------------------

After some hours working on it and with some friendly help on documentation I can release my GrimQ library for Grimrock.
It's a library which allows to create complex queries on Grimrock entities; the syntax is very similar to LINQ and reminds of SQL, for those who already know those languages. It uses a very basic subset of Lua, which allows it to be used also in Grimrock without problems.

It also has a pdf guide/tutorial to learn the library step by step, plus Grimrock specific extensions.

Since I got excited with it and had a longish night (yawn) I had also released a version for people using Lua outside Grimrock, called LuaLinq and put it on Sourceforge.

You can download it, with the pdf guide, here: http://code.google.com/p/lualinq/downlo ... -1.3.2.zip

Original post below:
--------------------------------------------------------

Hi all, I just written down in a few minutes this idea: a sort-of LINQ implementation for Grimrock Lua engine :)
A "pure" implementation done with only iterators is probably possible but very tedious (Lua iterators are complex beasts, not the yield return thingie of C# :) ) and my Lua knowledge only goes this far as to copy data over and over.. for the amount of data we manage this shouldn't be a problem.

Precautions
The following precautions should be taken at the moment:
  • Always declare the linq object as local
  • If a collection result must be stored, always go to one of the toTable/toArray/toArrayOfKeys methods!
If you don't do the above, savegames will crash.

Setup
Paste the code above in a scripting entity named "linq".

What is this for ?
If you have never experienced what LINQ is (in a fluent syntax, as query syntax is impossible to implement), it's an easy way to concatenate methods which apply over a collection to allow easy queries, much like SQL.

Example 1

Code: Select all

	grimq.from(allEntities(1))
		:where(function(v) return #v.name > 5; end)
		:select(function(v) return v.name; end)
		:foreach(print)
prints the number of all the entities whose name is longer than 5.


Example 2

Code: Select all

local x = grimq.from(allEntities(1))
	:max(function(v) return #v.name; end)
Stores in variable x the entity with the longest name (in level 1).

Example 3

Code: Select all

	grimq.from(allEntities(1))
		:where(grimq.isMonster)
		:select(function(v) return v.id; end)
		:foreach(print)
Prints the id of all monsters in level 1

Example 4a

Code: Select all

local monsters = grimq.from(allEntities(1)):where(grimq.isMonster):toIterator()
for m in monsters do 
    m:destroy() 
end
Destroys all monsters in level 1, using a for loop.

Example 4b

Code: Select all

	grimq.from(allEntities(1))
		:where(grimq.isMonster)
		:action(function(m) m:destroy() end)
Destroys all monsters in level 1, using an action (alternate syntax, more declarative).

TODO
Ideas to explore (done in green, impossible ? in red, abandoned in dark color)
  • Probably, implementing a series of predefined methods which aren't generic but focused on our domain (like isMonster etc.) is good, will do it along with further debugging of this.
  • Also I'm thinking of changing the underlying table from a key/value to an array (where key/value pairs would be stored in subtables if need be). This would allow us to preserve order semantics.
  • Thanks to Lua semantics, where can be implemented in terms of select. Probably keeping two functions is better for readability anyway.
  • New generators like grimq.fromChampions, etc.
  • On the fly code generation to allow for "lambda-style" coding through strings ? something like :where("v > 5") ..
  • Optimize simple cases (e.g. count / any with nil predicate)

This was very preliminary, just thought that it was cool enough that sharing early was worth.

Re: [WIP] - LINQ for Grimrock

Posted: Mon Nov 19, 2012 8:10 pm
by Xanathar
I've changed the implementation, so the following documentation is no more valid. Tomorrow/day after I'll post the new version, which is more promising ;)
SpoilerShow
Creation functions (must be called with linq.<methodname>):

function fromTable(collection)
Creates a linq data structure from a table, returns a new LINQ collection.

function fromIterator(iterator)
Creates a linq data structure from an iterator returning single items, returns a new LINQ collection.


Concatenable functions:

function select(self, selector)
Replaces keys and values with those returned by the selector function.
Returns the altered collection.

function where(self, predicate)
Returns a linq data structure where only items for whose the predicate has returned true are included
Returns the altered collection.

Terminating functions (return a result different from a LINQ collection):

function any(self, predicate)
Returns true if any item satisfies the predicate. If predicate is null, it returns true if the collection has at least one item.

function all(self, predicate)
Returns true if all items satisfy the predicate. If predicate is null, it returns true if the collection is empty.

function count(self, predicate)
Returns the number of items satisfying the predicate. If predicate is null, it returns the number of items in the collection.

function map(self, accumulator)
Calls the accumulator for each item in the collection. Accumulator takes three parameters: key, value and the previous result of
the accumulator itself (nil for the first call)
Returns the result of the last call.

function toTable(self)
Converts the collection to a table. Returns the table.

function toArray(self)
Converts the collection to an array of values. Returns the array.

function toArrayOfKeys(self)
Converts the collection to an array of keys. Returns the array.

Re: [WIP] - LINQ for Grimrock

Posted: Mon Nov 19, 2012 9:23 pm
by LordYig
Even if this is an early stage of developement, this is brillant Xanathar !
Surely there are some lua scripts addicts here that could fully use the power of this kind of function library.
With Linq for LoG and the LoG Framework by JKos, complex puzzles and more refine game mechanics are definitely feasible.

IMHO the only thing we lack now are ideas to use all those functions ! :lol:

Re: [WIP] - LINQ for Grimrock

Posted: Mon Nov 19, 2012 10:20 pm
by Xanathar
IMHO the only thing we lack now are ideas to use all those functions ! :lol:
That's the reason I am doing functions instead of working on my mod! :lol: :?

Re: [Library] - GrimQ - a query library for Grimrock and Lua

Posted: Tue Nov 20, 2012 10:58 pm
by Xanathar
After some hours working on it and with some friendly help on documentation I can release my GrimQ library for Grimrock.
It's a library which allows to create complex queries on Grimrock entities; the syntax is very similar to LINQ and reminds of SQL, for those who already know those languages. It uses a very basic subset of Lua, which allows it to be used also in Grimrock without problems.

It also has a pdf guide/tutorial to learn the library step by step, plus Grimrock specific extensions.

Since I got excited with it and had a longish night (yawn) I had also released a version for people using Lua outside Grimrock, called LuaLinq and put it on Sourceforge.

You can download it, with the pdf guide, here: https://sourceforge.net/projects/lualin ... 0Grimrock/

Re: [Library] - GrimQ - a query library for Grimrock and Lua

Posted: Tue Nov 20, 2012 11:03 pm
by Grimwold
Another outstanding piece of scripting work Xanathar... Now I just need to work out what I could use it for!

Re: [Library] - GrimQ - a query library for Grimrock and Lua

Posted: Wed Nov 21, 2012 12:03 am
by LordYig
I have already said it...
But this is definitely brilliant Xanathar ! Good work !

Re: [Library] - GrimQ - a query library for Grimrock and Lua

Posted: Wed Nov 21, 2012 11:07 am
by petri
I'm totally digging this! I've actually been thinking about a similar data mining tool for textures and other assets.

Re: [Library] - GrimQ - a query library for Grimrock and Lua

Posted: Wed Nov 21, 2012 3:57 pm
by Xanathar
Thanks! :)

Specially proud if this could come of any help to petri 8-)

In the lunch-break I've uploaded a small change, so that now the object is immutable (where/select etc. don't change the object anymore but return a new object). Should not change much about how they work (all the examples, tests etc. work the same way as before) but it's more faithful to the declarative paradigm.

Re: [Library] - GrimQ - a query library for Grimrock and Lua

Posted: Wed Nov 21, 2012 5:45 pm
by cromcrom
Hello there,
I will probably sound like a total stupid whatever, but what does "that" do that the current scripting language doesn't ?
What is the interest of this for me (us?), simple lua users ?
Not a troll question, just genuine basic coder curiosity.

What makes LoG's modding so amazing imo is its blend of "simplicity" and "power"...