Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  My entity properties... a bad idea?  (Read 1383 times)
0 Members and 1 Guest are viewing this topic.
Offline ags1

JGO Ninja


Medals: 46
Projects: 2
Exp: 5 years


Make code not war!


« Posted 2014-04-15 23:09:13 »

My entities for my fog game are just a collection of property classes. There will be thousands of entities so I want to multithread processing of the entities. To avoid race conditions, I plan to defer property updates like so (the earliest property update wins, although this might itself be a property of the property):

/**
 * A gettable/settable property of an entity.
 * Set ops are parked and applied in the future so entity processing can be safely multithreaded.
 * Created by agslinda on 4/15/14.
 */
public class Property<V> implements FutureUpdateable {

    public V prop, futureProp;
    //time is an abstract notion of when in a game loop something happens, it's not related to system time
    long time = 0;

    public V get() {
        return prop;
    }

    public void set(V p, long time) {
        if (futureProp == null || time < this.time) {
            futureProp = p;
            this.time = time;
        }
    }

    @Override
    public void update() {
        prop = futureProp;
        futureProp = null;
        time = 0;
    }
}


So the Name property looks like this:

/**
 * A name of a whatsit.
 * Created by agslinda on 4/15/14.
 */
public class Name extends Property<String> {
}


There will be other kinds of properties for primitive long, boolean and double values.

Offline loom_weaver

JGO Coder


Medals: 17



« Reply #1 - Posted 2014-04-16 00:28:21 »

> There will be thousands of entities so I want to multithread processing of the entities.

Premature optimization.  Also thousands of entities isn't even a blink in the eye of today's CPUs.

Getters/setters are overrated in my opinion.  Start with an immutable class (hey no threading problems) and then expose things as you need them.
Online Roquen
« Reply #2 - Posted 2014-04-16 07:40:38 »

Where's the optimization?  This design needlessly (as described) slows things down.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ags1

JGO Ninja


Medals: 46
Projects: 2
Exp: 5 years


Make code not war!


« Reply #3 - Posted 2014-04-16 08:10:17 »

It will be slower in a single thread case, but I think it will enable the multi thread case to work...

Obviously if all the properties are immutable there would be no problem. The question is HOW to expose mutable properties.

Offline Danny02
« Reply #4 - Posted 2014-04-16 08:23:31 »

you would just clone your whole entity

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
class Player
{
  final int health;
  Player(){health = 100;}
  Player(int h){health = h;}
  takeDamage(int dmg){ return new Player(health - dmg); }
}

//...
Player user = new Player();
user = user.takeDamage(15);

Online Roquen
« Reply #5 - Posted 2014-04-16 09:00:35 »

Don't multithread the AIs.  You don't need to.  If you think you need to: think again about how to lower the computations per frame.  About the only situation I'd think about it would be for a server bank targeting tens of thousands of active players and then I'd use a DSL (probably partly actor based).
Offline ags1

JGO Ninja


Medals: 46
Projects: 2
Exp: 5 years


Make code not war!


« Reply #6 - Posted 2014-04-16 09:01:17 »

Danny02, my original idea was to clone the whole entity, but now I think that would lead to a large amount of garbage collection...

Also, I think your sample is only going to work for single-property entities. Also, I think it will lead to lots of versions of the same instance floating about, which would not be desirable.

The main reasons I am thinking of multithreading are that (1) I am more accurately writing a sim than a game, so I want to go as big as I can go, and (2) the game has a fast forward button that multiplies the computational load.

@Roquen, I expect that AIs will not execute every frame for every entity. No real creature analyzes its situation 30 times a second... :-) So only a subset of the entities would be doing heavy lifting per frame.

Online Roquen
« Reply #7 - Posted 2014-04-17 14:41:09 »

Yeah that's one thing you can do...distribute across frames.  Sleep stuff as much as possible, etc. etc.

I've an example/mimimal prototype based variable here: https://github.com/roquendm/JGO-Grabbag/tree/master/src/roquen/wiki/dvar
and of course, it's targeting single threaded. Wink
Offline ags1

JGO Ninja


Medals: 46
Projects: 2
Exp: 5 years


Make code not war!


« Reply #8 - Posted 2014-05-19 23:13:31 »

Well, I'm inching towards getting my critters to think:


public class Mind {
    private static Random R = new Random();
    private Mood mood = new Mood();
    private int millisToAct;
    private World world;
    private int countdownToCognition;
    private Entity entity;
    private Behavior chosenBehavior;

    public Mind(int millisToAct, Entity entity, World world) {
        this.millisToAct = millisToAct;
        this.world = world;
        countdownToCognition = R.nextInt(millisToAct);
        this.entity = entity;
    }

    public void think(int millisElapsed) {
        countdownToCognition -= millisElapsed;
        if (countdownToCognition < 1) {
            //think
            Set<Entity> vicinity = world.getVicinity(entity);
            Set<Entity> awareness = world.getAwareness(entity);
            int priority = 0;
            for (FutureUpdateable futureUpdateable : entity.getProperties()) {
                if (futureUpdateable instanceof Behavior) {
                    Behavior behavior = (Behavior) futureUpdateable;
                    int thisPriority = behavior.plan(entity, world, mood, vicinity, awareness);
                    if (thisPriority > priority) {
                        chosenBehavior = behavior;
                        priority = thisPriority;
                    }
                }
            }
            mood.update();
            countdownToCognition = millisToAct;
        }
        if (chosenBehavior != null) {
            chosenBehavior.act(millisElapsed);
        }
    }
}


EDIT: ...it works! I gave my creatures a chatter behavior, and they correctly describe their surroundings.

Offline ags1

JGO Ninja


Medals: 46
Projects: 2
Exp: 5 years


Make code not war!


« Reply #9 - Posted 2014-05-22 23:09:56 »

I think I have a good way to multithread my AIs. I have split the AI into two phases - a planning phase that does heavy computation but changes no state, and an execution phase that makes simple updates according to the plan. The planning phase is multithreaded and the execution phase is single-threaded.

   private List<FutureTask<List<Mind>>> planningTasks = new LinkedList<FutureTask<List<Mind>>>();

...

    private void logicFrame() {
        //do expensive planning on multithread
        for (int i = 0; i < planningTasks.size(); i++) {
            planningTasks.get(i).run();
        }
        for (int i = 0; i < planningTasks.size(); i++) {
            try {
                planningTasks.get(i).get();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        //Update entities on a single thread
        for (Mind mind : minds) {
            mind.act(LogicFrameCallable.LOGIC_FRAME_LENGTH);
        }
        //Push new values to buffers, re-sort x,y,z maps
        model.update();
    }

Pages: [1]
  ignore  |  Print  
 
 

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (26 views)
2014-07-24 01:59:36

Riven (25 views)
2014-07-23 21:16:32

Riven (19 views)
2014-07-23 21:07:15

Riven (22 views)
2014-07-23 20:56:16

ctomni231 (51 views)
2014-07-18 06:55:21

Zero Volt (46 views)
2014-07-17 23:47:54

danieldean (37 views)
2014-07-17 23:41:23

MustardPeter (40 views)
2014-07-16 23:30:00

Cero (56 views)
2014-07-16 00:42:17

Riven (55 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!