[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [glob2-devel] proposed state machine for the building life cycle
From: |
Joe Wells |
Subject: |
Re: [glob2-devel] proposed state machine for the building life cycle |
Date: |
Mon, 30 Apr 2007 19:15:10 +0100 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) |
Dear Globulation 2 gurus,
Okay, I have revised my proposal for a state machine for the building
life cycle. There were some single-letter names that I have expanded
into self-describing words. I have made the notation more C++-like.
I have added more explanations. I have also fixed a bug where the
older version of this proposal didn't actually solve the
building-site-abuse problem; it does solve this problem now.
The technical details follow below.
Comments are welcome! Is this a good idea or does it suck?
Joe
----------------------------------------------------------------------
Here is a suggested state machine for the building life cycle. This
proposal solves a number of problems with the previous system:
1. Clearing is automatically requested for new buildings and upgrades
that will make larger buildings, saving the user from the pain of
setting clearing areas and flags before starting construction.
2. The user can request direct construction to any desired level
without stopping at the intervening levels.
3. This proposal solves the bug where upgrading is silently canceled
when resources grow on the larger area needed before all the
globules are out of the building and out of the larger area.
4. Abuse of construction sites is impossible, because the building
does not occupy any space until the first resources are supplied.
5. Visually distracting forbidden/guard/clearing areas are removed
from the areas occupied by buildings.
6. This proposal has a clean, precise semantics which is likely to
lead to fewer bugs (e.g., it would probably have helped avoid the
repair crash bug in glob2 version 0.8.22, because the desiredLevel
and currentLevel values are tracked separately).
7. In the new system, all of the different levels of a kind of
building are now considered to have the same type, whereas in the
previous system, they are all different types. This will make it
easier to develop new features.
8. There is no need to repair before upgrading (is there now?), as the
needed amount of resources will be calculated correctly.
9. Attempts to build on unsuitable territory (which can happen when
requesting a building site on undiscovered territory) are properly
cleaned up once the unsuitability is discovered. (In the previous
system sometimes a forbidden area is left behind.)
This proposal has benefited from comments by Eli Dupree, Leo, Kai, and
Xylix.
The proposed new system is as follows.
Each building B has several adjustable values associated with it: its
type (B.buildingType), its state (B.constructionState), two levels
(B.currentLevel and B.desiredLevel), and its number of requested
workers (B.requestedWorkers). During ordinary use, B.currentLevel ==
B.desiredLevel. It is only during the construction/upgrade/repair
process that B.currentLevel can differ from B.desiredLevel. Each
building also has two sets of resources: its construction resources
(all the resources used so far to build and upgrade it), and its
supply resources (the resources gathered for ordinary use of the
building). While in any state, as hitpoints are lost due to damage,
the construction resources of the building are reduced appropriately.
There is a table Work such that Work(T,S,L) gives the number of
workers to use for a building of type T in state S at level L. (For
the state USE (see more on this state below), Work(T,USE,L) should
only be non-zero for buildings that need workers to supply them during
ordinary use.)
There is a table Area such that Area(T,L) gives the space used by a
building of type T at level L. It must be the case that Area(T,0) is
the empty area for every building type T (i.e., zero-level buildings
occupy no space).
(Although I am writing “Work” and “Area” as though they were
functions, precisely how they is implemented is outside the scope of
this proposal.)
Let currentArea(B) == Area(B.buildingType,B.currentLevel).
Let desiredArea(B) == Area(B.buildingType,B.desiredLevel).
A new building B starts with B.constructionState = CLEARING, with
B.currentLevel = 0 (meaning the building does not yet exist), with no
resources (construction or supply), and with a target level
B.desiredLevel ≥ 1.
The possible values of B.constructionState are CLEARING, SHOOING,
GROUNDBREAKING, CONSTRUCTION, USE, and EMPTYING. The behavior in each
different state is defined as follows:
CLEARING (surveying the land and clearing resources):
The purpose of this state is to clear the land so construction can
begin.
While in this state, the building occupies the area given by
currentArea(B). (If B.currentLevel == 0, this must be no area at
all, and workers/warriors can walk on it and resources can grow on
it. In this case, it is probably desirable to show a ghost of the
size desiredLevel version so the user can see what they have
requested and have something to click on to see and adjust the
status.) Upon entry into this state, clearing cells are placed and
all forbidden or guard cells are removed on the area given by
desiredArea(B). Upon exit from this state, all
forbidden/guard/clearing cells are removed on the area given by
desiredArea(B).
While in this state, the building site acts like a clearing flag,
summoning a number of workers given by B.requestedWorkers, which is
set to Work(B.buildingType, CLEARING, B.desiredLevel) upon entry
into this state.
If all the resources are cleared and all the area is discovered and
is grass with no other buildings on it, then the building switches
to B.constructionState = SHOOING. If construction is canceled, or
unclearable resources (e.g., stone) or unsuitable land (sand/water)
are found on the area (perhaps a new building was requested on
unknown territory), or a conflicting building is found (perhaps an
enemy is also building here), then the building switches to
B.constructionState = USE, with the value of B.desiredLevel changing
to be the same as B.currentLevel (i.e., the building reverts to the
old level, or disappears if the old level is zero).
SHOOING (shooing the workers and warriors):
The purpose of this state is to get globules out of the way so
construction can begin.
While in this state, the building occupies the area given by
currentArea(B). (See comment for state CLEARING regarding the
B.currentLevel == 0 case.) Upon entry into this state, forbidden
and clearing cells are placed and all guard cells are removed on the
area given by desiredArea(B). Upon exit from this state, all
forbidden/guard/clearing cells are removed on the area given by
desiredArea(B).
If all the workers and warriors exit the area, the building switches
to B.constructionState = CONSTRUCTION. If any resources grow on the
area, the building switches to B.constructionState = CLEARING. If
construction is canceled, the building switches to
B.constructionState = USE, with the value of B.desiredLevel changing
to be the same as B.currentLevel (i.e., the building reverts to the
old level, or disappears if the old level is zero).
GROUNDBREAKING (applying the first resources to an enlarged area):
The purpose of this state is the same as the purpose of the
subsequent CONSTRUCTION: to get resources and use them for building.
The important difference between this state and CONSTRUCTION is the
area used by the building, which remains the old area until the
first resources are applied (thereby solving the building-site-abuse
problem).
While in this state, the building occupies the area given by
currentArea(B). (See comment for state CLEARING regarding the
B.currentLevel == 0 case.) Upon entry into this state, forbidden
and clearing cells are placed and all guard cells are removed on the
area given by desiredArea(B). Upon exit from this state, all
forbidden/guard/clearing cells are removed on the area given by
desiredArea(B).
While in this state, the building summons workers to bring it
resources to increase its construction resources to the level
required for a building of type B.buildingType and level
B.desiredLevel. The number of workers summoned is given by
B.requestedWorkers, which is set to Work(B.buildingType,
GROUNDBREAKING, B.desiredLevel) upon entry into this state.
If the building has any more construction resources than needed for
a building of type B.buildingType and level B.currentLevel (and this
may already be the case upon entry to this state if earlier canceled
upgrading is being resumed), then the building switches to
B.constructionState = CONSTRUCTION. If construction is canceled,
the building switches to B.constructionState = USE, with the value
of B.desiredLevel changing to be the same as B.currentLevel (i.e.,
the building reverts to the old level, or disappears if the old
level is zero).
CONSTRUCTION (building):
The purpose of this state is to get resources and use them for
building.
While in this state, the building occupies the area given by
desiredArea(B).
While in this state, the building summons workers to bring it
resources to increase its construction resources to the level
required for a building of type B.buildingType and level
B.desiredLevel. The number of workers summoned is given by
B.requestedWorkers, which is set to Work(B.buildingType,
CONSTRUCTION, B.desiredLevel) upon entry into this state.
If all the needed resources arrive, the building switches to
B.constructionState = USE, with the value of B.currentLevel changing
to be the same as B.desiredLevel (i.e., the new level has been
achieved). If construction is canceled, the building switches to
B.constructionState = USE, with the value of B.desiredLevel changing
to be the same as B.currentLevel (i.e., the building reverts to the
old level, or disappears if the old level is zero). (If
construction is canceled, the construction resources accumulated are
remembered, so one can restart an upgrade or repair later and
continue from where one left off.)
USE (use):
This is the state for normal use.
Upon entry to this state, B.desiredLevel and B.currentLevel must
have the same value. Upon entry to this state, if B.desiredLevel ==
B.currentLevel == 0, then the building disappears. (This happens if
you cancel construction on a new building before ever entering state
USE. In this case you lose any resources gathered so far.) While
in this state, the building occupies the area given by
desiredArea(B) == currentArea(B).
While in this state, the building summons to supply it the number of
workers given by B.requestedWorkers, which is set to
Work(B.buildingType, USE, B.currentLevel) upon entry into this
state.
If repair is requested, the building switches to B.constructionState
= EMPTYING (and B.desiredLevel remains the same as B.currentLevel).
If upgrade to level L > B.desiredLevel is requested, the building
switches to B.constructionState = EMPTYING with B.desiredLevel = L.
EMPTYING (emptying):
The purpose of this state is to wait for globules inside the
building to finish their feeding/healing/training so that
construction can begin.
While in this state, the building occupies the area given by
currentArea(B). Upon entry into this state, clearing cells are
placed and all forbidden or guard cells are removed on the area
given by desiredArea(B). Upon exit from this state, all
forbidden/guard/clearing cells are removed on the area given by
desiredArea(B).
In this state, the building waits for any globules inside to exit
and does not accept any new guests.
If the globules all exit, the building switches to
B.constructionState = CLEARING. If construction is canceled, the
building switches to B.constructionState = USE, with the value of
B.desiredLevel changing to be the same as B.currentLevel (i.e., the
building reverts to the old level).
(How the values in the table Work are determined is outside of the
scope of this proposal and is a completely separate issue. I suggest
the user interface should allow setting all of them separately. It
should be possible to solve problems like the fact that you currently
can not set the number of workers for a construction site of a new
building until the globules leave the construction location. Or the
fact that you can't set the number of workers while waiting for
globules to exit the building.)