Merge branch 'develop' of github.com:simon-brooke/the-great-game into develop

This commit is contained in:
Simon Brooke 2024-04-03 12:06:59 +01:00
commit 05da0884c8
31 changed files with 937 additions and 431 deletions

2
.gitignore vendored
View file

@ -52,3 +52,5 @@ docs/cloverage/coverage.xml
src/cc/journeyman/the_great_game/cloverage.clj
.DS_Store
.portal/

491
LICENSE
View file

@ -1,214 +1,361 @@
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
### GNU GENERAL PUBLIC LICENSE
1. DEFINITIONS
Version 2, June 1991
"Contribution" means:
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
a) in the case of the initial Contributor, the initial code and
documentation distributed under this Agreement, and
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
b) in the case of each subsequent Contributor:
### Preamble
i) changes to the Program, and
The licenses for most software are designed to take away your freedom
to share and change it. By contrast, the GNU General Public License is
intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
ii) additions to the Program;
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates' from
a Contributor if it was added to the Program by such Contributor itself or
anyone acting on such Contributor's behalf. Contributions do not include
additions to the Program which: (i) are separate modules of software
distributed in conjunction with the Program under their own license
agreement, and (ii) are not derivative works of the Program.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the software, or if you modify it.
"Contributor" means any person or entity that distributes the Program.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
"Licensed Patents" mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
"Program" means the Contributions distributed in accordance with this
Agreement.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on,
we want its recipients to know that what they have is not the
original, so that any problems introduced by others will not reflect
on the original authors' reputations.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at
all.
2. GRANT OF RIGHTS
The precise terms and conditions for copying, distribution and
modification follow.
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly perform,
distribute and sublicense the Contribution of such Contributor, if any, and
such derivative works, in source code and object code form.
### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under
Licensed Patents to make, use, sell, offer to sell, import and otherwise
transfer the Contribution of such Contributor, if any, in source code and
object code form. This patent license shall apply to the combination of the
Contribution and the Program if, at the time the Contribution is added by the
Contributor, such addition of the Contribution causes such combination to be
covered by the Licensed Patents. The patent license shall not apply to any
other combinations which include the Contribution. No hardware per se is
licensed hereunder.
**0.** This License applies to any program or other work which
contains a notice placed by the copyright holder saying it may be
distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work
based on the Program" means either the Program or any derivative work
under copyright law: that is to say, a work containing the Program or
a portion of it, either verbatim or with modifications and/or
translated into another language. (Hereinafter, translation is
included without limitation in the term "modification".) Each licensee
is addressed as "you".
c) Recipient understands that although each Contributor grants the licenses
to its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other
intellectual property rights of any other entity. Each Contributor disclaims
any liability to Recipient for claims brought by any other entity based on
infringement of intellectual property rights or otherwise. As a condition to
exercising the rights and licenses granted hereunder, each Recipient hereby
assumes sole responsibility to secure any other intellectual property rights
needed, if any. For example, if a third party patent license is required to
allow Recipient to distribute the Program, it is Recipient's responsibility
to acquire that license before distributing the Program.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the Program
(independent of having been made by running the Program). Whether that
is true depends on what the Program does.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright license
set forth in this Agreement.
**1.** You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
3. REQUIREMENTS
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a
fee.
A Contributor may choose to distribute the Program in object code form under
its own license agreement, provided that:
**2.** You may modify your copy or copies of the Program or any
portion of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
**a)** You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
i) effectively disclaims on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of title
and non-infringement, and implied warranties or conditions of merchantability
and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and consequential
damages, such as lost profits;
**b)** You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any part
thereof, to be licensed as a whole at no charge to all third parties
under the terms of this License.
iii) states that any provisions which differ from this Agreement are offered
by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable manner on
or through a medium customarily used for software exchange.
**c)** If the modified program normally reads commands interactively
when run, you must cause it, when started running for such interactive
use in the most ordinary way, to print or display an announcement
including an appropriate copyright notice and a notice that there is
no warranty (or else, saying that you provide a warranty) and that
users may redistribute the program under these conditions, and telling
the user how to view a copy of this License. (Exception: if the
Program itself is interactive but does not normally print such an
announcement, your work based on the Program is not required to print
an announcement.)
When the Program is made available in source code form:
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
a) it must be made available under this Agreement; and
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
b) a copy of this Agreement must be included with each copy of the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
Contributors may not remove or alter any copyright notices contained within
the Program.
**3.** You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
Each Contributor must identify itself as the originator of its Contribution,
if any, in a manner that reasonably allows subsequent Recipients to identify
the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
**a)** Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections 1
and 2 above on a medium customarily used for software interchange; or,
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor who
includes the Program in a commercial product offering should do so in a
manner which does not create potential liability for other Contributors.
Therefore, if a Contributor includes the Program in a commercial product
offering, such Contributor ("Commercial Contributor") hereby agrees to defend
and indemnify every other Contributor ("Indemnified Contributor") against any
losses, damages and costs (collectively "Losses") arising from claims,
lawsuits and other legal actions brought by a third party against the
Indemnified Contributor to the extent caused by the acts or omissions of such
Commercial Contributor in connection with its distribution of the Program in
a commercial product offering. The obligations in this section do not apply
to any claims or Losses relating to any actual or alleged intellectual
property infringement. In order to qualify, an Indemnified Contributor must:
a) promptly notify the Commercial Contributor in writing of such claim, and
b) allow the Commercial Contributor to control, and cooperate with the
Commercial Contributor in, the defense and any related settlement
negotiations. The Indemnified Contributor may participate in any such claim
at its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If
that Commercial Contributor then makes performance claims, or offers
warranties related to Product X, those performance claims and warranties are
such Commercial Contributor's responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a
court requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.
**b)** Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your cost of
physically performing source distribution, a complete machine-readable
copy of the corresponding source code, to be distributed under the
terms of Sections 1 and 2 above on a medium customarily used for
software interchange; or,
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
appropriateness of using and distributing the Program and assumes all risks
associated with its exercise of rights under this Agreement , including but
not limited to the risks and costs of program errors, compliance with
applicable laws, damage to or loss of data, programs or equipment, and
unavailability or interruption of operations.
**c)** Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is allowed
only for noncommercial distribution and only if you received the
program in object code or executable form with such an offer, in
accord with Subsection b above.)
6. DISCLAIMER OF LIABILITY
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
7. GENERAL
**4.** You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt otherwise
to copy, modify, sublicense or distribute the Program is void, and
will automatically terminate your rights under this License. However,
parties who have received copies, or rights, from you under this
License will not have their licenses terminated so long as such
parties remain in full compliance.
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of the
remainder of the terms of this Agreement, and without further action by the
parties hereto, such provision shall be reformed to the minimum extent
necessary to make such provision valid and enforceable.
**5.** You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
If Recipient institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
(excluding combinations of the Program with other software or hardware)
infringes such Recipient's patent(s), then such Recipient's rights granted
under Section 2(b) shall terminate as of the date such litigation is filed.
**6.** Each time you redistribute the Program (or any work based on
the Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
All Recipient's rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and
does not cure such failure in a reasonable period of time after becoming
aware of such noncompliance. If all Recipient's rights under this Agreement
terminate, Recipient agrees to cease use and distribution of the Program as
soon as reasonably practicable. However, Recipient's obligations under this
Agreement and any licenses granted by Recipient relating to the Program shall
continue and survive.
**7.** If, as a consequence of a court judgment or allegation of
patent infringement or for any other reason (not limited to patent
issues), conditions are imposed on you (whether by court order,
agreement or otherwise) that contradict the conditions of this
License, they do not excuse you from the conditions of this License.
If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations,
then as a consequence you may not distribute the Program at all. For
example, if a patent license would not permit royalty-free
redistribution of the Program by all those who receive copies directly
or indirectly through you, then the only way you could satisfy both it
and this License would be to refrain entirely from distribution of the
Program.
Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be
modified in the following manner. The Agreement Steward reserves the right to
publish new versions (including revisions) of this Agreement from time to
time. No one other than the Agreement Steward has the right to modify this
Agreement. The Eclipse Foundation is the initial Agreement Steward. The
Eclipse Foundation may assign the responsibility to serve as the Agreement
Steward to a suitable separate entity. Each new version of the Agreement will
be given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the
Agreement under which it was received. In addition, after a new version of
the Agreement is published, Contributor may elect to distribute the Program
(including its Contributions) under the new version. Except as expressly
stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
licenses to the intellectual property of any Contributor under this
Agreement, whether expressly, by implication, estoppel or otherwise. All
rights in the Program not expressly granted under this Agreement are
reserved.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury trial
in any resulting litigation.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
**8.** If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
**9.** The Free Software Foundation may publish revised and/or new
versions of the General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Program does not specify a
version number of this License, you may choose any version ever
published by the Free Software Foundation.
**10.** If you wish to incorporate parts of the Program into other
free programs whose distribution conditions are different, write to
the author to ask for permission. For software which is copyrighted by
the Free Software Foundation, write to the Free Software Foundation;
we sometimes make exceptions for this. Our decision will be guided by
the two goals of preserving the free status of all derivatives of our
free software and of promoting the sharing and reuse of software
generally.
**NO WARRANTY**
**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
### END OF TERMS AND CONDITIONS
### How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
one line to give the program's name and an idea of what it does.
Copyright (C) yyyy name of author
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Also add information on how to contact you by electronic and paper
mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'. This is free software, and you are welcome
to redistribute it under certain conditions; type `show c'
for details.
The hypothetical commands \`show w' and \`show c' should show the
appropriate parts of the General Public License. Of course, the
commands you use may be called something other than \`show w' and
\`show c'; they could even be mouse-clicks or menu items--whatever
suits your program.
You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the program,
if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written
by James Hacker.
signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library,
you may consider it more useful to permit linking proprietary
applications with the library. If this is what you want to do, use the
[GNU Lesser General Public
License](https://www.gnu.org/licenses/lgpl.html) instead of this
License.

33
doc/Appraisal.md Normal file
View file

@ -0,0 +1,33 @@
# Appraisal
## What is Appraisal
There's an thing that all non player characters can do, which varies greatly from person to person, and which is of particular importance to merchants, and that is appraisal.
Each category of goods has different dimensions of quality. A sword may be evaluated, for example, on
| Dimension | Better is | Ease of appraisal |
| -------------------- | ---------------------------------- | ----------------- |
| Hardness | More | Difficult |
| Toughness | More | Difficult |
| Wear | Less | Intermediate |
| Weight | There's a sweet spot, but it's low | Easy |
| Length | Judgement call | Easy |
| Decoration/Showiness | Judgement call | Intermediate |
| Workmanship | Better | Intermediate |
A person learns to appraise the qualities of a sword by having direct experience of swords with a range of values for the particular quality. A person who's only ever handled one sword does not know whether that sword heavy or light, pristine or worn. However, once a person has handled a dozen swords of different weights, they'll have some idea of what weight an average sword is, even if their idea may actually be a little off. Weight and length are easy to assess.
Similarly, once someone has handled a few dozen swords with different degrees of wear, will have an idea of how many chips, how much corrosion or pitting, is normal. Wear is harder to assess, but it doesn't need particular techniques or skills to assess, just observation. To assess hardness, you really need to have sharpened the blade and then used it to the extent that it needs sharpening again, but if you've handled a lot of blades of varying qualities you may associate patterns in the steel, such as pattern welding, damascus steel, or a hamun, or particular markers' marks, with varying hardnesses. Toughness is even harder to assess (without actually chipping or breaking the blade) and is really going to come down to recognising either high quality steels or particular makers' marks.
## Developing appraisal skill
So: how does one gain experience? I'm going to assume that anyone who's bought a sword has handled it before making the choice. That anyone who's survived on the winning side f a battle unwounded will also have handled eight of each type of weapon used, for each such battle (the victors will have the pick of the spoils on the battlefield). That a weapon smith has handled sixteen for each year they've been working. And possibly that a master weapon smith will at least examine more weapons in a year than a journeyman, who will at least examing more than an apprentice. But, essentially, appraisal skill develops with exposure to items in the particular category. The exact mechanism for tracking this I'm unsure of, because there is a tradeoff between richness of records and data compactness, and this game looks like getting rather big.
Of course, some people may be more observant than others, so it's possible that some people may gain appraisal skill on the basis of less exposure than others. But at this moment that's not a thing I'm planning to model.
## What does appraisal skill buy you?
In any category of goods, some individual items are better than others, and this difference may be significant. A person with good appraisal skill will recognise this difference. So a person with good skills, offered two items at the same price, will be able to select the better one; if bargaining for an item, will be prepared to offer a higher price for the better one; if selling items, will be prepared to sell the better one only for a higher price.
Price arbitrage is how a static merchant makes money.

130
doc/Biomes and ecology.md Normal file
View file

@ -0,0 +1,130 @@
# Biomes and ecology
*The motivation for this document was to explain the mulberry trees in the Tcha valley, and think about why Tchahua is especially a centre for the silk trade*
## Broader geography
The broader geography of the world is not a matter for this document, but TODO: there isn't yet a document which usefully describes it, and there needs to be.
## Biomes relevant at this stage
### 1. Steppe
The centre of the continent is the steppe; it is generally too arid for forest growth, and is therefore scrub and grassland. There is one principal river system, which feeds into a marshland in the south, from which the water then goes underground beneath the limestone plateau to become the Tcha and Sind rivers. In late summer there's little water in the river, and few other waterholes. Antelope, camels, horses, goats, possibly sheep are native to the steppe, and there are probably something like leopards which predate on them, but I haven't fleshed it out.
Big dragons don't hunt on the steppe because they can't take off from flat ground, but smaller dragons may do so.
Settled by the steppe tribes, who are nomadic herders, extremely warlike but not technically highly developed. They are the game world's principle horse breeders. Basically in the game as I'm working on it at present, the player cannot go north across the steppe because the steppe tribes are too hostile.
A single major road, the Caravan Road, runs north to south across the steppe. There were in the past fortified caravanserrais along the length of the road, established and protected by Hans'hua, but they have been progressively overrun and destroyed by the steppe tribes and are now ruinous. Only one remains: the North Inn, just below the northern slope of the plateau. There is some limited horticulture on land close to the South Inn, supplying markets in Hans'hua.
### 2. Plateau
The limestone plateau runs along the whole of the southern edge of the steppe, from the western massif to the rim of the crater which forms The Great Place. It is a landscape of clints and grykes, on which nothing grows, and on which there is no water. It is about four day's journey by fast horse from north to south. The caravan road crosses the plateau from the North Inn to another caravanserrai, the South Inn, located in the north end of the Tcha valley. Because of the dense chaotic pattern of clints and grykes and the lack of accessible water, it is effectively impossible to cross the plateau other than by the caravan road, or by another path to the extreme east of the plateau, where it abuts the mountains of the Rim.
#### 2.1 Hans'hua
There is one city, Hans'hua, on the caravan road about half way across the plateau, where wind-pumps lift water from the underground river. Apart from this one city, nothing lives on the plateau. Migrating birds cross it, and that is all.
The city is small, walled, and run as an extreme neoliberal oligarchy; the city's main industry is maintaining the wind pumps, and its entire income is from tolls on caravans passing along the caravan road. This has been, and is still, extremely lucrative, but it is obvious both to the long distance merchants and to the oligarchs that the new ships are going to make the caravans too slow, too risky and too expensive to compete, and that as more ships are built, traffic on the caravan road will dwindle.
### 3. Massif
There's a granite intrusion which forms the entire western coast of the continent. It's geologically old and consequently the hills, though high, are rounded rather than jagged; at the southern end of the range (which is the only part that's in the least fleshed out yet) they're not snow covered in summer. As the prevailing winds are westerly, this massif intercepts most of the rain, which is why the steppe is arid.
Consequently it's pretty thoroughly forested, and the southern parts of it are mainly broadleaf forests including high quality hardwoods and many fruiting trees. Understory typical of mediterranean littoral forests, about which I don't really know enough.
Deer, cattle, pigs, wolves, leopards, badgers, squirrels… masses of birds of all appropriate types.
Because it's an old granite intrusion, the soil in the valleys is largely clay. There are mineral rich veins with a considerable range of minerals, but, obviously, not all in the same place.
Settled by the Western Clans, a negroid people living mainly in small isolated villages in the forest, with mostly limited agriculture.
#### 3.1 Northern massif
I haven't yet fleshed this out, but there are probably permanent snows and the forests are probably coniferous. It's my current working assumption that the new great ships are built from old growth conifers, taken from forests in the northern massif; but as I say this is not yet fleshed out.
The northern culture have developed very high quality ceramics using clay from the massif, including stonewares and porcelaines. I think the same clays also exist in the south of the massif, but the technology for producing high quality ceramics does not exist there. The northerners are also making high quality steels from magnetite and haematite from the massif. Whether these ores exist in the south I don't yet know.
#### 3.2 Dor
The northernmost of the western clans, the Dor, live in the central massif north of Andale, but apart from the fact that they exist and they're there, I don't yet really know much.
#### 3.3 Andale
The river An rises in the east of the massif near the south-west corner of the steppe, west of where the village and market of Dawnhold now stand, and flows more or less due westward. There are two major drops in the river's course, the upper a day's travel east of Silverhold, which is an actual fall of at least six metres, and the lower at Anghold. Between Anghold and Silverhold the river is navigable by small shallow draught boats; west of Anghold it is navigable down to the sea at Anmouth.
There are freshwater and migratory fish in the river, and fishing is a source of protein and livelihood the whole length of the valley.
The valley is largely forested. Apart from wild animals, domestic cattle and pigs are herded in the forest. Trees include alder, almond, apple, apricot, ash, beech, birch, cherry, chestnut, hazel, holly, lime, maple, mulberry, oak, orange, pear, walnut, yew.
##### 3.3.1 Dawnhold
Dawnhold isn't strictly geographically in Andale — it's east of, on the steppe side of, the watershead, but it marks the eastern border of the lands settled by clan An. There's an annual market, a village, and a garrisoned fortification to deter raids by the steppe tribes.
##### 3.3.2 Silverhold
Small town serving the only significant silver mine in the world. A tributary flows in from the north here, but I know nothing about it yet. There is a major fortification/refinery/treasury. All around Silverhold, right up to the headwaters of the An and right down to Anghold, the valley is forested with only small clearings round villages, which are mainly close to the river.
Many other metals — certainly inluding lead, tin, and small quantities of gold, probably not copper — come out of the mines at Silverhold.
The An produce enough ferrous metals for their own tools and weapons, but their iron smelting technology is not advanced and they don't export iron or iron products. They produce eathernware ceramics for domestic consumption. They produce leather and linen, and textiles from nettle fibres. They produce timber, which is their principal building material, but they don't export it. In practice their major export is silver coinage.
##### 3.3.3 Longwater
Longwater is a long, narrow lake, like Loch Lomond, on a tributary which flows into the An from the south, joining upstream from Anghold. There is no major nucleated settlement on Longwater, but there are sufficient small villages and hamlets on its banks to form an identifiable settlement cluster. Small boats can make it downstream from Longwater from the An and back, probably with some degree of portage around rapids. There's a pass over from the south of the Longwater valley to Gor territory, but it's high, difficult, and not much used. The whole of the Longwater valley is broadleaf forest.
##### 3.3.4 Anghold
There's a small town, market and fortification — Anghold — on the south bank of the An, just above first cataract, where boats are portaged up from the lower river to the middle reach. Downstream from Anghold the river is wider, slower and more meandering, with marshy banks. The valley west of Anghold, especially on the southern side, is also more populated, with more of the forest cleared and more arable agriculture.
##### 3.3.5 Anmouth
The An meets the sea at Anmouth, where there is a deep harbour at a bend in the river just east of a long estuary, There is a bar, making it dangerous to enter the harbour in bad weather, and the whole estuary is pretty exposed to western storms, although there may be some islands providing some shelter for emergency anchorages — I don't have that level of detail yet. Certainly the big new ships do not yet call in here, but could.
There are farming and sea-fishing villages down both sides of the estuary. There is no tradition of ship building, however.
#### 3.4 Gor
Clan Gor occupy the south-western peninsula of the continent, and the south slope of the massif, east almost as far as the Tcha valley. Their land is forested with a similar mix of trees to Andale. They have no major rivers, but several minor ones. They live mainly in coastal villages, and sea fishing is a major economic activity. They have no deep water ports.
In addition they do mine iron, and they have exported swords, but the market for their swords is being undercut by better crucible steel swords from the north now being imported into the Cities of the Coast by the new ships. Similarly, the Gor used to export earthenware, but that too is now being undercut by stonewares and porcelaines from the north.
Because of a history of being victims of raiding from the Cities of the Coast, the Gor maintain a fortified eastern border along the line of hills to the west of the Tcha valley. Nevertheless they have mostly good trading relationships with Tchahua. In particular they export large quantities of raw and spun silk, and some woven silk cloth, to Tchahua.
I don't yet have nearly a clear enough picture of the organisation and layout of the Gor lands, but their major stronghold and administrative centre must be to the east. While they traditionally had the communist and democratic culture of the other Western Clans, one family have become dominant and have become effectively hereditary leaders, influenced by the cultures to their east. However the leading family do not self-identify as aristons.
### 4. Coast
"The Coast" is the name given to the southern littoral of the continent, west of the Great Place and east of the Massif. It's limestone, with deeply cut, steep sided valleys separated by high, arid uplands, with scrubby vegetation, grazed by domestic sheep and both domestic and wild goats.
The native culture were peaceable, communistic agriculturalists, not greatly different from the Western Clans. However some several hundred years ago they were invaded by a warrior group from the steppe tribes, who established themselves as a military aristocracy — the Aristae — and started to build cities — and impose taxes onto the peasantry, forcing them into a more or less cash oriented economy.
The valleys were once forested, but the central valleys, which were in any case rather dryer and where the Aristae first settled and established cities, are now mostly cleared, and are a mix of pastoral and arable, with considerable viticulture.
#### 4.1 Tcha valley
The Tcha is the westernmost — and largest — river of the coast. It emerges from under the plateau at a pool under the South Tower marking the southern limit of Hans'hua territory and runs south more or less along the divide between the granite to the west and the limestone to the east. It is still largely forested, partly because it is relatively recently occupied by the Aristae, but partly because of the growth of the silk industry. This has led to some forested areas, especially near the navigable reaches of the river, being converted into mulberry orchards. However, there's still a great deal of mixed forest, and the majority of mulberry leaves for feeding to silk worms are gathered from natural forest.
A road branches off from the main Caravan Road at the South Inn and runs down the eastern side of the valley, to a ferry across the Sind river, where it joins the Tcha as a tributary, at the village helpfully known as Sind Ferry, and thence to Tchahua.
Mulberries, by products of the silk industry, are used in the production of brandy. Mulberry wine is produced in villages in the forest, and transported down river to a distillery at Sind Ferry, where it is distilled. Some mulberry wine may be sold in Tchahua for drinking as wine (and it is certainly drunk in the villages), but it is generally considered inferior to grape wine.
There is some arable and mixed agriculture, mainly towards the southern end of the valley on the western (less steep) side, although this side is also largely forested.
##### 4.1.1 Tchahua
The city of Tchahua lies on the east bank of the river at the head of its estuary, and has deep water — the only really usable deep water port on the coast, being not only the largest river but also the least silted. Until quite recently it had been a small provincial silk weaving city, nominally independent but in fact paying tribute to both Sinhua to its east and the Gor to its west, in order to avoid being formally conquered by either.
There's a multi-span bridge here — I think a pontoon bridge — of which the eastern most span is a drawbridge which can be lifted into a fortified gateway on the eastern (Tchahua) shore. There is a fishing industry, but as the eastern side
Industries are silk weaving and dying, and fishing. Very recently, a new deep water quay has been constructed and the first large ships have begun to call. It is obvious that the city is going to become much more important as a strategic market and transport hub, but that has only just begun to have effect.
### 4.2 Sind valley
#### 4.2.1 Sinhua

View file

@ -0,0 +1,27 @@
# Division of tasks between server and client
An alternative nomentclature I may use for this dichotomy would be _planner_ and _performer_; it would be the same dichotomy. 'Planner' and 'server' are synonyms; 'performer' and 'client' are synonyms.
## What do I mean by the 'server'?
There is something which manages game state and things like the gossip network, merchant network, and major world events. This something is almost certainly written in some form of Lisp; I'd prefer Clojure but I don't think it's performant enough so probably Common Lisp. This means that it has inevitable pauses for garbage collection. Underneath this is a database which handles persistent storage of game state, which is probably an SQL database and quite likely [SQLite](https://www.sqlite.org/index.html).
The initial idea of The Great Game is that it is a single player game, but it actually doesn't need to be and it would be quite possible for one server to support multiple clients, each being used by a different player.
The server/planner decides what each actor does, models what each character knows, plans and records all actions and transactions. It plans speach acts, and handles conversations which happen off screen, but hands speech texts over to the client/performer layer for actual performance. It also plans journeys as described in [[Pathmaking]], but it doesn't deal with movement within a polygon or with collision avoidance. It deals with fights which happen off screen, but not those that happen on screen.
## What do I mean by the client?
There is something that renders an interesting and lively display of the part of the game world that the player can see from their current position. This display has to run without significant pauses — it's not OK, for example, for all conversation to stop suddenly in a market place just because the server is garbage collecting.
The client is written in some high level game engine system, possibly Unreal Engine (although for ideological reasons I'd prefer an open source one).
The client/performer renders and animates everything the player character can see, and performs every sound the player character can hear. In doing this it is responsible for
1. The rendering of landscape, vegetation, buildings, furniture, and everything else that is fixed within the visible scene;
2. The animation of everything which moves within the visible scene, and, to facilitate this, detailed route planning and collision avoidance;
3. The performance of all speech acts and gestures, all musical performance, and the playing of all [foley](https://en.wikipedia.org/wiki/Foley_(filmmaking)) sounds;
4. Combat which happens in the field of view, including specifically all combat (including sparring) involving the player character. This means that the client/performer is the bit of the system which decides what blows are struck and whether they hit their targets, and consequently which character wins each fight. It reports this information back to the server.

View file

@ -4,7 +4,7 @@ First, a framing disclaimer: in [Racundra's First Cruise](https://books.google.c
I will never build a complete version of The Great Game; it will probably never even be a playable prototype. It is a minor side-project of someone who
1. Is ill, and consequently has inconsistent levels of energy and concentration;
1. Is old and ill, and consequently has inconsistent levels of energy and concentration;
2. Has other things to do in the real world which necessarily take precedence.
Nevertheless, in making design choices I want to specify something which could be built, which could, except for the technical innovations I'm trying myself to build, be built with the existing state of the art, and which if built, would be engaging and interesting to play.
@ -27,7 +27,7 @@ I want the player to be able to interact with non-player characters (and, indeed
4. The particular non-player character's attitude towards the player;
5. The particular non-player character's speech idiosyncracies, dialect, and voice
and it must be pretty clear that the full range of potential responses is extremely large. Consequently, it's impossible that all non-player character speech acts can be voice acted; rather, this sort of generated speech must be synthesised. But a consequence of this is that the non-player character's facial animation during the conversation also cannot be motion captured from a human actor; rather, it, too, must be synthesized.
and it must be pretty clear that the full range of potential responses is extremely large. Consequently, it's impossible that all non-player character speech acts can be voice acted; rather, this sort of generated speech must be synthesised. But a consequence of this is that the non-player character's facial animation during the conversation also cannot be motion captured from a human actor; rather, [it, too, must be synthesized](https://youtu.be/fa3_Mfqu8KA).
This doesn't mean that speech acts by non-player characters which make plot points or advance the narrative can't be voice acted, but it does mean that the voice acting must be consistent with the simulated voice used for that non-player character - which is to say, probably, that the non-player character must use a synthetic voice derived from the voice performance of that particular voice actor in that role.
@ -35,25 +35,27 @@ This doesn't mean that speech acts by non-player characters which make plot poin
Modern Role Playing Games are, in effect, extremely complex state machines: if you do the same things in the same sequence, the same outcomes will always occur. In a world full of monsters, bandits, warring armies and other dangers, the same quest givers will be in the same places at the same times. They are clockwork worlds, filled with clockwork automata. Of course, this has the advantage that is makes testing easier - and in a game with a complex branching narrative and many quests, testing is inevitably hard.
Interestingly, [Kenshi](https://lofigames.com/) — a game I'm increasingly impressed and influenced by — is not quite clockwork in this sense. As the player upsets the equilibrium of the game's political economy, factions not impacted negatively will move against competing factions which are impacted negatively, in a way which *may* be scripted, but it's so well done it's hard to tell.
My vision for The Great Game is different. It is that the economy - and with it, the day to day choices of non-player characters - should be modelled. This means, non-player characters may unexpectedly die. Of course, you could implement a tag for plot-relevant characters which prevents them being killed (except when required by the plot).
## Plot follows player
As Role Playing Games have moved towards open worlds - where the player's movement in the environment is relatively unconstrained - the clockwork has become strained. The player has to get to particular locations where particular events happen, and so the player has to be very heavily signposted. Sometimes the mark you have to hit to trigger the next advance of the plot can be extremely awkward; [an example from Cyberpunk 2077](https://youtu.be/GEYkuctBUYE?t=2990) is finding the right spot, in the quest 'They Won't Go When I Go', to trigger the button which raises the cross.
Another solution - which I'd like to explore - is 'plot follows character'. The player is free to wander at will in the world, and plot relevant events will happen on their path. And by that I don't mean that we associate a set of non-player characters which each quest - as current Role Playing Games do - and then uproot the whole set from wherever they normally live in the world and dumping down in the player's path; but rather, for each role in a quest or plot event, we define a set of characteristics required to fulfill that role, and then, when the player comes to a place where there are a set of characters who have those characteristics, the quest or plot event will happen.
Another solution - which I'd like to explore - is 'plot follows character'. The player is free to wander at will in the world, and plot relevant events will happen on their path. And by that I don't mean that we associate a set of non-player characters which each quest - as current Role Playing Games do - and then uproot the whole set from wherever they normally live in the world and dump them down in the player's path; but rather, for each role in a quest or plot event, we define a set of characteristics required to fulfil that role, and then, when the player comes to a place where there are a set of characters who have those characteristics, the quest or plot event will happen.
## Cut scenes, cinematics and rewarding the player
There's no doubt at all that 'cut scenes' - in effect, short movies spliced into game play during which the player has no decisions to make but can simply watch the scene unroll - are elements of modern games which players enjoy, and see to some extent as 'rewards'. And in many games, these are beautifully constructed works. It is a very widely held view that the quality of cutscenes depends to a large degree on human authorship. The three choices I've made above:
There's no doubt at all that 'cut scenes' - in effect, short movies spliced into game play during which the player has no decisions to make but can simply watch the scene unroll - are elements of modern games which players enjoy, and see to some extent as 'rewards'. And in many games, these are beautifully constructed works. It is a very widely held view that the quality of cutscenes depends to a large degree on human authorship. The choices I've made above:
1. We can't always know exactly what non-player characters will say (although perhaps we can in the context of cut scenes where the player has no input);
2. We can't always know exactly which non-player characters will speak the lines;
3. We can't predict what a non-player character will say in response to a question, or how long that will take;
4. We can't always know where any particular plot event will take place.
4. We can't always know where any particular plot event will take place;
Each of these, obviously, make the task of authoring an animation harder. The general summary of what I'm saying here is that, although in animating a conversation or cutscene what the animator is essentially animating is the skeletons of the characters, and, provided that all character models are rigged on essentially similar skeletons, substituting one character model for another in an animated scene isn't a huge issue, with so much unknowable it is impossible that hand-authoring will be practicable, and so a lot will depend on the quality of the conversation system not merely to to produce convincingly enunciated and emoted sound, but also appropriate character animation and attractive cinematography. As you will have learned from the Mass Effect analysis videos I linked to above, that's a big ask.
each, make the task of authoring an animation harder. The general summary of what I'm saying here is that, although in animating a conversation or cutscene what the animator is essentially animating is the skeletons of the characters, and, provided that all character models are rigged on essentially similar skeletons, substituting one character model for another in an animated scene isn't a huge issue, with so much unknowable it is impossible that hand-authoring will be practicable, and so a lot will depend on the quality of the conversation system not merely to to produce convincingly enunciated and emoted sound, but also appropriate character animation and attractive cinematography. As you will have learned from the Mass Effect analysis videos I linked to above, that's a big ask.
Essentially the gamble here is that players will find the much richer conversations, and consequent emergent gameplay, possible with non-player charcaters who have dynamic knowledge about their world sufficiently engaging to compensate for a less compelling cinematic experience. I believe that they would; but really the only way to find out would be to try.
Interestingly, an [early preview](https://youtu.be/VwwZx5t5MIc?t=327) of CD PRoject Red's not-yet-complete [Cyberpunk 2077]() suggests that there will be very, very few cutscenes, suggesting that these very experienced storytellers don't feel they need cutscenes either to tell their story or maintain player engagement. (Later) It has to be said other commentators who have also played the Cyberpunk 2077 preview say that there are **a lot** of cutscenes, one of them describing the prologue as 'about half cutscenes' - so this impression I formed may be wrong).
Interestingly, an [early preview](https://youtu.be/VwwZx5t5MIc?t=327) of CD Project Red's [Cyberpunk 2077](https://www.cyberpunk.net/us/en/cyberpunk-2077) has relatively few cutscenes, suggesting that these very experienced storytellers don't feel they need cutscenes either to tell their story or maintain player engagement.

View file

@ -16,11 +16,11 @@ The principles of game play which I'm looking for are a reaction against all I s
6. Dumb and dumber: non-player characters, even important ones, have extremely limited vocal repertoire.
Of these, the last two, I think, are key: they are the root cause of the other problems. In fact, to take it further, the real key is the last. We talk a lot about 'Game AI', but really there's nothing remotely approaching artificial intelligence ins modern games. Non-player characters do not think; they do not learn; they do not reason; they do not know. They speak only from the script. And they speak only from the script because of the fetish for voice acting.
Of these, the last two, I think, are key: they are the root cause of the other problems. In fact, to take it further, the real key is the last. We talk a lot about 'Game AI', but really there's nothing remotely approaching artificial intelligence in modern games. Non-player characters do not think; they do not learn; they do not reason; they do not know. They speak only from the script. And they speak only from the script because of the fetish for voice acting.
## Death to Dumb-Dumb
As I've argued [elsewhere](), [repeatedly](), we can now generate a wide variety of naturalistic speaking voices, and have them narrate text. Now of course there's great deal of information conveyed in human vocal communication in addition to the words of which emotion is only an example, although an important one. Generating voices with the right tone, the right emphasis, for different situations may be harder than I anticipate; there may be an '[uncanny valley](Uncanny_dialogue)' in which generated speech just sounds uncomfortably off.
As I've argued [elsewhere](Voice-acting-considered-harmful), [repeatedly](Selecting Character), we can now generate a wide variety of naturalistic speaking voices, and have them narrate text. Now of course there's great deal of information conveyed in human vocal communication in addition to the words of which emotion is only an example, although an important one. Generating voices with the right tone, the right emphasis, for different situations may be harder than I anticipate; there may be an '[uncanny valley](Uncanny_dialogue)' in which generated speech just sounds uncomfortably off.
But it's a trade off. For possibly less than perfect vocal performance, you get the possibility of much richer repertoire. You get not only the possibility that non-player characters can talk about the weather, or gossip about their neighbours, or give you directions to local places of interest. You get the possibility that a non-player character's attitude to you may be conditioned by the fact that they've heard that you stole from their second cousin, or that you killed an outlaw who'd raped one of their friends.
@ -36,5 +36,5 @@ Dynamic side quests have fallen into disfavour, because, when they've been tried
## Death to Psycho-Killer
If the main way a player can interact with non-player characters is to kill them, and if the player doesn't have a systematic combat advantage over non-player characters, then it's going to be a short game. This is why players in many or most video games do start with a systematic combat advantage, and that combat advantage tends to increase over the course of the game as the player becomes more proficient with the combat system, and acquires better weapons, armour and combat buffs. This in turn means that to keep combat 'interesting', the game either has to through larger and larger armies of 'bad' non-player characters against the player a fault seen at its worst in [Dragon Age 2](https://youtu.be/Sc8Bn8yqPYQ?t=3150).
If the main way a player can interact with non-player characters is to kill them, and if the player doesn't have a systematic combat advantage over non-player characters, then it's going to be a short game. This is why players in many or most video games do start with a systematic combat advantage, and that combat advantage tends to increase over the course of the game as the player becomes more proficient with the combat system, and acquires better weapons, armour and combat buffs. This in turn means that to keep combat 'interesting', the game has to through larger and larger armies of 'bad' non-player characters against the player a fault seen at its worst in [Dragon Age 2](https://youtu.be/Sc8Bn8yqPYQ?t=3150).

View file

@ -1,13 +1,13 @@
# Gossip, scripted plot, and Johnny Silverhand
I've been writing literally for years -- since [Voice acting considered harmful](Voice-acting-considered-harmful.html) in 2015 -- about game worlds in which the player speaks to non-player characters just by speaking the words they choose in their normal voice, and the non-player character replies using a pipeline that goes, essentially,
I've been writing literally for years -- since [Voice acting considered harmful](Voice-acting-considered-harmful.md) in 2015 -- about game worlds in which the player speaks to non-player characters just by speaking the words they choose in their normal voice, and the non-player character replies using a pipeline that goes, essentially,
1. Alexa/Siri style speech interpretation;
2. A decision on whether to co-operate based on the particular NPC's general demeanor and particular attitude to the player;
3. A search of the game state and lore for relevant information;
4. A filtering of the results based on what the particular NPC can be expected to know;
5. Generation of a textual response from those results based on a library of templates which defines the particular NPC's dialect and style of speech;
6. Production of audio using a [Lyrebird]{https://www.descript.com/overdub?lyrebird=true) style generated voice.
6. Production of audio using a [Lyrebird](https://www.descript.com/overdub?lyrebird=true) style generated voice.
As I've argued before, the game engine necessarily knows everything about the lore, and the current state, of the game world. It would be possible for any non-player character to answer literally any question about the game world, from who was mayor of Night City in 2020 to who lives in the apartment one floor up from yours, to what the weather is like in North Oaks just now.

5
doc/My-setting.md Normal file
View file

@ -0,0 +1,5 @@
# My setting for the Great Game
It should be evident that all the key ideas in The Great Game project would be applicable to games set in the historic past of our world, to games set in its present, or to games set in some imagined or forecast future; the ideas are intended to be, and I believe are, largely independent of setting.
Nevertheless I feel the need for a concrete setting to ground the development of ideas. I've chosen deliberately not to place that setting in the real world; although it's broadly based on cultures from the late bronze age/early iron age mediterrainian.

26
doc/Not my problem.md Normal file
View file

@ -0,0 +1,26 @@
# Not my problem
## Introduction
This document is essentially a catalogue of side-tracks which I do not have to go down when implementing The Great Game. Solved problems; or problems which are common to many other games, so if I don't solve them someone else will. The object of doing this is to work down to a constrained set of problems which are genuinely things I'm trying to innovate, which I should focus on; which essentially come down to
1. Gossip
2. Reputation
3. Dynamic character motivation and action, and hence
4. Dynamic economy, and
5. Dynamic plot
6. Procedural ('genetic') buildings.
(Note that although procedural vegetation is in principle a solved problem and so I don't need to solve it, I need repeatable procedural vegetation so I need to be a bit careful about the procedural vegetation library I pick).
## Animation
I envisage a well rendered three dimensional world in which many non-player characters interact with one another and with the player character. All of my characters are either human, quadrupeds, or birds (my dragons animate like very large birds). The humans are all just human; there are infants, children, adolescents, youths, adults, elderly; there are multiple racial types — but they're all human. Systems for creating varied distinct human models exist; systems for animating them exist; systems for applying and animating clothing exist. Even systems for animating continuous speech exist.
## Rendering
Ideally I'd like a stylised, not-quite-photorealistic render, because such things age, in my opinion, better than things which do seek to be photorealistic. But actually that does not matter very much; the game won't be made or broken by its rendering. Photorealistic renders are sort of the current default, that most game engines.
## Continuous Open World
I've done a great deal of thinking about how to render a continuous open world over the years, and I think at least some of it is reasonably good; but I haven't actually written any code, and in the same time period other people have written continuous open world libraries which do work, so I'd be much better choosing an existing one.

View file

@ -0,0 +1,56 @@
# On Sex, and Sexual Violence, in Games
For me the purpose of games is to provide worlds in which players can explore moral actions, and the consequences of moral actions. Sexual violence is something that happens in the real world, and which happens, even within the real world, more frequently in areas of poor governance and open conflict; and those are areas in which there are important moral actions, and important moral consequences, so they are areas in which it is interesting to set games.
It would be ludicrous to argue 'sexual violence is wrong, therefore we should not represent it in games.' Killing people is also wrong, yet it is extremely common in games. However, sexual violence — and in particular the representation of sexual violence — does pose some specific problems that need to be addressed.
Firstly, sexual violence is extremely gendered. Yes, male people are sometimes subjected to sexual violence, but nevertheless the overwhelming majority of victims of sexual violence are female. Yes, female people are sometimes — extraordinarily rarely, but sometimes — perpetrators of sexual violence, but nevertheless perpetrators of sexual violence are almost exclusively male.
Secondly, it is extremely tricky to represent sexual violence in visual media without eroticising it. There's a [very famous scene in Last Tango in Paris](https://www.independent.co.uk/arts-entertainment/films/news/last-tango-in-paris-butter-scene-b2270513.html) which the director might claim is consented in context, but which appears to me to be a clear case of anal rape, which is nevertheless highly erotic. There's a scene in [High Plains Drifter](https://en.wikipedia.org/wiki/High_Plains_Drifter#Plot) where no part of the rape is actually represented — it happens off screen — but it is nevertheless perceived by many people (including me) as eroticised. Many people — I suspect more men than women, but certainly including women — do find the idea of rape erotic. It seems to me highly undesirable that a game should be seen to be rewarding immoral action.
(Yes, I know many modern games do quite explicitly reward killing, including of characters whose culpability is at best trivial, but — surely — this is something we should be seeking to move away from.)
## Subtlety and Nuance
A final issue here is that sexual interactions between people are subtle, and are subtle even around issues of consent. A less powerful person (normally a woman) — alone or as a member of a weak party, a party of perhaps older people, other women, children — may submit to sex with more powerful others without protest in order to protect others in their party, or to avoid death or serious injury, or to avoid starvation, or to escape debt. Do any of these things truly count as consent?
Again, a less powerful person may submit to sex with more powerful others transactionally in return to protection, or shelter, or food, or other resources. In modern society we might see this as sex work, and we might argue that sex work falls into the same moral category as any other labour entered into transactionally. But, generally, is it moral that people should be put into a position where their survival depends on their ability to sell any sort of unwilling labour?
(This is not to deny that some people, who do have secure living conditions or who could choose to do other things in order to gain secure living conditions do choose, willingly and voluntarily, to engage in sex work; and it isn't to criticise those people in any way).
Games are not very good at subtly and nuance. When, while playing a game, the character who is our avatar in the game, who we thought we were controlling, does something which we didn't intend them to do, it's very wrenching and immersion-breaking.
At the same time, if other characters in the game interpret something the player's character has done as sexual violence when the player did not intend sexual violence, that's also undesirable.
So, questions:
## Sex between non-player characters
People have sex. If people didn't have sex, there wouldn't be people; but more, if people didn't have sex, there wouldn't be (many) stories, since most stories are driven at least in part by sex. So pretending that non-player characters don't have sex is worse than unrealistic.
We live in a pathologically repressed society, in which open sex — sex in public places, sex with other people present — is rare, is seen as deviant, is (perhaps in consequence) highly eroticised. Does that mean that all the societies we represent in our games must be similarly repressed?
I would argue strongly to the contrary. Games are environments in which we can explore moral possibilities, and a society in which public sexuality was normal is clearly a possibility. Would such a society be a better society? Games are a mechanism through which we can ask that question, and questions of that sort.
If we're going to represent a society in which public sex is normal, then we're going to have to represent public sex on screen. It can take one of many forms:
1. Sex as normal activity — it's just going on in the background, and no other non-player characters pay much attention;
2. Sex as conscious performance — sex where the participants intend to be watched, and other non-player characters do pay attention (this may include consciously eroticised performance);
3. Sex as part of a religious or other ritual event — this is related to, and is, sex as conscious performance, but the purpose of the performance is symbolic and/or sacramental. This doesn't mean it is not eroticised, but it may not be eroticised.
By 'eroticised', I'm meaning deliberately intended to trigger sexual feelings in the audience — which, if the player character is present, includes the player.
## Sexual violence between non-player characters
In a world in which there are characters who are thuggish, who seek to dominate, terrorise and subdue other characters, whether those characters are outlaws or soldiers or aristocrats, to pretend that rape would not be used as a means to dominate, terrorise or subdue is… bowdlerisation. It's unrealistic, and it's a morally indefensible choice.
So there has to be a mechanism for non-player characters to decide to commit acts of sexual violence towards other non-player characters. The player must at least hear of such events through the gossip network, and should be able to find the specific non-player characters involved, and speak to them. Whether it's necessary to portray acts of sexual violence on screen is something I'm much less persuaded by, simply because it runs the risk of eroticising them.
## Mutually consented sexual activity between the player character and non-player characters
Mutually consented sexual behaviour between the player character and (certain, scripted) non-player characters has been a feature of video games for some time, and has occasionally been portrayed with real sensitivity and eroticism. Two cases I would point to are
1. The sex scene between Geralt and Shani in [The Witcher]()
## Sexual violence from the player character towards non-player characters

View file

@ -20,7 +20,7 @@ Routing is fundamentally by [A\*](https://www.redblobgames.com/pathfinding/a-sta
#### Algorithmic rules
1. No route may pass through any part of a reserved holding, except the holding which is its origin, if any, and the holding which is its destination (and in any case we won't render paths or roads within holdings, although traversal information may be used to determine whether a holding, or part of it, is paved/cobbled;
1. No route may pass through any part of a reserved holding, except the holding which is its origin, if any, and the holding which is its destination, if any (and in any case we won't render paths or roads within holdings, although traversal information may be used to determine whether a holding, or part of it, is paved/cobbled;
2. No route may pass through any building, with the exception of a city gate;
3. We don't have bicycles: going uphill costs work, and you don't get that cost back on the down hill. Indeed, downhills are at least as expensive to traverse as flat ground;
4. Any existing route segment costs only a third as much to traverse as open ground having the same gradient;

View file

@ -14,7 +14,7 @@ Limiting choice of player character, especially in games with increasingly highl
## The Self-voiced Player
If we have voice interaction sufficiently sophisticated that we can allow the player character to say more or less whatever they want to say - [and my argument here is that we can do this](Gossip_scripted_plot_and_Johnny_Silverhand.md) - then we don't need voice acting for the player character, and that gives us a lot of freedom. There's then really no reason why the player can't inhabit any character in the game world and play as that character.
If we have voice interaction sufficiently sophisticated that we can allow the player character to say more or less whatever they want to say — [and my argument here is that we can do this](Gossip_scripted_plot_and_Johnny_Silverhand.md) — then we don't need voice acting for the player character, and that gives us a lot of freedom. There's then really no reason why the player can't inhabit any character in the game world and play as that character.
## Tinder as a Character Selector
@ -41,7 +41,8 @@ So, sensibly refinable attributes might include things like
1. Strength;
2. Agility;
3. Dexterity.
3. Dexterity;
4. Endurance.
I did think that 'intelligence' or 'learning' might be on that list but the more I think of it, the harder I find it to understand how low intelligence might be represented in a game in which the player speaks freely.

View file

@ -14,7 +14,7 @@ This is mainly a land game. Broadly, caravans take the place of ships in Elite o
## A political simulation
Broadly, aristons claim territories in an essentiallu feudal arrangement, drive out outlaws, and levy taxes.
Broadly, aristons claim territories in an essentially feudal arrangement, drive out outlaws, and levy taxes.
An ariston will be popular if their regime is stable, if taxes are low, justice is considered fair, oppression is low and depredations by outlaws are minimal. The more unpopular an ariston is, the more resistant the populace will be to paying their taxes, meaning the more military force needs to be diverted to tax collection and the greater the oppression. Taxes are required to pay soldiers and to maintain high roads, bridges, markets and other infrastructure. Merchants will prefer to travel routes which are better policed and maintained, which means more merchants trading in your markets, which means more tax.

View file

@ -0,0 +1,83 @@
# A Generic Planning Algorithm for craftworker NPCs
## Preamble
The Great Game requires a number of different crafts to be performed, both because the economy depends on the products of those crafts and to provide verisimilitude and set dressing. Some of those crafts, the relations between them, and the progression within them are set out in [Populating a game world](Populating-a-game-world.html).
For the purposes of planning work, only Master craftspeople are considered.
A Master craftsperson has
1. a house and appropriate workshop, within a settlement;
2. zero or more apprentices;
3. zero or more journeyman;
4. a spouse, who is usually of lower status;
5. zero of more coresident children;
6. zero or more coresident non-working parents/elders.
There are limits to the number of apprentices and journeymen a master may take on, essentially based on demand in the local market. The master is responsible for housing and feeding all of the household including apprentices and journeymen, and for obtaining sufficient craft supplies. All craft work done in the household belongs to the master.
Apprentices are definitely not paid. Journeymen should be paid, but this is a detail to ignore until we have other things working.
Journeymen will move on from master to master from time to time -- infrequently, but it will happen; and may be dismissed by masters when markets are tight. Journeymen probably learn their craft recipes -- which is to say, the items and qualities of item they are able to craft -- from the masters they work with. Consequently, journeymen will seek out masters with higher reputation; masters will prefer journeymen with more experience.
Apprentices do not move on until the end of their period of apprenticeship (16th birthday?) when they become journeymen.
The master will plan work in four hour sessions - essentially, a morning session and an afternoon session each day.
All craftspeople have regular schedules covering mealtimes, sleep, and festivals. A lower status person within the household will have regular schedules covering each of fetching water, fetching fuel wood, taking out night soil, feeding chickens, washing dishes and laundry, and so on.
When the master works in the workshop, all the apprentices and journeymen will also work in the workshop; when the master is engaging in recreation, they're also engaging in recreation. What they do when the master is e.g. going to market, I haven't yet decided.
## Commodity items and special commissions
In principle all craftspeople may make both commodity items and special commission items, but in practice many crafts will be mostly commodity and a few will be almost entirely special commission (for example a diplomat doesn't produce peace treaties prèt-à-porter); but I don't yet have a good model of how I'm going to handle special commissions, so I'm just doing some hand waving here to say they will exist and must be handled.
## The algorithm
A master craftsperson needs to keep stock of a number of things
1. Sufficient food for the household;
2. Sufficient craft materials for immediate production;
3. Sufficient funds to buy more food/craft materials when needed;
4. Commodity craft items produced;
5. Craft items work in progress.
### Choosing tasks
So in planning a period of work, the master has to decide:
1. Do I need to go to market?
1. Is there news of a travelling merchant who buys what I produce arriving at my nearest market? -> go to market;
2. Is the household running low on food? -> go to market;
3. Is the household running low on craft materials? -> go to market;
2. Do I have any commissioned items to produce? -> produce commissioned items;
3. Should I work on commodities or take the day off?
This is a throw-of-the-dice decision, influenced by
1. Cash on hand (if there's little, greater incentive to work);
2. Weather (if it's especially good, less incentive to work);
3. Gossip (if there's interesting news, less incentive to work)
### Commodity production
If the decision is to work on commodities, the next decision is what commodity item to produce.
For each craft recipe the master knows there will be
1. A list of quantities of different craft materials needed per item, for example a sword might need two kilograms of steel of a particular quality, ten kilograms of charcoal, one kilogram of timber, half a square metre of leather;
2. An amount of craftsperson time - for example, a standard infantry sword might take ten hours;
3. Memory of prices achieved by item to that recipe in the local market.
The master will choose a recipe for which there are sufficient materials on hand, and which is profitable to make -- the more profitable, the more likely to be selected (but I think there's probably some furtive dice rolling under the table here too; you don't want all the smiths in town producing infantry swords at the same time, because that would swamp the market and drive prices down).
When an item is started, the materials for it are removed from stock and assigned to the item, which is added to the work in progress list. The number of items that can be produced in a work session is
(the number of hours in the session * the number of people in the team) / the hours to produce one item
At the end of the session, the integer number of items produced is removed from the work in progress queue and added to stock, and the modulus is added as `:work-done` to the remaining item, which is left in the work in progress queue.
Obviously items in the work in progress queue may need to be completed at the start of the next commodity work session.
Obviously, none planned at sufficient granularity to be animated unless the workplace is in the `:active` circle, and none of it gets actually animated unless it's actually on camera, but the book-keeping in terms of food and craft materials consumed and of items produced must be done.
This implies that at least many master craftspeople must be in the `:background` circle, i.e. woken up once every game day to plan a work session, no matter how far away the player character is.

View file

@ -177,7 +177,7 @@ easy:
2. **Master**: what is the sum of (or average of) the esteem held for this agent by other agents of the same craft?
3. **Explorer**: (e.g.) what is the sum of the distance between the most northerly and most southerly, and the most easterly and most westerly, locations this agent has visited?
4. **Climber**: how many 'promotions' has this agent had in the game?
6. **Conqueror**: how many total vassales, recursively, has this agent?
5. **Conqueror**: how many total vassals, recursively, has this agent?
6. **Citizen**: really, really tricky. Probably what is the average esteem for this agent among all agents within a specified radius? - although this will score more highly for agents who have taken part in notable events, and what I'm really thinking of for my ideal 'good citizen' is someone who really hasn't.
So each agent is assigned - by the dreaded random number generator - one top
@ -323,13 +323,19 @@ A caravan or ship costs so much per day to run, irrespective of whether full
or empty. So the base cost of a journey is a function of the time taken, which
is essentially a function of the distance.
Obviously, on top of the base cost of movement there are tolls, which are imposed
by the aristons through whose territory the journey passes (and therefore predictable,
and can be used in route planning), and also the risk of having to bribe or fight outlaws,
and the possible need to hire mercenaries to defend against outlaws, which is not predictable
but can be estimated and thus also used in route planning.
### Outlawry and merchants
Outside the domains of aristons, outlaws may intercept caravans; when this
happens the following outcomes are possible:
1. The merchant (together with any mercenaries the merchant has hired to protect the caravan) successfully fights off the outlaws;
2. The outlaws steal the entire cargo (and may kill the merchant);
2. The outlaws steal the entire cargo (and may kill the merchant and others);
3. The merchant pays protection money to the outlaws, typically around 5%-10% of the value of cargo carried;
4. The merchant employs the outlaws as caravan guards (see below);
5. The outlaws allow the caravan to pass unmolested;
@ -362,7 +368,7 @@ Generally, if a merchant buys goods in an ariston's market, or sells goods
in the ariston's market, then the economy benefits and the ariston benefits
from that; so the 'tax' element is part of the market markup. But if a
caravan passes through an ariston's territory without stopping at a market,
there's probably a tax of about 5% of value.
there's probably a toll of about 5% of value.
Generally, an ariston's army will control outlawry within the ariston's
domain, so outlaw encounters within a domain are unlikely. Soldiers could

View file

@ -1,4 +1,4 @@
# On Dying
# On Dying, and Injury
Death is the end of your story. One of the tropes in games which, for me, most breaks immersion is when you lose a fight and are presented with a screen that says 'you are dead. Do you want to reload your last save?' Life is not like that. We do not have save-states. We die.
@ -17,3 +17,11 @@ Obviously losing a fight must have weight, it must have meaning, it must have in
Similarly to death, injury must have meaning. Any injury takes time to recover from. It takes a certain amount of time if you're able to rest somewhere safe, and considerably longer if you're not. If you fight while injured, you'll have less strength, less stramina, and probably also less agility. Depending where you're injured, there will be certain things you cannot do. If you fight while injured, also, your recovery time will be extended, even if you take no further injury.
Some serious injuries will lead to permanent scarring, and permanent loss of agility; you'll be just slightly slower in fights.
It should be said that [Kenshi](https://lofigames.com/) — a game I've only recently become aware of and greatly admire — handles all of this extremely well, and is worth studying.
## Reciprocity
If the player is going to depend on good samaritans for rescue after losing a fight, then there must be at least a social convention that people should assist people found injured on the wayside. Consequently, if the player fails to do this, that should in itself become a 'gossip' event which will lower the player's reputation with non-player characters.
On the other hand, helping NPCs found injured at the wayside can be another category of [organic quest](Organic_Quests.md), as a special subcategory of an escort quest.

View file

@ -35,7 +35,7 @@ The next tier of playable roles rotates around issues arising from the mercantil
### Aristocracy
Aristocrats are basically settled outlaws who seek to establish a monopoly on extracting taxes from inhabitants and travellers in a particular region by driving out all other outlaws. Within the comain of an aristocrat, you have to pay tax but you're reasonably safe from being attacked by other outlaws and losing everything. Aristocrats may also maintain and improve roads and bridges and do other things to boost the economy of their territory, may expant into adjoining territory with no current aristocratic control, and may wage war on other aristocrats.
Aristocrats are basically settled outlaws who seek to establish a monopoly on extracting taxes from inhabitants and travellers in a particular region by driving out all other outlaws. Within the domain of an aristocrat, you have to pay tax but you're reasonably safe from being attacked by other outlaws and losing everything. Aristocrats may also maintain and improve roads and bridges and do other things to boost the economy of their territory, may expand into adjoining territory with no current aristocratic control, and may wage war on other aristocrats.
An outlaw ought to be able to become an aristocrat, by dominating an ungoverned area or by defeating an existing aristocrat.
@ -45,22 +45,24 @@ Soldiers, like aristocrats, are basically on the same spectrum as outlaws. Outla
## Routine, Discretion and Playability
There's a term that's used in criticism of many computer games which is worth thinking about hard here: that term is 'farming'. 'Farming', in this sense, is doing something repetitive and dull to earn credits in a game. Generally this is not fun. What makes roles in a game-world fun is having individual discretion - the ability to choose between actions and strategies - and a lack of routine.
There's a term that's used in criticism of many computer games which is worth thinking about hard here: that term is 'farming'. 'Farming', in this sense, is doing something repetitive and dull to earn credits in a game. Generally this is not fun. What makes roles in a game-world fun is having individual discretion — the ability to choose between actions and strategies — and a lack of routine.
Most craft skills - especially in the learning phase - are not like this, and crafts which are sophisticated enough to be actually engaging are very hard to model in a game. Learning a craft is essentially, inherently, repetitive and dull, and if you take that repetition out of it you probably don't have enough left to yield the feeling of mastery which would reward success; so it doesn't seem to me that making craft roles playable should be a priority.
Most craft skills — especially in the learning phase — are not like this, and crafts which are sophisticated enough to be actually engaging are very hard to model in a game. Learning a craft is essentially, inherently, repetitive and dull, and if you take that repetition out of it you probably don't have enough left to yield the feeling of mastery which would reward success; so it doesn't seem to me that making craft roles playable should be a priority.
## Cruise control
One of the most enjoyable aspects of The Witcher 3 - still my go-to game for ideas I want to improve on - is simply travelling through the world. Although fast travel is possible I find I rarely use it, and a journey which takes fifteen minutes of real world wall clock time can be enjoyable in and of itself. This is, of course, a credit to the beautiful way the world is realised.
One of the most enjoyable aspects of The Witcher 3 — still my go-to game for ideas I want to improve on — is simply travelling through the world. Although fast travel is possible I find I rarely use it, and a journey which takes fifteen minutes of real world wall clock time can be enjoyable in and of itself. This is, of course, a credit to the beautiful way the world is realised.
But nevertheless, in The Witcher 3, a decision was made to pack incident fairly densely - because players would find just travelling boring. This leads to a situation where peaceful villages exist two minutes travel from dangerous monsters or bandit camps, and the suspension of disbelief gets a little strained. Building a world big enough that a market simulation is believable means that for the individual, the travel time to a market where a particular desired good is likely to be cheaper becomes costly in itself. Otherwise, there's no arbitrage between markets and no ecological niche for a merchant to fill. The journey time from market to market has to be several in-game days.
(It's worth noting that [Kenshi](https://lofigames.com/), a game I'm coming to greatly admire, does not allow fast travel at all, but has an equivalent of 'cruise control' — you can set a destination and then accelerate time and simply watch as your characters journey).
An in-game day doesn't have to be as long as a wall clock day, and, indeed, typically isn't. But nevertheless, doing several game days of incident-free travel, even in beautiful scenery, is not going to be engaging - which implies a fast-travel mechanic.
But nevertheless, in The Witcher 3, a decision was made to pack incident fairly densely — because players would find just travelling boring. This leads to a situation where peaceful villages exist two minutes travel from dangerous monsters or bandit camps, and the suspension of disbelief gets a little strained. Building a world big enough that a market simulation is believable means that for the individual, the travel time to a market where a particular desired good is likely to be cheaper becomes costly in itself. Otherwise, there's no arbitrage between markets and no ecological niche for a merchant to fill. The journey time from market to market has to be several in-game days.
I don't like fast travel, I find it a too-obvious breaking of immersion. Also, of course, one of the interesting things about a game in a merchant/outlaw ecosystem is the risk of interception on a journey. The Dragon Age series handled interrupted travel in 'fast travel' by randomly interrupting the loading screen you get when moving from location to location in Dragon Age's patchwork worlds by dumping you into a tiny arena with enemies. That's really, really bad - there's no other way to say this. Everything about it shouts artifice.
An in-game day doesn't have to be as long as a wall clock day, and, indeed, typically isn't. But nevertheless, doing several game days of incident-free travel, even in beautiful scenery, is not going to be engaging — which implies a fast-travel mechanic.
I don't like fast travel, I find it a too-obvious breaking of immersion. Also, of course, one of the interesting things about a game in a merchant/outlaw ecosystem is the risk of interception on a journey. The Dragon Age series handled interrupted travel in 'fast travel' by randomly interrupting the loading screen you get when moving from location to location in Dragon Age's patchwork worlds by dumping you into a tiny arena with enemies. That's really, really bad — there's no other way to say this. Everything about it shouts artifice.
So I'm thinking of a different mechanism: one I'm calling cruise control.
You set out on a task which will take a long time - such as a journey, but also such as any routine task. You're shown either a 'fast forward' of your character carrying out this task, or a series of cinematic 'shots along the way'. This depends, of course, on there being continuous renderable landscape between your departure and your destination, but there will be. This fast-forward proceeds at a substantially higher time gearing than normal game time - ten times as fast perhaps; we need it to, because as well as doing backgound scenery loading to move from one location to another, we're also simulating lots of non-player agents' actions in parts of the world where the player currently isn't. So a 'jump cut' from one location to another isn't going to work anyway.
You set out on a task which will take a long time — such as a journey, but also such as any routine task. You're shown either a 'fast forward' of your character carrying out this task, or a series of cinematic 'shots along the way'. This depends, of course, on there being continuous renderable landscape between your departure and your destination, but there will be. This fast-forward proceeds at a substantially higher time gearing than normal game time — ten times as fast perhaps; we need it to, because as well as doing backgound scenery loading to move from one location to another, we're also simulating lots of non-player agents' actions in parts of the world where the player currently isn't. So a 'jump cut' from one location to another isn't going to work anyway.
The player can interrupt 'fast forward' at any time. But also, the game itself may bring you out of fast forward when it anticipates that there may be action which requires decision - for example, when there are outlaws in the vicinity. And it will do this **before** the player's party is under immediate attack - the player will have time to take stock of the situation and prepare appropriately. Finally, this will take place in the full open world; the player will have the option to choose *not* to enter the narrow defile, for example, to ask local people (if there are any) for any news of outlaw activity, or, if they are available, to send forward scouts.
The player can interrupt 'fast forward' at any time. But also, the game itself may bring you out of fast forward when it anticipates that there may be action which requires decision — for example, when there are outlaws in the vicinity. And it will do this **before** the player's party is under immediate attack — the player will have time to take stock of the situation and prepare appropriately. Finally, this will take place in the full open world; the player will have the option to choose *not* to enter the narrow defile, for example, to ask local people (if there are any) for any news of outlaw activity, or, if they are available, to send forward scouts.

View file

@ -42,4 +42,13 @@ Sex, done right, is an extremely pleasant pastime. Sex can also be used to creat
For women, sex with other women carries with it no risk of pregnancy, so can be enjoyed or used for any of these purposes in very much the same way as it can by men; in other words, particularly for women, homosexual sex can be more lighthearted and carefree than heterosexual sex. To what extend our notions of homosexuality and heterosexuality are cultural I simply don't know. But because no children will result, a woman can afford to be more promiscuous with other women than she can with men.
##
## Women and warrior/adventurer lifestyles
Generally speaking, people do not want to take their children onto a battlefield. If you're going to have a game world in which women significantly take on warrior or adventurer roles, then you must either have
* A culture which expects female warriors to be celibate; or
* A culture with access to and acceptance of safe and reliable contraception or abortion; or
* An acceptance of leaving infant children with grandparents, other relatives or foster carers for long periods;
* A system of long term creches;
* Any combination of the above.

View file

@ -8,13 +8,17 @@
;;; I'm probably going to want to defprotocol stuff, to define the hierarchy
;;; of things in the gameworld; either that or drop to Java, wich I'd rather not do.
;;; attitudes - liking/disliking, attraction/repulsion, amity/hostility, trust/fear
;;; also need to live at this layer, even though dynamic change in attitudes belongs
;;; in the character layer.
(defprotocol ProtoAgent
"An object which can act in the world"
(act
[actor world circle]
"Allow `actor` to do something in this `world`, in the context of this
`circle`; return the new state of the actor if something was done, `nil`
if nothing was done. Circle is expected to be one of
if nothing was done. `Circle` is expected to be one of
* `:active` - actors within visual/audible range of the player
character;
@ -22,19 +26,45 @@
to it that they may enter the active circle within a short period;
* `:background` - actors who are active in the background in order to
handle trade, news, et cetera;
* `other` - actors who are not members of any other circle, although
I'm not clear whether it would ever be appropriate to invoke an
`act` method on them.
* `:other` - actors who are not members of any other circle.
The `act` method *must not* have side effects; it must *only* return a
new state. If the actor's intention is to seek to change the state of
something else in the game world, it must add a representation of that
intention to the sequence which will be returned by its
`pending-intentions` method.")
(hungry? [actor world circle] "True if this actor is hungry and has no
immediate access to food.")
(pending-intentions
[actor]
"Returns a sequence of effects an actor intends, as a consequence of
acting. The encoding of these is not yet defined."))
acting.")
(pending-scheduled-action? [actor world circle]
"True if there is a plan in this `actor`'s
schedule which should be activated now.
NOTE THAT plans in the `daily` schedule are
NOT activated when in circles `:background`
or `:other`")
(plan-fight-or-flight [actor world circle]
"Return a plan to resolve any active threat to this
`actor` in this `world`.")
(plan-find-food [actor workd circle]
"Return a plan to find this `actor` food in this `world`.")
(plan-find-rest [actor workd circle]
"Return a plan to find this `actor` a safe place to rest, or
if in one, to actually rest, in this `world`.")
(plan-goal [actor world circle] "Return a plan to advance this `actor`
towards their personal objective, in this
world, or `nil` for default actors with no
objective.")
(plan-scheduled-action [actor workd circle]
"Return a plan taken from the schedule of this actor
for the current date and time, if any, else `nil`.")
(schedule [actor] "Return a map of scheduled actions for this `actor`.
TODO: work out the detailed format!")
(threatened? [actor world circle] "True if this `actor` is threatened in this
`world`.")
(tired? [actor world circle] "True if this `actor` needs rest."))
(defrecord Agent
;; "A default agent."
@ -42,4 +72,40 @@
ProtoObject
ProtoContainer
ProtoAgent
)
(act
Return a world like this `world `except that this `actor `has acted in it.
Circle indicates which activation circle the actor is in.
Note that this implies that a `plan `is a function of three arguments, an
actor, a world. and a circle.
[actor world circle]
(let [urgent (case circle
:other (cond
(pending-scheduled-action? actor world circle)
(plan-scheduled-action actor world circle)
(empty? (:plans actor))
(plan-goal actor world circle))
:background (cond
(threatened? actor world circle)
(plan-fight-or-flight actor world circle)
(pending-scheduled-action? actor world circle)
(plan-scheduled-action actor world circle)
(empty? (:plans actor))
(plan-goal actor world circle))
;; else
(cond
(threatened? actor world circle)
(plan-fight-or-flight actor world circle)
(hungry? actor world circle)
(plan-find-food actor world circle)
(tired? actor world circle)
(plan-find-rest actor world circle)
(pending-scheduled-action? actor world circle)
(plan-scheduled-action actor world circle)
(empty? (:plans actor))
(plan-goal actor world circle)))
a (if urgent
(assoc actor :plans (cons urgent (:plans actor)))
actor)]
(eval ((first (:plans a)) a world)))))

View file

@ -0,0 +1,55 @@
(ns cc.journeyman.the-great-game.agent.schedule
"Schedules of plans for actors in the game, in order that they may have
daily and seasonal patterns of behaviour.")
;; TODO: I don't have a good handle yet on when a new scheduled task can
;; interrupt an existing scheduled task. It's highly undesirable that
;; uncompleted scheduled tasks should be left on the queue. The simplest
;; solution is to arrange the schedule such that, under notmal circumstances,
;; no scheduled task will interrupt another. But if a scheduled task is
;; interrupted by an attack, say, or a conversation, and then continued,
;; there's a chance of overrunning the start of the next.
;;
;; Perhaps I need to give scheduled tasks the equivalent of a watchdog timer,
;; but that makes them much more sophisticated objects than I wanted them to
;; be.
;; NOTE: this assumes that a world contains a key `:time` whose values are
;; a map with at least the keys
;; 1. `:day`, whose value is an integer representing the current day of the
;; year, and
;; 2. `minute`, whose value is an integer representing the current minute of
;; the day.
;; it probably also includes a `:year`, but that isn't needed here.
;; (def default-human-schedule
;; "A sample schedule for a human actor. This assumes that each of:
;; 1. `find-food`;
;; 2. `goto-market`;
;; 3. `help-with-harvest`;
;; 3. `perform-craft`
;; 4. `sleep-until-dawn`
;; Are plans, which is to say, functions of three arguments, an `actor`,
;; a `world` and a `circle`."
;; {:annual {32 {:daily {1020 (fn [a w c] (attend-festival a w c :imbolc))}}
;; 122 {:daily {1020 (fn [a w c] (attend-festival a w c :bealtaine))}}
;; 210 {:daily {480 help-with-harvest}}
;; 211 {:daily {480 help-with-harvest}}
;; 212 {:daily {480 help-with-harvest}}
;; 213 {:daily {480 help-with-harvest}}
;; 214 {:daily {480 help-with-harvest
;; 1020 (fn [a w c](attend-festival a w c :lughnasadh))}}
;; 306 {:daily {1020 (fn [a w c] (attend-festival a w c :samhain))}}}
;; :daily {420 find-food
;; 720 find-food
;; 1020 find-food
;; 1320 sleep-until-dawn}})
(defn plan-scheduled-action [actor world circle]
"Return the scheduled plan for the current time in this `world` from the
schedule of this `actor`, provided the `actor is in an appropriate `circle`"
(case circle
(:active :pending) (let [s (:schedule actor)
d (or (:daily (-> s :annual (-> world :time :day)))
(:daily s))]
(when d (d (-> world :time :minute))))))

View file

@ -0,0 +1,9 @@
(ns cc.journeyman.the-great-game.character.character
"A character that can talk; either human or dragon (although very probably
we won't do talking dragons until really well into this process). All
characters have the news-passing abilities of a gossip, but we use `gossip`
to mean a special character who is part of the news-passing network."
(:require [cc.journeyman.the-great-game.gossip.gossip :refer [dialogue]]
[cc.journeyman.the-great-game.agent.agent :refer [Agent]]))

View file

@ -30,11 +30,14 @@
This namespace at present considers the `:knowledge` of a gossip to be a flat
list of propositions, each of which must be checked every time any new
proposition is offered. This is woefully inefficient. "
(:require [cc.journeyman.the-great-game.world.location :refer [distance-between]]
(:require [clojure.set :refer [union]]
[cc.journeyman.the-great-game.world.location :refer [distance-between]]
[cc.journeyman.the-great-game.time :refer [game-time]]
[cc.journeyman.the-great-game.utils :refer [inc-or-one truthy?]]
[taoensso.timbre :as l]))
(declare interesting-location?)
(def news-topics
"Topics of interest to gossip agents. Topics are keyed in this map by
their `verbs`. The `keys` associated with each topic are the extra pieces
@ -115,12 +118,10 @@
:war {:verb :war :keys [:actor :other :location]
:inferences [{:verb :war :actor :other :other :actor}]}})
(def all-known-verbs
"All verbs currently known to the gossip system."
(set (keys news-topics)))
(defn interest-in-character
"Integer representation of how interesting this `character` is to this
`gossip`.
@ -132,8 +133,9 @@
;; TODO: we ought also check the relationships of the gossip.
;; Are relationships just propositions in the knowledge base?
(filter #(= (:actor %) character) (:knowledge gossip))
(filter #(= (:other %) character) (:knowledge gossip)))))
(filter #(= (:other %) character) (:knowledge gossip))
(when (interesting-location? gossip (:home character))
(list true)))))
(defn interesting-character?
"Boolean representation of whether this `character` is interesting to this
@ -182,19 +184,13 @@
;; TODO: Not yet (really) implemented
true)
(defn interesting-topic?
[gossip topic]
;; TODO: Not yet (really) implemented
true)
(defn interesting-verb?
"Is this `verb` interesting to this `gossip`?"
[gossip verb]
(let [vs (:interesting-verbs gossip)]
(truthy?
(if (set? vs)
(vs verb)
false))))
(when (set? vs)
(vs verb)))))
;; (interesting-verb? {:interesting-verbs #{:kill :sell}} :sell)
@ -246,18 +242,17 @@
"True if anything about this news `item` is interesting to this `gossip`."
[gossip item]
(and (not (known-item? gossip item))
(interesting-verb? gossip item) ;; news is only interesting if the topic is.
(interesting-verb? gossip (:verb item)) ;; news is only interesting if the topic is.
(or
(interesting-character? gossip (:actor item))
(interesting-character? gossip (:other item))
(interesting-location? gossip (:location item))
(interesting-object? gossip (:object item))
(interesting-topic? gossip (:verb item)))))
(interesting-object? gossip (:object item)))))
(defn infer
"Infer a new knowledge item from this `item`, following this `rule`."
[item rule]
;; (l/info "Applying rule '" rule "' to item '" item "'")
(l/info "Applying rule '" rule "' to item '" item "'")
(reduce merge
item
(cons
@ -330,16 +325,17 @@
g (assoc
gossip
:knowledge
(set
(cons
item'
(:knowledge gossip)))]
(:knowledge gossip))))]
(if follow-inferences?
(assoc
g
:knowledge
(concat (:knowledge g) (make-all-inferences item')))
g)))
gossip))
(union (:knowledge g) (make-all-inferences item')))
g))
gossip)))

View file

@ -0,0 +1,4 @@
(ns cc.journeyman.the-great-game.lore.digester
(:require [org.clojurenlp.core :refer [pos-tag sentenize split-sentences
tag-ner tokenize word
]]))

View file

@ -146,8 +146,7 @@
#(let [q (-> world :cities origin :stock %)]
(and (number? q) (pos? q)))
(keys available)))]
(if
(not (empty? plans))
(when-not (empty? plans)
(first
(sort-by
#(- 0 (:dist-to-home %))

View file

@ -0,0 +1,2 @@
(ns cc.journeyman.the-great-game.objects.character
(:require [cc.journeyman.the-great-game.objects.game-object :as obj]))

View file

@ -1,159 +0,0 @@
(ns the-great-game.merchants.planning
"Trade planning for merchants, primarily. This follows a simple-minded
generate-and-test strategy and currently generates plans for all possible
routes from the current location. This may not scale. Also, routes do not
currently have cost or risk associated with them."
(:require [the-great-game.utils :refer [deep-merge make-target-filter]]
[the-great-game.merchants.merchant-utils :refer :all]
[the-great-game.world.routes :refer [find-route]]
[the-great-game.world.world :refer [actual-price default-world]]))
(defn generate-trade-plans
"Generate all possible trade plans for this `merchant` and this `commodity`
in this `world`.
Returned plans are maps with keys:
* :merchant - the id of the `merchant` for whom the plan was created;
* :origin - the city from which the trade starts;
* :destination - the city to which the trade is planned;
* :commodity - the `commodity` to be carried;
* :buy-price - the price at which that `commodity` can be bought;
* :expected-price - the price at which the `merchant` anticipates
that `commodity` can be sold;
* :distance - the number of stages in the planned journey
* :dist-to-home - the distance from `destination` to the `merchant`'s
home city."
[merchant world commodity]
(let [m (cond
(keyword? merchant)
(-> world :merchants merchant)
(map? merchant)
merchant)
origin (:location m)]
(map
#(hash-map
:merchant (:id m)
:origin origin
:destination %
:commodity commodity
:buy-price (actual-price world commodity origin)
:expected-price (expected-price
m
commodity
%)
:distance (count
(find-route world origin %))
:dist-to-home (count
(find-route
world
(:home m)
%)))
(remove #(= % origin) (-> world :cities keys)))))
(defn nearest-with-targets
"Return the distance to the nearest destination among those of these
`plans` which match these `targets`. Plans are expected to be plans
as returned by `generate-trade-plans`, q.v.; `targets` are expected to be
as accepted by `make-target-filter`, q.v."
[plans targets]
(apply
min
(map
:distance
(filter
(make-target-filter targets)
plans))))
(defn plan-trade
"Find the best destination in this `world` for this `commodity` given this
`merchant` and this `origin`. If two cities are anticipated to offer the
same price, the nearer should be preferred; if two are equally distant, the
ones nearer to the merchant's home should be preferred.
`merchant` may be passed as a map or a keyword; `commodity` should be
passed as a keyword.
The returned plan is a map with keys:
* :merchant - the id of the `merchant` for whom the plan was created;
* :origin - the city from which the trade starts;
* :destination - the city to which the trade is planned;
* :commodity - the `commodity` to be carried;
* :buy-price - the price at which that `commodity` can be bought;
* :expected-price - the price at which the `merchant` anticipates
that `commodity` can be sold;
* :distance - the number of stages in the planned journey
* :dist-to-home - the distance from `destination` to the `merchant`'s
home city."
[merchant world commodity]
(let [plans (generate-trade-plans merchant world commodity)
best-prices (filter
(make-target-filter
[[:expected-price
(apply
max
(filter number? (map :expected-price plans)))]])
plans)]
(first
(sort-by
;; all other things being equal, a merchant would prefer to end closer
;; to home.
#(- 0 (:dist-to-home %))
;; a merchant will seek the best price, but won't go further than
;; needed to get it.
(filter
(make-target-filter
[[:distance
(apply min (filter number? (map :distance best-prices)))]])
best-prices)))))
(defn augment-plan
"Augment this `plan` constructed in this `world` for this `merchant` with
the `:quantity` of goods which should be bought and the `:expected-profit`
of the trade.
Returns the augmented plan."
[merchant world plan]
(let [c (:commodity plan)
o (:origin plan)
q (min
(or
(-> world :cities o :stock c)
0)
(can-carry merchant world c)
(can-afford merchant world c))
p (* q (- (:expected-price plan) (:buy-price plan)))]
(assoc plan :quantity q :expected-profit p)))
(defn select-cargo
"A `merchant`, in a given location in a `world`, will choose to buy a cargo
within the limit they are capable of carrying, which they can anticipate
selling for a profit at a destination."
[merchant world]
(let [m (cond
(keyword? merchant)
(-> world :merchants merchant)
(map? merchant)
merchant)
origin (:location m)
available (-> world :cities origin :stock)
plans (map
#(augment-plan
m
world
(plan-trade m world %))
(filter
#(let [q (-> world :cities origin :stock %)]
(and (number? q) (> q 0)))
(keys available)))]
(if
(not (empty? plans))
(first
(sort-by
#(- 0 (:dist-to-home %))
(filter
(make-target-filter
[[:expected-profit
(apply max (filter number? (map :expected-profit plans)))]])
plans))))))

View file

@ -3,12 +3,12 @@
[cc.journeyman.the-great-game.gossip.news-items :refer
[all-known-verbs compatible-item? degrade-location infer
interest-in-character interesting-character? interest-in-location
interesting-location? learn-news-item make-all-inferences]]))
interesting-location? learn-news-item make-all-inferences known-item?]]))
(deftest interesting-character-tests
(testing "To what degree characters are of interest to the gossip"
(let [expected 1
gossip {:home [{0, 0} :test-home]
gossip {:home [{:x 0 :y 0} :test-home]
:interesting-verbs all-known-verbs
;; already knows about adam
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
@ -17,7 +17,7 @@
:adam)]
(is (= actual expected)))
(let [expected 0
gossip {:home [{0, 0} :test-home]
gossip {:home [{:x 0 :y 0} :test-home]
:interesting-verbs all-known-verbs
;; already knows about adam
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
@ -27,7 +27,7 @@
(is (= actual expected))))
(testing "Whether characters are of interest to the gossip"
(let [expected true
gossip {:home [{0, 0} :test-home]
gossip {:home [{:x 0 :y 0} :test-home]
:interesting-verbs all-known-verbs
;; already knows about adam
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
@ -36,7 +36,7 @@
:adam)]
(is (= actual expected)))
(let [expected false
gossip {:home [{0, 0} :test-home]
gossip {:home [{:x 0 :y 0} :test-home]
:interesting-verbs all-known-verbs
;; already knows about adam
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
@ -158,12 +158,12 @@
(testing "Degrading locations"
(let [expected [:galloway]
actual (degrade-location
{:home [{0 0} :test-home :galloway]}
{:home [{:x 0 :y 0} :test-home :galloway]}
[{-4 55} :auchencairn :galloway])]
(is (= actual expected)))
(let [expected nil
actual (degrade-location
{:home [{0 0} :test-home :galloway]}
{:home [{:x 0 :y 0} :test-home :galloway]}
[:froboz])]
(is (= actual expected)))))
@ -195,17 +195,16 @@
(deftest learn-tests
(testing "Learning from an interesting news item."
(let [expected {:home [{0 0} :test-home]
:interesting-verbs all-known-verbs
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}
{:verb :sex, :actor :adam, :other :belinda, :location [:test-home], :nth-hand 1}
{:verb :sex, :actor :belinda, :other :adam, :location [:test-home], :nth-hand 1}]}
gossip {:home [{0, 0} :test-home]
(let [before {:home [{:x 0 :y 0} :test-home]
:interesting-verbs all-known-verbs
;; already knows about adam
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
actual (learn-news-item
gossip
:knowledge #{{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}}}
after (learn-news-item
before
{:verb :sex :actor :adam :other :belinda :location [:test-home]})]
(is (= actual expected)))))
(and
(is (known-item? after {:verb :sex :actor :adam :other :belinda :location [:test-home]})
"has learned the item that was given")
(is (known-item? after {:verb :sex, :actor :belinda, :other :adam, :location [:test-home]})
"has learned information that can be inferred from that item")))))

View file

@ -9,12 +9,6 @@
{
"path": "../jme-clj"
},
{
"path": "../codox"
},
{
"path": "../cloverage"
},
{
"path": "../MicroWorld/mw-engine"
},
@ -23,9 +17,13 @@
},
{
"path": "../test-graphs"
},
{
"path": "../speechio"
}
],
"settings": {
"java.configuration.updateBuildConfiguration": "automatic"
"java.configuration.updateBuildConfiguration": "automatic",
"java.compile.nullAnalysis.mode": "automatic"
}
}