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 a with block, in which deserialized entities will be created as needed.

coinflip()[source]

Return True or False with equal probability.

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 with d 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 with d sides, sum them, and return whether they are <= target.

If comparator is provided, use it instead of <=. You may use a string like ‘<’ or ‘>=’.

loading()[source]

Context manager for when you need to instantiate entities upon unpacking

percent_chance(pct)[source]

Given a pct``% chance of something happening right now, decide at random whether it actually happens, and return ``True or False as appropriate.

Values not between 0 and 100 are treated as though they were 0 or 100, whichever is nearer.

roll_die(d)[source]

Roll a die with d faces. Return the result.

class LiSE.engine.DummyEntity(engine)[source]

Something to use in place of a node or edge

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 and turn 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 turn
  • character: A mapping of Character 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 return True 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 PlaceMapping(character)

Place objects that are in a 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).

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 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 my orig.

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 ThingMapping(character)

Thing objects that are in a 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).

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 or Place in a different Character.

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 keyword symmetrical == True, a mirror-Portal will be placed in the opposite direction between the same nodes. It will always appear to have the placed Portal’s stats, and any change to the mirror Portal’s stats will affect the placed Portal.

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 to True, all the Portal 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 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 to True, 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

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 the Portal connecting the one Place 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 a Portal direct to the given Place, schedule myself to travel to the given Place, taking an amount of time indicated by the weight stat on the Portal, if given; else 1 turn.

Return the number of turns the travel will take.

location

The Thing or Place 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 my Character. In either case, however, I will attempt to actually follow the path using my Character, which might not be possible if the supplied graph and my Character are too different. If it’s not possible, I’ll raise a TravelException, whose subpath attribute holds the part of the path that I can follow. To make me follow it, pass it to my follow_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 up name in my character 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

close()[source]

Commit changes and close the database.

critical(msg)[source]

Log a message at level ‘critical’

debug(msg)[source]

Log a message at level ‘debug’

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

error(msg)[source]

Log a message at level ‘error’

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.

info(msg)[source]

Log a message at level ‘info’

new_character(name, data=None, **kwargs)[source]

Create and return a new Character.

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

warning(msg)[source]

Log a message at level ‘warning’

class LiSE.engine.FinalRule[source]

A singleton sentinel for the rule iterator

exception LiSE.engine.InnerStopIteration[source]
class LiSE.engine.NextTurn(engine)[source]

Make time move forward in the simulation.

Calls advance repeatedly, returning a list of the rules’ return values.

I am also a Signal, so you can register functions to be called when the simulation runs. Pass them to my connect method.

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 and place are subsets of node
  • edge, adj, and succ are aliases of portal
  • pred is an alias to preportal
  • 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.

copy_from(g)[source]

Copy all nodes and edges from the given graph into this.

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).

grid_2d_8graph(m, n)[source]

Make a 2d graph that’s connected 8 ways, enabling diagonal movement

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 the RuleBook 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 or False, 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 PlaceMapping(character)[source]

Place objects that are in a 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).

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 Predecessors(container, dest)[source]

Mapping of possible origins from some destination.

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).

static send(self, **kwargs)[source]

Call all listeners to dest and to my orig.

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 ThingMapping(character)[source]

Thing objects that are in a 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).

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_avatar(a, b=None)[source]

Start keeping track of a Thing or Place in a different Character.

add_places_from(seq, **attrs)[source]

Take a series of place names and add the lot.

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 keyword symmetrical == True, a mirror-Portal will be placed in the opposite direction between the same nodes. It will always appear to have the placed Portal’s stats, and any change to the mirror Portal’s stats will affect the placed Portal.

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 to True, all the Portal 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

avatars()[source]

Iterate over all my avatars, regardless of what character they are in.

del_avatar(a, b=None)[source]

This is no longer my avatar, though it still exists on its own.

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.

portals()[source]

Iterate over all portals.

pred_cls

alias of Character.PortalPredecessorsMapping

thing2place(name)[source]

Unset a Thing’s location, and thus turn it into a Place.

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 StatMapping(facade)[source]
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 LiSE.character.FacadeEntity(mapping, **kwargs)[source]
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 type innercls.

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.FacadePortalMapping(facade)[source]
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.FacadeThing(mapping, real_or_name, **kwargs)[source]
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).

clear()[source]

Delete everything

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).

new_thing(name, **stats)[source]

Create a new thing, located here, and return it.

one_way(other, **stats)[source]

Connect a portal from here to another node, and return it.

one_way_portal(other, **stats)[source]

Connect a portal from here to another node, and return it.

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 if dest is not a node in my character or the name of one.

portal

Return a mapping of portals connecting this node to its neighbors.

portals()[source]

Iterate over Portal objects that lead away from me

predecessors()[source]

Iterate over nodes with edges leading here from there.

preportals()[source]

Iterate over Portal objects that lead to me

shortest_path(dest, weight=None)[source]

Return a list of node names leading from me to dest.

Raise ValueError if dest 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 if dest is not a node in my character or the name of one.

successor

Return a mapping of portals connecting this node to its neighbors.

successors()[source]

Iterate over nodes with edges leading from here to there.

two_way(other, **stats)[source]

Connect these nodes with a two-way portal and return it.

two_way_portal(other, **stats)[source]

Connect these nodes with a two-way portal and return it.

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).

delete()[source]

Remove myself from the world model immediately.

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.

clear()[source]

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()[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 the Portal connecting the one Place 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 a Portal direct to the given Place, schedule myself to travel to the given Place, taking an amount of time indicated by the weight stat on the Portal, if given; else 1 turn.

Return the number of turns the travel will take.

location

The Thing or Place 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 my Character. In either case, however, I will attempt to actually follow the path using my Character, which might not be possible if the supplied graph and my Character are too different. If it’s not possible, I’ll raise a TravelException, whose subpath attribute holds the part of the path that I can follow. To make me follow it, pass it to my follow_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 to True, 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()[source]

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()[source]

Return a deep copy of myself as a dict, and unwrap any wrapper objects in me.

update(d)[source]

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 LiSE.portal.RuleMapping(portal)[source]

Mapping to get rules followed by a portal.

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.ActionList(rule)[source]

A list of action functions for rules

class LiSE.rule.AllRuleBooks(engine)[source]
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.

new_empty(name)[source]

Make a new rule with no actions or anything, and return it.

class LiSE.rule.PrereqList(rule)[source]

A list of prereq functions for rules

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.

action(fun)[source]

Decorator to append the function to my actions list.

always()[source]

Arrange to be triggered every tick, regardless of circumstance.

duplicate(newname)[source]

Return a new rule that’s just like this one, but under a new name.

prereq(fun)[source]

Decorator to append the function to my prereqs list.

trigger(fun)[source]

Decorator to append the function to my triggers list.

class LiSE.rule.RuleBook(engine, name)[source]

A list of rules to be followed for some Character, or a part of it anyway.

index(value[, start[, stop]]) → integer -- return first index of value.[source]

Raises ValueError if the value is not present.

insert(i, v)[source]

S.insert(index, value) – insert value before index

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

append(v)[source]

S.append(value) – append value to the end of the sequence

index(value[, start[, stop]]) → integer -- return first index of value.[source]

Raises ValueError if the value is not present.

insert(i, v)[source]

S.insert(index, value) – insert value before index

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 the RuleBook 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.

class LiSE.rule.TriggerList(rule)[source]

A list of trigger functions for rules

LiSE.rule.roundtrip_dedent(source)[source]

Reformat some lines of code into what unparse makes.

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.

exist_node(character, 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.

initdb()[source]

Set up the database schema, both for allegedb and the special extensions for LiSE

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.

LiSE.query.windows_intersection(windows)[source]

Given a list of (beginning, ending), return another describing where they overlap.

Return type:list
LiSE.query.windows_union(windows)[source]

Given a list of (beginning, ending), return a minimal version that contains the same ranges.

Return type:list