HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
stassa
Gleemin
Prolog2015–2026
stassa / Gleemin

Gleemin

A Magic: the Gathering™ expert system

4Distinct people
9Mentions
0Explicit recommenders
98GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A Magic: the Gathering™ expert system

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 5:04:57 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year9 dated mentions

Observed mentions: 2015-06-11 03:55:57 UTC to 2026-05-18 16:17:59 UTC.

012342015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20152016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC101
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC101
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC000
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC000
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC000
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC101
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC404
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC000
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC101

What Hacker News says

9 sources
Hey, that's cool! I had the same idea too: https://github.com/stassa/Gleemin Although the code is nigh-on unreadable now ^_^@ >> The weird rule-breaking edge cases will always fail, but a large set of design space can fit, I think. Well, in that case you just update the parser or the rules engine. That's precisely how M:tG Arena works and they 've managed to keep up with new sets at a pace never before seen in official M:tG engines. There was a time when writing an M:tG parser was considered impossible [1] and M:tG engines, both official and community ones, each had their own little DSL that they had to manually translate ability text into which could take months especially if the engine also had to be updated to use the new rules in a set. Eventually someone in Wizards realised this is just dumb and they did it the way you go about it ab
Read the rest
ove. ______________ [1] Source: my conversations with the folks behind Forge and other community-made M:tG engines.
In Prolog Basics Explained with Pokémon
My guess is that fully modeling MtG's rules in Datalog would take a lot more work, because MtG's rules are a lot more complex. Looking through the source for one of the freely-available game engines like https://github.com/magefree/mage would probably be more informative, though. EDIT: I found an old project working on implementing the MtG rules in Prolog: https://github.com/stassa/Gleemin. It's definitely more concise than XMage's Java, but you can still get an idea of how much work it would take, especially since that project notes some pretty significant limitations that it didn't get to.
In Find Legal Moves in Brass Birmingham with Datalog
Here's some stuff I've written in Prolog, some for my own enjoyment, one for my degree project. Most of the benefits I found come down to two things: a) Prolog, like the various kanrens, is a relational language so a program is effectively a database. There's no need to do anything special to glue together a data layer and a logic layer, because you have both written in Prolog. No object-relational impedance mismatch whatsoever. b) Prolog's declarative style makes translating rules and directives into code a breeze. The three projects below are all games and benefit heavily from this feature. The same would go for business logic of any shape or form. 1. Warhammer 40K simulation: https://github.com/stassa/wh40ksim Runs simulations of combat between WH40k units. 2. Gleemin, a Magic: the Gathering expert system: https://github.com/stassa/Gle
Read the rest
emin Doesn't work anymore! Because backwards compatibility. Includes a) a parser for the rules text on M:tG cards written in Prolog's Definite Clause Grammars notation, b) a rules engine and c) a (primitive) AI player. The parser translates rules text from cards into rules engine calls. The cards themselves are Prolog predicates. Your data and your program are one and now you can also do stuff with them. 3. Nests & Insects, a roguelike TTRPG: https://github.com/stassa/nests-and-insects WIP! Here I use Prolog to keep the data about my tabletop rpg organised, and also to automatically fill-in the character sheets typeset in the rulebook. The Prolog code runs a character creation process and generates completed character sheets. I plan to do the same for enemies' stat blocks, various procedural generation tables, etc. I also use Prolog to typeset the ASCII-styled rulebook, but that's actually not a good application of Prolog (too imperative). You asked about "logic programming" in general and not miniKanren in particular. I haven't actually used miniKanren, so I commented about the logic programming language I've used the most, Prolog. I hope that's not a thread hijack! All three of the projects above are basically games. I have more "serious" stuff on my github but I am currently experiencing a certain shortfall of gravitas.
In Annotated implementation of microKanren: an embeddable logic language
Not a tutorial resource, but the following is an example from my degree project, that I wrote back in 2011 (don't judge me, OK? I've improved since then!). My project was a Magic: the Gaterhing expert system that included a rules engine, an AI player and an interpreter for the language on M:tG cards. The interpreter was written using Prolog's DCGs. The project was written in a proprietary Prolog (Win LPA Prolog) and I've had a lot of trouble porting it over to the free SWI-Prolog - you can't run the entire project. But the DCG rules in links I give below more or less work for any Prolog with a DCG module. Anyway, just looking at the grammars in them should help get an idea of DCGs in an application that is a step above trivial. First, this is the main M:tG game language interpreter (the "MGL" interpreter; "MGL" is my own terminology, sinc
Read the rest
e the langauge on M:tG cards doesn't have an official name): https://github.com/stassa/Gleemin/blob/master/mgl_interprete... The first two-thirds of the source in the linked file is a grammar of a subset of the M:tG game language as a set of production rules in DCG form. That's already a parser for that subset of the M:tG language, right there in the DCG rules themselves (DCGs are just syntactic sugar for ordinary Prolog clauses so a grammar in DCG form is a Prolog program that can be executed as any Prolog program). The rest of the file implements rule engine functions some of which are called by the grammar, while others act as an interface with the rest of the rules engine. Probably. I don't remember what everything does... The next file is a DCG for M:tG mana costs: https://github.com/stassa/Gleemin/blob/master/mana_grammar.p... This grammar is referenced from the previous source file where the "mana" nonterminal appears. So that's just an example of how you can modularise your code to avoid having all the rules in one big endless file. On the other hand, nothing stops you from making a big ball of mess by interleaving your grammar with the rest of your code. Like all Prolog programs, DCG grammars can be "run backwards" so that a grammar that acts as a recogniser when given an input string, can act as a generator when given no input (Prolog doesn't have clear input and outputs, just variables to be instantiated as the program runs). So with my M:tG grammar above I could generate text for new M:tG cards. To facilitate this I set up the "MGL parser interface" below: https://github.com/stassa/Gleemin/blob/master/mgl_parser_int... The first defined predicate in there, identify_MGL/0 is used to identify the type of an M:tG language expression (given or generated), such as "activated ability", "triggered ability", "static ability" etc. So that's one example how to use a DCG for semantic analysis of a bit of text. As a for instance, you could use my identify_MGL/0 to search for abilities of a certain type (alongside a keyword search) which most search engines don't really let you do. My "parser interface" used it to generate abilities of a given type. Anyway, that's an example of DCGs "in the wild" (though from someone who had no clue what she was doing when she wrote it). I hope it's instructive and I didn't just toot my own horn for no reason!
In 50 Years of Prolog and Beyond
I've been keeping an eye on this to use for the rules engine in a card game I'm writing[0]. Very excited to get back into using Prolog; I think it's fallen by the wayside a bit in the last decade or two but there's some sectors that still have strong arguments for using it if not as the main language then at least an extension language. [0] Inspired by a HN comment a while back about Gleemin, the MTG expert engine in Prolog: https://github.com/stassa/Gleemin
In An embeddable Prolog scripting language for Go
There's Prolog and its Definite Clause Grammars (DCG) formalism. Here's a DCG for a tiny subset of natural English (copied from wikipedia [1]): sentence --> noun_phrase, verb_phrase. noun_phrase --> det, noun. verb_phrase --> verb, noun_phrase. det --> [the]. det --> [a]. noun --> [cat]. noun --> [bat]. verb --> [eats]. The syntax is just like BNF. "-->" is "::=", terms in []'s are terminals and the rest are nonterminals. Nonterminals can have arguments and there's special syntax to include entire Prolog programs in the body of rules. I discovered DCGs at the end of my CS degree when I was working on my graduation project, a Magic: the Gathering expert system written in Prolog. I needed a way to script cards for my rules engine, to translate expressions in the M:tG ability text language to function calls in the engine. I
Read the rest
really wanted to write a parser using the standard parser generator tools, but I thought it would be too much work for a graduate project. Then I found out about DCGs. With DCGs I could write grammar rules like this: tap(X,Y) --> (['Tap'];[tap]), target(X,Y), (condition ; []), {permanent_Type(Y)}. tap(X,Y) --> (['Tap'];[tap]), all(X,Y), (condition ; []). And that would not only parse, but also _generate_ ability text like "Tap target Kavu" or "Tap all Goblins target player controls" etc. So as a side effect of adding a bunch of abilities to my engine, I also had a generator for new M:tG cards. [Edit: to be clear, the grammar rules above are already, by themselves, a parser for abilities that start with "tap". The Prolog interpreter executes those grammar rules as a program and instantiates their variables in the process. To integrate them with the engine all I had to do was write engine functions that called the nonterminals in the grammar and read the values of variables like X and Y in tap(X,Y).] Admittedly, my grammar was limited because I didn't have the time to hand-code a grammar for the entirety of M:tG ability text, as it was at the time (I graduated 2011). In any case my rules engine was also limited (I had no planeswalkers and static effects were only partially implemented, if I remember correctly; because the rules for static effects are a bit arcane). But I managed to cover a good subset of the rules and cards, so it was possible to play a basic game with creatures with activated and triggered abilities and with non-creature spells [2]. The important detail is that DCGs are syntactic sugar for ordinary Prolog, so I could code my parser in the same language as my engine and my player. My biggest problem was really to draw an imaginary line between the parser and the other two components, because the easiest thing would be to allow them to know about each other and be infinitely entangled in a big ball of mess. Anyway, yeah, there's something out there that is perfectly suited for creating DSLs, if you have the patience [3]. The tradeoff is that you have to learn Prolog. I suspect this is a cost too high for many who just want an easy-to-use tool. Btw, you can't easily run my degree project unfortunately. Like an idiot I wrote it for a proprietary Prolog system and although I tried to port it to the free and open-source SWI-Prolog, it's been a nightmare of incompatibilities. The ported project is here but it breaks unexpectedly all the time: https://github.com/stassa/Gleemin ________ [1] https://en.wikipedia.org/wiki/Definite_clause_grammar#Exampl... [2] I also had an alpha-beta minimax AI player. Not that good though. I wanted to program a player with background knowledge of M:tG but I didn't have the time. [3] Or you can learn them from examples... See Experiment 3 on page 19 of the pdf, here: https://link.springer.com/article/10.1007/s10994-020-05945-w
In Dear sir, you have built a compiler
Generating M:tG cards is interesting to me. Can we talk about this a bit? :) My degree dissertation was an M:tG expert system that included a hand-crafted parser and generator for (a small subset of) ability text [1]. My Masters' thesis was a grammar induction system trained on M:tG cards [2]. And I finally managed to sneak some M:tG grammar induction in my papers as a PhD student [3]. I had a quick look at the colab of your project. If I may be critical, the examples you have are ... so-so. I've seen previous attempts to generate M:tG text with neural nets, starting with the old project in M:tG Salvation that became Roborosewater and that used LSTMs if memory serves. Results have always been a mixed bag that looks promising but always falls down holes even with hand-curation. This still seems to be the case with your project. A couple of
Read the rest
examples (you probably know already): −2: Put a +1/+1 counter on each other creature you control. "Each other creature" should refer to a card with the (super) type "creature" but this card is a "planeswaker". +1: Each opponent chooses a creature they control. If that creature was a copy of that creature, each other player reveals their hand, chooses one of those cards, then puts it into their hand, then shuffles. Which creature was that creature a copy of? −10: Target opponent sacrifices a creature. −9: Each opponent sacrifices a creature. Representing costs in a meaningful manner is a constant problem in every M:tG generator I've seen. The problems I highlight above are not with grammaticality, which is certainly a big step forward with respect to the past. But many of the abilities still don't make a lot of sense, or don't make sense to be on the same card, or have weird costs etc. If you want your project to be something genuinely new, I have to say I don't think it's there yet. My intuition is that it would take a lot more than language modelling to generate M:tG cards that make enough sense that it's more fun to generate them than create them yourself. I think it would be necessary to have background knowledge of the game, at least its rules, if not some concept of a metagame. It might also help to re-train standard NLP pipelines specifically for M:tG (e.g. some kind of ability-text specific anaphora resolution might help with "that creature" above). Also, I note that the new online version of the game is capable of parsing cads as scripts in a programming language using a hand-crafted grammar rather than a machine-learned model [4] [5]. So it seems to me that the state-of-the-art for M:tG language modelling is still a hand-crafted grammar. __________________ [1] https://github.com/stassa/Gleemin - unfortunately, doesn't run anymore after multiple changes to Prolog interepreters used to create and then port the project over. [2] https://github.com/stassa/THELEMA - should work with older versions of Swi-Prolog, unfortunately not documented in the README. [3] https://link.springer.com/article/10.1007/s10994-020-05945-w - see Section 3.3 "Experiment 3: M:tG fragment". Cringe-inducing to read just a few months after writing, sorry. [4] https://www.reddit.com/r/magicTCG/comments/74hw1z/magic_aren... [5] https://www.reddit.com/r/magicTCG/comments/9kxid9/mtgadisper...
In The computers are getting better at writing
I'm first of all excited by the fact that this made first page on HN. I didn't realise there was that much interest in Prolog news (as in more than two or three people). Also, having more open-source Prolog engines is a very good thing, both for the language and for the project itself. For the project, it's good because it makes it easier for a community to grow around it. Swi has benefited enormously from its popularity (Jan Wielemaker has commented on this occasionally). For the language, it's good because the more healthy Prolog communities we have, the more we can hope to get new people interested in the language. Comparing to other Prologs (and Prologs-ish'es) the problem with having closed-source and only for-pay Prolog engines is mainly one of portability, which in the Prolog world is a bit shit (and that's a vast understatement).
Read the rest
Frex, I wrote my degree dissertation using Win-LPA Prolog in 2010-11. LPA is commercial and I don't have a licence anymore (I had a student one) so now I can't run my dissertation. I tried (and tried (and tried)) to make it work on Swi but failed (and failed (and failed))[1]. The problem is there are subtle differences between implementations that bite you in ways you never thought possible, and it's just aaaargh hard to get the same program running in the same way on two different Prologs. Apparently the exception to this portability hell is Yap and Swi, who have worked together to maintain some compatibility with each other. I don't have experience of this myself (after getting burned I've stuck to Swi) but if Amzi open-sourcing their stuff also means they'll be more open to this sort of working with others, then that's really, really amazing news. ____________________________ [1] It's here: https://github.com/stassa/Gleemin But it will hurt you. Also, graduate dissertation, 5 years ago: embarrassing.
In Amzi Prolog becomes open source
My understanding (based on some old blog posts[1]) is that while there's no (published) formal grammar there's definitely a set of internal rules that WoTC uses for determining how things are phrased. What is considered "technically correct" has changed somewhat over the years. I believe Sixth Edition was the first attempt to standardize and make consistent card text. Generally though cards that do the same or very similar things are going to follow consistent word ordering. For example take Shrewd Hatchling[2] and Coral Reef[3]. Both are fairly different cards, but notice the wording of the first part of their respective card text: > Shrewd Hatchling enters the battlefield with four -1/-1 counters on it. and > Coral Reef enters the battlefield with four polyp counters on it. Cards with that sort of ability are (almost) always going to ha
Read the rest
ve it phrased in a way that fits the pattern of "<card name> enters the battlefield with <n> <type> counters on it." Lots of other sorts of common mechanics are the same. Additionally, there are the so called "Golden Rules"[4] which are important to take note of when parsing the text of a card. While Googling for links for this reply I found Gleemin[5], a "rules engine that aims to fully and correctly implement the game's tournament rules, an AI player programmable with expert knowledge and an interpreter for the game's language (the rules text on the cards)"! Seems you're not the first person to think about this! [1]: http://archive.wizards.com/Magic/Magazine/Article.aspx?x=mtg... [2]: http://gatherer.wizards.com/Pages/Card/Details.aspx?multiver... [3]: http://gatherer.wizards.com/Pages/Card/Details.aspx?multiver... [4]: http://mtgsalvation.gamepedia.com/Magic_Golden_Rules [5]: https://github.com/stassa/Gleemin
In Generating Magic cards using deep, recursive neural networks

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.