Add markdown documentation

This commit is contained in:
2026-02-05 12:40:27 -05:00
parent f0228083c8
commit 12f8062d9a
22 changed files with 2853 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
## 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, its perfectly possible for the *login* to walk around and interact with objects. However, its 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 players ID pool, or the global ID pool to allocate IDs. In general, a thread uses the player pool if its just been awakened by “invoke_plan”. It uses the global pool if its 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:
- Theres a lua portion of the tangible.
- Theres 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:
- Theres still a lua portion, but its minimal.
- Theres no C++ portion of the tangible.
- The lua portion still has a class and a metatable, but its 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 doesnt 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.
Were 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
Were 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), were going to have to write our own garbage collector to handle that.