Add markdown documentation
This commit is contained in:
34
Docs/OLD/Attention Lock.md
Normal file
34
Docs/OLD/Attention Lock.md
Normal file
@@ -0,0 +1,34 @@
|
||||
### Attention Lock
|
||||
|
||||
Note: at this time, none of the following is implemented.
|
||||
|
||||
Attention lock is a new mechanism that is used when you want to force the player to give his *undivided* attention to a single activity. Attention lock is particularly relevant for turn-based combat. Let’s say you have a turn-based combat in progress. You don’t want the player to wander away and grow flax when it’s his turn to attack.
|
||||
|
||||
The attention lock mechanism can affect the following aspects of the game:
|
||||
|
||||
- Stops the player from walking around (or walking away).
|
||||
- Stops the player from clicking on unrelated sprites.
|
||||
- Hides the gui interfaces of unrelated sprites.
|
||||
- Forces the gui of a sprite to appear even if the user didn’t click on that sprite.
|
||||
- Directs the camera to point at a specific place, or a specific object.
|
||||
|
||||
## Enabling Attention Lock
|
||||
|
||||
The mechanism is as follows: the player sprite has a single field, *actor.attention*, which is a pointer to a sprite that is trying to hold the player’s attention. There is a second field, *actor.attentionID*, which must be equal to *place.attentionID* of the attention-holding sprite. If *attentionID* doesn’t match, then *actor.attention* field is considered no longer valid, and the attention is considered to be not held. With that protocol, it is easy to implement these functions:
|
||||
|
||||
- function attentionClear(place)
|
||||
|
||||
- Release the attention of all sprites paying attention to place.
|
||||
- Implementation: set attentionID to a new unique ID.
|
||||
|
||||
- function attentionHolder(actor)
|
||||
|
||||
- Return the ID of the sprite holding actor’s attention.
|
||||
- Implementation: returns actor.attention after verifying attentionID match.
|
||||
|
||||
- function attentionGrab(place, actor):
|
||||
|
||||
- Cause place to grab the attention of actor.
|
||||
- Implementation: sets actor.attention to place, copies attentionID to actor.
|
||||
|
||||
This is designed to be resilient to bugs: let’s say a battleground is holding the attention of some actor. If the battleground gets bulldozed, attention is implicitly released. Or if the battleground starts a new battle, attention of previous combatants would be implicitly released. In short, it should be pretty easy to clean up messes caused by buggy sprites grabbing attention.
|
||||
34
Docs/OLD/Combat Systems_ JRPG co-op.md
Normal file
34
Docs/OLD/Combat Systems_ JRPG co-op.md
Normal file
@@ -0,0 +1,34 @@
|
||||
## Mechanisms Discussed:
|
||||
|
||||
- Battlegrounds - using a sprite to implement combat.
|
||||
- Battle friends - how the friend system (separate) might designate “battle friends.”
|
||||
- Camera lock - a means where a sprite can force the camera to look in a specific place.
|
||||
- Attention lock - a means where a sprite can prevent a player from doing anything else.
|
||||
|
||||
Battlegrounds:
|
||||
|
||||
The JRPG combat system expects the god-mode player to build “battleground” in various places throughout the world. A “battleground” marks a physical place where combat can take place, and it defines the parameters of that combat. The battleground sprite contains all the combat-related scripts.
|
||||
|
||||
Every NPC that can fight names a single combat arena. If a player picks a fight with that NPC, then the battle takes place in the specified arena. The players automatically run (or get teleported) to the left side of the arena, and the NPC runs to the right side of the arena, and the battle takes place.
|
||||
|
||||
Combatant Selection:
|
||||
|
||||
The initial step of the combat is that a *single* player picks a fight with a *single* NPC. But the battleground object then drags additional NPCs and players into the fight.
|
||||
|
||||
NPCs: the battleground scans the vicinity for other NPCs that are linked to the battleground. It brings in any other NPC linked to that battleground. There may be additional rules that govern this.
|
||||
|
||||
Players: the battleground scans the area for other players that are “battle friends” with the player. It picks the closest ones, and brings them into combat. If that isn’t enough people on the player side, the battleground scans for non-friend players and brings them in instead.
|
||||
|
||||
Sometimes, the battleground might want to draw another player into the combat, but it might not be able to, because that other player is “too busy.” For example, the other player might already be involved in a different combat.
|
||||
|
||||
The friend system is also a plugin. The friend system plugin should be required to export a function “is_battle_friend” to make it possible for the combat plugin to interface with the friend system plugin.
|
||||
|
||||
Attention Lock:
|
||||
|
||||
When the player enters a combat, the battleground puts the player into “attention lock.” Attention lock is intended for activities where the player is supposed to give his full attention to the activity, and not do other things at the same time. There is a separate document that describes attention lock in greater detail. The attention lock mechanism is used to prevent the player from walking away from the combat, and prevents him from growing flax or doing other irrelevant activities while combat is in progress.
|
||||
|
||||
Turn-Based Combat:
|
||||
|
||||
In this combat system, all players move at the same time, then, all NPCs go at the same time. The players have 10 seconds to specify which attack they want to use. If a player fails to specify an attack in 10 seconds, then a simple combat AI takes over and makes a choice for them. The goal of the combat AI is to give players whose connection is lagging a fair chance.
|
||||
|
||||
When the 10 seconds are up, the battleground animates the combat round: it shows the players attacking one by one, then it shows the monsters attacking. The battleground sprite controls all the animation during this period.
|
||||
17
Docs/OLD/Configurable Elements.md
Normal file
17
Docs/OLD/Configurable Elements.md
Normal file
@@ -0,0 +1,17 @@
|
||||
This document lists all the configurable elements in the game.
|
||||
|
||||
The engine has a list of plugins that *must* be provided in order for the game to be operational. For example. you *must* choose a combat system plugin. The plugin is a lua file. When you select a lua file to fulfill the combat system requirement, the lua file is checked to verify that it defines all the functions that a combat system must define. For most plugin slots, a null plugin is available - for example, a “no combat” combat system plugin.
|
||||
|
||||
Combat System: a Plugin.
|
||||
|
||||
Friend System: a Plugin.
|
||||
|
||||
- Must export a function “battle_partner(A,B)” that returns true if player A has volunteered to help player B win fights. This exported function may be used by the combat system plugin.
|
||||
|
||||
Camera Control: Manually controlled, but can be overridden by sprites
|
||||
|
||||
- The camera system is an interactive camera control system like in the original Tale engine. (Not necessarily the same interactive control system). It’s mostly unscripted, but sprites can take control when they want to. This will involve some set of flags that I haven’t figured out yet.
|
||||
|
||||
Skill Tree: a Database of Skills
|
||||
|
||||
- Skill trees are a hardwired part of the game. Any particular game can choose not to use the skill tree system, or to have an empty skill tree, but the skill tree system’s code is always loaded.
|
||||
43
Docs/OLD/Design Decisions.md
Normal file
43
Docs/OLD/Design Decisions.md
Normal 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, 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.
|
||||
25
Docs/OLD/Hard Problem List.md
Normal file
25
Docs/OLD/Hard Problem List.md
Normal file
@@ -0,0 +1,25 @@
|
||||
### Solutions to Hard Problems
|
||||
|
||||
**Saving the Game:** This is accomplished by serializing the lua state using eris, and serializing the rest of the C++ data structures the usual way.
|
||||
|
||||
**Snapshotting for Client-Side Prediction:** we serialize the synchronous world model (using the save-game serialization code) to save it. Then we apply predictive commands, and it becomes the asynchronous model. When necessary, we roll it back to its synchronous state.
|
||||
|
||||
### []() Solutions we Didn’t Use
|
||||
|
||||
**Snapshotting Lua:** the function lua_newstate accepts a memory allocation function as a parameter. Using this hook, we can keep track of every block of memory that lua allocates. To snapshot lua’s state, it’s sufficient to memcpy all its memory blocks into a temporary buffer. To restore lua’s state, memcpy everything back, and also restore the heap to the state it was in. We built a proof-of-concept of this and it works. We could use this on the client side for asynchronous/synchronous work, instead of using eris serialization.
|
||||
|
||||
**Collision Detection:** We could have a function that is a bit different on the client vs. server. On the server:
|
||||
|
||||
```cpp
|
||||
bool TryEnter(Location OldLoc, Location NewLoc)
|
||||
```
|
||||
|
||||
And on the client:
|
||||
|
||||
```cpp
|
||||
void TryEnter(Location OldLoc, Location NewLoc, Location &NewLocMod)
|
||||
// NewLocMod will always be set to a value where the server version of this call will
|
||||
// succeed, or to OldLoc.
|
||||
```
|
||||
|
||||
We could have a data structure that is a pancake stack of heightfields. The area between odd and even heightfields is enterable. Given an x,y,z coordinate, it is easy to find the x,y,z’ coordinate that represents the floor. The resolution on the client will be higher of course.
|
||||
34
Docs/OLD/Recursion-Free Difference Transmission.md
Normal file
34
Docs/OLD/Recursion-Free Difference Transmission.md
Normal file
@@ -0,0 +1,34 @@
|
||||
## Definitions
|
||||
|
||||
- Synchronous Models and Connections have a one-to-one mapping. The terms are used interchangeably.
|
||||
- Sprites are objects in the 3D world. Each has a primary table associated with it.
|
||||
- Tables are Lua Tables. The runtime assigns each a two-part ID consisting of a Sprite ID and a Table Index that starts at 1 for a Sprite’s Primary Table.
|
||||
|
||||
**Synchronous Models** - Each has a few values within it, which are not directly accessible from Lua:
|
||||
|
||||
- Position (Plane, X, Y, Z)
|
||||
- SpriteID - If present, the connection’s Position gets updated periodically based on the Position of the Sprite
|
||||
|
||||
**Sprites** - These also have a few values which are not directly accessible from Lua:
|
||||
|
||||
- Position (Plane, X, Y, Z)
|
||||
- Sprite ID
|
||||
- NextTableID
|
||||
|
||||
**Tables** - Each table has a mode with hints to the difference transmitter when it’s OK to suppress it from a synchronous model. Each Table contains a two part ID consisting of a Sprite ID and a Table Index. A Table has an inferred position based on it’s Sprite ID. Some modes are:
|
||||
|
||||
- A: Never Suppress (A Global Table)
|
||||
- B: Always Suppress (A Secret Table)
|
||||
- C: Suppress from SM’s that are far away (A Sprite’s Primary Table, a Player’s publicly viewable data)
|
||||
- D: Suppress when a connection’s SpriteID differs from the Table’s Sprite ID (A player’s sensitive data)
|
||||
- E: Call the Table.Transmit(OtherSpriteID) to determine whether to transmit. (Does Lua have a way to make a const call that prohibits storing data in any table fields?)
|
||||
|
||||
**Table Creation** - I am assuming that whichever version of GUI->MethodCall we use there will be the notion of “Actor” and “Place” as in our old engine. The default mode of a table is:
|
||||
|
||||
- When Place is the same as Actor: D
|
||||
- When Place is different from Actor: C
|
||||
|
||||
**Difference Transmitter Manipulation** - Designers can explicitly override the default mode of a Table with an intrinsic function:
|
||||
|
||||
- SetDiffMode(Table,Mode)
|
||||
- SetOwner(Table,Sprite)
|
||||
15
Docs/OLD/Skills and Skill Trees.md
Normal file
15
Docs/OLD/Skills and Skill Trees.md
Normal file
@@ -0,0 +1,15 @@
|
||||
Every game has a database of possible skills. The database can be edited on the fly.
|
||||
|
||||
Skills have:
|
||||
|
||||
- Name: eg, “handgun accuracy”
|
||||
- Point cost: how many skill points do you need to increment this skill. Note that the game can bypass the point system by procedurally incrementing the player’s skill.
|
||||
- Maximum skill level: how high can this skill be incremented. Again, the game can bypass this by procedurally incrementing the player’s skill.
|
||||
- A graphical icon representing the skill.
|
||||
- Prerequisites list: other skills you have to have before incrementing this skill.
|
||||
|
||||
The skill tree isn’t hardwired into code. Instead, there’s an in-game skill tree editor which you can use when you’re in god mode. We should also provide facilities so that two different games can easily share a skill tree.
|
||||
|
||||
The engine should provide a built-in character progression screen, so that the player can spend skill points to advance along the skill tree.
|
||||
|
||||
When a player comes into a game, he brings his skills with him. There are two preliminary checks: first, that he hasn’t spent too many skill points. Second, every skill he has is checked against the skill tree. If he has acquired a skill in violation of the prerequisites, then that skill is “greyed out” until he buys the prerequisites.
|
||||
Reference in New Issue
Block a user