mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Clean up contrib docs, autogeneration
This commit is contained in:
parent
b922cf9b3c
commit
e96bbb4b86
94 changed files with 4126 additions and 2536 deletions
|
|
@ -1,12 +1,10 @@
|
|||
# AWSstorage system
|
||||
|
||||
Contrib by The Right Honourable Reverend (trhr) 2020
|
||||
|
||||
## What is this for?
|
||||
Contrib by The Right Honourable Reverend (trhr), 2020
|
||||
|
||||
This plugin migrates the Web-based portion of Evennia, namely images,
|
||||
javascript, and other items located inside staticfiles into Amazon AWS (S3) for
|
||||
hosting.
|
||||
javascript, and other items located inside staticfiles into Amazon AWS (S3)
|
||||
cloud hosting. Great for those serving media with the game.
|
||||
|
||||
Files hosted on S3 are "in the cloud," and while your personal
|
||||
server may be sufficient for serving multimedia to a minimal number of users,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# Input/Output Auditing
|
||||
|
||||
Contrib - Johnny 2017
|
||||
Contribution by Johnny, 2017
|
||||
|
||||
This is a tap that optionally intercepts all data sent to/from clients and the
|
||||
server and passes it to a callback of your choosing.
|
||||
Utility that taps and intercepts all data sent to/from clients and the
|
||||
server and passes it to a callback of your choosing. This is intended for
|
||||
quality assurance, post-incident investigations and debugging.
|
||||
|
||||
It is intended for quality assurance, post-incident investigations and debugging
|
||||
but obviously can be abused. All data is recorded in cleartext. Please
|
||||
be ethical, and if you are unwilling to properly deal with the implications of
|
||||
recording user passwords or private communications, please do not enable
|
||||
this module.
|
||||
Note that this should be used with care since it can obviously be abused. All
|
||||
data is recorded in cleartext. Please be ethical, and if you are unwilling to
|
||||
properly deal with the implications of recording user passwords or private
|
||||
communications, please do not enable this module.
|
||||
|
||||
Some checks have been implemented to protect the privacy of users.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
# Barter system
|
||||
|
||||
Evennia contribution - Griatch 2012
|
||||
Contribution by Griatch, 2012
|
||||
|
||||
This implements a full barter system - a way for players to safely
|
||||
trade items between each other using code rather than simple free-form
|
||||
talking. The advantage of this is increased buy/sell safety but it
|
||||
also streamlines the process and makes it faster when doing many
|
||||
transactions (since goods are automatically exchanged once both
|
||||
agree).
|
||||
|
||||
This system is primarily intended for a barter economy, but can easily
|
||||
be used in a monetary economy as well -- just let the "goods" on one
|
||||
side be coin objects (this is more flexible than a simple "buy"
|
||||
command since you can mix coins and goods in your trade).
|
||||
trade items between each other in code rather than simple `give/get`
|
||||
commands. This increases both safety (at no time will one player have
|
||||
both goods and payment in-hand) and speed, since agreed goods will
|
||||
be moved automatically). By just replacing one side with coin objects,
|
||||
(or a mix of coins and goods), this also works fine for regular money
|
||||
transactions.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Batch processor examples
|
||||
|
||||
Contibution - Griatch 2012
|
||||
Contibution by Griatch, 2012
|
||||
|
||||
The batch processor is used for generating in-game content from one or more
|
||||
static files. Files can be stored with version control and then 'applied'
|
||||
to the game to create content.
|
||||
Simple examples for the batch-processor. The batch processor is used for generating
|
||||
in-game content from one or more static files. Files can be stored with version
|
||||
control and then 'applied' to the game to create content.
|
||||
|
||||
There are two batch processor types:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Script example
|
||||
|
||||
Griatch - 2012
|
||||
Contribution by Griatch, 2012
|
||||
|
||||
Example script for testing. This adds a simple timer that has your
|
||||
character make observations and notices at irregular intervals.
|
||||
character make small verbal observations at irregular intervals.
|
||||
|
||||
To test, use (in game)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
# Building menu
|
||||
|
||||
Module containing the building menu system.
|
||||
|
||||
Evennia contributor: vincent-lg 2018
|
||||
Contrib by vincent-lg, 2018
|
||||
|
||||
Building menus are in-game menus, not unlike `EvMenu` though using a
|
||||
different approach. Building menus have been specifically designed to edit
|
||||
information as a builder. Creating a building menu in a command allows
|
||||
builders quick-editing of a given object, like a room. If you follow the
|
||||
steps below to add the contrib, you will have access to an `@edit` command
|
||||
that will edit any default object offering to change its key and description.
|
||||
different approach. Building menus have been specifically designed to edit
|
||||
information as a builder. Creating a building menu in a command allows
|
||||
builders quick-editing of a given object, like a room. If you follow the
|
||||
steps to add the contrib, you will have access to an `edit` command
|
||||
that will edit any default object, offering to change its key and description.
|
||||
|
||||
## Install
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Clothing
|
||||
|
||||
Evennia contribution - Tim Ashley Jenkins 2017
|
||||
Contribution by Tim Ashley Jenkins, 2017
|
||||
|
||||
Provides a typeclass and commands for wearable clothing,
|
||||
which is appended to a character's description when worn.
|
||||
Provides a typeclass and commands for wearable clothing. These
|
||||
look of these clothes are appended to the character's description when worn.
|
||||
|
||||
Clothing items, when worn, are added to the character's description
|
||||
in a list. For example, if wearing the following clothing items:
|
||||
|
|
@ -13,6 +13,11 @@ in a list. For example, if wearing the following clothing items:
|
|||
one nice hat
|
||||
a very pretty dress
|
||||
|
||||
Would result in this added description:
|
||||
|
||||
Tim is wearing one nice hat, a thin and delicate necklace,
|
||||
a very pretty dress and a pair of regular ol' shoes.
|
||||
|
||||
## Installation
|
||||
|
||||
To install, import this module and have your default character
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
# Color markups
|
||||
|
||||
Contribution, Griatch 2017
|
||||
Contrib by Griatch, 2017
|
||||
|
||||
Additional color markup styles for Evennia (extending or replacing the default
|
||||
`|r`, `|234` etc).
|
||||
`|r`, `|234`). Adds support for MUSH-style (`%cr`, `%c123`) and/or legacy-Evennia
|
||||
(`{r`, `{123`).
|
||||
|
||||
|
||||
## Installation
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
# Cooldown contrib module.
|
||||
# Cooldowns
|
||||
|
||||
Evennia contrib - owllex, 2021
|
||||
Contribution by owllex, 2021
|
||||
|
||||
This contrib provides a simple cooldown handler that can be attached to any
|
||||
typeclassed Object or Account. A cooldown is a lightweight persistent
|
||||
asynchronous timer that you can query to see if it is ready.
|
||||
|
||||
Cooldowns are good for modelling rate-limited actions, like how often a
|
||||
character can perform a given command.
|
||||
Cooldowns are used modelling rate-limited actions, like how often a
|
||||
character can perform a given action; until a certain time has passed their
|
||||
command can not be used again. This contrib provides a simple cooldown
|
||||
handler that can be attached to any typeclass. A cooldown is a lightweight persistent
|
||||
asynchronous timer that you can query to see if a certain time has yet passed.
|
||||
|
||||
Cooldowns are completely asynchronous and must be queried to know their
|
||||
state. They do not fire callbacks, so are not a good fit for use cases
|
||||
|
|
|
|||
|
|
@ -1,25 +1,46 @@
|
|||
# Crafting system
|
||||
|
||||
Contrib - Griatch 2020
|
||||
Contribution by Griatch 2020
|
||||
|
||||
This implements a full crafting system. The principle is that of a 'recipe':
|
||||
This implements a full crafting system. The principle is that of a 'recipe',
|
||||
where you combine items (tagged as ingredients) create something new. The recipe can also
|
||||
require certain (non-consumed) tools. An example would be to use the 'bread recipe' to
|
||||
combine 'flour', 'water' and 'yeast' with an 'oven' to bake a 'loaf of bread'.
|
||||
|
||||
ingredient1 + ingredient2 + ... + tool1 + tool2 + ... + craft_recipe -> objectA, objectB, ...
|
||||
The recipe process can be understood like this:
|
||||
|
||||
ingredient(s) + tool(s) + recipe -> object(s)
|
||||
|
||||
Here, 'ingredients' are consumed by the crafting process, whereas 'tools' are
|
||||
necessary for the process by will not be destroyed by it.
|
||||
necessary for the process but will not be destroyed by it.
|
||||
|
||||
An example would be to use the tools 'bowl' and 'oven' to use the ingredients
|
||||
'flour', 'salt', 'yeast' and 'water' to create 'bread' using the 'bread recipe'.
|
||||
The included `craft` command works like this:
|
||||
|
||||
A recipe does not have to use tools, like 'snow' + 'snowball-recipe' becomes
|
||||
'snowball'. Conversely one could also imagine using tools without consumables,
|
||||
like using 'spell book' and 'wand' to produce 'fireball' by having the recipe
|
||||
check some magic skill on the character.
|
||||
craft <recipe> [from <ingredient>,...] [using <tool>, ...]
|
||||
|
||||
The system is generic enough to be used also for adventure-like puzzles, like
|
||||
combining 'stick', 'string' and 'hook' to get a 'makeshift fishing rod' that
|
||||
you can use with 'storm drain' (treated as a tool) to get 'key' ...
|
||||
## Examples
|
||||
|
||||
Using the `craft` command:
|
||||
|
||||
craft toy car from plank, wooden wheels, nails using saw, hammer
|
||||
|
||||
A recipe does not have to use tools or even multiple ingredients:
|
||||
|
||||
snow + snowball_recipe -> snowball
|
||||
|
||||
Conversely one could also imagine using tools without consumables, like
|
||||
|
||||
spell_book + wand + fireball_recipe -> fireball
|
||||
|
||||
The system is generic enough to be used also for adventure-like puzzles (but
|
||||
one would need to change the command and determine the recipe on based on what
|
||||
is being combined instead):
|
||||
|
||||
stick + string + hook -> makeshift_fishing_rod
|
||||
makeshift_fishing_rod + storm_drain -> key
|
||||
|
||||
See the [sword example](evennia.contrib.game_systems.crafting.example_recipes) for an example
|
||||
of how to design a recipe tree for crafting a sword from base elements.
|
||||
|
||||
## Intallation and Usage
|
||||
|
||||
|
|
@ -29,18 +50,30 @@ available to you:
|
|||
|
||||
craft <recipe> [from <ingredient>,...] [using <tool>, ...]
|
||||
|
||||
For example
|
||||
In code, you can craft using the
|
||||
`evennia.contrib.game_systems.crafting.craft` function:
|
||||
|
||||
craft toy car from plank, wooden wheels, nails using saw, hammer
|
||||
```python
|
||||
from evennia.contrib.game_systems.crafting import craft
|
||||
|
||||
To use crafting you need recipes. Add a new variable to `mygame/server/conf/settings.py`:
|
||||
result = craft(caller, "recipename", *inputs)
|
||||
|
||||
```
|
||||
Here, `caller` is the one doing the crafting and `*inputs` is any combination of
|
||||
consumables and/or tool Objects. The system will identify which is which by the
|
||||
[Tags](../Components/Tags.md) on them (see below) The `result` is always a list.
|
||||
|
||||
To use crafting you need recipes. Add a new variable to
|
||||
`mygame/server/conf/settings.py`:
|
||||
|
||||
CRAFT_RECIPE_MODULES = ['world.recipes']
|
||||
|
||||
All top-level classes in these modules (whose name does not start with `_`)
|
||||
will be parsed by Evennia as recipes to make available to the crafting system.
|
||||
Using the above example, create `mygame/world/recipes.py` and add your recipies
|
||||
in there:
|
||||
All top-level classes in these modules (whose name does not start with `_`) will
|
||||
be parsed by Evennia as recipes to make available to the crafting system. Using
|
||||
the above example, create `mygame/world/recipes.py` and add your recipies in
|
||||
there:
|
||||
|
||||
A quick example (read on for more details):
|
||||
|
||||
```python
|
||||
|
||||
|
|
@ -69,37 +102,202 @@ class RecipeBread(CraftingRecipe):
|
|||
def pre_craft(self, **kwargs):
|
||||
# validates inputs etc. Raise `CraftingValidationError` if fails
|
||||
|
||||
def craft(self, **kwargs):
|
||||
# performs the craft - but it can still fail (check skills etc here)
|
||||
def do_craft(self, **kwargs):
|
||||
# performs the craft - report errors directly to user and return None (if
|
||||
# failed) and the created object(s) if successful.
|
||||
|
||||
def craft(self, result, **kwargs):
|
||||
# any post-crafting effects. Always called, even if crafting failed (be
|
||||
def post_craft(self, result, **kwargs):
|
||||
# any post-crafting effects. Always called, even if do_craft failed (the
|
||||
# result would be None then)
|
||||
|
||||
```
|
||||
|
||||
## Technical
|
||||
## Adding new recipes
|
||||
|
||||
The Recipe is a class that specifies the consumables, tools and output along
|
||||
with various methods (that you can override) to do the the validation of inputs
|
||||
and perform the crafting itself.
|
||||
A *recipe* is a class inheriting from
|
||||
`evennia.contrib.crafting.crafting.CraftingRecipe`. This class implements the
|
||||
most common form of crafting - that using in-game objects. Each recipe is a
|
||||
separate class which gets initialized with the consumables/tools you provide.
|
||||
|
||||
By default the input is a list of object-tags (using the "crafting_material"
|
||||
and "crafting_tool" tag-categories respectively). Providing a set of objects
|
||||
matching these tags are required for the crafting to be done. The use of tags
|
||||
means that multiple different objects could all work for the same recipe, as
|
||||
long as they have the right tag. This can be very useful for allowing players
|
||||
to experiment and explore alternative ways to create things!
|
||||
For the `craft` command to find your custom recipes, you need to tell Evennia
|
||||
where they are. Add a new line to your `mygame/server/conf/settings.py` file,
|
||||
with a list to any new modules with recipe classes.
|
||||
|
||||
The output is given by a set of prototype-dicts. If the input is correct and
|
||||
other checks are passed (such as crafting skill, for example), these prototypes
|
||||
will be used to generate the new object(s) being crafted.
|
||||
```python
|
||||
CRAFT_RECIPE_MODULES = ["world.myrecipes"]
|
||||
```
|
||||
|
||||
(You need to reload after adding this). All global-level classes in these
|
||||
modules (whose names don't start with underscore) are considered by the system
|
||||
as viable recipes.
|
||||
|
||||
Here we assume you created `mygame/world/myrecipes.py` to match the above
|
||||
example setting:
|
||||
|
||||
```python
|
||||
# in mygame/world/myrecipes.py
|
||||
|
||||
from evennia.contrib.crafting.crafting import CraftingRecipe
|
||||
|
||||
class WoodenPuppetRecipe(CraftingRecipe):
|
||||
"""A puppet""""
|
||||
name = "wooden puppet" # name to refer to this recipe as
|
||||
tool_tags = ["knife"]
|
||||
consumable_tags = ["wood"]
|
||||
output_prototypes = [
|
||||
{"key": "A carved wooden doll",
|
||||
"typeclass": "typeclasses.objects.decorations.Toys",
|
||||
"desc": "A small carved doll"}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
This specifies which tags to look for in the inputs. It defines a
|
||||
[Prototype](../Components/Prototypes.md) for the recipe to use to spawn the
|
||||
result on the fly (a recipe could spawn more than one result if needed).
|
||||
Instead of specifying the full prototype-dict, you could also just provide a
|
||||
list of `prototype_key`s to existing prototypes you have.
|
||||
|
||||
After reloading the server, this recipe would now be available to use. To try it
|
||||
we should create materials and tools to insert into the recipe.
|
||||
|
||||
|
||||
The recipe analyzes inputs, looking for [Tags](../Components/Tags.md) with
|
||||
specific tag-categories. The tag-category used can be set per-recipe using the
|
||||
(`.consumable_tag_category` and `.tool_tag_category` respectively). The defaults
|
||||
are `crafting_material` and `crafting_tool`. For
|
||||
the puppet we need one object with the `wood` tag and another with the `knife`
|
||||
tag:
|
||||
|
||||
```python
|
||||
from evennia import create_object
|
||||
|
||||
knife = create_object(key="Hobby knife", tags=[("knife", "crafting_tool")])
|
||||
wood = create_object(key="Piece of wood", tags[("wood", "crafting_material")])
|
||||
```
|
||||
|
||||
Note that the objects can have any name, all that matters is the
|
||||
tag/tag-category. This means if a "bayonet" also had the "knife" crafting tag,
|
||||
it could also be used to carve a puppet. This is also potentially interesting
|
||||
for use in puzzles and to allow users to experiment and find alternatives to
|
||||
know ingredients.
|
||||
|
||||
By the way, there is also a simple shortcut for doing this:
|
||||
|
||||
```
|
||||
tools, consumables = WoodenPuppetRecipe.seed()
|
||||
```
|
||||
|
||||
The `seed` class-method will create simple dummy objects that fulfills the
|
||||
recipe's requirements. This is great for testing.
|
||||
|
||||
Assuming these objects were put in our inventory, we could now craft using the
|
||||
in-game command:
|
||||
|
||||
```bash
|
||||
> craft wooden puppet from wood using hobby knife
|
||||
```
|
||||
In code we would do
|
||||
|
||||
```python
|
||||
from evennia.contrub.crafting.crafting import craft
|
||||
puppet = craft(crafter, "wooden puppet", knife, wood)
|
||||
|
||||
```
|
||||
In the call to `craft`, the order of `knife` and `wood` doesn't matter - the
|
||||
recipe will sort out which is which based on their tags.
|
||||
|
||||
## Deeper customization of recipes
|
||||
|
||||
For customizing recipes further, it helps to understand how to use the
|
||||
recipe-class directly:
|
||||
|
||||
```python
|
||||
class MyRecipe(CraftingRecipe):
|
||||
# ...
|
||||
|
||||
tools, consumables = MyRecipe.seed()
|
||||
recipe = MyRecipe(crafter, *(tools + consumables))
|
||||
result = recipe.craft()
|
||||
|
||||
```
|
||||
This is useful for testing and allows you to use the class directly without
|
||||
adding it to a module in `settings.CRAFTING_RECIPE_MODULES`.
|
||||
|
||||
Even without modifying more than the class properties, there are a lot of
|
||||
options to set on the `CraftingRecipe` class. Easiest is to refer to the
|
||||
[CraftingRecipe api
|
||||
documentation](evennia.contrib.game_systems.crafting.crafting.CraftingRecipe). For example,
|
||||
you can customize the validation-error messages, decide if the ingredients have
|
||||
to be exactly right, if a failure still consumes the ingredients or not, and
|
||||
much more.
|
||||
|
||||
For even more control you can override hooks in your own class:
|
||||
|
||||
- `pre_craft` - this should handle input validation and store its data in `.validated_consumables` and
|
||||
`validated_tools` respectively. On error, this reports the error to the crafter and raises the
|
||||
`CraftingValidationError`.
|
||||
- `craft` - this will only be called if `pre_craft` finished without an exception. This should
|
||||
return the result of the crafting, by spawnging the prototypes. Or the empty list if crafting
|
||||
fails for some reason. This is the place to add skill-checks or random chance if you need it
|
||||
for your game.
|
||||
- `post_craft` - this receives the result from `craft` and handles error messages and also deletes
|
||||
any consumables as needed. It may also modify the result before returning it.
|
||||
- `msg` - this is a wrapper for `self.crafter.msg` and should be used to send messages to the
|
||||
crafter. Centralizing this means you can also easily modify the sending style in one place later.
|
||||
|
||||
The class constructor (and the `craft` access function) takes optional `**kwargs`. These are passed
|
||||
into each crafting hook. These are unused by default but could be used to customize things per-call.
|
||||
|
||||
### Skilled crafters
|
||||
|
||||
What the crafting system does not have out of the box is a 'skill' system - the
|
||||
notion of being able to fail the craft if you are not skilled enough. Just how
|
||||
skills work is game-dependent, so to add this you need to make your own recipe
|
||||
parent class and have your recipes inherit from this.
|
||||
|
||||
|
||||
```python
|
||||
from random import randint
|
||||
from evennia.contrib.crafting.crafting import CraftingRecipe
|
||||
|
||||
class SkillRecipe(CraftingRecipe):
|
||||
"""A recipe that considers skill"""
|
||||
|
||||
difficulty = 20
|
||||
|
||||
def craft(self, **kwargs):
|
||||
"""The input is ok. Determine if crafting succeeds"""
|
||||
|
||||
# this is set at initialization
|
||||
crafter = self.crafte
|
||||
|
||||
# let's assume the skill is stored directly on the crafter
|
||||
# - the skill is 0..100.
|
||||
crafting_skill = crafter.db.skill_crafting
|
||||
# roll for success:
|
||||
if randint(1, 100) <= (crafting_skill - self.difficulty):
|
||||
# all is good, craft away
|
||||
return super().craft()
|
||||
else:
|
||||
self.msg("You are not good enough to craft this. Better luck next time!")
|
||||
return []
|
||||
```
|
||||
In this example we introduce a `.difficulty` for the recipe and makes a 'dice roll' to see
|
||||
if we succed. We would of course make this a lot more immersive and detailed in a full game. In
|
||||
principle you could customize each recipe just the way you want it, but you could also inherit from
|
||||
a central parent like this to cut down on work.
|
||||
|
||||
The [sword recipe example module](evennia.contrib.game_systems.crafting.example_recipes) also shows an example
|
||||
of a random skill-check being implemented in a parent and then inherited for multiple use.
|
||||
|
||||
## Even more customization
|
||||
|
||||
If you want to build something even more custom (maybe using different input types of validation logic)
|
||||
you could also look at the `CraftingRecipe` parent class `CraftingRecipeBase`.
|
||||
It implements just the minimum needed to be a recipe and for big changes you may be better off starting
|
||||
from this rather than the more opinionated `CraftingRecipe`.
|
||||
|
||||
Each recipe is a stand-alone entity which allows for very advanced
|
||||
customization for every recipe - for example one could have a recipe that
|
||||
checks other properties of the inputs (like quality, color etc) and have that
|
||||
affect the result. Your recipes could also (and likely would) tie into your
|
||||
game's skill system to determine the success or outcome of the crafting.
|
||||
|
||||
|
||||
----
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
# Custom gameime
|
||||
|
||||
Contrib - Griatch 2017, vlgeoff 2017
|
||||
Contrib by vlgeoff, 2017 - based on Griatch's core original
|
||||
|
||||
This reimplements the `evennia.utils.gametime` module but supporting a custom
|
||||
calendar for your game world. It allows for scheduling events to happen at given
|
||||
in-game times, taking this custom calendar into account.
|
||||
This reimplements the `evennia.utils.gametime` module but with a _custom_
|
||||
calendar (unusual number of days per week/month/year etc) for your game world.
|
||||
Like the original, it allows for scheduling events to happen at given
|
||||
in-game times, but now taking this custom calendar into account.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
# Dice
|
||||
|
||||
Rolls dice for roleplaying, in-game gambling or GM:ing
|
||||
Contribution by Griatch, 2012
|
||||
|
||||
A dice roller for any number and side of dice. Adds in-game dice rolling
|
||||
(`roll 2d10 + 1`) as well as conditionals (roll under/over/equal to a target)
|
||||
and functions for rolling dice in code. Command also supports hidden or secret
|
||||
rolls for use by a human game master.
|
||||
|
||||
Evennia contribution - Griatch 2012
|
||||
|
||||
# Installation:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
# Email-based login system
|
||||
|
||||
Evennia contrib - Griatch 2012
|
||||
Contrib by Griatch, 2012
|
||||
|
||||
This is a variant of the login system that requires an email-address
|
||||
instead of a username to login.
|
||||
This is a variant of the login system that asks for an email-address
|
||||
instead of a username to login. Note that it does not verify the email,
|
||||
it just uses it as the identifier rather than a username.
|
||||
|
||||
This used to be the default Evennia login before replacing it with a
|
||||
more standard username + password system (having to supply an email
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
# EvscapeRoom
|
||||
|
||||
Evennia contrib - Griatch 2019
|
||||
Contribution by Griatch, 2019
|
||||
|
||||
This 'Evennia escaperoom game engine' was created for the MUD Coders Guild game
|
||||
Jam, April 14-May 15 2019. The theme for the jam was "One Room". This contains the
|
||||
utilities and base classes and an empty example room.
|
||||
A full engine for creating multiplayer escape-rooms in Evennia. Allows players to
|
||||
spawn and join puzzle rooms that track their state independently. Any number of players
|
||||
can join to solve a room together. This is the engine created for 'EvscapeRoom', which won
|
||||
the MUD Coders Guild "One Room" Game Jam in April-May, 2019. The contrib has no game
|
||||
content but contains the utilities and base classes and an empty example room.
|
||||
|
||||
The original code for the contest is found at
|
||||
https://github.com/Griatch/evscaperoom but the version on the public Evennia
|
||||
demo is more updated, so if you really want the latest bug fixes etc you should
|
||||
rather look at https://github.com/evennia/evdemo/tree/master/evdemo/evscaperoom
|
||||
instead. A copy of the full game can also be played on the Evennia demo server
|
||||
instead. A copy of the full game can also be played on the Evennia demo server
|
||||
at https://demo.evennia.com - just connect to the server and write `evscaperoom`
|
||||
in the first room to start!
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
# Extended Room
|
||||
|
||||
Evennia Contribution - Griatch 2012, vincent-lg 2019
|
||||
Contribution - Griatch 2012, vincent-lg 2019
|
||||
|
||||
This is an extended Room typeclass for Evennia. It is supported
|
||||
by an extended `Look` command and an extended `desc` command, also
|
||||
in this module.
|
||||
This extends the normal `Room` typeclass to allow its description to change
|
||||
with time-of-day and/or season. It also adds 'details' for the player to look at
|
||||
in the room (without having to create a new in-game object for each). The room is
|
||||
supported by new `look` and `desc` commands.
|
||||
|
||||
## Installation/testing:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
# Easy fillable form
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2018
|
||||
Contribution by Tim Ashley Jenkins, 2018
|
||||
|
||||
This module contains a function that calls an easily customizable EvMenu - this
|
||||
menu presents the player with a fillable form, with fields that can be filled
|
||||
out in any order. Each field's value can be verified, with the function
|
||||
allowing easy checks for text and integer input, minimum and maximum values /
|
||||
character lengths, or can even be verified by a custom function. Once the form
|
||||
is submitted, the form's data is submitted as a dictionary to any callable of
|
||||
your choice.
|
||||
This module contains a function that generates an `EvMenu` for you - this
|
||||
menu presents the player with a form of fields that can be filled
|
||||
out in any order (e.g. for character generation or building). Each field's value can
|
||||
be verified, with the function allowing easy checks for text and integer input,
|
||||
minimum and maximum values / character lengths, or can even be verified by a custom
|
||||
function. Once the form is submitted, the form's data is submitted as a dictionary
|
||||
to any callable of your choice.
|
||||
|
||||
## Usage
|
||||
|
||||
The function that initializes the fillable form menu is fairly simple, and
|
||||
includes the caller, the template for the form, and the callback(caller, result)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Gendersub
|
||||
|
||||
Contrib - Griatch 2015
|
||||
Contribution by Griatch 2015
|
||||
|
||||
This is a simple gender-aware Character class for allowing users to
|
||||
insert custom markers in their text to indicate gender-aware
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
# Health Bar
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2017
|
||||
Contribution by Tim Ashley Jenkins, 2017
|
||||
|
||||
The function provided in this module lets you easily display visual
|
||||
bars or meters - "health bar" is merely the most obvious use for this,
|
||||
though these bars are highly customizable and can be used for any sort
|
||||
of appropriate data besides player health.
|
||||
bars or meters as a colorful bar instead of just a number. A "health bar"
|
||||
is merely the most obvious use for this, but the bar is highly customizable
|
||||
and can be used for any sort of appropriate data besides player health.
|
||||
|
||||
Today's players may be more used to seeing statistics like health,
|
||||
stamina, magic, and etc. displayed as bars rather than bare numerical
|
||||
|
|
|
|||
|
|
@ -1,23 +1,19 @@
|
|||
# Dialogues in events
|
||||
|
||||
|
||||
- Next tutorial: [adding a voice-operated elevator with events](A-voice-operated-elevator-using-
|
||||
events).
|
||||
|
||||
This tutorial will walk you through the steps to create several dialogues with characters, using the
|
||||
[in-game Python
|
||||
system](https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md).
|
||||
This tutorial assumes the in-game Python system is installed in your game. If it isn't, you can
|
||||
follow the installation steps given in [the documentation on in-game
|
||||
Python](https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md), and
|
||||
come back on this tutorial once the system is installed. **You do not need to read** the entire
|
||||
documentation, it's a good reference, but not the easiest way to learn about it. Hence these
|
||||
This tutorial will walk you through the steps to create several dialogues with
|
||||
characters, using the Ingame-Python system. This tutorial assumes the in-game
|
||||
Python system is installed in your game. If it isn't, you can follow the
|
||||
installation steps given in [The main In-game Python
|
||||
docs](./Contrib-Ingame-Python.md) and come back on this tutorial once the
|
||||
system is installed. **You do not need to read** the entire documentation, it's
|
||||
a good reference, but not the easiest way to learn about it. Hence these
|
||||
tutorials.
|
||||
|
||||
The in-game Python system allows to run code on individual objects in some situations. You don't
|
||||
have to modify the source code to add these features, past the installation. The entire system
|
||||
makes it easy to add specific features to some objects, but not all. This is why it can be very
|
||||
useful to create a dialogue system taking advantage of the in-game Python system.
|
||||
The in-game Python system allows to run code on individual objects in some
|
||||
situations. You don't have to modify the source code to add these features,
|
||||
past the installation. The entire system makes it easy to add specific features
|
||||
to some objects, but not all. This is why it can be very useful to create a
|
||||
dialogue system taking advantage of the in-game Python system.
|
||||
|
||||
> What will we try to do?
|
||||
|
||||
|
|
@ -115,7 +111,7 @@ This command has opened an editor where we can type our Python code.
|
|||
|
||||
```
|
||||
----------Line Editor [Callback say of a merchant]--------------------------------
|
||||
01|
|
||||
01|
|
||||
----------[l:01 w:000 c:0000]------------(:h for help)----------------------------
|
||||
```
|
||||
|
||||
|
|
@ -246,4 +242,4 @@ could share the same events as well. It is possible to do but requires modifica
|
|||
code.
|
||||
|
||||
- Next tutorial: [adding a voice-operated elevator with events](A-voice-operated-elevator-using-
|
||||
events).
|
||||
events).
|
||||
|
|
@ -1,15 +1,8 @@
|
|||
# A voice operated elevator using events
|
||||
|
||||
|
||||
- Previous tutorial: [Adding dialogues in events](./Dialogues-in-events.md)
|
||||
|
||||
This tutorial will walk you through the steps to create a voice-operated elevator, using the [in-
|
||||
game Python
|
||||
system](https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md).
|
||||
This tutorial assumes the in-game Python system is installed in your game. If it isn't, you can
|
||||
follow the installation steps given in [the documentation on in-game
|
||||
Python](https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md), and
|
||||
come back on this tutorial once the system is installed. **You do not need to read** the entire
|
||||
game Python system](./Contrib-Ingame-Python.md). This tutorial assumes the in-game Python
|
||||
system is installed per the instructions in that doc. **You do not need to read** the entire
|
||||
documentation, it's a good reference, but not the easiest way to learn about it. Hence these
|
||||
tutorials.
|
||||
|
||||
|
|
@ -97,7 +90,8 @@ things to decorate it a bit.
|
|||
But what we want now is to be able to say "1", "2" or "3" and have the elevator move in that
|
||||
direction.
|
||||
|
||||
If you have read [the previous tutorial about adding dialogues in events](./Dialogues-in-events.md), you
|
||||
If you have read
|
||||
[the other in-game Python tutorial about adding dialogues in events](./Contrib-Ingame-Python-Tutorial-Dialogue.md), you
|
||||
may remember what we need to do. If not, here's a summary: we need to run some code when somebody
|
||||
speaks in the room. So we need to create a callback (the callback will contain our lines of code).
|
||||
We just need to know on which event this should be set. You can enter `call here` to see the
|
||||
|
|
@ -132,7 +126,7 @@ Variables you can use in this event:
|
|||
message: the text having been spoken by the character.
|
||||
|
||||
----------Line Editor [Callback say of Inside of an elevator]---------------------
|
||||
01|
|
||||
01|
|
||||
----------[l:01 w:000 c:0000]------------(:h for help)----------------------------
|
||||
```
|
||||
|
||||
|
|
@ -244,7 +238,7 @@ This is a great opportunity to learn about chained events. Chained events are v
|
|||
pauses. Contrary to the events we have seen so far, chained events aren't called automatically.
|
||||
They must be called by you, and can be called after some time.
|
||||
|
||||
- Chained events always have the name "chain_X". Usually, X is a number, but you can give the
|
||||
- Chained events always have the name `"chain_X"`. Usually, X is a number, but you can give the
|
||||
chained event a more explicit name.
|
||||
- In our original callback, we will call our chained events in, say, 15 seconds.
|
||||
- We'll also have to make sure the elevator isn't already moving.
|
||||
|
|
@ -254,7 +248,7 @@ event in our elevator, that will only contain the code necessary to open the doo
|
|||
|
||||
call/add here = chain_1
|
||||
|
||||
The callback is added to the "chain_1" event, an event that will not be automatically called by the
|
||||
The callback is added to the `"chain_1"` event, an event that will not be automatically called by the
|
||||
system when something happens. Inside this event, you can paste the code to open the doors at the
|
||||
new floor. You can notice a few differences:
|
||||
|
||||
|
|
@ -273,7 +267,7 @@ Now let's edit our callback in the "say" event. We'll have to change it a bit:
|
|||
|
||||
- The callback will have to check the elevator isn't already moving.
|
||||
- It must change the exits when the elevator move.
|
||||
- It has to call the "chain_1" event we have defined. It should call it 15 seconds later.
|
||||
- It has to call the `"chain_1"` event we have defined. It should call it 15 seconds later.
|
||||
|
||||
Let's see the code in our callback.
|
||||
|
||||
|
|
@ -415,8 +409,8 @@ constraints on persistent attributes. A callback will not be stored in this way
|
|||
This variable will not be available in your chained event.
|
||||
- **Q:** when you say I can call my chained events something else than "chain_1", "chain_2" and
|
||||
such, what is the naming convention?
|
||||
- **A:** chained events have names beginning by "chain_". This is useful for you and for the
|
||||
system. But after the underscore, you can give a more useful name, like "chain_open_doors" in our
|
||||
- **A:** chained events have names beginning by `"chain_"`. This is useful for you and for the
|
||||
system. But after the underscore, you can give a more useful name, like `"chain_open_doors"` in our
|
||||
case.
|
||||
- **Q:** do I have to pause several seconds to call a chained event?
|
||||
- **A:** no, you can call it right away. Just leave the third parameter of `call_event` out (it
|
||||
|
|
@ -424,13 +418,11 @@ will default to 0, meaning the chained event will be called right away). This w
|
|||
task.
|
||||
- **Q:** can I have chained events calling themselves?
|
||||
- **A:** you can. There's no limitation. Just be careful, a callback that calls itself,
|
||||
particularly without delay, might be a good recipe for an infinite loop. However, in some cases, it
|
||||
particularly without delay, might be a good recipe for an infinite loop. However, in some cases, it
|
||||
is useful to have chained events calling themselves, to do the same repeated action every X seconds
|
||||
for instance.
|
||||
- **Q:** what if I need several elevators, do I need to copy/paste these callbacks each time?
|
||||
- **A:** not advisable. There are definitely better ways to handle this situation. One of them is
|
||||
to consider adding the code in the source itself. Another possibility is to call chained events
|
||||
with the expected behavior, which makes porting code very easy. This side of chained events will be
|
||||
with the expected behavior, which makes porting code very easy. This side of chained events will be
|
||||
shown in the next tutorial.
|
||||
|
||||
- Previous tutorial: [Adding dialogues in events](./Dialogues-in-events.md)
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
# Evennia in-game Python system
|
||||
|
||||
Vincent Le Goff 2017
|
||||
Contrib by Vincent Le Goff 2017
|
||||
|
||||
This contrib adds the system of in-game Python in Evennia, allowing immortals
|
||||
(or other trusted builders) to dynamically add features to individual objects.
|
||||
Using custom Python set in-game, every immortal or privileged users could have a
|
||||
specific room, exit, character, object or something else behave differently from
|
||||
its "cousins". For these familiar with the use of softcode in MU`*`, like SMAUG
|
||||
MudProgs, the ability to add arbitrary behavior to individual objects is a step
|
||||
toward freedom. Keep in mind, however, the warning below, and read it carefully
|
||||
before the rest of the documentation.
|
||||
This contrib adds the ability to script with Python in-game. It allows trusted
|
||||
staff/builders to dynamically add features and triggers to individual objects
|
||||
without needing to do it in external Python modules. Using custom Python in-game,
|
||||
specific rooms, exits, characters, objects etc can be made to behave differently from
|
||||
its "cousins". This is similar to how softcode works for MU or MudProgs for DIKU.
|
||||
Keep in mind, however, that allowing Python in-game comes with _severe_
|
||||
security concerns (you must trust your builders deeply), so read the warnings in
|
||||
this module carefully before continuing.
|
||||
|
||||
## A WARNING REGARDING SECURITY
|
||||
|
||||
|
|
@ -22,6 +22,17 @@ will have to keep in mind these points before deciding to install it:
|
|||
2. You can do all of this in Python outside the game. The in-game Python system
|
||||
is not to replace all your game feature.
|
||||
|
||||
## Extra tutorials
|
||||
|
||||
These tutorials cover examples of using ingame python. Once you have the system
|
||||
installed (see below) they may be an easier way to learn than reading the full
|
||||
documentation from beginning to end.
|
||||
|
||||
- [Dialogue events](./Contrib-Ingame-Python-Tutorial-Dialogue.md), where
|
||||
NPCs react to things said.
|
||||
- [A voice operated elevator](./Contrib-Ingame-Python-Tutorial-Elevator.md)
|
||||
using ingame-python events.
|
||||
|
||||
## Basic structure and vocabulary
|
||||
|
||||
- At the basis of the in-game Python system are **events**. An **event**
|
||||
|
|
@ -73,7 +84,9 @@ default. You need to do it manually, following these steps:
|
|||
This is the quick summary. Scroll down for more detailed help on each step.
|
||||
|
||||
1. Launch the main script (important!):
|
||||
```py evennia.create_script("evennia.contrib.base_systems.ingame_python.scripts.EventHandler")```
|
||||
|
||||
py evennia.create_script("evennia.contrib.base_systems.ingame_python.scripts.EventHandler")
|
||||
|
||||
2. Set the permissions (optional):
|
||||
- `EVENTS_WITH_VALIDATION`: a group that can edit callbacks, but will need approval (default to
|
||||
`None`).
|
||||
|
|
@ -176,7 +189,7 @@ the `EVENTS_WITH_VALIDATION` setting will be able to call the command (with diff
|
|||
### Adding the `call` command
|
||||
|
||||
You also have to add the `@call` command to your Character CmdSet. This command allows your users
|
||||
to add, edit and delete callbacks in-game. In your `commands/default_cmdsets, it might look like
|
||||
to add, edit and delete callbacks in-game. In your `commands/default_cmdsets`, it might look like
|
||||
this:
|
||||
|
||||
```python
|
||||
|
|
@ -277,7 +290,7 @@ We'll see callbacks with parameters later. For the time being, let's try to pre
|
|||
from going through the "north" exit of this room:
|
||||
|
||||
```
|
||||
@call north
|
||||
call north
|
||||
+------------------+---------+-----------------------------------------------+
|
||||
| Event name | Number | Description |
|
||||
+~~~~~~~~~~~~~~~~~~+~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
# In-Game Mail system
|
||||
|
||||
Evennia Contribution - grungies1138 2016
|
||||
Contribution by grungies1138 2016
|
||||
|
||||
A simple Brandymail style mail system that uses the Msg class from Evennia
|
||||
Core. It has two Commands, both of which can be used on their own:
|
||||
A simple Brandymail style mail system that uses the `Msg` class from Evennia
|
||||
Core. It has two Commands for either sending mails between Accounts (out of game)
|
||||
or between Characters (in-game). The two types of mails can be used together or
|
||||
on their own.
|
||||
|
||||
- CmdMail - this should sit on the Account cmdset and makes the `mail` command
|
||||
- `CmdMail` - this should sit on the Account cmdset and makes the `mail` command
|
||||
available both IC and OOC. Mails will always go to Accounts (other players).
|
||||
- CmdMailCharacter - this should sit on the Character cmdset and makes the `mail`
|
||||
- `CmdMailCharacter` - this should sit on the Character cmdset and makes the `mail`
|
||||
command ONLY available when puppeting a character. Mails will be sent to other
|
||||
Characters only and will not be available when OOC.
|
||||
- If adding *both* commands to their respective cmdsets, you'll get two separate
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Map Builder
|
||||
|
||||
Contribution - Cloud_Keeper 2016
|
||||
Contribution by Cloud_Keeper 2016
|
||||
|
||||
Build a map from a 2D ASCII map.
|
||||
Build a game map from the drawing of a 2D ASCII map.
|
||||
|
||||
This is a command which takes two inputs:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Menu-based login system
|
||||
|
||||
Contribution - Vincent-lg 2016, Griatch 2019 (rework for modern EvMenu)
|
||||
Contribution by Vincent-lg 2016. Reworked for modern EvMenu by Griatch, 2019.
|
||||
|
||||
This changes the Evennia login to ask for the account name and password in
|
||||
sequence instead of requiring you to enter both at once. It uses EvMenu under
|
||||
the hood.
|
||||
This changes the Evennia login to ask for the account name and password as a series
|
||||
of questions instead of requiring you to enter both at once. It uses Evennia's
|
||||
menu system `EvMenu` under the hood.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# TutorialMirror
|
||||
|
||||
A simple mirror object to experiment with.
|
||||
Contribution by Griatch, 2017
|
||||
|
||||
A simple mirror object that
|
||||
A simple mirror object to experiment with. It will respond to being looked at.
|
||||
|
||||
- echoes back the description of the object looking at it
|
||||
- echoes back whatever is being sent to its .msg - to the
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
# Evennia Multidescer
|
||||
|
||||
Contrib - Griatch 2016
|
||||
Contribution by Griatch 2016
|
||||
|
||||
A "multidescer" is a concept from the MUSH world. It allows for
|
||||
creating, managing and switching between multiple character
|
||||
descriptions. This multidescer will not require any changes to the
|
||||
Character class, rather it will use the `multidescs` Attribute (a
|
||||
list) and create it if it does not exist.
|
||||
descriptions and is a way for quickly managing your look (such as when
|
||||
changing clothes) in more free-form roleplaying systems. This will also
|
||||
work well together with the `rpsystem` contrib.
|
||||
|
||||
This contrib also works well together with the rpsystem contrib (which
|
||||
also adds the short descriptions and the `sdesc` command).
|
||||
This multidescer will not
|
||||
require any changes to the Character class, rather it will use the `multidescs`
|
||||
Attribute (a list) and create it if it does not exist.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,24 @@
|
|||
# Legacy Comms-commands
|
||||
|
||||
Contribution - Griatch 2021
|
||||
Contribution by Griatch 2021
|
||||
|
||||
In Evennia 1.0, the old Channel commands (originally inspired by MUX) were
|
||||
replaced by the single `channel` command that performs all these function.
|
||||
That command is still required to talk on channels. This contrib (extracted
|
||||
from Evennia 0.9.5) reuses the channel-management of the base Channel command
|
||||
but breaks out its functionality into separate Commands with MUX-familiar names.
|
||||
In Evennia 1.0+, the old Channel commands (originally inspired by MUX) were
|
||||
replaced by the single `channel` command that performs all these functions.
|
||||
This contrib (extracted from Evennia 0.9.5) breaks out the functionality into
|
||||
separate Commands more familiar to MU* users. This is just for show though, the
|
||||
main `channel` command is still called under the hood.
|
||||
|
||||
- `allcom` - `channel/all` and `channel`
|
||||
- `addcom` - `channel/alias`, `channel/sub` and `channel/unmute`
|
||||
- `delcom` - `channel/unalias`, `alias/unsub` and `channel/mute`
|
||||
- `cboot` - `channel/boot` (`channel/ban` and `/unban` not supported)
|
||||
- `cwho` - `channel/who`
|
||||
- `ccreate` - `channel/create`
|
||||
- `cdestroy` - `channel/destroy`
|
||||
- `clock` - `channel/lock`
|
||||
- `cdesc` - `channel/desc`
|
||||
| Contrib syntax | Default `channel` syntax |
|
||||
| -------------- | --------------------------------------------------------- |
|
||||
| `allcom` | `channel/all` and `channel` |
|
||||
| `addcom` | `channel/alias`, `channel/sub` and `channel/unmute` |
|
||||
| `delcom` | `channel/unalias`, `alias/unsub` and `channel/mute` |
|
||||
| `cboot` | `channel/boot` (`channel/ban` and `/unban` not supported) |
|
||||
| `cwho` | `channel/who` |
|
||||
| `ccreate` | `channel/create` |
|
||||
| `cdestroy` | `channel/destroy` |
|
||||
| `clock` | `channel/lock` |
|
||||
| `cdesc` | `channel/desc` |
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -13,11 +13,10 @@ Each contrib contains installation instructions for how to integrate it
|
|||
with your other code. If you want to tweak the code of a contrib, just
|
||||
copy its entire folder to your game directory and modify/use it from there.
|
||||
|
||||
If you want to contribute yourself, see [here](../Contributing.md)!
|
||||
|
||||
> Hint: Additional (potentially un-maintained) code snippets from the community can be found
|
||||
in our discussion forum's [Community Contribs & Snippets](https://github.com/evennia/evennia/discussions/categories/community-contribs-snippets) category.
|
||||
|
||||
If you want to contribute yourself, see [here](../Contributing.md)!
|
||||
|
||||
|
||||
## base_systems
|
||||
|
|
@ -29,113 +28,123 @@ login systems, new command syntaxes, and build helpers._
|
|||
|
||||
### Contrib: `awsstorage`
|
||||
|
||||
Contrib by The Right Honourable Reverend (trhr) 2020
|
||||
_Contrib by The Right Honourable Reverend (trhr), 2020_
|
||||
|
||||
## What is this for?
|
||||
This plugin migrates the Web-based portion of Evennia, namely images,
|
||||
javascript, and other items located inside staticfiles into Amazon AWS (S3)
|
||||
cloud hosting. Great for those serving media with the game.
|
||||
|
||||
[Read the documentation](./Contrib-AWSStorage.md)
|
||||
[Read the documentation](./Contrib-AWSStorage.md) - [Browse the Code](evennia.contrib.base_systems.awsstorage)
|
||||
|
||||
|
||||
|
||||
### Contrib: `building_menu`
|
||||
|
||||
Module containing the building menu system.
|
||||
_Contrib by vincent-lg, 2018_
|
||||
|
||||
Evennia contributor: vincent-lg 2018
|
||||
Building menus are in-game menus, not unlike `EvMenu` though using a
|
||||
different approach. Building menus have been specifically designed to edit
|
||||
information as a builder. Creating a building menu in a command allows
|
||||
builders quick-editing of a given object, like a room. If you follow the
|
||||
steps to add the contrib, you will have access to an `edit` command
|
||||
that will edit any default object, offering to change its key and description.
|
||||
|
||||
[Read the documentation](./Contrib-Building-Menu.md)
|
||||
[Read the documentation](./Contrib-Building-Menu.md) - [Browse the Code](evennia.contrib.base_systems.building_menu)
|
||||
|
||||
|
||||
|
||||
### Contrib: `color_markups`
|
||||
|
||||
Contribution, Griatch 2017
|
||||
_Contrib by Griatch, 2017_
|
||||
|
||||
Additional color markup styles for Evennia (extending or replacing the default
|
||||
`|r`, `|234` etc).
|
||||
`|r`, `|234`). Adds support for MUSH-style (`%cr`, `%c123`) and/or legacy-Evennia
|
||||
(`{r`, `{123`).
|
||||
|
||||
[Read the documentation](./Contrib-Color-Markups.md)
|
||||
[Read the documentation](./Contrib-Color-Markups.md) - [Browse the Code](evennia.contrib.base_systems.color_markups)
|
||||
|
||||
|
||||
|
||||
### Contrib: `custom_gametime`
|
||||
|
||||
Contrib - Griatch 2017, vlgeoff 2017
|
||||
_Contrib by vlgeoff, 2017 - based on Griatch's core original_
|
||||
|
||||
This reimplements the `evennia.utils.gametime` module but supporting a custom
|
||||
calendar for your game world. It allows for scheduling events to happen at given
|
||||
in-game times, taking this custom calendar into account.
|
||||
This reimplements the `evennia.utils.gametime` module but with a _custom_
|
||||
calendar (unusual number of days per week/month/year etc) for your game world.
|
||||
Like the original, it allows for scheduling events to happen at given
|
||||
in-game times, but now taking this custom calendar into account.
|
||||
|
||||
[Read the documentation](./Contrib-Custom-Gametime.md)
|
||||
[Read the documentation](./Contrib-Custom-Gametime.md) - [Browse the Code](evennia.contrib.base_systems.custom_gametime)
|
||||
|
||||
|
||||
|
||||
### Contrib: `email_login`
|
||||
|
||||
Evennia contrib - Griatch 2012
|
||||
_Contrib by Griatch, 2012_
|
||||
|
||||
This is a variant of the login system that requires an email-address
|
||||
instead of a username to login.
|
||||
This is a variant of the login system that asks for an email-address
|
||||
instead of a username to login. Note that it does not verify the email,
|
||||
it just uses it as the identifier rather than a username.
|
||||
|
||||
[Read the documentation](./Contrib-Email-Login.md)
|
||||
[Read the documentation](./Contrib-Email-Login.md) - [Browse the Code](evennia.contrib.base_systems.email_login)
|
||||
|
||||
|
||||
|
||||
### Contrib: `ingame_python`
|
||||
|
||||
Vincent Le Goff 2017
|
||||
_Contrib by Vincent Le Goff 2017_
|
||||
|
||||
This contrib adds the system of in-game Python in Evennia, allowing immortals
|
||||
(or other trusted builders) to dynamically add features to individual objects.
|
||||
Using custom Python set in-game, every immortal or privileged users could have a
|
||||
specific room, exit, character, object or something else behave differently from
|
||||
its "cousins". For these familiar with the use of softcode in MU`*`, like SMAUG
|
||||
MudProgs, the ability to add arbitrary behavior to individual objects is a step
|
||||
toward freedom. Keep in mind, however, the warning below, and read it carefully
|
||||
before the rest of the documentation.
|
||||
This contrib adds the ability to script with Python in-game. It allows trusted
|
||||
staff/builders to dynamically add features and triggers to individual objects
|
||||
without needing to do it in external Python modules. Using custom Python in-game,
|
||||
specific rooms, exits, characters, objects etc can be made to behave differently from
|
||||
its "cousins". This is similar to how softcode works for MU or MudProgs for DIKU.
|
||||
Keep in mind, however, that allowing Python in-game comes with _severe_
|
||||
security concerns (you must trust your builders deeply), so read the warnings in
|
||||
this module carefully before continuing.
|
||||
|
||||
[Read the documentation](./Contrib-Ingame-Python.md)
|
||||
[Read the documentation](./Contrib-Ingame-Python.md) - [Browse the Code](evennia.contrib.base_systems.ingame_python)
|
||||
|
||||
|
||||
|
||||
### Contrib: `menu_login`
|
||||
|
||||
Contribution - Vincent-lg 2016, Griatch 2019 (rework for modern EvMenu)
|
||||
_Contribution by Vincent-lg 2016. Reworked for modern EvMenu by Griatch, 2019._
|
||||
|
||||
This changes the Evennia login to ask for the account name and password in
|
||||
sequence instead of requiring you to enter both at once. It uses EvMenu under
|
||||
the hood.
|
||||
This changes the Evennia login to ask for the account name and password as a series
|
||||
of questions instead of requiring you to enter both at once. It uses Evennia's
|
||||
menu system `EvMenu` under the hood.
|
||||
|
||||
[Read the documentation](./Contrib-Menu-Login.md)
|
||||
[Read the documentation](./Contrib-Menu-Login.md) - [Browse the Code](evennia.contrib.base_systems.menu_login)
|
||||
|
||||
|
||||
|
||||
### Contrib: `mux_comms_cmds`
|
||||
|
||||
Contribution - Griatch 2021
|
||||
_Contribution by Griatch 2021_
|
||||
|
||||
In Evennia 1.0, the old Channel commands (originally inspired by MUX) were
|
||||
replaced by the single `channel` command that performs all these function.
|
||||
That command is still required to talk on channels. This contrib (extracted
|
||||
from Evennia 0.9.5) reuses the channel-management of the base Channel command
|
||||
but breaks out its functionality into separate Commands with MUX-familiar names.
|
||||
In Evennia 1.0+, the old Channel commands (originally inspired by MUX) were
|
||||
replaced by the single `channel` command that performs all these functions.
|
||||
This contrib (extracted from Evennia 0.9.5) breaks out the functionality into
|
||||
separate Commands more familiar to MU* users. This is just for show though, the
|
||||
main `channel` command is still called under the hood.
|
||||
|
||||
[Read the documentation](./Contrib-Mux-Comms-Cmds.md)
|
||||
[Read the documentation](./Contrib-Mux-Comms-Cmds.md) - [Browse the Code](evennia.contrib.base_systems.mux_comms_cmds)
|
||||
|
||||
|
||||
|
||||
### Contrib: `unixcommand`
|
||||
|
||||
Evennia contribution, Vincent Le Geoff 2017
|
||||
_Contribution by Vincent Le Geoff (vlgeoff), 2017_
|
||||
|
||||
This module contains a command class that allows for unix-style command syntax
|
||||
in-game, using --options, positional arguments and stuff like -n 10 etc
|
||||
similarly to a unix command. It might not the best syntax for the average player
|
||||
This module contains a command class with an alternate syntax parser implementing
|
||||
Unix-style command syntax in-game. This means `--options`, positional arguments
|
||||
and stuff like `-n 10`. It might not the best syntax for the average player
|
||||
but can be really useful for builders when they need to have a single command do
|
||||
many things with many options. It uses the ArgumentParser from Python's standard
|
||||
many things with many options. It uses the `ArgumentParser` from Python's standard
|
||||
library under the hood.
|
||||
|
||||
[Read the documentation](./Contrib-Unixcommand.md)
|
||||
[Read the documentation](./Contrib-Unixcommand.md) - [Browse the Code](evennia.contrib.base_systems.unixcommand)
|
||||
|
||||
|
||||
|
||||
|
|
@ -150,13 +159,15 @@ to start creating content without no further additions (unless you want to)._
|
|||
|
||||
### Contrib: `evscaperoom`
|
||||
|
||||
Evennia contrib - Griatch 2019
|
||||
_Contribution by Griatch, 2019_
|
||||
|
||||
This 'Evennia escaperoom game engine' was created for the MUD Coders Guild game
|
||||
Jam, April 14-May 15 2019. The theme for the jam was "One Room". This contains the
|
||||
utilities and base classes and an empty example room.
|
||||
A full engine for creating multiplayer escape-rooms in Evennia. Allows players to
|
||||
spawn and join puzzle rooms that track their state independently. Any number of players
|
||||
can join to solve a room together. This is the engine created for 'EvscapeRoom', which won
|
||||
the MUD Coders Guild "One Room" Game Jam in April-May, 2019. The contrib has no game
|
||||
content but contains the utilities and base classes and an empty example room.
|
||||
|
||||
[Read the documentation](./Contrib-Evscaperoom.md)
|
||||
[Read the documentation](./Contrib-Evscaperoom.md) - [Browse the Code](evennia.contrib.full_systems.evscaperoom)
|
||||
|
||||
|
||||
|
||||
|
|
@ -173,104 +184,115 @@ roleplaying-specific systems, those are found in the `rpg` folder._
|
|||
|
||||
### Contrib: `barter`
|
||||
|
||||
Evennia contribution - Griatch 2012
|
||||
_Contribution by Griatch, 2012_
|
||||
|
||||
This implements a full barter system - a way for players to safely
|
||||
trade items between each other using code rather than simple free-form
|
||||
talking. The advantage of this is increased buy/sell safety but it
|
||||
also streamlines the process and makes it faster when doing many
|
||||
transactions (since goods are automatically exchanged once both
|
||||
agree).
|
||||
trade items between each other in code rather than simple `give/get`
|
||||
commands. This increases both safety (at no time will one player have
|
||||
both goods and payment in-hand) and speed, since agreed goods will
|
||||
be moved automatically). By just replacing one side with coin objects,
|
||||
(or a mix of coins and goods), this also works fine for regular money
|
||||
transactions.
|
||||
|
||||
[Read the documentation](./Contrib-Barter.md)
|
||||
[Read the documentation](./Contrib-Barter.md) - [Browse the Code](evennia.contrib.game_systems.barter)
|
||||
|
||||
|
||||
|
||||
### Contrib: `clothing`
|
||||
|
||||
Evennia contribution - Tim Ashley Jenkins 2017
|
||||
_Contribution by Tim Ashley Jenkins, 2017_
|
||||
|
||||
Provides a typeclass and commands for wearable clothing,
|
||||
which is appended to a character's description when worn.
|
||||
Provides a typeclass and commands for wearable clothing. These
|
||||
look of these clothes are appended to the character's description when worn.
|
||||
|
||||
[Read the documentation](./Contrib-Clothing.md)
|
||||
[Read the documentation](./Contrib-Clothing.md) - [Browse the Code](evennia.contrib.game_systems.clothing)
|
||||
|
||||
|
||||
|
||||
### Contrib: `cooldowns`
|
||||
|
||||
Evennia contrib - owllex, 2021
|
||||
_Contribution by owllex, 2021_
|
||||
|
||||
This contrib provides a simple cooldown handler that can be attached to any
|
||||
typeclassed Object or Account. A cooldown is a lightweight persistent
|
||||
asynchronous timer that you can query to see if it is ready.
|
||||
Cooldowns are used modelling rate-limited actions, like how often a
|
||||
character can perform a given action; until a certain time has passed their
|
||||
command can not be used again. This contrib provides a simple cooldown
|
||||
handler that can be attached to any typeclass. A cooldown is a lightweight persistent
|
||||
asynchronous timer that you can query to see if a certain time has yet passed.
|
||||
|
||||
[Read the documentation](./Contrib-Cooldowns.md)
|
||||
[Read the documentation](./Contrib-Cooldowns.md) - [Browse the Code](evennia.contrib.game_systems.cooldowns)
|
||||
|
||||
|
||||
|
||||
### Contrib: `crafting`
|
||||
|
||||
Contrib - Griatch 2020
|
||||
_Contribution by Griatch 2020_
|
||||
|
||||
This implements a full crafting system. The principle is that of a 'recipe':
|
||||
This implements a full crafting system. The principle is that of a 'recipe',
|
||||
where you combine items (tagged as ingredients) create something new. The recipe can also
|
||||
require certain (non-consumed) tools. An example would be to use the 'bread recipe' to
|
||||
combine 'flour', 'water' and 'yeast' with an 'oven' to bake a 'loaf of bread'.
|
||||
|
||||
[Read the documentation](./Contrib-Crafting.md)
|
||||
[Read the documentation](./Contrib-Crafting.md) - [Browse the Code](evennia.contrib.game_systems.crafting)
|
||||
|
||||
|
||||
|
||||
### Contrib: `gendersub`
|
||||
|
||||
Contrib - Griatch 2015
|
||||
_Contribution by Griatch 2015_
|
||||
|
||||
This is a simple gender-aware Character class for allowing users to
|
||||
insert custom markers in their text to indicate gender-aware
|
||||
messaging. It relies on a modified msg() and is meant as an
|
||||
inspiration and starting point to how to do stuff like this.
|
||||
|
||||
[Read the documentation](./Contrib-Gendersub.md)
|
||||
[Read the documentation](./Contrib-Gendersub.md) - [Browse the Code](evennia.contrib.game_systems.gendersub)
|
||||
|
||||
|
||||
|
||||
### Contrib: `mail`
|
||||
|
||||
Evennia Contribution - grungies1138 2016
|
||||
_Contribution by grungies1138 2016_
|
||||
|
||||
A simple Brandymail style mail system that uses the Msg class from Evennia
|
||||
Core. It has two Commands, both of which can be used on their own:
|
||||
A simple Brandymail style mail system that uses the `Msg` class from Evennia
|
||||
Core. It has two Commands for either sending mails between Accounts (out of game)
|
||||
or between Characters (in-game). The two types of mails can be used together or
|
||||
on their own.
|
||||
|
||||
[Read the documentation](./Contrib-Mail.md)
|
||||
[Read the documentation](./Contrib-Mail.md) - [Browse the Code](evennia.contrib.game_systems.mail)
|
||||
|
||||
|
||||
|
||||
### Contrib: `multidescer`
|
||||
|
||||
Contrib - Griatch 2016
|
||||
_Contribution by Griatch 2016_
|
||||
|
||||
A "multidescer" is a concept from the MUSH world. It allows for
|
||||
creating, managing and switching between multiple character
|
||||
descriptions. This multidescer will not require any changes to the
|
||||
Character class, rather it will use the `multidescs` Attribute (a
|
||||
list) and create it if it does not exist.
|
||||
descriptions and is a way for quickly managing your look (such as when
|
||||
changing clothes) in more free-form roleplaying systems. This will also
|
||||
work well together with the `rpsystem` contrib.
|
||||
|
||||
[Read the documentation](./Contrib-Multidescer.md)
|
||||
[Read the documentation](./Contrib-Multidescer.md) - [Browse the Code](evennia.contrib.game_systems.multidescer)
|
||||
|
||||
|
||||
|
||||
### Contrib: `puzzles`
|
||||
|
||||
Evennia contribution - Henddher 2018
|
||||
_Contribution by Henddher 2018_
|
||||
|
||||
Provides a typeclass and commands for objects that can be combined (i.e. 'use'd)
|
||||
to produce new objects.
|
||||
Intended for adventure-game style combination puzzles, such as combining fruits
|
||||
and a blender to create a smoothie. Provides a typeclass and commands for objects
|
||||
that can be combined (i.e. used together). Unlike the `crafting` contrib, each
|
||||
puzzle is built from unique objects rather than using tags and a builder can create
|
||||
the puzzle entirely from in-game.
|
||||
|
||||
[Read the documentation](./Contrib-Puzzles.md)
|
||||
[Read the documentation](./Contrib-Puzzles.md) - [Browse the Code](evennia.contrib.game_systems.puzzles)
|
||||
|
||||
|
||||
|
||||
### Contrib: `turnbattle`
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2017
|
||||
_Contribution by Tim Ashley Jenkins, 2017_
|
||||
|
||||
This is a framework for a simple turn-based combat system, similar
|
||||
to those used in D&D-style tabletop role playing games. It allows
|
||||
|
|
@ -280,7 +302,7 @@ has a limited time to decide their action for that turn (30 seconds by
|
|||
default), and combat progresses through the turn order, looping through
|
||||
the participants until the fight ends.
|
||||
|
||||
[Read the documentation](./Contrib-Turnbattle.md)
|
||||
[Read the documentation](./Contrib-Turnbattle.md) - [Browse the Code](evennia.contrib.game_systems.turnbattle)
|
||||
|
||||
|
||||
|
||||
|
|
@ -295,80 +317,77 @@ contribs related to rooms, exits and map building._
|
|||
|
||||
### Contrib: `extended_room`
|
||||
|
||||
Evennia Contribution - Griatch 2012, vincent-lg 2019
|
||||
_Contribution - Griatch 2012, vincent-lg 2019_
|
||||
|
||||
This is an extended Room typeclass for Evennia. It is supported
|
||||
by an extended `Look` command and an extended `desc` command, also
|
||||
in this module.
|
||||
This extends the normal `Room` typeclass to allow its description to change
|
||||
with time-of-day and/or season. It also adds 'details' for the player to look at
|
||||
in the room (without having to create a new in-game object for each). The room is
|
||||
supported by new `look` and `desc` commands.
|
||||
|
||||
[Read the documentation](./Contrib-Extended-Room.md)
|
||||
[Read the documentation](./Contrib-Extended-Room.md) - [Browse the Code](evennia.contrib.grid.extended_room)
|
||||
|
||||
|
||||
|
||||
### Contrib: `mapbuilder`
|
||||
|
||||
Contribution - Cloud_Keeper 2016
|
||||
_Contribution by Cloud_Keeper 2016_
|
||||
|
||||
Build a map from a 2D ASCII map.
|
||||
Build a game map from the drawing of a 2D ASCII map.
|
||||
|
||||
[Read the documentation](./Contrib-Mapbuilder.md)
|
||||
[Read the documentation](./Contrib-Mapbuilder.md) - [Browse the Code](evennia.contrib.grid.mapbuilder)
|
||||
|
||||
|
||||
|
||||
### Contrib: `simpledoor`
|
||||
|
||||
Contribution - Griatch 2016
|
||||
_Contribution by Griatch, 2016_
|
||||
|
||||
A simple two-way exit that represents a door that can be opened and
|
||||
closed. Can easily be expanded from to make it lockable, destroyable
|
||||
etc. Note that the simpledoor is based on Evennia locks, so it will
|
||||
not work for a superuser (which bypasses all locks) - the superuser
|
||||
will always appear to be able to close/open the door over and over
|
||||
without the locks stopping you. To use the door, use `@quell` or a
|
||||
non-superuser account.
|
||||
closed from both sides. Can easily be expanded to make it lockable,
|
||||
destroyable etc.
|
||||
|
||||
[Read the documentation](./Contrib-Simpledoor.md)
|
||||
[Read the documentation](./Contrib-Simpledoor.md) - [Browse the Code](evennia.contrib.grid.simpledoor)
|
||||
|
||||
|
||||
|
||||
### Contrib: `slow_exit`
|
||||
|
||||
Contribution - Griatch 2014
|
||||
_Contribution by Griatch 2014_
|
||||
|
||||
This is an example of an Exit-type that delays its traversal. This simulates
|
||||
slow movement, common in many different types of games. The contrib also
|
||||
contains two commands, `CmdSetSpeed` and CmdStop for changing the movement speed
|
||||
An example of an Exit-type that delays its traversal. This simulates
|
||||
slow movement, common in many games. The contrib also
|
||||
contains two commands, `setspeed` and `stop` for changing the movement speed
|
||||
and abort an ongoing traversal, respectively.
|
||||
|
||||
[Read the documentation](./Contrib-Slow-Exit.md)
|
||||
[Read the documentation](./Contrib-Slow-Exit.md) - [Browse the Code](evennia.contrib.grid.slow_exit)
|
||||
|
||||
|
||||
|
||||
### Contrib: `wilderness`
|
||||
|
||||
Evennia contrib - titeuf87 2017
|
||||
_Contribution by titeuf87, 2017_
|
||||
|
||||
This contrib provides a wilderness map without actually creating a large number
|
||||
of rooms - as you move, your room is instead updated with different
|
||||
descriptions. This means you can make huge areas with little database use as
|
||||
of rooms - as you move, you instead end up back in the same room but its description
|
||||
changes. This means you can make huge areas with little database use as
|
||||
long as the rooms are relatively similar (name/desc changing).
|
||||
|
||||
[Read the documentation](./Contrib-Wilderness.md)
|
||||
[Read the documentation](./Contrib-Wilderness.md) - [Browse the Code](evennia.contrib.grid.wilderness)
|
||||
|
||||
|
||||
|
||||
### Contrib: `xyzgrid`
|
||||
|
||||
Full grid coordinate- pathfinding and visualization system
|
||||
Evennia Contrib by Griatch 2021
|
||||
_Contribution by Griatch 2021_
|
||||
|
||||
The default Evennia's rooms are non-euclidian - they can connect
|
||||
to each other with any types of exits without necessarily having a clear
|
||||
position relative to each other. This gives maximum flexibility, but many games
|
||||
want to use cardinal movements (north, east etc) and also features like finding
|
||||
the shortest-path between two points.
|
||||
Places Evennia's game world on an xy (z being different maps) coordinate grid.
|
||||
Grid is created and maintained externally by drawing and parsing 2D ASCII maps,
|
||||
including teleports, map transitions and special markers to aid pathfinding.
|
||||
Supports very fast shortest-route pathfinding on each map. Also includes a
|
||||
fast view function for seeing only a limited number of steps away from your
|
||||
current location (useful for displaying the grid as an in-game, updating map).
|
||||
|
||||
[Read the documentation](./Contrib-XYZGrid.md)
|
||||
[Read the documentation](./Contrib-XYZGrid.md) - [Browse the Code](evennia.contrib.grid.xyzgrid)
|
||||
|
||||
|
||||
|
||||
|
|
@ -383,48 +402,59 @@ and rule implementation like character traits, dice rolling and emoting._
|
|||
|
||||
### Contrib: `dice`
|
||||
|
||||
Rolls dice for roleplaying, in-game gambling or GM:ing
|
||||
_Contribution by Griatch, 2012_
|
||||
|
||||
Evennia contribution - Griatch 2012
|
||||
A dice roller for any number and side of dice. Adds in-game dice rolling
|
||||
(`roll 2d10 + 1`) as well as conditionals (roll under/over/equal to a target)
|
||||
and functions for rolling dice in code. Command also supports hidden or secret
|
||||
rolls for use by a human game master.
|
||||
|
||||
[Read the documentation](./Contrib-Dice.md)
|
||||
[Read the documentation](./Contrib-Dice.md) - [Browse the Code](evennia.contrib.rpg.dice)
|
||||
|
||||
|
||||
|
||||
### Contrib: `health_bar`
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2017
|
||||
_Contribution by Tim Ashley Jenkins, 2017_
|
||||
|
||||
The function provided in this module lets you easily display visual
|
||||
bars or meters - "health bar" is merely the most obvious use for this,
|
||||
though these bars are highly customizable and can be used for any sort
|
||||
of appropriate data besides player health.
|
||||
bars or meters as a colorful bar instead of just a number. A "health bar"
|
||||
is merely the most obvious use for this, but the bar is highly customizable
|
||||
and can be used for any sort of appropriate data besides player health.
|
||||
|
||||
[Read the documentation](./Contrib-Health-Bar.md)
|
||||
[Read the documentation](./Contrib-Health-Bar.md) - [Browse the Code](evennia.contrib.rpg.health_bar)
|
||||
|
||||
|
||||
|
||||
### Contrib: `rpsystem`
|
||||
|
||||
Roleplaying emotes/sdescs - Griatch, 2015
|
||||
Language/whisper emotes - Griatch, 2015
|
||||
_Contribution by Griatch, 2015_
|
||||
|
||||
## Roleplaying emotes
|
||||
A full roleplaying emote system. Short-descriptions and recognition (only
|
||||
know people by their looks until you assign a name to them). Room poses. Masks/disguises
|
||||
(hide your description). Speak directly in emote, with optional language obscuration
|
||||
(words get garbled if you don't know the language, you can also have different languages
|
||||
with different 'sounding' garbling). Whispers can be partly overheard from a distance. A
|
||||
very powerful in-emote reference system, for referencing and differentiate targets
|
||||
(including objects).
|
||||
|
||||
[Read the documentation](./Contrib-RPSystem.md)
|
||||
[Read the documentation](./Contrib-RPSystem.md) - [Browse the Code](evennia.contrib.rpg.rpsystem)
|
||||
|
||||
|
||||
|
||||
### Contrib: `traits`
|
||||
|
||||
Whitenoise 2014, Ainneve contributors,
|
||||
Griatch 2020
|
||||
_Contribution by Griatch 2020, based on code by Whitenoise and Ainneve contribs, 2014_
|
||||
|
||||
A `Trait` represents a modifiable property on (usually) a Character. They can
|
||||
be used to represent everything from attributes (str, agi etc) to skills
|
||||
(hunting 10, swords 14 etc) and dynamically changing things like HP, XP etc.
|
||||
(hunting 10, swords 14 etc) and dynamically changing things like HP, XP etc.
|
||||
Traits differ from normal Attributes in that they track their changes and limit
|
||||
themselves to particular value-ranges. One can add/subtract from them easily and
|
||||
they can even change dynamically at a particular rate (like you being poisoned or
|
||||
healed).
|
||||
|
||||
[Read the documentation](./Contrib-Traits.md)
|
||||
[Read the documentation](./Contrib-Traits.md) - [Browse the Code](evennia.contrib.rpg.traits)
|
||||
|
||||
|
||||
|
||||
|
|
@ -440,71 +470,72 @@ tutorials are found here. Also the home of the Tutorial World demo adventure._
|
|||
|
||||
### Contrib: `batchprocessor`
|
||||
|
||||
Contibution - Griatch 2012
|
||||
_Contibution by Griatch, 2012_
|
||||
|
||||
The batch processor is used for generating in-game content from one or more
|
||||
static files. Files can be stored with version control and then 'applied'
|
||||
to the game to create content.
|
||||
Simple examples for the batch-processor. The batch processor is used for generating
|
||||
in-game content from one or more static files. Files can be stored with version
|
||||
control and then 'applied' to the game to create content.
|
||||
|
||||
[Read the documentation](./Contrib-Batchprocessor.md)
|
||||
[Read the documentation](./Contrib-Batchprocessor.md) - [Browse the Code](evennia.contrib.tutorials.batchprocessor)
|
||||
|
||||
|
||||
|
||||
### Contrib: `bodyfunctions`
|
||||
|
||||
Griatch - 2012
|
||||
_Contribution by Griatch, 2012_
|
||||
|
||||
Example script for testing. This adds a simple timer that has your
|
||||
character make observations and notices at irregular intervals.
|
||||
character make small verbal observations at irregular intervals.
|
||||
|
||||
[Read the documentation](./Contrib-Bodyfunctions.md)
|
||||
[Read the documentation](./Contrib-Bodyfunctions.md) - [Browse the Code](evennia.contrib.tutorials.bodyfunctions)
|
||||
|
||||
|
||||
|
||||
### Contrib: `mirror`
|
||||
|
||||
A simple mirror object to experiment with.
|
||||
_Contribution by Griatch, 2017_
|
||||
|
||||
A simple mirror object that
|
||||
A simple mirror object to experiment with. It will respond to being looked at.
|
||||
|
||||
[Read the documentation](./Contrib-Mirror.md)
|
||||
[Read the documentation](./Contrib-Mirror.md) - [Browse the Code](evennia.contrib.tutorials.mirror)
|
||||
|
||||
|
||||
|
||||
### Contrib: `red_button`
|
||||
|
||||
Griatch - 2011
|
||||
_Contribution by Griatch, 2011_
|
||||
|
||||
This is a more advanced example object with its own functionality (commands)
|
||||
on it.
|
||||
A red button that you can press to have an effect. This is a more advanced example
|
||||
object with its own functionality and state tracking.
|
||||
|
||||
[Read the documentation](./Contrib-Red-Button.md)
|
||||
[Read the documentation](./Contrib-Red-Button.md) - [Browse the Code](evennia.contrib.tutorials.red_button)
|
||||
|
||||
|
||||
|
||||
### Contrib: `talking_npc`
|
||||
|
||||
Contribution - Griatch 2011, grungies1138, 2016
|
||||
_Contribution by Griatch 2011. Updated by grungies1138, 2016_
|
||||
|
||||
This is a static NPC object capable of holding a simple menu-driven
|
||||
conversation. It's just meant as an example.
|
||||
This is an example of a static NPC object capable of holding a simple menu-driven
|
||||
conversation. Suitable for example as a quest giver or merchant.
|
||||
|
||||
[Read the documentation](./Contrib-Talking-Npc.md)
|
||||
[Read the documentation](./Contrib-Talking-Npc.md) - [Browse the Code](evennia.contrib.tutorials.talking_npc)
|
||||
|
||||
|
||||
|
||||
### Contrib: `tutorial_world`
|
||||
|
||||
Griatch 2011, 2015
|
||||
_Contribution by Griatch 2011, 2015_
|
||||
|
||||
This is a stand-alone tutorial area for an unmodified Evennia install.
|
||||
A stand-alone tutorial area for an unmodified Evennia install.
|
||||
Think of it as a sort of single-player adventure rather than a
|
||||
full-fledged multi-player game world. The various rooms and objects
|
||||
herein are designed to show off features of the engine, not to be a
|
||||
are designed to show off features of Evennia, not to be a
|
||||
very challenging (nor long) gaming experience. As such it's of course
|
||||
only skimming the surface of what is possible.
|
||||
only skimming the surface of what is possible. Taking this apart
|
||||
is a great way to start learning the system.
|
||||
|
||||
[Read the documentation](./Contrib-Tutorial-World.md)
|
||||
[Read the documentation](./Contrib-Tutorial-World.md) - [Browse the Code](evennia.contrib.tutorials.tutorial_world)
|
||||
|
||||
|
||||
|
||||
|
|
@ -519,54 +550,53 @@ and more._
|
|||
|
||||
### Contrib: `auditing`
|
||||
|
||||
Contrib - Johnny 2017
|
||||
_Contribution by Johnny, 2017_
|
||||
|
||||
This is a tap that optionally intercepts all data sent to/from clients and the
|
||||
server and passes it to a callback of your choosing.
|
||||
Utility that taps and intercepts all data sent to/from clients and the
|
||||
server and passes it to a callback of your choosing. This is intended for
|
||||
quality assurance, post-incident investigations and debugging.
|
||||
|
||||
[Read the documentation](./Contrib-Auditing.md)
|
||||
[Read the documentation](./Contrib-Auditing.md) - [Browse the Code](evennia.contrib.utils.auditing)
|
||||
|
||||
|
||||
|
||||
### Contrib: `fieldfill`
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2018
|
||||
_Contribution by Tim Ashley Jenkins, 2018_
|
||||
|
||||
This module contains a function that calls an easily customizable EvMenu - this
|
||||
menu presents the player with a fillable form, with fields that can be filled
|
||||
out in any order. Each field's value can be verified, with the function
|
||||
allowing easy checks for text and integer input, minimum and maximum values /
|
||||
character lengths, or can even be verified by a custom function. Once the form
|
||||
is submitted, the form's data is submitted as a dictionary to any callable of
|
||||
your choice.
|
||||
This module contains a function that generates an `EvMenu` for you - this
|
||||
menu presents the player with a form of fields that can be filled
|
||||
out in any order (e.g. for character generation or building). Each field's value can
|
||||
be verified, with the function allowing easy checks for text and integer input,
|
||||
minimum and maximum values / character lengths, or can even be verified by a custom
|
||||
function. Once the form is submitted, the form's data is submitted as a dictionary
|
||||
to any callable of your choice.
|
||||
|
||||
[Read the documentation](./Contrib-Fieldfill.md)
|
||||
[Read the documentation](./Contrib-Fieldfill.md) - [Browse the Code](evennia.contrib.utils.fieldfill)
|
||||
|
||||
|
||||
|
||||
### Contrib: `random_string_generator`
|
||||
|
||||
Contribution - Vincent Le Goff 2017
|
||||
_Contribution by Vincent Le Goff (vlgeoff), 2017_
|
||||
|
||||
This contrib can be used to generate pseudo-random strings of information
|
||||
This utility can be used to generate pseudo-random strings of information
|
||||
with specific criteria. You could, for instance, use it to generate
|
||||
phone numbers, license plate numbers, validation codes, non-sensivite
|
||||
passwords and so on. The strings generated by the generator will be
|
||||
stored and won't be available again in order to avoid repetition.
|
||||
Here's a very simple example:
|
||||
phone numbers, license plate numbers, validation codes, in-game security
|
||||
passwords and so on. The strings generated will be stored and won't be repeated.
|
||||
|
||||
[Read the documentation](./Contrib-Random-String-Generator.md)
|
||||
[Read the documentation](./Contrib-Random-String-Generator.md) - [Browse the Code](evennia.contrib.utils.random_string_generator)
|
||||
|
||||
|
||||
|
||||
### Contrib: `tree_select`
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2017
|
||||
_Contribution by Tim Ashley Jenkins, 2017_
|
||||
|
||||
This module allows you to create and initialize an entire branching EvMenu
|
||||
instance with nothing but a multi-line string passed to one function.
|
||||
This utility allows you to create and initialize an entire branching EvMenu
|
||||
instance from a multi-line string passed to one function.
|
||||
|
||||
[Read the documentation](./Contrib-Tree-Select.md)
|
||||
[Read the documentation](./Contrib-Tree-Select.md) - [Browse the Code](evennia.contrib.utils.tree_select)
|
||||
|
||||
|
||||
|
||||
|
|
@ -574,52 +604,52 @@ instance with nothing but a multi-line string passed to one function.
|
|||
|
||||
|
||||
```{toctree}
|
||||
:depth: 2
|
||||
|
||||
Contribs/Contrib-AWSStorage.md
|
||||
Contribs/Contrib-Building-Menu.md
|
||||
Contribs/Contrib-Color-Markups.md
|
||||
Contribs/Contrib-Custom-Gametime.md
|
||||
Contribs/Contrib-Email-Login.md
|
||||
Contribs/Contrib-Ingame-Python.md
|
||||
Contribs/Contrib-Menu-Login.md
|
||||
Contribs/Contrib-Mux-Comms-Cmds.md
|
||||
Contribs/Contrib-Unixcommand.md
|
||||
Contribs/Contrib-Evscaperoom.md
|
||||
Contribs/Contrib-Barter.md
|
||||
Contribs/Contrib-Clothing.md
|
||||
Contribs/Contrib-Cooldowns.md
|
||||
Contribs/Contrib-Crafting.md
|
||||
Contribs/Contrib-Gendersub.md
|
||||
Contribs/Contrib-Mail.md
|
||||
Contribs/Contrib-Multidescer.md
|
||||
Contribs/Contrib-Puzzles.md
|
||||
Contribs/Contrib-Turnbattle.md
|
||||
Contribs/Contrib-Extended-Room.md
|
||||
Contribs/Contrib-Mapbuilder.md
|
||||
Contribs/Contrib-Simpledoor.md
|
||||
Contribs/Contrib-Slow-Exit.md
|
||||
Contribs/Contrib-Wilderness.md
|
||||
Contribs/Contrib-XYZGrid.md
|
||||
Contribs/Contrib-Dice.md
|
||||
Contribs/Contrib-Health-Bar.md
|
||||
Contribs/Contrib-RPSystem.md
|
||||
Contribs/Contrib-Traits.md
|
||||
Contribs/Contrib-Batchprocessor.md
|
||||
Contribs/Contrib-Bodyfunctions.md
|
||||
Contribs/Contrib-Mirror.md
|
||||
Contribs/Contrib-Red-Button.md
|
||||
Contribs/Contrib-Talking-Npc.md
|
||||
Contribs/Contrib-Tutorial-World.md
|
||||
Contribs/Contrib-Auditing.md
|
||||
Contribs/Contrib-Fieldfill.md
|
||||
Contribs/Contrib-Random-String-Generator.md
|
||||
Contribs/Contrib-Tree-Select.md
|
||||
Contribs/Contrib-Building-Menu.md
|
||||
Contribs/Contrib-Color-Markups.md
|
||||
Contribs/Contrib-Custom-Gametime.md
|
||||
Contribs/Contrib-Email-Login.md
|
||||
Contribs/Contrib-Ingame-Python.md
|
||||
Contribs/Contrib-Menu-Login.md
|
||||
Contribs/Contrib-Mux-Comms-Cmds.md
|
||||
Contribs/Contrib-Unixcommand.md
|
||||
Contribs/Contrib-Evscaperoom.md
|
||||
Contribs/Contrib-Barter.md
|
||||
Contribs/Contrib-Clothing.md
|
||||
Contribs/Contrib-Cooldowns.md
|
||||
Contribs/Contrib-Crafting.md
|
||||
Contribs/Contrib-Gendersub.md
|
||||
Contribs/Contrib-Mail.md
|
||||
Contribs/Contrib-Multidescer.md
|
||||
Contribs/Contrib-Puzzles.md
|
||||
Contribs/Contrib-Turnbattle.md
|
||||
Contribs/Contrib-Extended-Room.md
|
||||
Contribs/Contrib-Mapbuilder.md
|
||||
Contribs/Contrib-Simpledoor.md
|
||||
Contribs/Contrib-Slow-Exit.md
|
||||
Contribs/Contrib-Wilderness.md
|
||||
Contribs/Contrib-XYZGrid.md
|
||||
Contribs/Contrib-Dice.md
|
||||
Contribs/Contrib-Health-Bar.md
|
||||
Contribs/Contrib-RPSystem.md
|
||||
Contribs/Contrib-Traits.md
|
||||
Contribs/Contrib-Batchprocessor.md
|
||||
Contribs/Contrib-Bodyfunctions.md
|
||||
Contribs/Contrib-Mirror.md
|
||||
Contribs/Contrib-Red-Button.md
|
||||
Contribs/Contrib-Talking-Npc.md
|
||||
Contribs/Contrib-Tutorial-World.md
|
||||
Contribs/Contrib-Auditing.md
|
||||
Contribs/Contrib-Fieldfill.md
|
||||
Contribs/Contrib-Random-String-Generator.md
|
||||
Contribs/Contrib-Tree-Select.md
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
<small>This document page is auto-generated from the sources. Manual changes
|
||||
<small>This document page is auto-generated. Manual changes
|
||||
will be overwritten.</small>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
# Puzzles System
|
||||
|
||||
Evennia contribution - Henddher 2018
|
||||
Contribution by Henddher 2018
|
||||
|
||||
Provides a typeclass and commands for objects that can be combined (i.e. 'use'd)
|
||||
to produce new objects.
|
||||
Intended for adventure-game style combination puzzles, such as combining fruits
|
||||
and a blender to create a smoothie. Provides a typeclass and commands for objects
|
||||
that can be combined (i.e. used together). Unlike the `crafting` contrib, each
|
||||
puzzle is built from unique objects rather than using tags and a builder can create
|
||||
the puzzle entirely from in-game.
|
||||
|
||||
A Puzzle is a recipe of what objects (aka parts) must be combined by a player so
|
||||
A `Puzzle` is a recipe of what objects (aka parts) must be combined by a player so
|
||||
a new set of objects (aka results) are automatically created.
|
||||
|
||||
## Installation
|
||||
|
||||
Add the PuzzleSystemCmdSet to all players (e.g. in their Character typeclass).
|
||||
Add the `PuzzleSystemCmdSet` to all players (e.g. in their Character typeclass).
|
||||
|
||||
Alternatively:
|
||||
Alternatively (for quick testing):
|
||||
|
||||
py self.cmdset.add('evennia.contrib.game_systems.puzzles.PuzzleSystemCmdSet')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,17 @@
|
|||
# Roleplaying base system for Evennia
|
||||
|
||||
Roleplaying emotes/sdescs - Griatch, 2015
|
||||
Language/whisper emotes - Griatch, 2015
|
||||
Contribution by Griatch, 2015
|
||||
|
||||
A full roleplaying emote system. Short-descriptions and recognition (only
|
||||
know people by their looks until you assign a name to them). Room poses. Masks/disguises
|
||||
(hide your description). Speak directly in emote, with optional language obscuration
|
||||
(words get garbled if you don't know the language, you can also have different languages
|
||||
with different 'sounding' garbling). Whispers can be partly overheard from a distance. A
|
||||
very powerful in-emote reference system, for referencing and differentiate targets
|
||||
(including objects).
|
||||
|
||||
The system contains of two main modules - the roleplaying emote system and the language
|
||||
obscuration module.
|
||||
|
||||
## Roleplaying emotes
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
# Pseudo-random generator and registry
|
||||
|
||||
Contribution - Vincent Le Goff 2017
|
||||
Contribution by Vincent Le Goff (vlgeoff), 2017
|
||||
|
||||
This contrib can be used to generate pseudo-random strings of information
|
||||
This utility can be used to generate pseudo-random strings of information
|
||||
with specific criteria. You could, for instance, use it to generate
|
||||
phone numbers, license plate numbers, validation codes, non-sensivite
|
||||
passwords and so on. The strings generated by the generator will be
|
||||
stored and won't be available again in order to avoid repetition.
|
||||
phone numbers, license plate numbers, validation codes, in-game security
|
||||
passwords and so on. The strings generated will be stored and won't be repeated.
|
||||
|
||||
## Usage Example
|
||||
|
||||
Here's a very simple example:
|
||||
|
||||
```python
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Red Button example
|
||||
|
||||
Griatch - 2011
|
||||
Contribution by Griatch, 2011
|
||||
|
||||
This is a more advanced example object with its own functionality (commands)
|
||||
on it.
|
||||
A red button that you can press to have an effect. This is a more advanced example
|
||||
object with its own functionality and state tracking.
|
||||
|
||||
Create the button with
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
# SimpleDoor
|
||||
|
||||
Contribution - Griatch 2016
|
||||
Contribution by Griatch, 2016
|
||||
|
||||
A simple two-way exit that represents a door that can be opened and
|
||||
closed. Can easily be expanded from to make it lockable, destroyable
|
||||
etc. Note that the simpledoor is based on Evennia locks, so it will
|
||||
not work for a superuser (which bypasses all locks) - the superuser
|
||||
closed from both sides. Can easily be expanded to make it lockable,
|
||||
destroyable etc.
|
||||
|
||||
Note that the simpledoor is based on Evennia locks, so it will
|
||||
not work for a superuser (which bypasses all locks). The superuser
|
||||
will always appear to be able to close/open the door over and over
|
||||
without the locks stopping you. To use the door, use `@quell` or a
|
||||
without the locks stopping you. To use the door, use `quell` or a
|
||||
non-superuser account.
|
||||
|
||||
## Installation:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Slow Exit
|
||||
|
||||
Contribution - Griatch 2014
|
||||
Contribution by Griatch 2014
|
||||
|
||||
This is an example of an Exit-type that delays its traversal. This simulates
|
||||
slow movement, common in many different types of games. The contrib also
|
||||
contains two commands, `CmdSetSpeed` and CmdStop for changing the movement speed
|
||||
An example of an Exit-type that delays its traversal. This simulates
|
||||
slow movement, common in many games. The contrib also
|
||||
contains two commands, `setspeed` and `stop` for changing the movement speed
|
||||
and abort an ongoing traversal, respectively.
|
||||
|
||||
## Installation:
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Talkative NPC example
|
||||
|
||||
Contribution - Griatch 2011, grungies1138, 2016
|
||||
Contribution by Griatch 2011. Updated by grungies1138, 2016
|
||||
|
||||
This is a static NPC object capable of holding a simple menu-driven
|
||||
conversation. It's just meant as an example.
|
||||
This is an example of a static NPC object capable of holding a simple menu-driven
|
||||
conversation. Suitable for example as a quest giver or merchant.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
# Traits
|
||||
|
||||
Whitenoise 2014, Ainneve contributors,
|
||||
Griatch 2020
|
||||
Contribution by Griatch 2020, based on code by Whitenoise and Ainneve contribs, 2014
|
||||
|
||||
A `Trait` represents a modifiable property on (usually) a Character. They can
|
||||
be used to represent everything from attributes (str, agi etc) to skills
|
||||
(hunting 10, swords 14 etc) and dynamically changing things like HP, XP etc.
|
||||
|
||||
(hunting 10, swords 14 etc) and dynamically changing things like HP, XP etc.
|
||||
Traits differ from normal Attributes in that they track their changes and limit
|
||||
themselves to particular value-ranges. One can add/subtract from them easily and
|
||||
they can even change dynamically at a particular rate (like you being poisoned or
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
# Easy menu selection tree
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2017
|
||||
Contribution by Tim Ashley Jenkins, 2017
|
||||
|
||||
This module allows you to create and initialize an entire branching EvMenu
|
||||
instance with nothing but a multi-line string passed to one function.
|
||||
This utility allows you to create and initialize an entire branching EvMenu
|
||||
instance from a multi-line string passed to one function.
|
||||
|
||||
EvMenu is incredibly powerful and flexible, but using it for simple menus
|
||||
can often be fairly cumbersome - a simple menu that can branch into five
|
||||
categories would require six nodes, each with options represented as a list
|
||||
of dictionaries.
|
||||
> Note: Since the time this contrib was created, EvMenu itself got its own templating
|
||||
> language that has more features and is not compatible with the style used in
|
||||
> this contrib. Both can still be used in parallel.
|
||||
|
||||
`EvMenu` is incredibly powerful and flexible but it can be a little overwhelming
|
||||
and offers a lot of power that may not be needed for a simple multiple-choice menu.
|
||||
|
||||
This module provides a function, `init_tree_selection`, which acts as a frontend
|
||||
for EvMenu, dynamically sourcing the options from a multi-line string you
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Turn based battle system framework
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2017
|
||||
Contribution by Tim Ashley Jenkins, 2017
|
||||
|
||||
This is a framework for a simple turn-based combat system, similar
|
||||
to those used in D&D-style tabletop role playing games. It allows
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
# Evennia Tutorial World
|
||||
|
||||
Griatch 2011, 2015
|
||||
Contribution by Griatch 2011, 2015
|
||||
|
||||
This is a stand-alone tutorial area for an unmodified Evennia install.
|
||||
A stand-alone tutorial area for an unmodified Evennia install.
|
||||
Think of it as a sort of single-player adventure rather than a
|
||||
full-fledged multi-player game world. The various rooms and objects
|
||||
herein are designed to show off features of the engine, not to be a
|
||||
are designed to show off features of Evennia, not to be a
|
||||
very challenging (nor long) gaming experience. As such it's of course
|
||||
only skimming the surface of what is possible.
|
||||
only skimming the surface of what is possible. Taking this apart
|
||||
is a great way to start learning the system.
|
||||
|
||||
The tutorial world also includes a game tutor menu example, exemplifying
|
||||
Evmenu.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
# Unix-like Command style parent
|
||||
|
||||
Evennia contribution, Vincent Le Geoff 2017
|
||||
Contribution by Vincent Le Geoff (vlgeoff), 2017
|
||||
|
||||
This module contains a command class that allows for unix-style command syntax
|
||||
in-game, using --options, positional arguments and stuff like -n 10 etc
|
||||
similarly to a unix command. It might not the best syntax for the average player
|
||||
This module contains a command class with an alternate syntax parser implementing
|
||||
Unix-style command syntax in-game. This means `--options`, positional arguments
|
||||
and stuff like `-n 10`. It might not the best syntax for the average player
|
||||
but can be really useful for builders when they need to have a single command do
|
||||
many things with many options. It uses the ArgumentParser from Python's standard
|
||||
many things with many options. It uses the `ArgumentParser` from Python's standard
|
||||
library under the hood.
|
||||
|
||||
## Installation
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Wilderness system
|
||||
|
||||
Evennia contrib - titeuf87 2017
|
||||
Contribution by titeuf87, 2017
|
||||
|
||||
This contrib provides a wilderness map without actually creating a large number
|
||||
of rooms - as you move, your room is instead updated with different
|
||||
descriptions. This means you can make huge areas with little database use as
|
||||
of rooms - as you move, you instead end up back in the same room but its description
|
||||
changes. This means you can make huge areas with little database use as
|
||||
long as the rooms are relatively similar (name/desc changing).
|
||||
|
||||
## Installation
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,222 +0,0 @@
|
|||
# Crafting system contrib
|
||||
|
||||
_Contrib by Griatch 2020_
|
||||
```{versionadded} 1.0
|
||||
```
|
||||
|
||||
This contrib implements a full Crafting system that can be expanded and modified to fit your game.
|
||||
|
||||
- See the [evennia/contrib/crafting/crafting.py API](evennia.contrib.crafting.crafting) for installation
|
||||
instructrions.
|
||||
- See the [sword example](evennia.contrib.crafting.example_recipes) for an example of how to design
|
||||
a crafting tree for crafting a sword from base elements.
|
||||
|
||||
From in-game it uses the new `craft` command:
|
||||
|
||||
```bash
|
||||
> craft bread from flour, eggs, salt, water, yeast using oven, roller
|
||||
> craft bandage from cloth using scissors
|
||||
```
|
||||
|
||||
The syntax is `craft <recipe> [from <ingredient>,...][ using <tool>,...]`.
|
||||
|
||||
The above example uses the `bread` *recipe* and requires `flour`, `eggs`, `salt`, `water` and `yeast` objects
|
||||
to be in your inventory. These will be consumed as part of crafting (baking) the bread.
|
||||
|
||||
The `oven` and `roller` are "tools" that can be either in your inventory or in your current location (you are not carrying an oven
|
||||
around with you after all). Tools are *not* consumed in the crafting. If the added ingredients/tools matches
|
||||
the requirements of the recipe, a new `bread` object will appear in the crafter's inventory.
|
||||
|
||||
If you wanted, you could also picture recipes without any consumables:
|
||||
|
||||
```
|
||||
> craft fireball using wand, spellbook
|
||||
```
|
||||
|
||||
With a little creativity, the 'recipe' concept could be adopted to all sorts of things, like puzzles or
|
||||
magic systems.
|
||||
|
||||
In code, you can craft using the `evennia.contrib.crafting.crafting.craft` function:
|
||||
|
||||
```python
|
||||
from evennia.contrib.crafting.crafting import craft
|
||||
|
||||
result = craft(caller, "recipename", *inputs)
|
||||
|
||||
```
|
||||
Here, `caller` is the one doing the crafting and `*inputs` is any combination of consumables and/or tool
|
||||
Objects. The system will identify which is which by the [Tags](../Components/Tags.md) on them (see below)
|
||||
The `result` is always a list.
|
||||
|
||||
## Adding new recipes
|
||||
|
||||
A *recipe* is a class inheriting from `evennia.contrib.crafting.crafting.CraftingRecipe`. This class
|
||||
implements the most common form of crafting - that using in-game objects. Each recipe is a separate class
|
||||
which gets initialized with the consumables/tools you provide.
|
||||
|
||||
For the `craft` command to find your custom recipes, you need to tell Evennia where they are. Add a new
|
||||
line to your `mygame/server/conf/settings.py` file, with a list to any new modules with recipe classes.
|
||||
|
||||
```python
|
||||
CRAFT_RECIPE_MODULES = ["world.myrecipes"]
|
||||
```
|
||||
|
||||
(You need to reload after adding this). All global-level classes in these modules (whose names don't start
|
||||
with underscore) are considered by the system as viable recipes.
|
||||
|
||||
Here we assume you created `mygame/world/myrecipes.py` to match the above example setting:
|
||||
|
||||
```python
|
||||
# in mygame/world/myrecipes.py
|
||||
|
||||
from evennia.contrib.crafting.crafting import CraftingRecipe
|
||||
|
||||
class WoodenPuppetRecipe(CraftingRecipe):
|
||||
"""A puppet""""
|
||||
name = "wooden puppet" # name to refer to this recipe as
|
||||
tool_tags = ["knife"]
|
||||
consumable_tags = ["wood"]
|
||||
output_prototypes = [
|
||||
{"key": "A carved wooden doll",
|
||||
"typeclass": "typeclasses.objects.decorations.Toys",
|
||||
"desc": "A small carved doll"}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
This specifies which tags to look for in the inputs. It defines a [Prototype](../Components/Prototypes.md)
|
||||
for the recipe to use to spawn the result on the fly (a recipe could spawn more than one result if needed).
|
||||
Instead of specifying the full prototype-dict, you could also just provide a list of `prototype_key`s to
|
||||
existing prototypes you have.
|
||||
|
||||
After reloading the server, this recipe would now be available to use. To try it we should
|
||||
create materials and tools to insert into the recipe.
|
||||
|
||||
|
||||
The recipe analyzes inputs, looking for [Tags](../Components/Tags.md) with specific tag-categories.
|
||||
The tag-category used can be set per-recipe using the (`.consumable_tag_category` and
|
||||
`.tool_tag_category` respectively). The defaults are `crafting_material` and `crafting_tool`. For
|
||||
the puppet we need one object with the `wood` tag and another with the `knife` tag:
|
||||
|
||||
```python
|
||||
from evennia import create_object
|
||||
|
||||
knife = create_object(key="Hobby knife", tags=[("knife", "crafting_tool")])
|
||||
wood = create_object(key="Piece of wood", tags[("wood", "crafting_material")])
|
||||
```
|
||||
|
||||
Note that the objects can have any name, all that matters is the tag/tag-category. This means if a
|
||||
"bayonet" also had the "knife" crafting tag, it could also be used to carve a puppet. This is also
|
||||
potentially interesting for use in puzzles and to allow users to experiment and find alternatives to
|
||||
know ingredients.
|
||||
|
||||
By the way, there is also a simple shortcut for doing this:
|
||||
|
||||
```
|
||||
tools, consumables = WoodenPuppetRecipe.seed()
|
||||
```
|
||||
|
||||
The `seed` class-method will create simple dummy objects that fulfills the recipe's requirements. This
|
||||
is great for testing.
|
||||
|
||||
Assuming these objects were put in our inventory, we could now craft using the in-game command:
|
||||
|
||||
```bash
|
||||
> craft wooden puppet from wood using hobby knife
|
||||
```
|
||||
In code we would do
|
||||
|
||||
```python
|
||||
from evennia.contrub.crafting.crafting import craft
|
||||
puppet = craft(crafter, "wooden puppet", knife, wood)
|
||||
|
||||
```
|
||||
In the call to `craft`, the order of `knife` and `wood` doesn't matter - the recipe will sort out which
|
||||
is which based on their tags.
|
||||
|
||||
## Deeper customization of recipes
|
||||
|
||||
For customizing recipes further, it helps to understand how to use the recipe-class directly:
|
||||
|
||||
```python
|
||||
class MyRecipe(CraftingRecipe):
|
||||
# ...
|
||||
|
||||
tools, consumables = MyRecipe.seed()
|
||||
recipe = MyRecipe(crafter, *(tools + consumables))
|
||||
result = recipe.craft()
|
||||
|
||||
```
|
||||
This is useful for testing and allows you to use the class directly without adding it to a module
|
||||
in `settings.CRAFTING_RECIPE_MODULES`.
|
||||
|
||||
Even without modifying more than the class properties, there are a lot of options to set on
|
||||
the `CraftingRecipe` class. Easiest is to refer to the
|
||||
[CraftingRecipe api documentation](evennia.contrib.crafting.crafting.CraftingRecipe).
|
||||
For example, you can customize the validation-error messages, decide if the ingredients have
|
||||
to be exactly right, if a failure still consumes the ingredients or not, and much more.
|
||||
|
||||
For even more control you can override hooks in your own class:
|
||||
|
||||
- `pre_craft` - this should handle input validation and store its data in `.validated_consumables` and
|
||||
`validated_tools` respectively. On error, this reports the error to the crafter and raises the
|
||||
`CraftingValidationError`.
|
||||
- `craft` - this will only be called if `pre_craft` finished without an exception. This should
|
||||
return the result of the crafting, by spawnging the prototypes. Or the empty list if crafting
|
||||
fails for some reason. This is the place to add skill-checks or random chance if you need it
|
||||
for your game.
|
||||
- `post_craft` - this receives the result from `craft` and handles error messages and also deletes
|
||||
any consumables as needed. It may also modify the result before returning it.
|
||||
- `msg` - this is a wrapper for `self.crafter.msg` and should be used to send messages to the
|
||||
crafter. Centralizing this means you can also easily modify the sending style in one place later.
|
||||
|
||||
The class constructor (and the `craft` access function) takes optional `**kwargs`. These are passed
|
||||
into each crafting hook. These are unused by default but could be used to customize things per-call.
|
||||
|
||||
### Skilled crafters
|
||||
|
||||
What the crafting system does not have out of the box is a 'skill' system - the notion of being able
|
||||
to fail the craft if you are not skilled enough. Just how skills work is game-dependent, so to add
|
||||
this you need to make your own recipe parent class and have your recipes inherit from this.
|
||||
|
||||
|
||||
```python
|
||||
from random import randint
|
||||
from evennia.contrib.crafting.crafting import CraftingRecipe
|
||||
|
||||
class SkillRecipe(CraftingRecipe):
|
||||
"""A recipe that considers skill"""
|
||||
|
||||
difficulty = 20
|
||||
|
||||
def craft(self, **kwargs):
|
||||
"""The input is ok. Determine if crafting succeeds"""
|
||||
|
||||
# this is set at initialization
|
||||
crafter = self.crafte
|
||||
|
||||
# let's assume the skill is stored directly on the crafter
|
||||
# - the skill is 0..100.
|
||||
crafting_skill = crafter.db.skill_crafting
|
||||
# roll for success:
|
||||
if randint(1, 100) <= (crafting_skill - self.difficulty):
|
||||
# all is good, craft away
|
||||
return super().craft()
|
||||
else:
|
||||
self.msg("You are not good enough to craft this. Better luck next time!")
|
||||
return []
|
||||
```
|
||||
In this example we introduce a `.difficulty` for the recipe and makes a 'dice roll' to see
|
||||
if we succed. We would of course make this a lot more immersive and detailed in a full game. In
|
||||
principle you could customize each recipe just the way you want it, but you could also inherit from
|
||||
a central parent like this to cut down on work.
|
||||
|
||||
The [sword recipe example module](evennia.contrib.crafting.example_recipes) also shows an example
|
||||
of a random skill-check being implemented in a parent and then inherited for multiple use.
|
||||
|
||||
## Even more customization
|
||||
|
||||
If you want to build something even more custom (maybe using different input types of validation logic)
|
||||
you could also look at the `CraftingRecipe` parent class `CraftingRecipeBase`.
|
||||
It implements just the minimum needed to be a recipe and for big changes you may be better off starting
|
||||
from this rather than the more opinionated `CraftingRecipe`.
|
||||
|
|
@ -1,495 +0,0 @@
|
|||
# Dynamic In Game Map
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
An often desired feature in a MUD is to show an in-game map to help navigation. The [Static in-game
|
||||
map](./Static-In-Game-Map.md) tutorial solves this by creating a *static* map, meaning the map is pre-
|
||||
drawn once and for all - the rooms are then created to match that map. When walking around, parts of
|
||||
the static map is then cut out and displayed next to the room description.
|
||||
|
||||
In this tutorial we'll instead do it the other way around; We will dynamically draw the map based on
|
||||
the relationships we find between already existing rooms.
|
||||
|
||||
## The Grid of Rooms
|
||||
|
||||
There are at least two requirements needed for this tutorial to work.
|
||||
|
||||
1. The structure of your mud has to follow a logical layout. Evennia supports the layout of your
|
||||
world to be 'logically' impossible with rooms looping to themselves or exits leading to the other
|
||||
side of the map. Exits can also be named anything, from "jumping out the window" to "into the fifth
|
||||
dimension". This tutorial assumes you can only move in the cardinal directions (N, E, S and W).
|
||||
2. Rooms must be connected and linked together for the map to be generated correctly. Vanilla
|
||||
Evennia comes with a admin command [tunnel](evennia.commands.default.building.CmdTunnel) that allows a
|
||||
user to create rooms in the cardinal directions, but additional work is needed to assure that rooms
|
||||
are connected. For example, if you `tunnel east` and then immediately do `tunnel west` you'll find
|
||||
that you have created two completely stand-alone rooms. So care is needed if you want to create a
|
||||
"logical" layout. In this tutorial we assume you have such a grid of rooms that we can generate the
|
||||
map from.
|
||||
|
||||
## Concept
|
||||
|
||||
Before getting into the code, it is beneficial to understand and conceptualize how this is going to
|
||||
work. The idea is analogous to a worm that starts at your current position. It chooses a direction
|
||||
and 'walks' outward from it, mapping its route as it goes. Once it has traveled a pre-set distance
|
||||
it stops and starts over in another direction. An important note is that we want a system which is
|
||||
easily callable and not too complicated. Therefore we will wrap this entire code into a custom
|
||||
Python class (not a typeclass as this doesn't use any core objects from evennia itself).
|
||||
|
||||
We are going to create something that displays like this when you type 'look':
|
||||
|
||||
```
|
||||
Hallway
|
||||
|
||||
[.] [.]
|
||||
[@][.][.][.][.]
|
||||
[.] [.] [.]
|
||||
|
||||
The distant echoes of the forgotten
|
||||
wail throughout the empty halls.
|
||||
|
||||
Exits: North, East, South
|
||||
```
|
||||
|
||||
Your current location is defined by `[@]` while the `[.]`s are other rooms that the "worm" has seen
|
||||
since departing from your location.
|
||||
|
||||
## Setting up the Map Display
|
||||
|
||||
First we must define the components for displaying the map. For the "worm" to know what symbol to
|
||||
draw on the map we will have it check an Attribute on the room it visits called `sector_type`. For
|
||||
this tutorial we understand two symbols - a normal room and the room with us in it. We also define a
|
||||
fallback symbol for rooms without said Attribute - that way the map will still work even if we
|
||||
didn't prepare the room correctly. Assuming your game folder is named `mygame`, we create this code
|
||||
in `mygame/world/map.py.`
|
||||
|
||||
```python
|
||||
# in mygame/world/map.py
|
||||
|
||||
# the symbol is identified with a key "sector_type" on the
|
||||
# Room. Keys None and "you" must always exist.
|
||||
SYMBOLS = { None : ' . ', # for rooms without sector_type Attribute
|
||||
'you' : '[@]',
|
||||
'SECT_INSIDE': '[.]' }
|
||||
```
|
||||
|
||||
Since trying to access an unset Attribute returns `None`, this means rooms without the `sector_type`
|
||||
Atttribute will show as ` . `. Next we start building the custom class `Map`. It will hold all
|
||||
methods we need.
|
||||
|
||||
```python
|
||||
# in mygame/world/map.py
|
||||
|
||||
class Map(object):
|
||||
|
||||
def __init__(self, caller, max_width=9, max_length=9):
|
||||
self.caller = caller
|
||||
self.max_width = max_width
|
||||
self.max_length = max_length
|
||||
self.worm_has_mapped = {}
|
||||
self.curX = None
|
||||
self.curY = None
|
||||
```
|
||||
|
||||
- `self.caller` is normally your Character object, the one using the map.
|
||||
- `self.max_width/length` determine the max width and length of the map that will be generated. Note
|
||||
that it's important that these variables are set to *odd* numbers to make sure the display area has
|
||||
a center point.
|
||||
- ` self.worm_has_mapped` is building off the worm analogy above. This dictionary will store all
|
||||
rooms the "worm" has mapped as well as its relative position within the grid. This is the most
|
||||
important variable as it acts as a 'checker' and 'address book' that is able to tell us where the
|
||||
worm has been and what it has mapped so far.
|
||||
- `self.curX/Y` are coordinates representing the worm's current location on the grid.
|
||||
|
||||
|
||||
Before any sort of mapping can actually be done we need to create an empty display area and do some
|
||||
sanity checks on it by using the following methods.
|
||||
|
||||
```python
|
||||
# in mygame/world/map.py
|
||||
|
||||
class Map(object):
|
||||
# [... continued]
|
||||
|
||||
def create_grid(self):
|
||||
# This method simply creates an empty grid/display area
|
||||
# with the specified variables from __init__(self):
|
||||
board = []
|
||||
for row in range(self.max_width):
|
||||
board.append([])
|
||||
for column in range(self.max_length):
|
||||
board[row].append(' ')
|
||||
return board
|
||||
|
||||
def check_grid(self):
|
||||
# this method simply checks the grid to make sure
|
||||
# that both max_l and max_w are odd numbers.
|
||||
return True if self.max_length % 2 != 0 or self.max_width % 2 != 0\
|
||||
else False
|
||||
```
|
||||
|
||||
Before we can set our worm on its way, we need to know some of the computer science behind all this
|
||||
called 'Graph Traversing'. In Pseudo code what we are trying to accomplish is this:
|
||||
|
||||
```python
|
||||
# pseudo code
|
||||
|
||||
def draw_room_on_map(room, max_distance):
|
||||
self.draw(room)
|
||||
|
||||
if max_distance == 0:
|
||||
return
|
||||
|
||||
for exit in room.exits:
|
||||
if self.has_drawn(exit.destination):
|
||||
# skip drawing if we already visited the destination
|
||||
continue
|
||||
else:
|
||||
# first time here!
|
||||
self.draw_room_on_map(exit.destination, max_distance - 1)
|
||||
```
|
||||
|
||||
The beauty of Python is that our actual code of doing this doesn't differ much if at all from this
|
||||
Pseudo code example.
|
||||
|
||||
- `max_distance` is a variable indicating to our Worm how many rooms AWAY from your current location
|
||||
will it map. Obviously the larger the number the more time it will take if your current location has
|
||||
many many rooms around you.
|
||||
|
||||
The first hurdle here is what value to use for 'max_distance'. There is no reason for the worm to
|
||||
travel further than what is actually displayed to you. For example, if your current location is
|
||||
placed in the center of a display area of size `max_length = max_width = 9`, then the worm need only
|
||||
go `4` spaces in either direction:
|
||||
|
||||
```
|
||||
[.][.][.][.][@][.][.][.][.]
|
||||
4 3 2 1 0 1 2 3 4
|
||||
```
|
||||
|
||||
The max_distance can be set dynamically based on the size of the display area. As your width/length
|
||||
changes it becomes a simple algebraic linear relationship which is simply `max_distance =
|
||||
(min(max_width, max_length) -1) / 2`.
|
||||
|
||||
## Building the Mapper
|
||||
|
||||
Now we can start to fill our Map object with some methods. We are still missing a few methods that
|
||||
are very important:
|
||||
|
||||
* `self.draw(self, room)` - responsible for actually drawing room to grid.
|
||||
* `self.has_drawn(self, room)` - checks to see if the room has been mapped and worm has already been
|
||||
here.
|
||||
* `self.median(self, number)` - a simple utility method that finds the median (middle point) from 0,
|
||||
n
|
||||
* `self.update_pos(self, room, exit_name)` - updates the worm's physical position by reassigning
|
||||
self.curX/Y. .accordingly
|
||||
* `self.start_loc_on_grid(self)` - the very first initial draw on the grid representing your
|
||||
location in the middle of the grid
|
||||
* 'self.show_map` - after everything is done convert the map into a readable string`
|
||||
* `self.draw_room_on_map(self, room, max_distance)` - the main method that ties it all together.`
|
||||
|
||||
|
||||
Now that we know which methods we need, let's refine our initial `__init__(self)` to pass some
|
||||
conditional statements and set it up to start building the display.
|
||||
|
||||
|
||||
```python
|
||||
#mygame/world/map.py
|
||||
|
||||
class Map(object):
|
||||
|
||||
def __init__(self, caller, max_width=9, max_length=9):
|
||||
self.caller = caller
|
||||
self.max_width = max_width
|
||||
self.max_length = max_length
|
||||
self.worm_has_mapped = {}
|
||||
self.curX = None
|
||||
self.curY = None
|
||||
|
||||
if self.check_grid():
|
||||
# we have to store the grid into a variable
|
||||
self.grid = self.create_grid()
|
||||
# we use the algebraic relationship
|
||||
self.draw_room_on_map(caller.location,
|
||||
((min(max_width, max_length) -1 ) / 2)
|
||||
|
||||
```
|
||||
|
||||
Here we check to see if the parameters for the grid are okay, then we create an empty canvas and map
|
||||
our initial location as the first room!
|
||||
|
||||
As mentioned above, the code for the `self.draw_room_on_map()` is not much different than the Pseudo
|
||||
code. The method is shown below:
|
||||
|
||||
```python
|
||||
# in mygame/world/map.py, in the Map class
|
||||
|
||||
def draw_room_on_map(self, room, max_distance):
|
||||
self.draw(room)
|
||||
|
||||
if max_distance == 0:
|
||||
return
|
||||
|
||||
for exit in room.exits:
|
||||
if exit.name not in ("north", "east", "west", "south"):
|
||||
# we only map in the cardinal directions. Mapping up/down would be
|
||||
# an interesting learning project for someone who wanted to try it.
|
||||
continue
|
||||
if self.has_drawn(exit.destination):
|
||||
# we've been to the destination already, skip ahead.
|
||||
continue
|
||||
|
||||
self.update_pos(room, exit.name.lower())
|
||||
self.draw_room_on_map(exit.destination, max_distance - 1)
|
||||
```
|
||||
|
||||
The first thing the "worm" does is to draw your current location in `self.draw`. Lets define that...
|
||||
|
||||
```python
|
||||
#in mygame/word/map.py, in the Map class
|
||||
|
||||
def draw(self, room):
|
||||
# draw initial ch location on map first!
|
||||
if room == self.caller.location:
|
||||
self.start_loc_on_grid()
|
||||
self.worm_has_mapped[room] = [self.curX, self.curY]
|
||||
else:
|
||||
# map all other rooms
|
||||
self.worm_has_mapped[room] = [self.curX, self.curY]
|
||||
# this will use the sector_type Attribute or None if not set.
|
||||
self.grid[self.curX][self.curY] = SYMBOLS[room.db.sector_type]
|
||||
```
|
||||
|
||||
In `self.start_loc_on_grid()`:
|
||||
|
||||
```python
|
||||
def median(self, num):
|
||||
lst = sorted(range(0, num))
|
||||
n = len(lst)
|
||||
m = n -1
|
||||
return (lst[n//2] + lst[m//2]) / 2.0
|
||||
|
||||
def start_loc_on_grid(self):
|
||||
x = self.median(self.max_width)
|
||||
y = self.median(self.max_length)
|
||||
# x and y are floats by default, can't index lists with float types
|
||||
x, y = int(x), int(y)
|
||||
|
||||
self.grid[x][y] = SYMBOLS['you']
|
||||
self.curX, self.curY = x, y # updating worms current location
|
||||
```
|
||||
|
||||
After the system has drawn the current map it checks to see if the `max_distance` is `0` (since this
|
||||
is the inital start phase it is not). Now we handle the iteration once we have each individual exit
|
||||
in the room. The first thing it does is check if the room the Worm is in has been mapped already..
|
||||
lets define that...
|
||||
|
||||
|
||||
```python
|
||||
def has_drawn(self, room):
|
||||
return True if room in self.worm_has_mapped.keys() else False
|
||||
```
|
||||
|
||||
If `has_drawn` returns `False` that means the worm has found a room that hasn't been mapped yet. It
|
||||
will then 'move' there. The self.curX/Y sort of lags behind, so we have to make sure to track the
|
||||
position of the worm; we do this in `self.update_pos()` below.
|
||||
|
||||
```python
|
||||
def update_pos(self, room, exit_name):
|
||||
# this ensures the coordinates stays up to date
|
||||
# to where the worm is currently at.
|
||||
self.curX, self.curY = \
|
||||
self.worm_has_mapped[room][0], self.worm_has_mapped[room][1]
|
||||
|
||||
# now we have to actually move the pointer
|
||||
# variables depending on which 'exit' it found
|
||||
if exit_name == 'east':
|
||||
self.curY += 1
|
||||
elif exit_name == 'west':
|
||||
self.curY -= 1
|
||||
elif exit_name == 'north':
|
||||
self.curX -= 1
|
||||
elif exit_name == 'south':
|
||||
self.curX += 1
|
||||
```
|
||||
|
||||
Once the system updates the position of the worm it feeds the new room back into the original
|
||||
`draw_room_on_map()` and starts the process all over again..
|
||||
|
||||
That is essentially the entire thing. The final method is to bring it all together and make a nice
|
||||
presentational string out of it using the `self.show_map()` method.
|
||||
|
||||
```python
|
||||
def show_map(self):
|
||||
map_string = ""
|
||||
for row in self.grid:
|
||||
map_string += " ".join(row)
|
||||
map_string += "\n"
|
||||
|
||||
return map_string
|
||||
```
|
||||
|
||||
## Using the Map
|
||||
|
||||
In order for the map to get triggered we store it on the Room typeclass. If we put it in
|
||||
`return_appearance` we will get the map back every time we look at the room.
|
||||
|
||||
> `return_appearance` is a default Evennia hook available on all objects; it is called e.g. by the
|
||||
`look` command to get the description of something (the room in this case).
|
||||
|
||||
```python
|
||||
# in mygame/typeclasses/rooms.py
|
||||
|
||||
from evennia import DefaultRoom
|
||||
from world.map import Map
|
||||
|
||||
class Room(DefaultRoom):
|
||||
|
||||
def return_appearance(self, looker):
|
||||
# [...]
|
||||
string = f"{Map(looker).show_map()}\n"
|
||||
# Add all the normal stuff like room description,
|
||||
# contents, exits etc.
|
||||
string += "\n" + super().return_appearance(looker)
|
||||
return string
|
||||
```
|
||||
|
||||
Obviously this method of generating maps doesn't take into account of any doors or exits that are
|
||||
hidden.. etc.. but hopefully it serves as a good base to start with. Like previously mentioned, it
|
||||
is very important to have a solid foundation on rooms before implementing this. You can try this on
|
||||
vanilla evennia by using @tunnel and essentially you can just create a long straight/edgy non-
|
||||
looping rooms that will show on your in-game map.
|
||||
|
||||
The above example will display the map above the room description. You could also use an
|
||||
[EvTable](github:evennia.utils.evtable) to place description and map next to each other. Some other
|
||||
things you can do is to have a [Command](../Components/Commands.md) that displays with a larger radius, maybe with a
|
||||
legend and other features.
|
||||
|
||||
Below is the whole `map.py` for your reference. You need to update your `Room` typeclass (see above)
|
||||
to actually call it. Remember that to see different symbols for a location you also need to set the
|
||||
`sector_type` Attribute on the room to one of the keys in the `SYMBOLS` dictionary. So in this
|
||||
example, to make a room be mapped as `[.]` you would set the room's `sector_type` to
|
||||
`"SECT_INSIDE"`. Try it out with `@set here/sector_type = "SECT_INSIDE"`. If you wanted all new
|
||||
rooms to have a given sector symbol, you could change the default in the `SYMBOLS´ dictionary below,
|
||||
or you could add the Attribute in the Room's `at_object_creation` method.
|
||||
|
||||
```python
|
||||
#mygame/world/map.py
|
||||
|
||||
# These are keys set with the Attribute sector_type on the room.
|
||||
# The keys None and "you" must always exist.
|
||||
SYMBOLS = { None : ' . ', # for rooms without a sector_type attr
|
||||
'you' : '[@]',
|
||||
'SECT_INSIDE': '[.]' }
|
||||
|
||||
class Map(object):
|
||||
|
||||
def __init__(self, caller, max_width=9, max_length=9):
|
||||
self.caller = caller
|
||||
self.max_width = max_width
|
||||
self.max_length = max_length
|
||||
self.worm_has_mapped = {}
|
||||
self.curX = None
|
||||
self.curY = None
|
||||
|
||||
if self.check_grid():
|
||||
# we actually have to store the grid into a variable
|
||||
self.grid = self.create_grid()
|
||||
self.draw_room_on_map(caller.location,
|
||||
((min(max_width, max_length) -1 ) / 2))
|
||||
|
||||
def update_pos(self, room, exit_name):
|
||||
# this ensures the pointer variables always
|
||||
# stays up to date to where the worm is currently at.
|
||||
self.curX, self.curY = \
|
||||
self.worm_has_mapped[room][0], self.worm_has_mapped[room][1]
|
||||
|
||||
# now we have to actually move the pointer
|
||||
# variables depending on which 'exit' it found
|
||||
if exit_name == 'east':
|
||||
self.curY += 1
|
||||
elif exit_name == 'west':
|
||||
self.curY -= 1
|
||||
elif exit_name == 'north':
|
||||
self.curX -= 1
|
||||
elif exit_name == 'south':
|
||||
self.curX += 1
|
||||
|
||||
def draw_room_on_map(self, room, max_distance):
|
||||
self.draw(room)
|
||||
|
||||
if max_distance == 0:
|
||||
return
|
||||
|
||||
for exit in room.exits:
|
||||
if exit.name not in ("north", "east", "west", "south"):
|
||||
# we only map in the cardinal directions. Mapping up/down would be
|
||||
# an interesting learning project for someone who wanted to try it.
|
||||
continue
|
||||
if self.has_drawn(exit.destination):
|
||||
# we've been to the destination already, skip ahead.
|
||||
continue
|
||||
|
||||
self.update_pos(room, exit.name.lower())
|
||||
self.draw_room_on_map(exit.destination, max_distance - 1)
|
||||
|
||||
def draw(self, room):
|
||||
# draw initial caller location on map first!
|
||||
if room == self.caller.location:
|
||||
self.start_loc_on_grid()
|
||||
self.worm_has_mapped[room] = [self.curX, self.curY]
|
||||
else:
|
||||
# map all other rooms
|
||||
self.worm_has_mapped[room] = [self.curX, self.curY]
|
||||
# this will use the sector_type Attribute or None if not set.
|
||||
self.grid[self.curX][self.curY] = SYMBOLS[room.db.sector_type]
|
||||
|
||||
def median(self, num):
|
||||
lst = sorted(range(0, num))
|
||||
n = len(lst)
|
||||
m = n -1
|
||||
return (lst[n//2] + lst[m//2]) / 2.0
|
||||
|
||||
def start_loc_on_grid(self):
|
||||
x = self.median(self.max_width)
|
||||
y = self.median(self.max_length)
|
||||
# x and y are floats by default, can't index lists with float types
|
||||
x, y = int(x), int(y)
|
||||
|
||||
self.grid[x][y] = SYMBOLS['you']
|
||||
self.curX, self.curY = x, y # updating worms current location
|
||||
|
||||
|
||||
def has_drawn(self, room):
|
||||
return True if room in self.worm_has_mapped.keys() else False
|
||||
|
||||
|
||||
def create_grid(self):
|
||||
# This method simply creates an empty grid
|
||||
# with the specified variables from __init__(self):
|
||||
board = []
|
||||
for row in range(self.max_width):
|
||||
board.append([])
|
||||
for column in range(self.max_length):
|
||||
board[row].append(' ')
|
||||
return board
|
||||
|
||||
def check_grid(self):
|
||||
# this method simply checks the grid to make sure
|
||||
# both max_l and max_w are odd numbers
|
||||
return True if self.max_length % 2 != 0 or \
|
||||
self.max_width % 2 != 0 else False
|
||||
|
||||
def show_map(self):
|
||||
map_string = ""
|
||||
for row in self.grid:
|
||||
map_string += " ".join(row)
|
||||
map_string += "\n"
|
||||
|
||||
return map_string
|
||||
```
|
||||
|
||||
## Final Comments
|
||||
|
||||
The Dynamic map could be expanded with further capabilities. For example, it could mark exits or
|
||||
allow NE, SE etc directions as well. It could have colors for different terrain types. One could
|
||||
also look into up/down directions and figure out how to display that in a good way.
|
||||
|
|
@ -1,416 +0,0 @@
|
|||
# Static In Game Map
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
This tutorial describes the creation of an in-game map display based on a pre-drawn map. It also
|
||||
details how to use the [Batch code processor](../Components/Batch-Code-Processor.md) for advanced building. There is
|
||||
also the [Dynamic in-game map tutorial](./Dynamic-In-Game-Map.md) that works in the opposite direction,
|
||||
by generating a map from an existing grid of rooms.
|
||||
|
||||
Evennia does not require its rooms to be positioned in a "logical" way. Your exits could be named
|
||||
anything. You could make an exit "west" that leads to a room described to be in the far north. You
|
||||
could have rooms inside one another, exits leading back to the same room or describing spatial
|
||||
geometries impossible in the real world.
|
||||
|
||||
That said, most games *do* organize their rooms in a logical fashion, if nothing else to retain the
|
||||
sanity of their players. And when they do, the game becomes possible to map. This tutorial will give
|
||||
an example of a simple but flexible in-game map system to further help player's to navigate. We will
|
||||
|
||||
To simplify development and error-checking we'll break down the work into bite-size chunks, each
|
||||
building on what came before. For this we'll make extensive use of the [Batch code processor](Batch-
|
||||
Code-Processor), so you may want to familiarize yourself with that.
|
||||
|
||||
1. **Planning the map** - Here we'll come up with a small example map to use for the rest of the
|
||||
tutorial.
|
||||
2. **Making a map object** - This will showcase how to make a static in-game "map" object a
|
||||
Character could pick up and look at.
|
||||
3. **Building the map areas** - Here we'll actually create the small example area according to the
|
||||
map we designed before.
|
||||
4. **Map code** - This will link the map to the location so our output looks something like this:
|
||||
|
||||
```
|
||||
crossroads(#3)
|
||||
↑╚∞╝↑
|
||||
≈↑│↑∩ The merger of two roads. To the north looms a mighty castle.
|
||||
O─O─O To the south, the glow of a campfire can be seen. To the east lie
|
||||
≈↑│↑∩ the vast mountains and to the west is heard the waves of the sea.
|
||||
↑▲O▲↑
|
||||
|
||||
Exits: north(#8), east(#9), south(#10), west(#11)
|
||||
```
|
||||
|
||||
We will henceforth assume your game folder is name named `mygame` and that you haven't modified the
|
||||
default commands. We will also not be using [Colors](../Concepts/Colors.md) for our map since they
|
||||
don't show in the documentation wiki.
|
||||
|
||||
## Planning the Map
|
||||
|
||||
Let's begin with the fun part! Maps in MUDs come in many different [shapes and
|
||||
sizes](http://journal.imaginary-realities.com/volume-05/issue-01/modern-interface-modern-
|
||||
mud/index.html). Some appear as just boxes connected by lines. Others have complex graphics that are
|
||||
external to the game itself.
|
||||
|
||||
Our map will be in-game text but that doesn't mean we're restricted to the normal alphabet! If
|
||||
you've ever selected the [Wingdings font](https://en.wikipedia.org/wiki/Wingdings) in Microsoft Word
|
||||
you will know there are a multitude of other characters around to use. When creating your game with
|
||||
Evennia you have access to the [UTF-8 character encoding](https://en.wikipedia.org/wiki/UTF-8) which
|
||||
put at your disposal [thousands of letters, number and geometric shapes](https://mcdlr.com/utf-8/#1).
|
||||
|
||||
For this exercise, we've copy-and-pasted from the pallet of special characters used over at
|
||||
[Dwarf Fortress](https://dwarffortresswiki.org/index.php/Character_table) to create what is hopefully
|
||||
a pleasing and easy to understood landscape:
|
||||
|
||||
```
|
||||
≈≈↑↑↑↑↑∩∩
|
||||
≈≈↑╔═╗↑∩∩ Places the account can visit are indicated by "O".
|
||||
≈≈↑║O║↑∩∩ Up the top is a castle visitable by the account.
|
||||
≈≈↑╚∞╝↑∩∩ To the right is a cottage and to the left the beach.
|
||||
≈≈≈↑│↑∩∩∩ And down the bottom is a camp site with tents.
|
||||
≈≈O─O─O⌂∩ In the center is the starting location, a crossroads
|
||||
≈≈≈↑│↑∩∩∩ which connect the four other areas.
|
||||
≈≈↑▲O▲↑∩∩
|
||||
≈≈↑↑▲↑↑∩∩
|
||||
≈≈↑↑↑↑↑∩∩
|
||||
```
|
||||
There are many considerations when making a game map depending on the play style and requirements
|
||||
you intend to implement. Here we will display a 5x5 character map of the area surrounding the
|
||||
account. This means making sure to account for 2 characters around every visitable location. Good
|
||||
planning at this stage can solve many problems before they happen.
|
||||
|
||||
## Creating a Map Object
|
||||
|
||||
In this section we will try to create an actual "map" object that an account can pick up and look
|
||||
at.
|
||||
|
||||
Evennia offers a range of [default commands](../Components/Default-Commands.md) for
|
||||
[creating objects and rooms in-game](../Howto/Starting/Part1/Building-Quickstart.md). While readily accessible, these commands are made to do very
|
||||
specific, restricted things and will thus not offer as much flexibility to experiment (for an
|
||||
advanced exception see [the FuncParser](../Components/FuncParser.md)). Additionally, entering long
|
||||
descriptions and properties over and over in the game client can become tedious; especially when
|
||||
testing and you may want to delete and recreate things over and over.
|
||||
|
||||
To overcome this, Evennia offers [batch processors](../Components/Batch-Processors.md) that work as input-files
|
||||
created out-of-game. In this tutorial we'll be using the more powerful of the two available batch
|
||||
processors, the [Batch Code Processor ](../Components/Batch-Code-Processor.md), called with the `@batchcode` command.
|
||||
This is a very powerful tool. It allows you to craft Python files to act as blueprints of your
|
||||
entire game world. These files have access to use Evennia's Python API directly. Batchcode allows
|
||||
for easy editing and creation in whatever text editor you prefer, avoiding having to manually build
|
||||
the world line-by-line inside the game.
|
||||
|
||||
> Important warning: `@batchcode`'s power is only rivaled by the `@py` command. Batchcode is so
|
||||
powerful it should be reserved only for the [superuser](../Concepts/Building-Permissions.md). Think carefully
|
||||
before you let others (such as `Developer`- level staff) run `@batchcode` on their own - make sure
|
||||
you are okay with them running *arbitrary Python code* on your server.
|
||||
|
||||
While a simple example, the map object it serves as good way to try out `@batchcode`. Go to
|
||||
`mygame/world` and create a new file there named `batchcode_map.py`:
|
||||
|
||||
```Python
|
||||
# mygame/world/batchcode_map.py
|
||||
|
||||
from evennia import create_object
|
||||
from evennia import DefaultObject
|
||||
|
||||
# We use the create_object function to call into existence a
|
||||
# DefaultObject named "Map" wherever you are standing.
|
||||
|
||||
map = create_object(DefaultObject, key="Map", location=caller.location)
|
||||
|
||||
# We then access its description directly to make it our map.
|
||||
|
||||
map.db.desc = """
|
||||
≈≈↑↑↑↑↑∩∩
|
||||
≈≈↑╔═╗↑∩∩
|
||||
≈≈↑║O║↑∩∩
|
||||
≈≈↑╚∞╝↑∩∩
|
||||
≈≈≈↑│↑∩∩∩
|
||||
≈≈O─O─O⌂∩
|
||||
≈≈≈↑│↑∩∩∩
|
||||
≈≈↑▲O▲↑∩∩
|
||||
≈≈↑↑▲↑↑∩∩
|
||||
≈≈↑↑↑↑↑∩∩
|
||||
"""
|
||||
|
||||
# This message lets us know our map was created successfully.
|
||||
caller.msg("A map appears out of thin air and falls to the ground.")
|
||||
```
|
||||
|
||||
Log into your game project as the superuser and run the command
|
||||
|
||||
```
|
||||
@batchcode batchcode_map
|
||||
```
|
||||
|
||||
This will load your `batchcode_map.py` file and execute the code (Evennia will look in your `world/`
|
||||
folder automatically so you don't need to specify it).
|
||||
|
||||
A new map object should have appeared on the ground. You can view the map by using `look map`. Let's
|
||||
take it with the `get map` command. We'll need it in case we get lost!
|
||||
|
||||
## Building the map areas
|
||||
|
||||
We've just used batchcode to create an object useful for our adventures. But the locations on that
|
||||
map does not actually exist yet - we're all mapped up with nowhere to go! Let's use batchcode to
|
||||
build a game area based on our map. We have five areas outlined: a castle, a cottage, a campsite, a
|
||||
coastal beach and the crossroads which connects them. Create a new batchcode file for this in
|
||||
`mygame/world`, named `batchcode_world.py`.
|
||||
|
||||
```Python
|
||||
# mygame/world/batchcode_world.py
|
||||
|
||||
from evennia import create_object, search_object
|
||||
from typeclasses import rooms, exits
|
||||
|
||||
# We begin by creating our rooms so we can detail them later.
|
||||
|
||||
centre = create_object(rooms.Room, key="crossroads")
|
||||
north = create_object(rooms.Room, key="castle")
|
||||
east = create_object(rooms.Room, key="cottage")
|
||||
south = create_object(rooms.Room, key="camp")
|
||||
west = create_object(rooms.Room, key="coast")
|
||||
|
||||
# This is where we set up the cross roads.
|
||||
# The rooms description is what we see with the 'look' command.
|
||||
|
||||
centre.db.desc = """
|
||||
The merger of two roads. A single lamp post dimly illuminates the lonely crossroads.
|
||||
To the north looms a mighty castle. To the south the glow of a campfire can be seen.
|
||||
To the east lie a wall of mountains and to the west the dull roar of the open sea.
|
||||
"""
|
||||
|
||||
# Here we are creating exits from the centre "crossroads" location to
|
||||
# destinations to the north, east, south, and west. We will be able
|
||||
# to use the exit by typing it's key e.g. "north" or an alias e.g. "n".
|
||||
|
||||
centre_north = create_object(exits.Exit, key="north",
|
||||
aliases=["n"], location=centre, destination=north)
|
||||
centre_east = create_object(exits.Exit, key="east",
|
||||
aliases=["e"], location=centre, destination=east)
|
||||
centre_south = create_object(exits.Exit, key="south",
|
||||
aliases=["s"], location=centre, destination=south)
|
||||
centre_west = create_object(exits.Exit, key="west",
|
||||
aliases=["w"], location=centre, destination=west)
|
||||
|
||||
# Now we repeat this for the other rooms we'll be implementing.
|
||||
# This is where we set up the northern castle.
|
||||
|
||||
north.db.desc = "An impressive castle surrounds you. " \
|
||||
"There might be a princess in one of these towers."
|
||||
north_south = create_object(exits.Exit, key="south",
|
||||
aliases=["s"], location=north, destination=centre)
|
||||
|
||||
# This is where we set up the eastern cottage.
|
||||
|
||||
east.db.desc = "A cosy cottage nestled among mountains " \
|
||||
"stretching east as far as the eye can see."
|
||||
east_west = create_object(exits.Exit, key="west",
|
||||
aliases=["w"], location=east, destination=centre)
|
||||
|
||||
# This is where we set up the southern camp.
|
||||
|
||||
south.db.desc = "Surrounding a clearing are a number of " \
|
||||
"tribal tents and at their centre a roaring fire."
|
||||
south_north = create_object(exits.Exit, key="north",
|
||||
aliases=["n"], location=south, destination=centre)
|
||||
|
||||
# This is where we set up the western coast.
|
||||
|
||||
west.db.desc = "The dark forest halts to a sandy beach. " \
|
||||
"The sound of crashing waves calms the soul."
|
||||
west_east = create_object(exits.Exit, key="east",
|
||||
aliases=["e"], location=west, destination=centre)
|
||||
|
||||
# Lastly, lets make an entrance to our world from the default Limbo room.
|
||||
|
||||
limbo = search_object('Limbo')[0]
|
||||
limbo_exit = create_object(exits.Exit, key="enter world",
|
||||
aliases=["enter"], location=limbo, destination=centre)
|
||||
|
||||
```
|
||||
|
||||
Apply this new batch code with `@batchcode batchcode_world`. If there are no errors in the code we
|
||||
now have a nice mini-world to explore. Remember that if you get lost you can look at the map we
|
||||
created!
|
||||
|
||||
## In-game minimap
|
||||
|
||||
Now we have a landscape and matching map, but what we really want is a mini-map that displays
|
||||
whenever we move to a room or use the `look` command.
|
||||
|
||||
We *could* manually enter a part of the map into the description of every room like we did our map
|
||||
object description. But some MUDs have tens of thousands of rooms! Besides, if we ever changed our
|
||||
map we would have to potentially alter a lot of those room descriptions manually to match the
|
||||
change. So instead we will make one central module to hold our map. Rooms will reference this
|
||||
central location on creation and the map changes will thus come into effect when next running our
|
||||
batchcode.
|
||||
|
||||
To make our mini-map we need to be able to cut our full map into parts. To do this we need to put it
|
||||
in a format which allows us to do that easily. Luckily, python allows us to treat strings as lists
|
||||
of characters allowing us to pick out the characters we need.
|
||||
|
||||
`mygame/world/map_module.py`
|
||||
```Python
|
||||
# We place our map into a sting here.
|
||||
world_map = """\
|
||||
≈≈↑↑↑↑↑∩∩
|
||||
≈≈↑╔═╗↑∩∩
|
||||
≈≈↑║O║↑∩∩
|
||||
≈≈↑╚∞╝↑∩∩
|
||||
≈≈≈↑│↑∩∩∩
|
||||
≈≈O─O─O⌂∩
|
||||
≈≈≈↑│↑∩∩∩
|
||||
≈≈↑▲O▲↑∩∩
|
||||
≈≈↑↑▲↑↑∩∩
|
||||
≈≈↑↑↑↑↑∩∩
|
||||
"""
|
||||
|
||||
# This turns our map string into a list of rows. Because python
|
||||
# allows us to treat strings as a list of characters, we can access
|
||||
# those characters with world_map[5][5] where world_map[row][column].
|
||||
world_map = world_map.split('\n')
|
||||
|
||||
def return_map():
|
||||
"""
|
||||
This function returns the whole map
|
||||
"""
|
||||
map = ""
|
||||
|
||||
#For each row in our map, add it to map
|
||||
for valuey in world_map:
|
||||
map += valuey
|
||||
map += "\n"
|
||||
|
||||
return map
|
||||
|
||||
def return_minimap(x, y, radius = 2):
|
||||
"""
|
||||
This function returns only part of the map.
|
||||
Returning all chars in a 2 char radius from (x,y)
|
||||
"""
|
||||
map = ""
|
||||
|
||||
#For each row we need, add the characters we need.
|
||||
for valuey in world_map[y-radius:y+radius+1]: for valuex in valuey[x-radius:x+radius+1]:
|
||||
map += valuex
|
||||
map += "\n"
|
||||
|
||||
return map
|
||||
```
|
||||
|
||||
With our map_module set up, let's replace our hardcoded map in `mygame/world/batchcode_map.py` with
|
||||
a reference to our map module. Make sure to import our map_module!
|
||||
|
||||
```python
|
||||
# mygame/world/batchcode_map.py
|
||||
|
||||
from evennia import create_object
|
||||
from evennia import DefaultObject
|
||||
from world import map_module
|
||||
|
||||
map = create_object(DefaultObject, key="Map", location=caller.location)
|
||||
|
||||
map.db.desc = map_module.return_map()
|
||||
|
||||
caller.msg("A map appears out of thin air and falls to the ground.")
|
||||
```
|
||||
|
||||
Log into Evennia as the superuser and run this batchcode. If everything worked our new map should
|
||||
look exactly the same as the old map - you can use `@delete` to delete the old one (use a number to
|
||||
pick which to delete).
|
||||
|
||||
Now, lets turn our attention towards our game's rooms. Let's use the `return_minimap` method we
|
||||
created above in order to include a minimap in our room descriptions. This is a little more
|
||||
complicated.
|
||||
|
||||
By itself we would have to settle for either the map being *above* the description with
|
||||
`room.db.desc = map_string + description_string`, or the map going *below* by reversing their order.
|
||||
Both options are rather unsatisfactory - we would like to have the map next to the text! For this
|
||||
solution we'll explore the utilities that ship with Evennia. Tucked away in `evennia\evennia\utils`
|
||||
is a little module called [EvTable](github:evennia.utils.evtable) . This is an advanced ASCII table
|
||||
creator for you to utilize in your game. We'll use it by creating a basic table with 1 row and two
|
||||
columns (one for our map and one for our text) whilst also hiding the borders. Open the batchfile
|
||||
again
|
||||
|
||||
```python
|
||||
# mygame\world\batchcode_world.py
|
||||
|
||||
# Add to imports
|
||||
from evennia.utils import evtable
|
||||
from world import map_module
|
||||
|
||||
# [...]
|
||||
|
||||
# Replace the descriptions with the below code.
|
||||
|
||||
# The cross roads.
|
||||
# We pass what we want in our table and EvTable does the rest.
|
||||
# Passing two arguments will create two columns but we could add more.
|
||||
# We also specify no border.
|
||||
centre.db.desc = evtable.EvTable(map_module.return_minimap(4,5),
|
||||
"The merger of two roads. A single lamp post dimly " \
|
||||
"illuminates the lonely crossroads. To the north " \
|
||||
"looms a mighty castle. To the south the glow of " \
|
||||
"a campfire can be seen. To the east lie a wall of " \
|
||||
"mountains and to the west the dull roar of the open sea.",
|
||||
border=None)
|
||||
# EvTable allows formatting individual columns and cells. We use that here
|
||||
# to set a maximum width for our description, but letting the map fill
|
||||
# whatever space it needs.
|
||||
centre.db.desc.reformat_column(1, width=70)
|
||||
|
||||
# [...]
|
||||
|
||||
# The northern castle.
|
||||
north.db.desc = evtable.EvTable(map_module.return_minimap(4,2),
|
||||
"An impressive castle surrounds you. There might be " \
|
||||
"a princess in one of these towers.",
|
||||
border=None)
|
||||
north.db.desc.reformat_column(1, width=70)
|
||||
|
||||
# [...]
|
||||
|
||||
# The eastern cottage.
|
||||
east.db.desc = evtable.EvTable(map_module.return_minimap(6,5),
|
||||
"A cosy cottage nestled among mountains stretching " \
|
||||
"east as far as the eye can see.",
|
||||
border=None)
|
||||
east.db.desc.reformat_column(1, width=70)
|
||||
|
||||
# [...]
|
||||
|
||||
# The southern camp.
|
||||
south.db.desc = evtable.EvTable(map_module.return_minimap(4,7),
|
||||
"Surrounding a clearing are a number of tribal tents " \
|
||||
"and at their centre a roaring fire.",
|
||||
border=None)
|
||||
south.db.desc.reformat_column(1, width=70)
|
||||
|
||||
# [...]
|
||||
|
||||
# The western coast.
|
||||
west.db.desc = evtable.EvTable(map_module.return_minimap(2,5),
|
||||
"The dark forest halts to a sandy beach. The sound of " \
|
||||
"crashing waves calms the soul.",
|
||||
border=None)
|
||||
west.db.desc.reformat_column(1, width=70)
|
||||
```
|
||||
|
||||
Before we run our new batchcode, if you are anything like me you would have something like 100 maps
|
||||
lying around and 3-4 different versions of our rooms extending from limbo. Let's wipe it all and
|
||||
start with a clean slate. In Command Prompt you can run `evennia flush` to clear the database and
|
||||
start anew. It won't reset dbref values however, so if you are at #100 it will start from there.
|
||||
Alternatively you can navigate to `mygame/server` and delete the `evennia.db3` file. Now in Command
|
||||
Prompt use `evennia migrate` to have a completely freshly made database.
|
||||
|
||||
Log in to evennia and run `@batchcode batchcode_world` and you'll have a little world to explore.
|
||||
|
||||
## Conclusions
|
||||
|
||||
You should now have a mapped little world and a basic understanding of batchcode, EvTable and how
|
||||
easily new game defining features can be added to Evennia.
|
||||
|
||||
You can easily build from this tutorial by expanding the map and creating more rooms to explore. Why
|
||||
not add more features to your game by trying other tutorials: [Add weather to your world](Weather-
|
||||
Tutorial), [fill your world with NPC's](../Howto/Tutorial-Aggressive-NPCs.md) or
|
||||
[implement a combat system](../Howto/Starting/Part3/Turn-based-Combat-System.md).
|
||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue