Abstrct / Schemaverse

The Schemaverse is a space-based strategy game implemented entirely within a PostgreSQL database. Compete against other players using raw SQL commands to command your fleet. Or, if your PL/pgSQL-foo is strong, wield it to write AI and have your fleet command itself!
schemaverse.com
PostgreSQL License
383 stars 43 forks source link

Some performancey things #10

Open cbbrowne opened 12 years ago

cbbrowne commented 12 years ago
  1. location (in the form point(x,y)) has been added to Ships; would be nice to have this on Planets, too.
  2. I imagine it might be useful to have a GIST index on location.
  3. It would be lovely to have two tables that capture a) Relative positions of ships to each other, which notably allows capturing distance (e.g. - point(a_x, a_y) <=> point(b_x, b_y). It sure would be nice to have an index on distance!

    This table would need to be captured via firing triggers whenever ships are created or move.
    
    And presumably you'd only be allowed to see tuples  where one of the ships belongs to you AND the distance is low enough to allow visibility.  (Yep, needs that index on distance!)

    Probably... create table ship_relative_position ( ship_1_id integer, ship_2_id integer, primary key (ship_1_id, ship_2_id), ship_1_owner_id integer, ship_2_owner_id integer, ship_1_location point, ship_2_location point, distance float );

    b) Ditto for ships relative to planets

There would need to be a couple views to make this useful; the data would make ships_in_range into a query on a single table, which should make queries on it wicked fast.

I'd be happy to take a poke at an implementation, if that seems like a good idea.

Abstrct commented 12 years ago

Thanks for the comments cbbrowne!

1) location/destination columns using a Point data type will be replacing all areas in the game where two integers are currently used (generally location_x integer and location_y integer). You will see these slowly show up in the public server as I start to write and test the code. These changes will include planets, event logs and items as well, along with any views and functions that deal with these columns.

2) Definitely agree here, the switch to the Point data type is being done for two main reasons: Code legibility and performance increases. Once the location Point data types are in place and working these columns will certainly be indexed.

3) I hadn't actually given this a fair thought at first because off the top of my head it seemed like it would be far too much processing but now that you mentioned it, caching these details makes as much sense as caching the stats. It may take some extra processing to pull off but at least then it is only calculated once and all players can access the results at a much quicker rate.

I think these ship/ship and ship/planet position tables will definitely be a good addition but I want to finish converting all the data types to point first. Let me finish up this migration and then we can see about getting this build into the game. It may make sense to move some columns around so that the trigger update doesn't get called during non-movement updates like ship upgrades or ship/planet name changes. Or this could end up slowing it down due to the joins. We will need to test this out a bit and find the best mix.

Thanks again for the input. I will leave this open for now and we can revisit it again in the near future. -Abstrct

Abstrct commented 12 years ago

Wow, never mind! I just saw your latest commit. You certainly just saved me a huge amount of time. I will get all this into the public server over the next couple days and then commit everything once I finish reviewing it all.

Again, thanks for the contribution! -Abstrct

cbbrowne commented 12 years ago

I'm still musing about this, by the way.

I'm unhappy at this point with the MOVE() interface. It doesn't appear to be working, in the sample game. Take a look at user "funbuster"'s ships... I have requested destinations that are visible, and for some reason, they're not going there at any speed.

I'm thinking about 2 changes: a) Separate motion into 3 functions that don't mix APIs together (e.g. - no NULLs get used)

  1. move_to( ship_id, fuel_burn, target_point )
  2. stop (ship_id)
  3. move_direction ( ship_id, fuel_burn, angle )

And I'm not sure I'll ever want to use move_direction().

b) My sense is that the representation of movement isn't quite right right now. I think it should be vector-based, so that you do NOT have "direction + speed", rather, you have a point(dx,dy) indicating the direction vector. That should be easier to work with, particularly for the most common case, where you want to go from A to B, and where that is readily expressed by subtracting the points from each other to give a direction vector.

Abstrct commented 12 years ago

The current move system is about a week old so it may need some tweaks but I think it is actually getting really close to the right system. If you are not getting to your destination, it may be that you do not have enough fuel to turn in the right direction, or you do not have enough fuel to stop once you get close to your destination.

If you have considered both of those and you are still not getting there, let me know an example current position, target speed, and destination.

I worry about adding more functions to move making it more complicated. Especially something like stop. I don't think players should have to call stop on their own if they already specified a destination. Right now you can do the same thing by giving a new target speed of 0.

Moving in only a specific direction/speed with no destination is actually a pretty popular strategy for exploring.

If giving NULL's is a bit annoying, I usually make a couple MOVE aliases which shorten the calls as you described. There are: MOVE(ship_id, destination_x, destination_y) MOVE(ship_id, speed, destination_x, destination_y)

Of course, with the new move system, these MOVE() functions simply pass along the entered parameters into the new SHIP_COURSE_CONTROL() function which handles the actual setting of course.

I don't disagree that using a vector would be helpful, but I think the math in move_ships() should be correct regardless. Let's give the new move system a round or two and if it doesn't work out then we can look into a new solution.