[dead] Combinable logic framework

Update: this project won’t be developed any further



Few days ago i was re-reading something about parse-combinators, so i came up with a kind of combinator system for the logical part of my game (btw an horror game in the sense that if you have played anything else than you will end up screaming “oh my god, this is horrible!”).



I don’t know if it is a viable system or if it has been already implemented somewhere, I found the idea interesting and i like to share ideas.



The system is based on a Controller - TriggerSystem - (they can be more than one, i just use one for now). The controller has a list of Trigger. A trigger has a Condition and a Reaction. If the condition holds, controller executes the reaction. And the framework ends here (i like complicated stuff :D).



How it works in a concrete example. We start with an empty trigger:



Trigger trigger = new Trigger();



The game has pickable elements (batteries). A battery is picked up when the player goes near it, if the energy level is below its maximum. So we have two conditions combined toghether:


Condition nearPlayer = new SpatialsAreNear(playerSpatial, batterySpatial, new Threshold(0.5f));
Conditon energyMax = new Condition() {
public boolean hold(float tpf) { return gui.getEnergyLevel() == 100; }
};
Condition condition = nearPlayer.andNot(energyMax);



When the battery is picked up, the audioRenderer plays a sound, the energy bar is increased and the trigger is removed.

Reaction removeBattery = new DetachSpatial(batterySpatial);
Reaction playSound = new PlaySound(dingNode, audioRenderer);
Reaction increaseEnergyBar = new Reaction() {
public boolean act(float tpf) { gui.setEnergyLevel(gui.getEnergyLevel() + 25); }
};
Reaction removeTrigger = new RemoveTrigger(trigger);



The reactions are combined to be executed simultaneously:

Reaction pickup = playSound.and(removeBattery).and(increaseEnergyBar).and(removeTrigger);



Condition and reaction are used to setup the Trigger:

trigger.setCondition(condition);
trigger.setReaction(reaction);



And the trigger is passed to the controller:

triggerSystem.addTrigger(trigger);



The batteries are "animated" by rotating them around the y axis when the player is near them:

Condition condition = new SpatialsAreNear(player, battery, new Threshold(10f));
Reaction rotation = new RotateAround(battery, Vector3f.UNIT_Y, new Velocity(1f));
Trigger trigger = new Trigger(condition, rotation);
triggerSystem.addTrigger(trigger);



The doors are more interesting. There are a few automatic doors. When the player is near the door, the door opens. When the player is gone, the door closes. When the player moves, the system plays a sound.

triggerSystem.addTrigger(
new SpatialsAreNear(player, door, new Threshold(4f)),
new MoveTo(door, door.getWorldTranslation().add(0, 8, 0), new Velocity(2f), new Threshold(0.1f)));
triggerSystem.addTrigger(
new SpatialIsMoving(door),
new PlaySound(doorOpen, audioRenderer));
triggerSystem.addTrigger(
new SpatialIsNotMoving(door),
new StopSound(doorOpen, audioRenderer));
triggerSystem.addTrigger(
new SpatialsAreNear(player, door, new Threshold(10f)).negate(),
new MoveTo(door, door.getWorldTranslation(), new Velocity(1f), new Threshold(0.1f)));



One of the funniest thing is the fact that combinators can be shared so one could write a little library made with small "logic" bricks and the user could eventually combine those bricks to create a complicated logic (in the same way one can represent a complicated grammar using many little parser combinators).

What do you think? Am I totally crazy?

Isn’t this also similar to the way the UDK does it? :slight_smile: It’s been a while since I used it, but this sounds similar alright (and I know the UDK ain’t all that different from Source Engine). There you usually combine blocks through the Kismet editor, adding movers, basic AI, cinematics cues etc.



Probably isn’t a long shot away from Blender’s (Game Engine) game logic either:

http://wiki.blender.org/index.php/Doc:Manual/Game_Engine/Logic wrote:
Game Logic is what causes anything to happen in the game. It is designed to provide a powerful tool to set up the logic through a graphical interface. The blocks (or

This looks good, keep the code xD

We'll have to see how such gaming elements can be woven into what we get out of jme3. The terrain system has to be in first because it will define a lot how the surroundings of the game entity work (are spatials hidden or detached when they get out of view etc…) also there would have to be hooks for physics events etc. etc. but a generalized trigger / bind system for game logic is certainly interesting.

I've also been digging into systems like GOAP which go more in the AI direction, a list of actions that the NPC "intelligently" arranges based on conditions which could also be changed by your trigger system… :smiley:

I have uploaded the code (netbeans project) here:



https://jpspj.svn.sourceforge.net/svnroot/jpspj/jme3clogic



(that repository is becoming a mud of projects, much like my hd).



"MIT-do what you like" license, as always.



As you can see, the core (package jme3clogic) is so simple it is barely worth a project of it own. I will update it with the bricks i need for my game but I think the core won't change.



Creating a visual tool to compose triggers looks funny enough that i'll probably start doing it.



As per the ambitions of the framework, there aren't many. It is useful in my project and i think it could be useful to someone else. I don't know if its usefulness is general enough to make it (or something similar) an embedded utility of jme3.

pgi said:

Creating a visual tool to compose triggers looks funny enough that i'll probably start doing it.

The NetBeans Platform has support built-in for a generalized logic view like blenders compositing area, with fields, values and "cables" connecting them. Maybe you wanna check into that.
normen said:

pgi said:

Creating a visual tool to compose triggers looks funny enough that i'll probably start doing it.

The NetBeans Platform has support built-in for a generalized logic view like blenders compositing area, with fields, values and "cables" connecting them. Maybe you wanna check into that.
It's also worth noting that I didn't think Kismet was any good, at all really. I would have been much better off just learning basic scripting, but instead I was spending half of my time just re-organizing my visual blocks and connectors to make sense of what I had created.

For inspirational purposes, you could look into http://yuml.me/. This thing looks really cool. It's a UML editor that works by typing a pseudo-code of sorts, and the visual blocks follow suit. I would greatly prefer such an approach, having both text and visuals.

triggers in action.



ogg applet video



Except staying away from walls, everything else is done via triggers. Moving to pick location:



Vector3f swapBuffer = new Vector3f();

Condition pick = new PickPoint(inputManager, cam, rootNode, swapBuffer);

Reaction walk = new WalkTo(player, playerPhysics, swapBuffer, new Velocity(0.1f));

triggerSystem.addTrigger(pick, walk);

triggerSystem.addTrigger(pick.clone(), new ResetReaction(walk));



Moving the camera to follow the player:



Vector3f delta = new Vector3f(10, 20, -10);

Condition always = Condition.ALWAYS;

Reaction followPlayer = new CopyLocalTranslation(player, cam, delta);

triggerSystem.addTrigger(always, followPlayer);



The reset reaction is required because of how WalkTo works, it’s a kind of patch, the way walk-to walks is fraught with problems.

i love it  :slight_smile:

more!!!

I made an experiment for a visual editor for the experimental framework.



http://www.youtube.com/watch?v=96miVP4B_vo



The video shows a few of the problems that need to be addressed (the user input for fields, the definition of a binding system to attach the logic to an actual scene, the loss of visual information for complex combinations and so on) but, as an interaction prototype, it kinda works.



What this experiment made clear to me is that to reach a minimum decency level, this stuff requires careful design because generating a logic writing code is simple enough that to do better the UI has to be very, very user friendly.

This is sooooo awesome!

Awwweeesome! :slight_smile:

What i dont like at you UI implementation is the way you handle "multi-events". So if one trigger has more than one actions.

What about a container where you can drag in as much events as you like which acts like a single event in your ui? Would make it easier…



You could make it this way:

You add a trigger condition, then an event. But you like one more things to happen, so you just drag another event on the event you just added and automatically both are added to an container and more events can be added.



Would be much easier to handle, wont you think?





Btw: Great work. I'm looking forward to a final!

The ui is just an experiment, it won't reach a final stage, at least not this year.



It won't be easier (but this doesn't mean it will be harder).



The reason why is the when you put more than one reaction/condition in the trigger you have to indicate to the framework how those elements will be combined together.



So if you drop a second reaction the UI has to ask to the user to choose the operator that will combine the reactions (reactions are combined in two ways for now, execute simultaneously, execute one after the other, but more combinations are possible, especially because some reaction might be instantaneous while other might be persistent).



And this is not the problem. The problem comes when the slots are more than two, because combinatorics kicks in. The UI has to ask the user the operator and the grouping, because one thing could be to say (a -> b -> c), one to say ((a -> b) -> c), one to say (a -> (b -> c)).



This is why the slots allowed are two: there is no choice to make but what "combinator" to drop in the workspace and where to put (left or right) the combined elements.



From an implementation point of view having two slots of having two thousands it's the same, the elements are just JLabels with a bitmap border and a "slot" layout that can accept any amount of area tokens.



Having said that I must also say that your solution is more logical. The underlying framework is not uniform in the sense that the "condition" element isn't really the only condition a user can introduce in a trigger. Even reactions are combined to form logical expressions. The difference is that the result of the logical combination of two conditions is a boolean expression while the combination of reactions produces a reaction that is logically bound to the reactions it is composed from.



So the framework allow to create triggers like:



[when the player presses K] -> [move the gun, play the shot sound and when this is finished play the "cartridge on the floor" sound]



whereas it would be more uniform to have two triggers:



[when the player pressed K] -> [move the gun, play the shot sound]

[when the shot sound is finished] -> [play the "cartridge on the floor" sound]



In this case (where reactions are not combinable) the multi-reaction-slot trigger would be the best choice because there is no decision to make, just drop and go to execute reactions simultaneously.



But, for some odd reason, it looked more logical to me to do the illogical thing, that is to treat conditions that depends on reactions as a special kind of conditions that could be represented by reaction combinators.

I just checked out the jme3clogic and played around a little bit. Unfortunately, I couldn't find the Visual Editor anywhere in the respository. Even though it's still under development it would be interesting to have a look at it, is it available somewhere else?

zeitverschwendung said:

I just checked out the jme3clogic and played around a little bit. Unfortunately, I couldn't find the Visual Editor anywhere in the respository. Even though it's still under development it would be interesting to have a look at it, is it available somewhere else?
This framework is not part of the jME3 core, so it doesn't reside in our repository. You can find pgi's project here:
http://www.jmonkeyengine.com/forum/index.php?topic=14505.msg104030#msg104030
zeitverschwendung said:

I just checked out the jme3clogic and played around a little bit. Unfortunately, I couldn't find the Visual Editor anywhere in the respository. Even though it's still under development it would be interesting to have a look at it, is it available somewhere else?


The editor was just a local experiment. I have uploaded it now to the svn repository but I remark that it is not even partially functional, it is just a test to explore a possible interactive solution to the combination of elements.

If you run it (it is now the main class of the netbeans project) you will se the UI, you can drag and drop elements and combine them but the is no real utility in it. For example if you drop some condition the UI will ask you the type some value in a cheap input dialog but there is no explanation of what the value should be or where it come from, because the program doesn't produce anything. In any case, if you want to try it, now it is on the repository.

As advised by Erlend here is a link to AppInventor from Google.

http://appinventor.googlelabs.com/about/index.html



It's logic oriented programming, maybe there should be good ideas to grab for a logic framework

I have to agree the learning curve is a bit steep but I grew quite fond of many functions of the Platform already. If you have problems, just ask away, I have quite some experience with it by now and zathras was working in the NetBeans team for quite a while :slight_smile:

I revised the logic framework after the rollingtracks experience. The revision reopened the door for a visual editor. Here’s the new version i’m writing:



youtube video



The editor is built so that it should be easy to integrate in JMP as a plug-in. A lot of work remains before that task but there are some chances it will survive the experimentation phase and become something practical.



More soon.

I was planning to say "Wow"…but i can't because my jaw just dropped…



Incredible work!