Welcome to LiSE’s documentation!¶
allegedb¶
Object relational mapper for graphs with in-built revision control.
allegedb serves its own special variants on the networkx graph classes: Graph, DiGraph, MultiGraph, and MultiDiGraph. Every change to them is stored in an SQL database.
This means you can keep multiple versions of one set of graphs and switch between them without the need to save, load, or run git-checkout. Just point the ORM at the correct branch and revision, and all of the graphs in the program will change. All the different branches and revisions remain in the database to be brought back when needed.
usage¶
>>> from allegedb import ORM
>>> orm = ORM('sqlite:///test.db')
>>> orm.initdb() # only necessary the first time you use a particular database
>>> g = orm.new_graph('test') # also new_digraph, new_multigraph, new_multidigraph
>>> g.add_nodes_from(['spam', 'eggs', 'ham'])
>>> g.add_edge('spam', 'eggs')
>>> g.edge # strings become unicode because that's the way sqlite3 rolls
{u'eggs': {u'ham': {}, u'spam': {}}, u'ham': {u'eggs': {}}, u'spam': {u'eggs': {}}}
>>> del g
>>> orm.close()
>>> del orm
>>> orm = ORM('sqlite:///test.db')
>>> g = orm.get_graph('test') # returns whatever graph type you stored by that name
>>> g.edge
{u'eggs': {u'ham': {}, u'spam': {}}, u'ham': {u'eggs': {}}, u'spam': {u'eggs': {}}}
>>> import networkx as nx
>>> red = nx.random_lobster(10,0.9,0.9)
>>> blue = orm.new_graph('red', red) # initialize with data from the given graph
>>> red.edge == blue.edge
True
>>> orm.rev = 1
>>> blue.add_edge(17, 15)
>>> red.edge = blue.edge
False
>>> orm.rev = 0 # undoing what I did when rev-1
>>> red.edge == blue.edge
True
>>> orm.rev = 0
>>> orm.branch = 'test' # navigating to a branch for the first time creates that branch
>>> orm.rev = 1
>>> red.edge == blue.edge
True
>>> orm.branch = 'trunk'
>>> red.edge == blue.edge
False
ORM¶
The main interface to the allegedb ORM, and some supporting functions and classes
-
class
allegedb.
ORM
(dbstring, alchemy=True, connect_args={}, validate=False)[source]¶ Instantiate this with the same string argument you’d use for a SQLAlchemy
create_engine
call. This will be your interface to allegedb.-
advancing
()[source]¶ A context manager for when time is moving forward one turn at a time.
When used in LiSE, this means that the game is being simulated. It changes how the caching works, making it more efficient.
-
batch
()[source]¶ A context manager for when you’re creating lots of state.
Reads will be much slower in a batch, but writes will be faster.
You can combine this with
advancing
but it isn’t any faster.
-
commit
()[source]¶ Write the state of all graphs to the database and commit the transaction.
Also saves the current branch, turn, and tick.
-
contextmanager
()¶ @contextmanager decorator.
Typical usage:
@contextmanager def some_generator(<arguments>):
<setup> try:
yield <value>- finally:
- <cleanup>
This makes this:
- with some_generator(<arguments>) as <variable>:
- <body>
equivalent to this:
<setup> try:
<variable> = <value> <body>- finally:
- <cleanup>
-
edge_cls
¶ alias of
allegedb.graph.Edge
-
get_delta
(branch, turn_from, tick_from, turn_to, tick_to)[source]¶ Get a dictionary describing changes to all graphs.
The keys are graph names. Their values are dictionaries of the graphs’ attributes’ new values, with
None
for deleted keys. Also in those graph dictionaries are special keys ‘node_val’ and ‘edge_val’ describing changes to node and edge attributes, and ‘nodes’ and ‘edges’ full of booleans indicating whether a node or edge exists.
-
get_graph
(name)[source]¶ Return a graph previously created with
new_graph
,new_digraph
,new_multigraph
, ornew_multidigraph
-
get_turn_delta
(branch=None, turn=None, tick_from=0, tick_to=None)[source]¶ Get a dictionary describing changes made on a given turn.
If
tick_to
is not supplied, report all changes aftertick_from
(default 0).The keys are graph names. Their values are dictionaries of the graphs’ attributes’ new values, with
None
for deleted keys. Also in those graph dictionaries are special keys ‘node_val’ and ‘edge_val’ describing changes to node and edge attributes, and ‘nodes’ and ‘edges’ full of booleans indicating whether a node or edge exists.
-
is_parent_of
(parent, child)[source]¶ Return whether
child
is a branch descended fromparent
at any remove.
-
nbtt
()[source]¶ Increment the tick and return branch, turn, tick
Unless we’re viewing the past, in which case raise HistoryError.
Idea is you use this when you want to advance time, which you can only do once per branch, turn, tick.
-
new_digraph
(name, data=None, **attr)[source]¶ Return a new instance of type DiGraph, initialized with the given data if provided.
-
new_graph
(name, data=None, **attr)[source]¶ Return a new instance of type Graph, initialized with the given data if provided.
-
new_multidigraph
(name, data=None, **attr)[source]¶ Return a new instance of type MultiDiGraph, initialized with the given data if provided.
-
new_multigraph
(name, data=None, **attr)[source]¶ Return a new instance of type MultiGraph, initialized with the given data if provided.
-
node_cls
¶ alias of
allegedb.graph.Node
-
plan
()[source]¶ A context manager for ‘hypothetical’ edits.
Start a block of code like:
``` with orm.plan():
…and any changes you make to the world state within that block will be ‘plans,’ meaning that they are used as defaults. The world will obey your plan unless you make changes to the same entities outside of the plan, in which case the world will obey those, and cancel any future plan.
New branches cannot be started within plans.
-
query_engine_cls
¶ alias of
allegedb.query.QueryEngine
-
-
class
allegedb.
PlanningContext
(orm)[source]¶ A context manager for ‘hypothetical’ edits.
Start a block of code like:
``` with orm.plan():
…and any changes you make to the world state within that block will be ‘plans,’ meaning that they are used as defaults. The world will obey your plan unless you make changes to the same entities outside of the plan, in which case the world will obey those, and cancel any future plan.
New branches cannot be started within plans.
-
class
allegedb.
TimeSignal
(engine)[source]¶ Acts like a list of
[branch, turn]
for the most part.You can set these to new values, or even replace them with a whole new
[branch, turn]
if you wish. It’s even possible to use the strings'branch'
or'turn'
in the place of indices, but at that point you might prefer to setengine.branch
orengine.turn
directly.This is a Signal, so pass a function to the connect(…) method and it will be called whenever the time changes. Not when the tick changes, though. If you really need something done whenever the tick changes, override the _set_tick method of
allegedb.ORM
.
-
class
allegedb.
TimeSignalDescriptor
[source]¶ Acts like a list of
[branch, turn]
for the most part.You can set these to new values, or even replace them with a whole new
[branch, turn]
if you wish. It’s even possible to use the strings'branch'
or'turn'
in the place of indices, but at that point you might prefer to setengine.branch
orengine.turn
directly.This is a Signal, so pass a function to the connect(…) method and it will be called whenever the time changes. Not when the tick changes, though. If you really need something done whenever the tick changes, override the _set_tick method of
allegedb.ORM
.
-
allegedb.
setedge
(delta, is_multigraph, graph, orig, dest, idx, exists)[source]¶ Change a delta to say that an edge was created or deleted
-
allegedb.
setedgeval
(delta, is_multigraph, graph, orig, dest, idx, key, value)[source]¶ Change a delta to say that an edge stat was set to a certain value
-
allegedb.
setgraphval
(delta, graph, key, val)[source]¶ Change a delta to say that a graph stat was set to a certain value
cache¶
Classes for in-memory storage and retrieval of historical graph data.
-
class
allegedb.cache.
Cache
(db)[source]¶ A data store that’s useful for tracking graph revisions.
-
branches
= None¶ A less structured alternative to
keys
.For when you already know the entity and the key within it, but still need to iterate through history to find the value.
-
contains_entity
(*args)¶ Check if an entity has a key at the given time, if entity specified.
Otherwise check if the entity exists.
-
contains_entity_key
(*args)¶ Check if an entity has a key at the given time, if entity specified.
Otherwise check if the entity exists.
-
contains_entity_or_key
(*args)[source]¶ Check if an entity has a key at the given time, if entity specified.
Otherwise check if the entity exists.
-
contains_key
(*args)¶ Check if an entity has a key at the given time, if entity specified.
Otherwise check if the entity exists.
-
count_entities
(*args, forward=None)¶ Return the number of keys an entity has, if you specify an entity.
Otherwise return the number of entities.
-
count_entities_or_keys
(*args, forward=None)[source]¶ Return the number of keys an entity has, if you specify an entity.
Otherwise return the number of entities.
-
count_entity_keys
(*args, forward=None)¶ Return the number of keys an entity has, if you specify an entity.
Otherwise return the number of entities.
-
count_keys
(*args, forward=None)¶ Return the number of keys an entity has, if you specify an entity.
Otherwise return the number of entities.
-
iter_entities
(*args, forward=None)¶ Iterate over the keys an entity has, if you specify an entity.
Otherwise iterate over the entities themselves, or at any rate the tuple specifying which entity.
-
iter_entities_or_keys
(*args, forward=None)[source]¶ Iterate over the keys an entity has, if you specify an entity.
Otherwise iterate over the entities themselves, or at any rate the tuple specifying which entity.
-
iter_entity_keys
(*args, forward=None)¶ Iterate over the keys an entity has, if you specify an entity.
Otherwise iterate over the entities themselves, or at any rate the tuple specifying which entity.
-
iter_keys
(*args, forward=None)¶ Iterate over the keys an entity has, if you specify an entity.
Otherwise iterate over the entities themselves, or at any rate the tuple specifying which entity.
-
keycache
= None¶ Keys an entity has at a given turn and tick.
-
keys
= None¶ Cache of entity data keyed by the entities themselves.
That means the whole tuple identifying the entity is the top-level key in this cache here. The second-to-top level is the key within the entity.
Deeper layers of this cache are keyed by branch, turn, and tick.
-
load
(data, validate=False, cb=None)[source]¶ Add a bunch of data. It doesn’t need to be in chronological order.
With
validate=True
, raise ValueError if this results in an incoherent cache.If a callable
cb
is provided, it will be called with each row. It will also be passed myvalidate
argument.
-
parents
= None¶ Entity data keyed by the entities’ parents.
An entity’s parent is what it’s contained in. When speaking of a node, this is its graph. When speaking of an edge, the parent is usually the graph and the origin in a pair, though for multigraphs the destination might be part of the parent as well.
Deeper layers of this cache are keyed by branch and revision.
-
presettings
= None¶ The values prior to
entity[key] = value
operations performed on some turn
-
retrieve
(*args)[source]¶ Get a value previously .store(…)’d.
Needs at least five arguments. The -1th is the tick within the turn you want, the -2th is that turn, the -3th is the branch, and the -4th is the key. All other arguments identify the entity that the key is in.
-
settings
= None¶ All the
entity[key] = value
operations that were performed on some turn
-
shallowest
= None¶ A dictionary for plain, unstructured hinting.
-
store
(*args, planning=None, forward=None)[source]¶ Put a value in various dictionaries for later .retrieve(…).
Needs at least five arguments, of which the -1th is the value to store, the -2th is the tick to store it at, the -3th is the turn to store it in, the -4th is the branch the revision is in, the -5th is the key the value is for, and the remaining arguments identify the entity that has the key, eg. a graph, node, or edge.
With
planning=True
, you will be permitted to alter “history” that takes place after the last non-planning moment of time, without much regard to consistency. Otherwise, contradictions will be handled by deleting everything after the present moment.
-
-
class
allegedb.cache.
EdgesCache
(db)[source]¶ A cache for remembering whether edges exist at a given time.
-
count_predecessors
(graph, dest, branch, turn, tick, *, forward=None)[source]¶ Return the number of predecessors from a given destination node at a given time.
-
count_successors
(graph, orig, branch, turn, tick, *, forward=None)[source]¶ Return the number of successors to a given origin node at a given time.
-
has_predecessor
(graph, dest, orig, branch, turn, tick)[source]¶ Return whether an edge connects the destination to the origin at the given time.
-
has_successor
(graph, orig, dest, branch, turn, tick)[source]¶ Return whether an edge connects the origin to the destination at the given time.
-
-
class
allegedb.cache.
FuturistWindowDict
(data=None)[source]¶ A WindowDict that does not let you rewrite the past.
-
class
allegedb.cache.
NodesCache
(db)[source]¶ A cache for remembering whether nodes exist at a given time.
-
class
allegedb.cache.
PickyDefaultDict
(type=<class 'object'>, args_munger=<function _default_args_munger>, kwargs_munger=<function _default_kwargs_munger>)[source]¶ A
defaultdict
alternative that requires values of a specific type.Pass some type object (such as a class) to the constructor to specify what type to use by default, which is the only type I will accept.
Default values are constructed with no arguments by default; supply
args_munger
and/orkwargs_munger
to override this. They take argumentsself
and the unused key being looked up.
-
class
allegedb.cache.
StructuredDefaultDict
(layers, type=<class 'object'>, args_munger=<function _default_args_munger>, kwargs_munger=<function _default_kwargs_munger>)[source]¶ A
defaultdict
-like class that expects values stored at a specific depth.Requires an integer to tell it how many layers deep to go. The innermost layer will be
PickyDefaultDict
, which will take thetype
,args_munger
, andkwargs_munger
arguments supplied to my constructor.
-
class
allegedb.cache.
TurnDict
(data=None)[source]¶ -
cls
¶ alias of
FuturistWindowDict
-
graph¶
allegedb’s special implementations of the NetworkX graph objects
-
class
allegedb.graph.
AbstractSuccessors
(container, orig)[source]¶ -
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
allegedb.graph.
AllegedGraph
(db, name, data=None, **attr)[source]¶ Class giving the graphs those methods they share in common.
-
clear
()[source]¶ Remove all nodes and edges from the graph.
Unlike the regular networkx implementation, this does not remove the graph’s name. But all the other graph, node, and edge attributes go away.
-
graph_map_cls
¶ alias of
GraphMapping
-
node_map_cls
¶ alias of
GraphNodeMapping
-
-
class
allegedb.graph.
AllegedMapping
[source]¶ Common amenities for mappings
-
class
allegedb.graph.
DiGraph
(db, name, data=None, **attr)[source]¶ A version of the networkx.DiGraph class that stores its state in a database.
-
add_edge
(u, v, attr_dict=None, **attr)[source]¶ Version of add_edge that only writes to the database once
-
add_edges_from
(ebunch, attr_dict=None, **attr)[source]¶ Version of add_edges_from that only writes to the database once
-
adj_cls
¶ alias of
DiGraphSuccessorsMapping
-
pred_cls
¶ alias of
DiGraphPredecessorsMapping
-
-
class
allegedb.graph.
DiGraphPredecessorsMapping
(graph)[source]¶ Mapping for Predecessors instances, which map to Edges that end at the dest provided to this
-
class
allegedb.graph.
Edge
(graph, orig, dest, idx=0)[source]¶ Mapping for edge attributes
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
exception
allegedb.graph.
EntityCollisionError
[source]¶ For when there’s a discrepancy between the kind of entity you’re creating and the one by the same name
-
class
allegedb.graph.
Graph
(db, name, data=None, **attr)[source]¶ A version of the networkx.Graph class that stores its state in a database.
-
adj_cls
¶ alias of
GraphSuccessorsMapping
-
-
class
allegedb.graph.
GraphEdgeMapping
(graph)[source]¶ Provides an adjacency mapping and possibly a predecessor mapping for a graph.
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
allegedb.graph.
GraphMapping
(graph)[source]¶ Mapping for graph attributes
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
allegedb.graph.
GraphNodeMapping
(graph)[source]¶ Mapping for nodes in a graph
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
allegedb.graph.
GraphSuccessorsMapping
(graph)[source]¶ Mapping for Successors (itself a MutableMapping)
-
class
allegedb.graph.
MultiDiGraph
(db, name, data=None, **attr)[source]¶ A version of the networkx.MultiDiGraph class that stores its state in a database.
-
add_edge
(u, v, key=None, attr_dict=None, **attr)[source]¶ Version of add_edge that only writes to the database once.
-
adj_cls
¶ alias of
MultiDiGraphSuccessorsMapping
-
pred_cls
¶ alias of
MultiDiGraphPredecessorsMapping
-
-
class
allegedb.graph.
MultiDiGraphPredecessorsMapping
(graph)[source]¶ Version of DiGraphPredecessorsMapping for multigraphs
-
class
allegedb.graph.
MultiEdges
(graph, orig, dest)[source]¶ Mapping of Edges between two nodes
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
allegedb.graph.
MultiGraph
(db, name, data=None, **attr)[source]¶ A version of the networkx.MultiGraph class that stores its state in a database.
-
adj_cls
¶ alias of
MultiGraphSuccessorsMapping
-
-
class
allegedb.graph.
MultiGraphSuccessorsMapping
(graph)[source]¶ Mapping of Successors that map to MultiEdges
-
class
allegedb.graph.
Node
(graph, node)[source]¶ Mapping for node attributes
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
query¶
Wrapper to run SQL queries in a lightly abstracted way, such that code that’s more to do with the queries than with the data per se doesn’t pollute the other files so much.
-
class
allegedb.query.
GlobalKeyValueStore
(qe)[source]¶ A dict-like object that keeps its contents in a table.
Mostly this is for holding the current branch and revision.
-
class
allegedb.query.
QueryEngine
(dbstring, connect_args, alchemy, pack=None, unpack=None)[source]¶ Wrapper around either a DBAPI2.0 connection or an Alchemist. Provides methods to run queries using either.
-
edge_val_del
(graph, orig, dest, idx, key, branch, turn, tick)[source]¶ Declare that the key no longer applies to this edge, as of this branch and revision.
-
edge_val_set
(graph, orig, dest, idx, key, branch, turn, tick, value)[source]¶ Set this key of this edge to this value.
-
exist_edge
(graph, orig, dest, idx, branch, turn, tick, extant)[source]¶ Declare whether or not this edge exists.
-
exist_node
(graph, node, branch, turn, tick, extant)[source]¶ Declare that the node exists or doesn’t.
Inserts a new record or updates an old one, as needed.
-
global_set
(key, value)[source]¶ Set
key
tovalue
globally (not at any particular branch or revision)
-
new_branch
(branch, parent, parent_turn, parent_tick)[source]¶ Declare that the
branch
is descended fromparent
atparent_turn
,parent_tick
-
node_val_del
(graph, node, key, branch, turn, tick)[source]¶ Delete a key from a node at a specific branch and revision
-
node_val_set
(graph, node, key, branch, turn, tick, value)[source]¶ Set a key-value pair on a node at a specific branch and revision
-
wrap¶
Wrapper classes to let you store mutable data types in the allegedb ORM
-
class
allegedb.wrap.
DictWrapper
(getter, setter, outer, key)[source]¶ A dictionary synchronized with a serialized field.
This is meant to be used in allegedb entities (graph, node, or edge), for when the user stores a dictionary in them.
-
class
allegedb.wrap.
ListWrapper
(getter, setter, outer, key)[source]¶ A list synchronized with a serialized field.
This is meant to be used in allegedb entities (graph, node, or edge), for when the user stores a list in them.
-
class
allegedb.wrap.
SetWrapper
(getter, setter, outer, key)[source]¶ A set synchronized with a serialized field.
This is meant to be used in allegedb entities (graph, node, or edge), for when the user stores a set in them.
LiSE¶
engine¶
The “engine” of LiSE is an object relational mapper with special stores for game data and entities, as well as properties for manipulating the flow of time.
-
class
LiSE.engine.
AbstractEngine
[source]¶ Parent class to the real Engine as well as EngineProxy.
Implements serialization methods and the __getattr__ for stored methods.
By default, the deserializers will refuse to create LiSE entities. If you want them to, use my
loading
property to open awith
block, in which deserialized entities will be created as needed.-
contextmanager
()¶ @contextmanager decorator.
Typical usage:
@contextmanager def some_generator(<arguments>):
<setup> try:
yield <value>- finally:
- <cleanup>
This makes this:
- with some_generator(<arguments>) as <variable>:
- <body>
equivalent to this:
<setup> try:
<variable> = <value> <body>- finally:
- <cleanup>
-
dice
(n, d)[source]¶ Roll
n
dice withd
faces, and yield the results.This is an iterator. You’ll get the result of each die in successon.
-
dice_check
(n, d, target, comparator='<=')[source]¶ Roll
n
dice withd
sides, sum them, and return whether they are <=target
.If
comparator
is provided, use it instead of <=. You may use a string like ‘<’ or ‘>=’.
-
-
class
LiSE.engine.
Engine
(worlddb, *, string='strings.json', function='function.py', method='method.py', trigger='trigger.py', prereq='prereq.py', action='action.py', connect_args={}, alchemy=False, commit_modulus=None, random_seed=None, logfun=None, validate=False, clear_code=False, clear_world=False)[source]¶ LiSE, the Life Simulator Engine.
Each instance of LiSE maintains a connection to a database representing the state of a simulated world. Simulation rules within this world are described by lists of Python functions, some of which make changes to the world.
The top-level data structure within LiSE is the character. Most data within the world model is kept in some character or other; these will quite frequently represent people, but can be readily adapted to represent any kind of data that can be comfortably described as a graph or a JSON object. Every change to a character will be written to the database.
LiSE tracks history as a series of turns. In each turn, each simulation rule is evaluated once for each of the simulated entities it’s been applied to. World changes in a given turn are remembered together, such that the whole world state can be rewound: simply set the properties
branch
andturn
back to what they were just before the change you want to undo.Properties:
branch
: The fork of the timestream that we’re on.turn
: Units of time that have passed since the sim started.time
:(branch, turn)
tick
: A counter of how many changes have occurred this turncharacter
: A mapping ofCharacter
objects by name.rule
: A mapping of all rules that have been made.rulebook
: A mapping of lists of rules. They are followed in their order. A whole rulebook full of rules may be assigned to an entity at once.trigger
: A mapping of functions that might trigger a rule.prereq
: A mapping of functions a rule might require to returnTrue
for it to run.action
: A mapping of functions that might manipulate the world state as a result of a rule running.function
: A mapping of generic functions.string
: A mapping of strings, probably shown to the player at some point.eternal
: Mapping of arbitrary serializable objects. It isn’t sensitive to sim-time. A good place to keep game settings.universal
: Another mapping of arbitrary serializable objects, but this one is sensitive to sim-time. Each turn, the state of the randomizer is saved here under the key'rando_state'
.
-
class
Character
(engine, name, data=None, *, init_rulebooks=True, **attr)¶ A graph that follows game rules and has a containment hierarchy.
Nodes in a Character are subcategorized into Things and Places. Things have locations, and those locations may be Places or other Things.
Characters may have avatars in other Characters. These are just nodes. You can apply rules to a Character’s avatars, and thus to any collection of nodes you want, perhaps in many different Characters. But you may want a Character to have exactly one avatar, representing their location in physical space – the Character named ‘physical’. So when a Character has only one avatar, you can treat the
avatar
property as an alias of the avatar.-
class
AvatarGraphMapping
(char)¶ A mapping of other characters in which one has an avatar.
Maps to a mapping of the avatars themselves, unless there’s only one other character you have avatars in, in which case this maps to those.
If you have only one avatar anywhere, you can pretend this is that entity.
-
class
CharacterAvatarMapping
(outer, graphn)¶ Mapping of avatars of one Character in another Character.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
node
¶ If I have avatars in only one graph, return a map of them.
Otherwise, raise AttributeError.
-
only
¶ If I have only one avatar, return it.
Otherwise, raise AttributeError.
-
class
-
class
PlaceMapping
(character)¶ Place
objects that are in aCharacter
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
PortalPredecessorsMapping
(graph)¶ Mapping of nodes that have at least one incoming edge.
Maps to another mapping keyed by the origin nodes, which maps to Portal objects.
-
class
Predecessors
(container, dest)¶ Mapping of possible origins from some destination.
-
class
-
class
PortalSuccessorsMapping
(graph)¶ Mapping of nodes that have at least one outgoing edge.
Maps them to another mapping, keyed by the destination nodes, which maps to Portal objects.
-
class
Successors
(container, orig)¶ Mapping for possible destinations from some node.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
static
send
(self, **kwargs)¶ Call all listeners to
dest
and to myorig
.
-
-
character
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
class
-
class
ThingMapping
(character)¶ Thing
objects that are in aCharacter
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
ThingPlaceMapping
(character)¶ GraphNodeMapping but for Place and Thing
-
character
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
add_avatar
(a, b=None)¶ Start keeping track of a
Thing
orPlace
in a differentCharacter
.
-
add_places_from
(seq, **attrs)¶ Take a series of place names and add the lot.
-
add_portal
(origin, destination, symmetrical=False, **kwargs)¶ Connect the origin to the destination with a
Portal
.Keyword arguments are the
Portal
’s attributes. Exception: if keywordsymmetrical
==True
, a mirror-Portal
will be placed in the opposite direction between the same nodes. It will always appear to have the placedPortal
’s stats, and any change to the mirrorPortal
’s stats will affect the placedPortal
.
-
add_portals_from
(seq, symmetrical=False)¶ Take a sequence of (origin, destination) pairs and make a
Portal
for each.Actually, triples are acceptable too, in which case the third item is a dictionary of stats for the new
Portal
.If optional argument
symmetrical
is set toTrue
, all thePortal
instances will have a mirror portal going in the opposite direction, which will always have the same stats.
-
add_thing
(name, location, **kwargs)¶ Create a Thing, set its location, and set its initial attributes from the keyword arguments (if any).
-
adj_cls
¶ alias of
Character.PortalSuccessorsMapping
-
avatars
()¶ Iterate over all my avatars, regardless of what character they are in.
-
del_avatar
(a, b=None)¶ This is no longer my avatar, though it still exists on its own.
-
node_map_cls
¶ alias of
Character.ThingPlaceMapping
-
place2thing
(name, location)¶ Turn a Place into a Thing with the given location.
It will keep all its attached Portals.
-
portals
()¶ Iterate over all portals.
-
pred_cls
¶ alias of
Character.PortalPredecessorsMapping
-
thing2place
(name)¶ Unset a Thing’s location, and thus turn it into a Place.
-
class
-
class
Place
(character, name)¶ The kind of node where a thing might ultimately be located.
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
delete
()¶ Remove myself from the world model immediately.
-
-
class
Portal
(graph, orig, dest, idx=0)¶ Connection between two Places that Things may travel along.
Portals are one-way, but you can make one appear two-way by setting the
symmetrical
key toTrue
, eg.character.add_portal(orig, dest, symmetrical=True)
. The portal going the other way will appear to have all the stats of this one, and attempting to set a stat on it will set it here instead.-
character
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
delete
()¶ Remove myself from my
Character
.For symmetry with
Thing
and :class`Place`.
-
destination
¶ Return the Place object at which I end
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
origin
¶ Return the Place object that is where I begin
-
reciprocal
¶ If there’s another Portal connecting the same origin and destination that I do, but going the opposite way, return it. Else raise KeyError.
-
unwrap
()¶ Return a deep copy of myself as a dict, and unwrap any wrapper objects in me.
-
update
(d)¶ Works like regular update, but only actually updates when the new value and the old value differ. This is necessary to prevent certain infinite loops.
-
-
class
QueryEngine
(dbstring, connect_args, alchemy, pack=None, unpack=None)¶ -
exception
IntegrityError
¶
-
exception
OperationalError
¶
-
exist_edge
(character, orig, dest, idx, branch, turn, tick, extant=None)¶ Declare whether or not this edge exists.
-
exist_node
(character, node, branch, turn, tick, extant)¶ Declare that the node exists or doesn’t.
Inserts a new record or updates an old one, as needed.
-
initdb
()¶ Set up the database schema, both for allegedb and the special extensions for LiSE
-
exception
-
class
Thing
(character, name)¶ The sort of item that has a particular location at any given time.
If a Thing is in a Place, it is standing still. If it is in a Portal, it is moving through that Portal however fast it must in order to arrive at the other end when it is scheduled to. If it is in another Thing, then it is wherever that is, and moving the same.
-
clear
()¶ Unset everything.
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
delete
()¶ Get rid of this, starting now.
Apart from deleting the node, this also informs all its users that it doesn’t exist and therefore can’t be their avatar anymore.
-
follow_path
(path, weight=None)¶ Go to several
Place`s in succession, deciding how long to spend in each by consulting the ``weight`
stat of thePortal
connecting the onePlace
to the next.Return the total number of turns the travel will take. Raise
TravelException
if I can’t follow the whole path, either because some of its nodes don’t exist, or because I’m scheduled to be somewhere else.
-
go_to_place
(place, weight='')¶ Assuming I’m in a
Place
that has aPortal
direct to the givenPlace
, schedule myself to travel to the givenPlace
, taking an amount of time indicated by theweight
stat on thePortal
, if given; else 1 turn.Return the number of turns the travel will take.
-
location
¶ The
Thing
orPlace
I’m in.
-
travel_to
(dest, weight=None, graph=None)¶ Find the shortest path to the given
Place
from where I am now, and follow it.If supplied, the
weight
stat of the :class:`Portal`s along the path will be used in pathfinding, and for deciding how long to stay in each Place along the way.The
graph
argument may be any NetworkX-style graph. It will be used for pathfinding if supplied, otherwise I’ll use myCharacter
. In either case, however, I will attempt to actually follow the path using myCharacter
, which might not be possible if the suppliedgraph
and myCharacter
are too different. If it’s not possible, I’ll raise aTravelException
, whosesubpath
attribute holds the part of the path that I can follow. To make me follow it, pass it to myfollow_path
method.Return value is the number of turns the travel will take.
-
-
add_character
(name, data=None, **kwargs)[source]¶ Create a new character.
You’ll be able to access it as a
Character
object by looking upname
in mycharacter
property.data
, if provided, should be a networkx-compatible graph object. Your new character will be a copy of it.Any keyword arguments will be set as stats of the new character.
-
advance
()[source]¶ Follow the next rule if available.
If we’ve run out of rules, reset the rules iterator.
-
char_cls
¶ alias of
LiSE.character.Character
-
del_character
(name)[source]¶ Remove the Character from the database entirely.
This also deletes all its history. You’d better be sure.
-
edge_cls
¶ alias of
LiSE.portal.Portal
-
get_delta
(branch, turn_from, tick_from, turn_to, tick_to)[source]¶ Get a dictionary describing changes to the world.
Most keys will be character names, and their values will be dictionaries of the character’s stats’ new values, with
None
for deleted keys. Characters’ dictionaries have special keys ‘nodes’ and ‘edges’ which contain booleans indicating whether the node or edge exists at the moment, and ‘node_val’ and ‘edge_val’ for the stats of those entities. For edges (also called portals) these dictionaries are two layers deep, keyed first by the origin, then by the destination.Characters also have special keys for the various rulebooks they have:
- ‘character_rulebook’
- ‘avatar_rulebook’
- ‘character_thing_rulebook’
- ‘character_place_rulebook’
- ‘character_portal_rulebook’
And each node and edge may have a ‘rulebook’ stat of its own. If a node is a thing, it gets a ‘location’; when the ‘location’ is deleted, that means it’s back to being a place.
Keys at the top level that are not character names:
- ‘rulebooks’, a dictionary keyed by the name of each changed rulebook, the value
being a list of rule names * ‘rules’, a dictionary keyed by the name of each changed rule, containing any of the lists ‘triggers’, ‘prereqs’, and ‘actions’
-
get_turn_delta
(branch=None, turn=None, tick=None, start_tick=0)[source]¶ Get a dictionary describing changes to the world within a given turn
Defaults to the present turn, and stops at the present tick unless specified.
See the documentation for
get_delta
for a detailed description of the delta format.
-
node_cls
¶ alias of
LiSE.place.Place
-
place_cls
¶ alias of
LiSE.place.Place
-
portal_cls
¶ alias of
LiSE.portal.Portal
-
query_engine_cls
¶ alias of
LiSE.query.QueryEngine
-
thing_cls
¶ alias of
LiSE.thing.Thing
character¶
The top level of the LiSE world model, the Character.
Based on NetworkX DiGraph objects with various additions and conveniences.
A Character is a graph that follows rules. Its rules may be assigned
to run on only some portion of it: just edges (called Portals), just
nodes, or just nodes of the kind that have a location in another node
(called Places and Things, respectively). Each Character has a
stat
property that acts very much like a dictionary, in which you
can store game-relevant data for the rules to use.
You can designate some nodes in one Character as avatars of another, and then assign a rule to run on all of a Character’s avatars. This is useful for the common case where someone in your game has a location in the physical world (here, a Character, called ‘physical’) but also has a behavior flowchart, or a skill tree, that isn’t part of the physical world. In that case the flowchart is the person’s Character, and their node in the physical world is an avatar of it.
-
class
LiSE.character.
AbstractCharacter
[source]¶ The Character API, with all requisite mappings and graph generators.
Mappings resemble those of a NetworkX digraph:
thing
andplace
are subsets ofnode
edge
,adj
, andsucc
are aliases ofportal
pred
is an alias topreportal
stat
is a dict-like mapping of data that changes over game-time,
to be used in place of graph attributes
-
become
(g)[source]¶ Erase all my nodes and edges. Replace them with a copy of the graph provided.
Return myself.
-
cull_edges
(stat, threshold=0.5, comparator=<built-in function ge>)[source]¶ Delete edges whose stat >=
threshold
(default 0.5).Optional argument
comparator
will replace >= as the test for whether to cull. You can use the name of a stored function.
-
cull_nodes
(stat, threshold=0.5, comparator=<built-in function ge>)[source]¶ Delete nodes whose stat >=
threshold
(default 0.5).Optional argument
comparator
will replace >= as the test for whether to cull. You can use the name of a stored function.
-
cull_portals
(stat, threshold=0.5, comparator=<built-in function ge>)[source]¶ Delete portals whose stat >=
threshold
(default 0.5).Optional argument
comparator
will replace >= as the test for whether to cull. You can use the name of a stored function.
-
do
(func, *args, **kwargs)[source]¶ Apply the function to myself, and return myself.
Look up the function in the database if needed. Pass it any arguments given, keyword or positional.
Useful chiefly when chaining.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
perlin
(stat='perlin')[source]¶ Apply Perlin noise to my nodes, and return myself.
I’ll try to use the name of the node as its spatial position for this purpose, or use its stats ‘x’, ‘y’, and ‘z’, or skip the node if neither are available. z is assumed 0 if not provided for a node.
Result will be stored in a node stat named ‘perlin’ by default. Supply the name of another stat to use it instead.
-
stat
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
class
LiSE.character.
CharRuleMapping
(character, rulebook, booktyp)[source]¶ Wraps one of a character’s rulebooks so you can get its rules by name.
You can access the rules in this either dictionary-style or as attributes. This is for convenience if you want to get at a rule’s decorators, eg. to add an Action to the rule.
Using this as a decorator will create a new rule, named for the decorated function, and using the decorated function as the initial Action.
Using this like a dictionary will let you create new rules, appending them onto the underlying
RuleBook
; replace one rule with another, where the new one will have the same index in theRuleBook
as the old one; and activate or deactivate rules. The name of a rule may be used in place of the actual rule, so long as the rule already exists.You can also set a rule active or inactive by setting it to
True
orFalse
, respectively. Inactive rules are still in the rulebook, but won’t be followed.
-
class
LiSE.character.
Character
(engine, name, data=None, *, init_rulebooks=True, **attr)[source]¶ A graph that follows game rules and has a containment hierarchy.
Nodes in a Character are subcategorized into Things and Places. Things have locations, and those locations may be Places or other Things.
Characters may have avatars in other Characters. These are just nodes. You can apply rules to a Character’s avatars, and thus to any collection of nodes you want, perhaps in many different Characters. But you may want a Character to have exactly one avatar, representing their location in physical space – the Character named ‘physical’. So when a Character has only one avatar, you can treat the
avatar
property as an alias of the avatar.-
class
AvatarGraphMapping
(char)[source]¶ A mapping of other characters in which one has an avatar.
Maps to a mapping of the avatars themselves, unless there’s only one other character you have avatars in, in which case this maps to those.
If you have only one avatar anywhere, you can pretend this is that entity.
-
class
CharacterAvatarMapping
(outer, graphn)[source]¶ Mapping of avatars of one Character in another Character.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
node
¶ If I have avatars in only one graph, return a map of them.
Otherwise, raise AttributeError.
-
only
¶ If I have only one avatar, return it.
Otherwise, raise AttributeError.
-
class
-
class
PlaceMapping
(character)[source]¶ Place
objects that are in aCharacter
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
PortalPredecessorsMapping
(graph)[source]¶ Mapping of nodes that have at least one incoming edge.
Maps to another mapping keyed by the origin nodes, which maps to Portal objects.
-
class
PortalSuccessorsMapping
(graph)[source]¶ Mapping of nodes that have at least one outgoing edge.
Maps them to another mapping, keyed by the destination nodes, which maps to Portal objects.
-
class
Successors
(container, orig)[source]¶ Mapping for possible destinations from some node.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
character
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
class
-
class
ThingMapping
(character)[source]¶ Thing
objects that are in aCharacter
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
ThingPlaceMapping
(character)[source]¶ GraphNodeMapping but for Place and Thing
-
character
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
add_portal
(origin, destination, symmetrical=False, **kwargs)[source]¶ Connect the origin to the destination with a
Portal
.Keyword arguments are the
Portal
’s attributes. Exception: if keywordsymmetrical
==True
, a mirror-Portal
will be placed in the opposite direction between the same nodes. It will always appear to have the placedPortal
’s stats, and any change to the mirrorPortal
’s stats will affect the placedPortal
.
-
add_portals_from
(seq, symmetrical=False)[source]¶ Take a sequence of (origin, destination) pairs and make a
Portal
for each.Actually, triples are acceptable too, in which case the third item is a dictionary of stats for the new
Portal
.If optional argument
symmetrical
is set toTrue
, all thePortal
instances will have a mirror portal going in the opposite direction, which will always have the same stats.
-
add_thing
(name, location, **kwargs)[source]¶ Create a Thing, set its location, and set its initial attributes from the keyword arguments (if any).
-
adj_cls
¶ alias of
Character.PortalSuccessorsMapping
-
node_map_cls
¶ alias of
Character.ThingPlaceMapping
-
place2thing
(name, location)[source]¶ Turn a Place into a Thing with the given location.
It will keep all its attached Portals.
-
pred_cls
¶ alias of
Character.PortalPredecessorsMapping
-
class
-
class
LiSE.character.
CharacterSense
(container, sensename)[source]¶ Mapping for when you’ve selected a sense for a character to use but haven’t yet specified what character to look at
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
func
¶ Return the function most recently associated with this sense.
-
observer
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
LiSE.character.
CharacterSenseMapping
(character)[source]¶ Used to view other Characters as seen by one, via a particular sense.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
LiSE.character.
Facade
(character=None)[source]¶ -
class
PlaceMapping
(facade)[source]¶ -
facadecls
¶ alias of
FacadePlace
-
innercls
¶ alias of
LiSE.place.Place
-
-
class
PortalPredecessorsMapping
(facade)[source]¶ -
cls
¶ alias of
FacadePortalPredecessors
-
-
class
PortalSuccessorsMapping
(facade)[source]¶ -
cls
¶ alias of
FacadePortalSuccessors
-
-
class
ThingMapping
(facade)[source]¶ -
facadecls
¶ alias of
FacadeThing
-
innercls
¶ alias of
LiSE.thing.Thing
-
-
add_edge
(orig, dest, **kwargs)[source]¶ Add an edge between u and v.
The nodes u and v will be automatically added if they are not already in the graph.
Edge attributes can be specified with keywords or by directly accessing the edge’s attribute dictionary. See examples below.
- u, v : nodes
- Nodes can be, for example, strings or numbers. Nodes must be hashable (and not None) Python objects.
- attr : keyword arguments, optional
- Edge data (or labels or objects) can be assigned using keyword arguments.
add_edges_from : add a collection of edges
Adding an edge that already exists updates the edge data.
Many NetworkX algorithms designed for weighted graphs use an edge attribute (by default weight) to hold a numerical value.
The following all add the edge e=(1, 2) to graph G:
>>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc >>> e = (1, 2) >>> G.add_edge(1, 2) # explicit two-node form >>> G.add_edge(*e) # single edge as tuple of two nodes >>> G.add_edges_from( [(1, 2)] ) # add edges from iterable container
Associate data to edges using keywords:
>>> G.add_edge(1, 2, weight=3) >>> G.add_edge(1, 3, weight=7, capacity=15, length=342.7)
For non-string attribute keys, use subscript notation.
>>> G.add_edge(1, 2) >>> G[1][2].update({0: 5}) >>> G.edges[1, 2].update({0: 5})
-
add_node
(name, **kwargs)[source]¶ Add a single node node_for_adding and update node attributes.
- node_for_adding : node
- A node can be any hashable Python object except None.
- attr : keyword arguments, optional
- Set or change node attributes using key=value.
add_nodes_from
>>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc >>> G.add_node(1) >>> G.add_node('Hello') >>> K3 = nx.Graph([(0, 1), (1, 2), (2, 0)]) >>> G.add_node(K3) >>> G.number_of_nodes() 3
Use keywords set/change node attributes:
>>> G.add_node(1, size=10) >>> G.add_node(3, weight=0.4, UTM=('13S', 382871, 3972649))
A hashable object is one that can be used as a key in a Python dictionary. This includes strings, numbers, tuples of strings and numbers, etc.
On many platforms hashable items also include mutables such as NetworkX Graphs, though one should be careful that the hash doesn’t change on mutables.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
class
-
class
LiSE.character.
FacadeEntityMapping
(facade)[source]¶ Mapping that contains entities in a Facade.
All the entities are of the same type,
facadecls
, possibly being distorted views of entities of the typeinnercls
.-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
-
class
LiSE.character.
FacadePlace
(mapping, real_or_name, **kwargs)[source]¶ Lightweight analogue of Place for Facade use.
-
class
LiSE.character.
FacadePortal
(mapping, other, **kwargs)[source]¶ Lightweight analogue of Portal for Facade use.
-
class
LiSE.character.
FacadePortalPredecessors
(facade, destname)[source]¶ -
facadecls
¶ alias of
FacadePortal
-
innercls
¶ alias of
LiSE.portal.Portal
-
-
class
LiSE.character.
FacadePortalSuccessors
(facade, origname)[source]¶ -
facadecls
¶ alias of
FacadePortal
-
innercls
¶ alias of
LiSE.portal.Portal
-
-
class
LiSE.character.
RuleFollower
[source]¶ Mixin class. Has a rulebook, which you can get a RuleMapping into.
-
class
LiSE.character.
SenseFuncWrap
(character, fun)[source]¶ Wrapper for a sense function that looks it up in the code store if provided with its name, and prefills the first two arguments.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
node¶
A base class for nodes that can be in a character.
Every actual node that you’re meant to use will be a place or thing. This module is for what they have in common.
-
class
LiSE.node.
Node
(character, name)[source]¶ The fundamental graph component, which edges (in LiSE, “portals”) go between.
Every LiSE node is either a thing or a place. They share in common the abilities to follow rules; to be connected by portals; and to contain things.
-
adj
¶ Return a mapping of portals connecting this node to its neighbors.
-
character
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
delete
()[source]¶ Get rid of this, starting now.
Apart from deleting the node, this also informs all its users that it doesn’t exist and therefore can’t be their avatar anymore.
-
edge
¶ Return a mapping of portals connecting this node to its neighbors.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
historical
(stat)[source]¶ Return a reference to the values that a stat has had in the past.
You can use the reference in comparisons to make a history query, and execute the query by calling it, or passing it to
self.engine.ticks_when
.
-
name
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
path_exists
(dest, weight=None)[source]¶ Return whether there is a path leading from me to
dest
.With
weight
, only consider edges that have a stat by the given name.Raise
ValueError
ifdest
is not a node in my character or the name of one.
-
portal
¶ Return a mapping of portals connecting this node to its neighbors.
-
shortest_path
(dest, weight=None)[source]¶ Return a list of node names leading from me to
dest
.Raise
ValueError
ifdest
is not a node in my character or the name of one.
-
shortest_path_length
(dest, weight=None)[source]¶ Return the length of the path from me to
dest
.Raise
ValueError
ifdest
is not a node in my character or the name of one.
-
successor
¶ Return a mapping of portals connecting this node to its neighbors.
-
-
class
LiSE.node.
RuleMapping
(node)[source]¶ Version of
LiSE.rule.RuleMapping
that works more easily with a node.
-
class
LiSE.node.
UserDescriptor
[source]¶ Give a node’s user if there’s only one
If there are many users, but one of them has the same name as this node, give that one.
Otherwise, raise AmbiguousUserError.
-
usermapping
¶ alias of
UserMapping
-
-
class
LiSE.node.
UserMapping
(node)[source]¶ A mapping of the characters that have a particular node as an avatar.
Getting characters from here isn’t any better than getting them from the engine direct, but with this you can do things like use the .get() method to get a character if it’s a user and otherwise get something else; or test whether the character’s name is in the keys; and so on.
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
place¶
The type of node that is a location.
Though both things and places are nodes, things are obliged to be located in another node. Places are not.
-
class
LiSE.place.
Place
(character, name)[source]¶ The kind of node where a thing might ultimately be located.
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
thing¶
The sort of node that is ultimately located in a Place.
Things may be located in other Things as well, but eventually must be recursively located in a Place.
There’s a subtle distinction between “location” and “containment”: a Thing may be contained by a Portal, but cannot be located there – only in one of the Portal’s endpoints. Things are both located in and contained by Places, or possibly other Things.
-
class
LiSE.thing.
Thing
(character, name)[source]¶ The sort of item that has a particular location at any given time.
If a Thing is in a Place, it is standing still. If it is in a Portal, it is moving through that Portal however fast it must in order to arrive at the other end when it is scheduled to. If it is in another Thing, then it is wherever that is, and moving the same.
-
db
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
delete
()[source]¶ Get rid of this, starting now.
Apart from deleting the node, this also informs all its users that it doesn’t exist and therefore can’t be their avatar anymore.
-
follow_path
(path, weight=None)[source]¶ Go to several
Place`s in succession, deciding how long to spend in each by consulting the ``weight`
stat of thePortal
connecting the onePlace
to the next.Return the total number of turns the travel will take. Raise
TravelException
if I can’t follow the whole path, either because some of its nodes don’t exist, or because I’m scheduled to be somewhere else.
-
go_to_place
(place, weight='')[source]¶ Assuming I’m in a
Place
that has aPortal
direct to the givenPlace
, schedule myself to travel to the givenPlace
, taking an amount of time indicated by theweight
stat on thePortal
, if given; else 1 turn.Return the number of turns the travel will take.
-
location
¶ The
Thing
orPlace
I’m in.
-
travel_to
(dest, weight=None, graph=None)[source]¶ Find the shortest path to the given
Place
from where I am now, and follow it.If supplied, the
weight
stat of the :class:`Portal`s along the path will be used in pathfinding, and for deciding how long to stay in each Place along the way.The
graph
argument may be any NetworkX-style graph. It will be used for pathfinding if supplied, otherwise I’ll use myCharacter
. In either case, however, I will attempt to actually follow the path using myCharacter
, which might not be possible if the suppliedgraph
and myCharacter
are too different. If it’s not possible, I’ll raise aTravelException
, whosesubpath
attribute holds the part of the path that I can follow. To make me follow it, pass it to myfollow_path
method.Return value is the number of turns the travel will take.
-
portal¶
Directed edges, as used by LiSE.
-
class
LiSE.portal.
Portal
(graph, orig, dest, idx=0)[source]¶ Connection between two Places that Things may travel along.
Portals are one-way, but you can make one appear two-way by setting the
symmetrical
key toTrue
, eg.character.add_portal(orig, dest, symmetrical=True)
. The portal going the other way will appear to have all the stats of this one, and attempting to set a stat on it will set it here instead.-
character
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
destination
¶ Return the Place object at which I end
-
engine
¶ attrgetter(attr, …) –> attrgetter object
Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter(‘name’), the call f(r) returns r.name. After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date). After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns (r.name.first, r.name.last).
-
origin
¶ Return the Place object that is where I begin
-
reciprocal
¶ If there’s another Portal connecting the same origin and destination that I do, but going the opposite way, return it. Else raise KeyError.
-
rule¶
The fundamental unit of game logic, the Rule, and structures to store and organize them in.
A Rule is three lists of functions: triggers, prereqs, and actions. The actions do something, anything that you need your game to do, but probably making a specific change to the world model. The triggers and prereqs between them specify when the action should occur: any of its triggers can tell it to happen, but then any of its prereqs may stop it from happening.
Rules are assembled into RuleBooks, essentially just lists of Rules that can then be assigned to be followed by any game entity – but each game entity has its own RuleBook by default, and you never really need to change that.
-
class
LiSE.rule.
AllRules
(engine)[source]¶ A mapping of every rule in the game.
You can use this as a decorator to make a rule and not assign it to anything.
-
class
LiSE.rule.
Rule
(engine, name, triggers=None, prereqs=None, actions=None, create=True)[source]¶ A collection of actions, being functions that enact some change on the world, which will be called each tick if and only if all of the prereqs return True, they being boolean functions that do not change the world.
-
class
LiSE.rule.
RuleBook
(engine, name)[source]¶ A list of rules to be followed for some Character, or a part of it anyway.
-
class
LiSE.rule.
RuleFollower
[source]¶ Interface for that which has a rulebook associated, which you can get a
RuleMapping
into
-
class
LiSE.rule.
RuleFuncList
(rule)[source]¶ Abstract class for lists of functions like trigger, prereq, action
-
class
LiSE.rule.
RuleFuncListDescriptor
(cls)[source]¶ Descriptor that lets you get and set a whole RuleFuncList at once
-
class
LiSE.rule.
RuleMapping
(engine, rulebook)[source]¶ Wraps a
RuleBook
so you can get its rules by name.You can access the rules in this either dictionary-style or as attributes. This is for convenience if you want to get at a rule’s decorators, eg. to add an Action to the rule.
Using this as a decorator will create a new rule, named for the decorated function, and using the decorated function as the initial Action.
Using this like a dictionary will let you create new rules, appending them onto the underlying
RuleBook
; replace one rule with another, where the new one will have the same index in theRuleBook
as the old one; and activate or deactivate rules. The name of a rule may be used in place of the actual rule, so long as the rule already exists.
query¶
The query engine provides Pythonic methods to access the database.
This module also contains a notably unfinished implementation of a query
language specific to LiSE. Access some stats using entities’ method
historical
, and do comparisons on those, and instead of a boolean
result you’ll get a callable object that will return an iterator over
turn numbers in which the comparison evaluated to True
.
-
class
LiSE.query.
QueryEngine
(dbstring, connect_args, alchemy, pack=None, unpack=None)[source]¶ -
exception
IntegrityError
¶
-
exception
OperationalError
¶
-
exist_edge
(character, orig, dest, idx, branch, turn, tick, extant=None)[source]¶ Declare whether or not this edge exists.
-
exception
-
LiSE.query.
slow_iter_turns_eval_cmp
(qry, oper, start_branch=None, engine=None)[source]¶ Iterate over all turns on which a comparison holds.
This is expensive. It evaluates the query for every turn in history.