It is currently 26 Apr 2019, 12:29
Text Size

JPortal first Release!

Moderators: Malban, CCGHQ Admins

JPortal first Release!

Postby Malban » 28 Apr 2010, 23:26

Good day to you!

May I present to you my first "official" release of a program called:

JPortal (preliminary Hompage: )

I am not 100% correct in this forum, but I hope you are interested in the project anyway.

JPortal is ment as a computer port of the old trading card game starter "Portal", which I played
in my youth. I never found my way to the complete Magic game but I loved the starter version.

In the last 3 month (I think nearly exactly three months to the day) I coded that little monster which I
now call JPortal.

What is JPortal:
- a game environment to play Portal against a computer AI (in the future maybe more)
- it has a grafical user interface which - once learned - is very easy to play with
- extensive help
- expandable AI via scripting
- expandable Card-Engine via scripting (although base card types only of Portal-packages available)
- all "Portal" and "Portal The Second Age" cards implemented
(all instants, sorceries and creatures, that means even "weird" once like:
"Alluring Scent", "Omen", "Piracy", "Exhaustion", "Last Chance", "Sylvan Yeti",...)
- "interesting" computer AI´s with "personality" - which also can be configured
- a quest system (although this can still be expanded - I have some ideas left)
can buy boosters in a shop, edit your decks and browse your Card-collection
in a "booklet"-like display... (and a Quest-Designer)
- AI- Battles against each other...
- all that in open source (java)

As I have done all development by myself and all testing, ... I need to go public now to improve it further because:

a) one can only test ones own code to a certain point untill one gets blind to errors
b) I´m getting out of "breath", so to say and it is time for me to get some feedback, be it good or bad...

I have opened a sourceforge page, with a bug tracker, any bugs or issues can be entered there.
(at least until it gets shut down...)

So - thats about it.

Have fun, I would love to get some sort of feedback.
(but please don´t mention just the obvious: this and that MTG feature is missing - that allright, its Portal).

bye bye

Posts: 84
Joined: 26 Apr 2010, 14:11
Has thanked: 0 time
Been thanked: 12 times

Re: JPortal first Release!

Postby Huggybaby » 29 Apr 2010, 00:36

Hey, that looks extremely interesting, and you have a great looking website too. Thanks for posting and welcome to the forum!
User avatar
Posts: 3081
Joined: 15 Jan 2006, 19:44
Location: Finally out of Atlanta
Has thanked: 578 times
Been thanked: 572 times

Re: JPortal first Release!

Postby mtgrares » 30 Apr 2010, 18:27

Like Wagic, JPortal has AI versus AI. I'm glad you include all of the card pictures for convienance.
Posts: 1352
Joined: 08 Sep 2008, 22:10
Has thanked: 3 times
Been thanked: 12 times

Re: JPortal first Release!

Postby frwololo » 03 May 2010, 02:21

Congrats, and I'm happy you found your own graphics for mana and stuff (sorry for my negative reply on that btw :( ), they look great :)

Edit: Scriptable AI is an extremely cool feature, I hope you'll write a bit about how you achieve this :D
Posts: 265
Joined: 21 Jun 2008, 04:33
Has thanked: 0 time
Been thanked: 3 times

JPortal - AI

Postby Malban » 19 May 2010, 12:11

AI in JPortal

I don´t know how much you have read in the available documentation of the JPortal. If you have, you already might have a basic idea how
I implemented AI.

For the sake of all who haven´t I´ll shortly draw a picture how AI is handled.
(This information might be redundant to what is written in the available game documentation)

To begin I recall the scripting mechanism I used.

Bean Shell
This is REALY easy. You get the jars and call an interpreter class for a given script. You can pass environment information to the interpreter environment via easy "set" calls. For JPortal I pass (in general) the whole game to the interpreter environment. Which in fact means that the script can access ALL information available and actually call any methods that one could also call in "hardcoded" Java code.

There virtually is NO DIFFERENCE between interpreted code and Java "compiled" classes.
With that in mind you can wrtite your scripts like they were just parts of the main program. This is what is actually done!

Communication between game and players

1) The main game is ignorant whether a player is human or a computer AI. All communication is done via message passing.

2) All kind of players must implement the interface "MatchPlayable" (only about 10 methods)

The AI is called to handle "situations". Situations can be divided into two major categories
a) answer a concrete "call"
b) do something that is appropriate

"Concrete calls"
This usually means something is happening and the player is asked to make a decision. Like chosing a target of some kind, draw a card from the library, destroy a target etc.
For each possible combination available I have implemented so called "situation keys".
Within the player code there is something like a "switch case" which handles the situation keys.
Depending on the situation key, a special code section is called.
(I also implemented a "general" situation, which "could" handle all calls - so no switching would be needed in the code, but than there would be some decision making in the AI code - which really amounts to the same... in the end).

What it comes down to is - that for a special situation key a special script is called, which handles the situation.
Since the script more or less knows everything from it´s environment it can react appropriatly.
(Scripts for the "allround" AI are kept withing the "./scripts/Allround/" folder)

An example.
Card "Angelic Blessing" - +3 / +3 Flying
The player can chose a target. There is no specification on the card what kind of target. Even an enemy unit can be selected.
Within the card code there is a call:
match.askForCreatureFromCreature(player, card, ev);

Which basically means:
- Tell the match to ask player "Player" (card owner)
- To select any creature from any creature panel
- The selection is done because card "card" was played
- the current environment to ask this question in is "ev"

The match initiates communication with player "player" (which is same one who just played the card) if it is a computer player and allround AI is the AI than the script:

Is called.
This is a communication call which expects a card (creature) as return. The script must set that information within the environment
(c.E.mTargetCardTo = target;)

Apart from being given a whole lot of information about the current game - script calls are usually stateless.
Meaning, usually script calls don´t rememeber anything. Which also means a whole battalion of information must be collected from available resources in order to procede in any meaningfull way. The script does that by using some "helper" methods.
(Things like: who is the current player, what card is played, how muchlife is left, is this a good card (buffing ourself or creatured) or harmfull card doing damage or destroying a creature etc)
(by usually I mean, there is a backdoor to implemented state information using self made global variables)

Decision making within the script is quite easy since I implemented quite a few helper methods. If you look at the code there are calls like:
else if (isBufCard(card))
else if (isReplayCard(card))

(After that you check if your opponent does have creatures, if yes, damage them, if no, check if it a "must" card, if yes chose a creature which survives the damage, if none, than chose the "cheapest" etc....)

Do something that is appropriate
This is a bit more complicated, since there are no "boundaries" to move in.
The calling of these "script" is exactly the same as above.
Only the situation keys differ. If the situation key is like "Handle Stack" or "Main Phase" than the area is wide open for all good and bad things.

Script calls are than done to (e.g.):

Here the going gets rough...
There are quite a lot of helper methods envolved, scriped helpers (via include) are collected in: "".
There are also quite a few hardcoded helpers which can be found in the package "".

All of these are just "helpers" and are called from the script. You CAN program an AI by just scripting!

First step as allways (since stateless) is collect information. Which round are we in. How many creatures do we have, what life what cards on hand etc...

After collecting all needed information (this includes sorting of cards to only the ones which can be played (mana, and other restrictions)).
(some code: )
CardList possibleCreatures = AIHelper.onlyEnoughMana(creatureHand, lands);
CardList possibleSorceries = AIHelper.onlyEnoughMana(sorceriesHand, lands);

for (int i=0; i < possibleSorceries.size();i++)
Card card = possibleSorceries.getCard(i);
if (sorceryHintMakesSenseNow(player, match, card))
(Hints I will explain later)


A "dubious" method (pseudo):

is called.

This method is more or less the heart of the current AI. Within that method is decided which card is played from hand
(found in "").

Within that method basically a "scoring" is done depending on the current situation.
Scorings for:
Is currently implemented. After the scoring is built the high scores are selected from top to bottom and if a card is found in hand which
furthers the need of the score, than that card "wins" and will be played.
The selection takes into account (e.g.) that if "CREATURE_DAMAGE" is selected, to use more than one card to kill a creature, also taken into
account (where buffs / debuffs are concerned) whether we plan to attack this round or not (after all buffung +3/+0 doesn´t make much sense if
we don´t attack).

The scripts, just like any hardcoded class than tells the match to play the selected card just like this:
match.playCard(player, card);
Thats it.

Other "interesting helpers"
There is a java - package called "" within that package a subpackage "sim" exists.

Within that subpackage there are to noteworthy classes called:

These classes are used to simulate battle situations in advance to the actual battle.
Implemented is (more or less) a MiniMax algorithm (with some supportive Alpha Beta suggestions).
(Actually very huge number of battle situations can occur (4 creatures against 4 creatures are likely to result in possible battle situations of
over 100.000 possibilities). Because of that not ALLWAYS all situations are taken into account, if army sizes get to big, I use divide an conquour to
reduce the actual possibilities).

Anyway these two classes are used to simulate pending battles and after "all" situations are tested the AI selects (by criteria) the best result
and uses it to play cards or commense battle.

The criteria used are "Aggressivness" and "Intelligense"


The AI does not know any card by itself. (well but since the AI itself doesn´t know anything thats ok).
You COULD build an AI anyway you like, even with a gigantic switch statement for 12000+ cards (well that wouldn`t work with java...).
The way I implemented the current AI is with the use of something I call "Hints"

(This is actually well explained in the available help - nonethless - here a COPY of that).

AI Hints
AI hints are entirely user defined. JPortal doesn´t know anything about them.
Well it provides the functionality, but otherwise JPortal is entirely ignorant of anything related to hints.
Hints can be created by the user. A hint or a collection of hints can be related to cards - this is why
they are here in the card detail view of the set.

The AI can get hints for these cards and chose to react to them. But since the AI itself is
entirely user defined. We have a "communication" of user defined settings and routines. JPortal hasn´t got anything
to do with them. You could use any other XML-Editor to create and relate them to cards.

AI Hints
Even if it is up to the user to define anything he wants... In order to have a basic AI delivered with JPortal a general implementation of hints was made.
I created numerous hints and related them to cards. It does make a whole lot of sense to "sort"
hints and group them in some ways. I will go into this here - in the hope that someone who will
provide new cards does not reenvent the wheel from ground but rather keep up in the same spirit (or better?).

AI Hint

A Hint consists of several parts, as there are:

1. a name
2. a name of a corresponding variable (which at the moment is allways exaclty the same as the name, which makes it quite redundant)
3. a type, one of: Integer, Boolean or String
4. a value - depending on the type
often for strings a use comma sperate values to support more than just one string,
e.g. if something requires 4 colors, I will give a list like "W,R,G,B" - this works out quite well
5. a comment, what is this hint used for

Hint Templates (4)
Hints are not alone in the world. And usually you don´t use a hint just once but often.
In order to ensure some continuety - and to enable the AI to group cards with hints.
Every hint must have a template bevor you can use it! A Template hint is a hint without a value.
In the GUI you can enter a new template hint at the bottom line (4).
After pressing the add-button it will appear as an entry in the corresponding combobox (3).

For one card a hint is unique. Meaning you can not add the same hint with different values to one card.
If you think about it - it even doesn´t make sense if you would be able to. If you ever find yourself in
the need to enter the same hint with different values to your card - think hard again - and restructure your hints!


When can the card be played, or when does the effect of the card take effect?
These hints are collected by hints with names starting with:


What area must be accessed
For the card to be successfull, these hints start with:


What is needed
For the card to be successfull, these hints start with a player description (PLAYER, OPPONENT a further describtion -
and end with NEED.


What is happening to whom?
These hints start all with EFFECT, than a part which describes the target: ONE (either player),
PLAYER or OPPONENT and than a describtion what kind of action is happening.

Restrictions on cards effected all start with CARD and go on with what is restricted.
Ending with either NEEDED or MUST NOT


Just look at the hints allready in service... :-)

Ok that are all mumblings for the moment.
Any questions left :-)?

Bye bye

Homepage of JPortal:
Posts: 84
Joined: 26 Apr 2010, 14:11
Has thanked: 0 time
Been thanked: 12 times

Re: JPortal first Release!

Postby silly freak » 19 May 2010, 21:55

hi Malban!
your division of situations into decisions and actions sounds like a great concept, and plugging scripts for individual situations makes it extensible - i like it! thanks, your program is great for inspiration!

where's the "trust me, that will work!" switch for the compiler?
Laterna Magica - blog, forum, project, 2010/09/06 release!
silly freak
Posts: 598
Joined: 26 Mar 2009, 07:18
Location: Vienna, Austria
Has thanked: 93 times
Been thanked: 25 times

Return to JPortal

Who is online

Users browsing this forum: No registered users and 1 guest

Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 10 minutes)
Most users ever online was 287 on 31 Mar 2019, 04:11

Users browsing this forum: No registered users and 1 guest

Login Form