## Login System

When you first connect to the server, the server calls *World::create_login_actor()* on the master world model. This creates a tangible of class *login*. This login tangible becomes the actor until further notice. On the server side, the ID of this actor is associated with the connection. This ID is also forwarded to the client so that the client may know its actor ID.

The *login* is an actor like any other actor. In theory, it’s perfectly possible for the *login* to walk around and interact with objects. However, it’s more commonly the case that the login script prompts the player for a username and password. The login script then uses the lua *redirect(old_actor_id, new_actor_id)* command [not implemented yet].

In standalone mode, the standalone client mimics this sequence.

## Current Actor, Current Place, Current ID Player Pool flag.

Before a thread is awakened (by calling ‘lua_resume’ or ‘lua_pcall’ from C), the actorid and placeid are is stored in World::lthread_actor_id and World::lthread_place_id. As soon as lua_resume or lua_pcall returns, these two variables are cleared. That way, whenever any thread is running, those two variables contain the current actor and place. These two variables can be fetched using the lua functions tangible.actor and tangible.place.

Of course, the lua thread scheduling code (which is responsible for calling lua_resume) needs to know the actorid and placeid in order to be able to put them into World::lthread_actor_id and World::lthread_place_id. That is possible because the thread info table stores the actor and implicitly the place.

In addition to “current actor” and “current place,” we also store “current ID player pool flag.” This flag determines whether a thread uses the player’s ID pool, or the global ID pool to allocate IDs. In general, a thread uses the player pool if it’s just been awakened by “invoke_plan”. It uses the global pool if it’s been awakened by the system clock (ie, after a “wait” statement). This flag is in World::lthread_use_ppool, and in the thread info table.

## Deleted Tangibles and Tangible Garbage Collection

Tangibles can be in three states: “created”, “deleted,” and “nothing”. When a tangible is in the created state,, the following things are true:

- There’s a lua portion of the tangible.
- There’s a C++ portion of the tangible.
- The lua portion has a class, a metatable, and several important fields.

When a tangible is in the deleted state, the following things are true:

- There’s still a lua portion, but it’s minimal.
- There’s no C++ portion of the tangible.
- The lua portion still has a class and a metatable, but it’s mostly blank and writes are forbidden.

When a tangible is in the nothing state, nothing is stored. No lua portion, no C++ portion.

The function LuaStack::maketan retrieves a tangible. If that tangible doesn’t exist, it creates a tangible in the deleted state and returns that.

The function World::tangible_make creates a tangible. If a deleted tangible with the same ID already exists, that deleted tangible is converted into a created tangible. The function World::tangible_delete transforms a created tangible into a deleted tangible.

We’re going to have to write our own garbage collector to convert deleted tangibles into nothing tangibles only when there are no references to the deleted tangible.

## Makeclass

We’re going to store a table in the registry, “classes”, that maps names to class tables. When you call makeclass, it creates a class in this table and copies it into the global environment. If for some reason the global environment gets trashed, the “classes” table in the registry will still be good. In this way, we can guarantee that the class of a given name is really a unique table.

If we want class tables to be garbage collected (as opposed to just cleared), we’re going to have to write our own garbage collector to handle that.
