Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement in-memory graph store #68

Closed
9 tasks done
Tracked by #41
oubiwann opened this issue Jul 28, 2022 · 3 comments
Closed
9 tasks done
Tracked by #41

Implement in-memory graph store #68

oubiwann opened this issue Jul 28, 2022 · 3 comments
Milestone

Comments

@oubiwann
Copy link
Contributor

oubiwann commented Jul 28, 2022

Part of:

Tasks:

  • Use Erlang's digraph library (see Find a good graph library for Erlang #42)
  • Decide what will be stored in the graph
    • rooms for sure
    • but anything else?
  • Define graph models for game data #43
  • Create a new module that will hold the graph gen_server responsible for maintaining the graph
    • name will depend upon what all is to be stored in the graph
  • Set up the gen_server to hold the graph in state
  • Wrap stdlib functions (developer should never have to pass the graph object)
@oubiwann oubiwann added this to the 0.7.0 milestone Jul 28, 2022
@oubiwann
Copy link
Contributor Author

oubiwann commented Jul 30, 2022

Making good progress on this one. Here's some usage I've been testing tonight ...

Load data from files:

(set `#(ok ,rm1) (mudgraph-v1:load "rooms" "room1"))
(set `#(ok ,rm2) (mudgraph-v1:load "rooms" "room2"))
(set `#(ok ,obj1) (mudgraph-v1:load "objects" "sword"))
(set `#(ok ,obj2) (mudgraph-v1:load "objects" "painting"))
(set `#(ok ,per1) (mudgraph-v1:load "characters" "eve"))

Convert these to maps for use as "labels" (arbitrary data storage) on the nodes:

(set rm1 (proplists:to_map rm1))
(set rm2 (proplists:to_map rm2))
(set obj1 (proplists:to_map obj1))
(set obj2 (proplists:to_map obj2))
(set per1 (proplists:to_map per1))

Now actually use the graph DB :-)

(set v1 (mg:add-vertex rm1)) ; we'll store the vertex's ID in a variable so we can look it up latter
(mg:add-vertex rm2)
(set e1 (mg:add-edge rm1 rm2 #m(type transit direction east size normal))) ; again, for later look-up
(mg:add-edge rm2 rm1 #m(type transit direction west size normal))

(mg:add-vertex obj1)
(mg:add-vertex obj2)
(mg:add-vertex per1)
(mg:add-edge obj1 rm1 #m(type contains))
(mg:add-edge obj2 rm1 #m(type contains))
(mg:add-edge per1 rm1 #m(type contains))

(mg:in-edges rm1)
(mg:in-neighbours rm1)
(mg:out-neighbours rm1)

(mg:in-neighbours rm1 'contains) ; get all objects in the room
(mg:out-neighbours rm1 'transit) ; get all exits out of the room

(mg:vertex v1)
(mg:edge e1)

I don't have a good, general solution for filtering edges (and thus neighbours) on all possible k/vs in a map ... only filtering by one (type) right now.

@oubiwann
Copy link
Contributor Author

There are more Erlang digraph funcs to wrap; I'll do that as I need them.

@oubiwann
Copy link
Contributor Author

More thoughts about data modelling:

  • maybe make it more abstract?
  • for instance, instead of having an inventory node, and querying for all "in" vertices on it ...
  • instead have edge labels like "owned", "equipped", "carrying", etc.
  • this allows one to build inventories of all objects in-game, e.g., in a house, in a cave, buried under a tree, or even in a backpack -- much more generally useful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant