mirror of
https://github.com/evennia/evennia.git
synced 2026-03-17 05:16:31 +01:00
Updated HTML docs.
This commit is contained in:
parent
59e50f3fa5
commit
06bc3c8bcd
663 changed files with 2 additions and 61705 deletions
|
|
@ -1,773 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
### Evennia 1.0
|
||||
|
||||
> Not released yet
|
||||
> 2019-2022 develop branch (WIP)
|
||||
|
||||
Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10
|
||||
|
||||
- New `drop:holds()` lock default to limit dropping nonsensical things. Access check
|
||||
defaults to True for backwards-compatibility in 0.9, will be False in 1.0
|
||||
- REST API allows you external access to db objects through HTTP requests (Tehom)
|
||||
- `Object.normalize_name` and `.validate_name` added to (by default) enforce latinify
|
||||
on character name and avoid potential exploits using clever Unicode chars (trhr)
|
||||
- New `utils.format_grid` for easily displaying long lists of items in a block.
|
||||
- Using `lunr` search indexing for better `help` matching and suggestions. Also improve
|
||||
the main help command's default listing output.
|
||||
- Added `content_types` indexing to DefaultObject's ContentsHandler. (volund)
|
||||
- Made most of the networking classes such as Protocols and the SessionHandlers
|
||||
replaceable via `settings.py` for modding enthusiasts. (volund)
|
||||
- The `initial_setup.py` file can now be substituted in `settings.py` to customize
|
||||
initial game database state. (volund)
|
||||
- Added new Traits contrib, converted and expanded from Ainneve project.
|
||||
- Added new `requirements_extra.txt` file for easily getting all optional dependencies.
|
||||
- Change default multi-match syntax from 1-obj, 2-obj to obj-1, obj-2.
|
||||
- Make `object.search` support 'stacks=0' keyword - if ``>0``, the method will return
|
||||
N identical matches instead of triggering a multi-match error.
|
||||
- Add `tags.has()` method for checking if an object has a tag or tags (PR by ChrisLR)
|
||||
- Make IP throttle use Django-based cache system for optional persistence (PR by strikaco)
|
||||
- Renamed Tutorial classes "Weapon" and "WeaponRack" to "TutorialWeapon" and
|
||||
"TutorialWeaponRack" to prevent collisions with classes in mygame
|
||||
- New `crafting` contrib, adding a full crafting subsystem (Griatch 2020)
|
||||
- The `rplanguage` contrib now auto-capitalizes sentences and retains ellipsis (...). This
|
||||
change means that proper nouns at the start of sentences will not be treated as nouns.
|
||||
- Make MuxCommand `lhs/rhslist` always be lists, also if empty (used to be the empty string)
|
||||
- Fix typo in UnixCommand contrib, where `help` was given as `--hel`.
|
||||
- Latin (la) i18n translation (jamalainm)
|
||||
- Made the `evennia` dir possible to use without gamedir for purpose of doc generation.
|
||||
- Make Scripts' timer component independent from script object deletion; can now start/stop
|
||||
timer without deleting Script. The `.persistent` flag now only controls if timer survives
|
||||
reload - Script has to be removed with `.delete()` like other typeclassed entities.
|
||||
- Add `utils.repeat` and `utils.unrepeat` as shortcuts to TickerHandler add/remove, similar
|
||||
to how `utils.delay` is a shortcut for TaskHandler add.
|
||||
- Refactor the classic `red_button` example to use `utils.delay/repeat` and modern recommended
|
||||
code style and paradigms instead of relying on `Scripts` for everything.
|
||||
- Expand `CommandTest` with ability to check multiple message-receivers; inspired by PR by
|
||||
user davewiththenicehat. Also add new doc string.
|
||||
- Add central `FuncParser` as a much more powerful replacement for the old `parse_inlinefunc`
|
||||
function.
|
||||
- Attribute/NAttribute got a homogenous representation, using intefaces, both
|
||||
`AttributeHandler` and `NAttributeHandler` has same api now.
|
||||
- Add `evennia/utils/verb_conjugation` for automatic verb conjugation (English only). This
|
||||
is useful for implementing actor-stance emoting for sending a string to different targets.
|
||||
- New version of Italian translation (rpolve)
|
||||
- `utils.evmenu.ask_yes_no` is a helper function that makes it easy to ask a yes/no question
|
||||
to the user and respond to their input. This complements the existing `get_input` helper.
|
||||
- Allow sending messages with `page/tell` without a `=` if target name contains no spaces.
|
||||
- New FileHelpStorage system allows adding help entries via external files.
|
||||
- `sethelp` command now warns if shadowing other help-types when creating a new
|
||||
entry.
|
||||
- Help command now uses `view` lock to determine if cmd/entry shows in index and
|
||||
`read` lock to determine if it can be read. It used to be `view` in the role
|
||||
of the latter. Migration swaps these around.
|
||||
- In modules given by `settings.PROTOTYPE_MODULES`, spawner will now first look for a global
|
||||
list `PROTOTYPE_LIST` of dicts before loading all dicts in the module as prototypes.
|
||||
- New Channel-System using the `channel` command and nicks. Removed the `ChannelHandler` and the
|
||||
concept of a dynamically created `ChannelCmdSet`.
|
||||
- Add `Msg.db_receiver_external` field to allowe external, string-id message-receivers.
|
||||
- Renamed `app.css` to `website.css` for consistency. Removed old prosimii-css files.
|
||||
- Remove `mygame/web/static_overrides` and -`template_overrides`, reorganize website/admin/client/api
|
||||
into a more consistent structure for overriding. Expanded webpage documentation considerably.
|
||||
- REST API list-view was shortened (#2401). New CSS/HTML. Add ReDoc for API autodoc page.
|
||||
- Update and fix dummyrunner with cleaner code and setup.
|
||||
- Made `iter_to_str` format prettier strings, using Oxford comma.
|
||||
- Added an MXP anchor tag to also support clickable web links.
|
||||
- New `tasks` command for managing tasks started with `utils.delay` (PR by davewiththenicehat)
|
||||
- Make `help` index output clickable for webclient/clients with MXP (PR by davewiththenicehat)
|
||||
- Custom `evennia` launcher commands (e.g. `evennia mycmd foo bar`). Add new commands as callables
|
||||
accepting `*args`, as `settings.EXTRA_LAUNCHER_COMMANDS = {'mycmd': 'path.to.callable', ...}`.
|
||||
- New `XYZGrid` contrib, adding x,y,z grid coordinates with in-game map and
|
||||
pathfinding. Controlled outside of the game via custom evennia launcher command.
|
||||
- `Script.delete` has new kwarg `stop_task=True`, that can be used to avoid
|
||||
infinite recursion when wanting to set up Script to delete-on-stop.
|
||||
- Command executions now done on copies to make sure `yield` don't cause crossovers. Add
|
||||
`Command.retain_instance` flag for reusing the same command instance.
|
||||
- The `typeclass` command will now correctly search the correct database-table for the target
|
||||
obj (avoids mistakenly assigning an AccountDB-typeclass to a Character etc).
|
||||
- Merged `script` and `scripts` commands into one, for both managing global- and
|
||||
on-object Scripts. Moved `CmdScripts` and `CmdObjects` to `commands/default/building.py`.
|
||||
- Keep GMCP function case if outputfunc starts with capital letter (so `cmd_name` -> `Cmd.Name`
|
||||
but `Cmd_nAmE` -> `Cmd.nAmE`). This helps e.g Mudlet's legacy `Client_GUI` implementation)
|
||||
- Prototypes now allow setting `prototype_parent` directly to a prototype-dict.
|
||||
This makes it easier when dynamically building in-module prototypes.
|
||||
- `RPSystem contrib` was expanded to support case, so /tall becomes 'tall man'
|
||||
while /Tall becomes 'Tall man'. One can turn this off if wanting the old style.
|
||||
- Change `EvTable` fixed-height rebalance algorithm to fill with empty lines at end of
|
||||
column instead of inserting rows based on cell-size (could be mistaken for a bug).
|
||||
- Split `return_appearance` hook with helper methods and have it use a template
|
||||
string in order to make it easier to override.
|
||||
- Add validation question to default account creation.
|
||||
- Add `LOCALECHO` client option to add server-side echo for clients that does
|
||||
not support this (useful for getting a complete log).
|
||||
- Make `@lazy_property` decorator create read/delete-protected properties. This is
|
||||
because it's used for handlers, and e.g. self.locks=[] is a common beginner mistake.
|
||||
- Add `$pron()` inlinefunc for pronoun parsing in actor-stance strings using
|
||||
`msg_contents`.
|
||||
- Update defauklt website to show Telnet/SSL/SSH connect info. Added new
|
||||
`SERVER_HOSTNAME` setting for use in the server:port stanza.
|
||||
- Changed all `at_before/after_*` hooks to `at_pre/post_*` for consistency
|
||||
across Evennia (the old names still work but are deprecated)
|
||||
- Change `settings.COMMAND_DEFAULT_ARG_REGEX` default from `None` to a regex meaning that
|
||||
a space or `/` must separate the cmdname and args. This better fits common expectations.
|
||||
- Add confirmation question to `ban`/`unban` commands.
|
||||
- Check new `teleport` and `teleport_here` lock-types in `teleport` command to optionally
|
||||
allow to limit teleportation of an object or to a specific destination.
|
||||
- Add `settings.MXP_ENABLED=True` and `settings.MXP_OUTGOING_ONLY=True` as sane defaults,
|
||||
to avoid known security issues with players entering MXP links.
|
||||
- Add browser name to webclient `CLIENT_NAME` in `session.protocol_flags`, e.g.
|
||||
`"Evennia webclient (websocket:firefox)"` or `"evennia webclient (ajax:chrome)"`.
|
||||
- `TagHandler.add/has(tag=...)` kwarg changed to `add/has(key=...)` for consistency
|
||||
with other handlers.
|
||||
- Make `DefaultScript.delete`, `DefaultChannel.delete` and `DefaultAccount.delete` return
|
||||
bool True/False if deletion was successful (like `DefaultObject.delete` before them)
|
||||
- `contrib.custom_gametime` days/weeks/months now always starts from 1 (to match
|
||||
the standard calendar form ... there is no month 0 every year after all).
|
||||
- `AttributeProperty`/`NAttributeProperty` to allow managing Attributes/NAttributes
|
||||
on typeclasses in the same way as Django fields.
|
||||
- Give build/system commands a `@name` to fall back to if the non-@ name is used
|
||||
by another command (like `open` and `@open`. If no duplicate, @ is optional.
|
||||
- Move legacy channel-management commands (`ccreate`, `addcom` etc) to a contrib
|
||||
since their work is now fully handled by the single `channel` command.
|
||||
- Expand `examine` command's code to much more extensible and modular. Show
|
||||
attribute categories and value types (when not strings).
|
||||
- `AttributeHandler.remove(key, return_exception=False, category=None, ...)` changed
|
||||
to `.remove(key, category=None, return_exception=False, ...)` for consistency.
|
||||
- New `command cooldown` contrib for making it easier to manage commands using
|
||||
dynamic cooldowns between uses (owllex)
|
||||
- Restructured `contrib/` folder, placing all contribs as separate packages under
|
||||
subfolders. All imports will need to be updated.
|
||||
- Made `MonitorHandler.add/remove` support `category` for monitoring Attributes
|
||||
with a category (before only key was used, ignoring category entirely).
|
||||
- Move `create_*` functions into db managers, leaving `utils.create` only being
|
||||
wrapper functions (consistent with `utils.search`). No change of api otherwise.
|
||||
- Add support for `$dbref()` and `$search` when assigning an Attribute value
|
||||
with the `set` command. This allows assigning real objects from in-game.
|
||||
- Add ability to examine `/script` and `/channel` entities with `examine` command.
|
||||
- Homogenize manager search methods to return querysets and not lists.
|
||||
- Restructure unit tests to always honor default settings; make new parents in
|
||||
on location for easy use in game dir.
|
||||
- The `Lunr` search engine used by help excludes common words; the settings-list
|
||||
`LUNR_STOP_WORD_FILTER_EXCEPTIONS` can be extended to make sure common names are included.
|
||||
- Add `.deserialize()` method to `_Saver*` structures to help completely
|
||||
decouple structures from database without needing separate import.
|
||||
- Add `run_in_main_thread` as a helper for those wanting to code server code
|
||||
from a web view.
|
||||
- Update `evennia.utils.logger` to use Twisted's new logging API. No change in Evennia API
|
||||
except more standard aliases logger.error/info/exception/debug etc can now be used.
|
||||
- Have `type/force` default to `update`-mode rather than `reset`mode and add more verbose
|
||||
warning when using reset mode.
|
||||
- Attribute storage support defaultdics (Hendher)
|
||||
- Add ObjectParent mixin to default game folder template as an easy, ready-made
|
||||
way to override features on all ObjectDB-inheriting objects easily.
|
||||
source location, mimicking behavior of `at_pre_move` hook - returning False will abort move.
|
||||
- Add `TagProperty`, `AliasProperty` and `PermissionProperty` to assign these
|
||||
data in a similar way to django fields.
|
||||
- New `at_pre_object_receive(obj, source_location)` method on Objects. Called on
|
||||
destination, mimicking behavior of `at_pre_move` hook - returning False will abort move.
|
||||
- New `at_pre_object_leave(obj, destination)` method on Objects. Called on
|
||||
- The db pickle-serializer now checks for methods `__serialize_dbobjs__` and `__deserialize_dbobjs__`
|
||||
to allow custom packing/unpacking of nested dbobjs, to allow storing in Attribute.
|
||||
- Optimizations to rpsystem contrib performance. Breaking change: `.get_sdesc()` will
|
||||
now return `None` instead of `.db.desc` if no sdesc is set; fallback in hook (inspectorCaracal)
|
||||
- Reworked text2html parser to avoid problems with stateful color tags (inspectorCaracal)
|
||||
- Simplified `EvMenu.options_formatter` hook to use `EvColumn` and f-strings (inspectorcaracal)
|
||||
- Allow `# CODE`, `# HEADER` etc as well as `#CODE`/`#HEADER` in batchcode
|
||||
files - this works better with black linting.
|
||||
- Added `move_type` str kwarg to `move_to()` calls, optionally identifying the type of
|
||||
move being done ('teleport', 'disembark', 'give' etc). (volund)
|
||||
- Made RPSystem contrib msg calls pass `pose` or `say` as msg-`type` for use in
|
||||
e.g. webclient pane filtering where desired. (volund)
|
||||
- Added `Account.uses_screenreader(session=None)` as a quick shortcut for
|
||||
finding if a user uses a screenreader (and adjust display accordingly).
|
||||
- Fixed bug in `cmdset.remove()` where a command could not be deleted by `key`,
|
||||
even though doc suggested one could (ChrisLR)
|
||||
- New contrib `name_generator` for building random real-world based or fantasy-names
|
||||
based on phonetic rules.
|
||||
- Enable proper serialization of dict subclasses in Attributes (aogier)
|
||||
- `object.search` fuzzy-matching now uses `icontains` instead of `istartswith`
|
||||
to better match how search works elsewhere (volund)
|
||||
- The `.at_traverse` hook now receives a `exit_obj` kwarg, linking back to the
|
||||
exit triggering the hook (volund)
|
||||
- Contrib `buffs` for managing temporary and permanent RPG status buffs effects (tegiminis)
|
||||
- New `at_server_init()` hook called before all other startup hooks for all
|
||||
startup modes. Used for more generic overriding (volund)
|
||||
- New `search` lock type used to completely hide an object from being found by
|
||||
the `DefaultObject.search` (`caller.search`) method. (CloudKeeper)
|
||||
- Change setting `MULTISESSION_MODE` to now only control sessions, not how many
|
||||
characters can be puppeted simultaneously. New settings now control that.
|
||||
- Add new setting `AUTO_CREATE_CHARACTER_WITH_ACCOUNT`, a boolean deciding if
|
||||
the new account should also get a matching character (legacy MUD style).
|
||||
- Add new setting `AUTO_PUPPET_ON_LOGIN`, boolean deciding if one should
|
||||
automatically puppet the last/available character on connection (legacy MUD style)
|
||||
- Add new setting `MAX_NR_SIMULTANEUS_PUPPETS` - how many puppets the account
|
||||
can run at the same time. Used to limit multi-playing.
|
||||
- Make setting `MAX_NR_CHARACTERS` interact better with the new settings above.
|
||||
- Allow `$search` funcparser func to search tags and to accept kwargs for more
|
||||
powerful searches passed into the regular search functions.
|
||||
- `spawner.spawn` and linked methods now has a kwarg `protfunc_raise_errors`
|
||||
(default True) to disable strict errors on malformed/not-found protfuncs
|
||||
- Improve search performance when having many DB-based prototypes via caching.
|
||||
- Remove the `return_parents` kwarg of `evennia.prototypes.spawner.spawn` since it
|
||||
was inefficient and unused.
|
||||
- Made all id fields BigAutoField for all databases. (owllex)
|
||||
- `EvForm` refactored. New `literals` mapping, for literal mappings into the
|
||||
main template (e.g. for single-character replacements).
|
||||
- `EvForm` `cells` kwarg now accepts `EvCells` with custom formatting options
|
||||
(mainly for custom align/valign). `EvCells` now makes use of `utils.justify`.
|
||||
- `utils.justify` now supports `align="a"` (absolute alignments. This keeps
|
||||
the given left indent but crops/fills to the width. Used in EvCells.
|
||||
- `EvTable` now supports passing `EvColumn`s as a list directly, (`EvTable(table=[colA,colB])`)
|
||||
|
||||
## Evennia 0.9.5
|
||||
|
||||
> 2019-2020
|
||||
> Released 2020-11-14.
|
||||
> Transitional release, including new doc system.
|
||||
|
||||
Backported from develop: Python 3.8, 3.9 support. Django 3.2+ support, Twisted 21+ support.
|
||||
|
||||
- `is_typeclass(obj (Object), exact (bool))` now defaults to exact=False
|
||||
- `py` command now reroutes stdout to output results in-game client. `py`
|
||||
without arguments starts a full interactive Python console.
|
||||
- Webclient default to a single input pane instead of two. Now defaults to no help-popup.
|
||||
- Webclient fix of prompt display
|
||||
- Webclient multimedia support for relaying images, video and sounds via
|
||||
`.msg(image=URL)`, `.msg(video=URL)`
|
||||
and `.msg(audio=URL)`
|
||||
- Add Spanish translation (fermuch)
|
||||
- Expand `GLOBAL_SCRIPTS` container to always start scripts and to include all
|
||||
global scripts regardless of how they were created.
|
||||
- Change settings to always use lists instead of tuples, to make mutable
|
||||
settings easier to add to. (#1912)
|
||||
- Make new `CHANNEL_MUDINFO` setting for specifying the mudinfo channel
|
||||
- Make `CHANNEL_CONNECTINFO` take full channel definition
|
||||
- Make `DEFAULT_CHANNELS` list auto-create channels missing at reload
|
||||
- Webclient `ANSI->HTML` parser updated. Webclient line width changed from 1.6em to 1.1em
|
||||
to better make ANSI graphics look the same as for third-party clients
|
||||
- `AttributeHandler.get(return_list=True)` will return `[]` if there are no
|
||||
Attributes instead of `[None]`.
|
||||
- Remove `pillow` requirement (install especially if using imagefield)
|
||||
- Add Simplified Korean translation (aceamro)
|
||||
- Show warning on `start -l` if settings contains values unsafe for production.
|
||||
- Make code auto-formatted with Black.
|
||||
- Make default `set` command able to edit nested structures (PR by Aaron McMillan)
|
||||
- Allow running Evennia test suite from core repo with `make test`.
|
||||
- Return `store_key` from `TickerHandler.add` and add `store_key` as a kwarg to
|
||||
the `TickerHandler.remove` method. This makes it easier to manage tickers.
|
||||
- EvMore auto-justify now defaults to False since this works better with all types
|
||||
of texts (such as tables). New `justify` bool. Old `justify_kwargs` remains
|
||||
but is now only used to pass extra kwargs into the justify function.
|
||||
- EvMore `text` argument can now also be a list or a queryset. Querysets will be
|
||||
sliced to only return the required data per page.
|
||||
- Improve performance of `find` and `objects` commands on large data sets (strikaco)
|
||||
- New `CHANNEL_HANDLER_CLASS` setting allows for replacing the ChannelHandler entirely.
|
||||
- Made `py` interactive mode support regular quit() and more verbose.
|
||||
- Made `Account.options.get` accept `default=None` kwarg to mimic other uses of get. Set
|
||||
the new `raise_exception` boolean if ranting to raise KeyError on a missing key.
|
||||
- Moved behavior of unmodified `Command` and `MuxCommand` `.func()` to new
|
||||
`.get_command_info()` method for easier overloading and access. (Volund)
|
||||
- Removed unused `CYCLE_LOGFILES` setting. Added `SERVER_LOG_DAY_ROTATION`
|
||||
and `SERVER_LOG_MAX_SIZE` (and equivalent for PORTAL) to control log rotation.
|
||||
- Addded `inside_rec` lockfunc - if room is locked, the normal `inside()` lockfunc will
|
||||
fail e.g. for your inventory objs (since their loc is you), whereas this will pass.
|
||||
- RPSystem contrib's CmdRecog will now list all recogs if no arg is given. Also multiple
|
||||
bugfixes.
|
||||
- Remove `dummy@example.com` as a default account email when unset, a string is no longer
|
||||
required by Django.
|
||||
- Fixes to `spawn`, make updating an existing prototype/object work better. Add `/raw` switch
|
||||
to `spawn` command to extract the raw prototype dict for manual editing.
|
||||
- `list_to_string` is now `iter_to_string` (but old name still works as legacy alias). It will
|
||||
now accept any input, including generators and single values.
|
||||
- EvTable should now correctly handle columns with wider asian-characters in them.
|
||||
- Update Twisted requirement to >=2.3.0 to close security vulnerability
|
||||
- Add `$random` inlinefunc, supports minval,maxval arguments that can be ints and floats.
|
||||
- Add `evennia.utils.inlinefuncs.raw(<str>)` as a helper to escape inlinefuncs in a string.
|
||||
- Make CmdGet/Drop/Give give proper error if `obj.move_to` returns `False`.
|
||||
- Make `Object/Room/Exit.create`'s `account` argument optional. If not given, will set perms
|
||||
to that of the object itself (along with normal Admin/Dev permission).
|
||||
- Make `INLINEFUNC_STACK_MAXSIZE` default visible in `settings_default.py`.
|
||||
- Change how `ic` finds puppets; non-priveleged users will use `_playable_characters` list as
|
||||
candidates, Builders+ will use list, local search and only global search if no match found.
|
||||
- Make `cmd.at_post_cmd()` always run after `cmd.func()`, even when the latter uses delays
|
||||
with yield.
|
||||
- `EvMore` support for db queries and django paginators as well as easier to override for custom
|
||||
pagination (e.g. to create EvTables for every page instead of splittine one table)
|
||||
- Using `EvMore pagination`, dramatically improves performance of `spawn/list` and `scripts` listings
|
||||
(100x speed increase for displaying 1000+ prototypes/scripts).
|
||||
- `EvMenu` now uses the more logically named `.ndb._evmenu` instead of `.ndb._menutree` to store itself.
|
||||
Both still work for backward compatibility, but `_menutree` is deprecated.
|
||||
- `EvMenu.msg(txt)` added as a central place to send text to the user, makes it easier to override.
|
||||
Default `EvMenu.msg` sends with OOB type="menu" for use with OOB and webclient pane-redirects.
|
||||
- New EvMenu templating system for quickly building simpler EvMenus without as much code.
|
||||
- Add `Command.client_height()` method to match existing `.client_width` (stricako)
|
||||
- Include more Web-client info in `session.protocol_flags`.
|
||||
- Fixes in multi-match situations - don't allow finding/listing multimatches for 3-box when
|
||||
only two boxes in location.
|
||||
- Fix for TaskHandler with proper deferred returns/ability to cancel etc (PR by davewiththenicehat)
|
||||
- Add `PermissionHandler.check` method for straight string perm-checks without needing lockstrings.
|
||||
- Add `evennia.utils.utils.strip_unsafe_input` for removing html/newlines/tags from user input. The
|
||||
`INPUT_CLEANUP_BYPASS_PERMISSIONS` is a list of perms that bypass this safety stripping.
|
||||
- Make default `set` and `examine` commands aware of Attribute categories.
|
||||
|
||||
## Evennia 0.9
|
||||
|
||||
> 2018-2019
|
||||
> Released Oct 2019
|
||||
|
||||
### Distribution
|
||||
|
||||
- New requirement: Python 3.7 (py2.7 support removed)
|
||||
- Django 2.1
|
||||
- Twisted 19.2.1
|
||||
- Autobahn websockets (removed old tmwx)
|
||||
- Docker image updated
|
||||
|
||||
### Commands
|
||||
|
||||
- Remove `@`-prefix from all default commands (prefixes still work, optional)
|
||||
- Removed default `@delaccount` command, incorporating as `@account/delete` instead. Added confirmation
|
||||
question.
|
||||
- Add new `@force` command to have another object perform a command.
|
||||
- Add the Portal uptime to the `@time` command.
|
||||
- Make the `@link` command first make a local search before a global search.
|
||||
- Have the default Unloggedin-look command look for optional `connection_screen()` callable in
|
||||
`mygame/server/conf/connection_screen.py`. This allows for more flexible welcome screens
|
||||
that are calculated on the fly.
|
||||
- `@py` command now defaults to escaping html tags in its output when viewing in the webclient.
|
||||
Use new `/clientraw` switch to get old behavior (issue #1369).
|
||||
- Shorter and more informative, dynamic, listing of on-command vars if not
|
||||
setting func() in child command class.
|
||||
- New Command helper methods
|
||||
- `.client_width()` returns client width of the session running the command.
|
||||
- `.styled_table(*args, **kwargs)` returns a formatted evtable styled by user's options
|
||||
- `.style_header(*args, **kwargs)` creates styled header entry
|
||||
- `.style_separator(*args, **kwargs)` " separator
|
||||
- `.style_footer(*args, **kwargs)` " footer
|
||||
|
||||
### Web
|
||||
|
||||
- Change webclient from old txws version to use more supported/feature-rich Autobahn websocket library
|
||||
|
||||
#### Evennia game index
|
||||
|
||||
- Made Evennia game index client a part of core - now configured from settings file (old configs
|
||||
need to be moved)
|
||||
- The `evennia connections` command starts a wizard that helps you connect your game to the game index.
|
||||
- The game index now accepts games with no public telnet/webclient info (for early prototypes).
|
||||
|
||||
#### New golden-layout based Webclient UI (@friarzen)
|
||||
- Features
|
||||
- Much slicker behavior and more professional look
|
||||
- Allows tabbing as well as click and drag of panes in any grid position
|
||||
- Renaming tabs, assignments of data tags and output types are simple per-pane menus now
|
||||
- Any number of input panes, with separate histories
|
||||
- Button UI (disabled in JS by default)
|
||||
|
||||
#### Web/Django standard initiative (@strikaco)
|
||||
- Features
|
||||
- Adds a series of web-based forms and generic class-based views
|
||||
- Accounts
|
||||
- Register - Enhances registration; allows optional collection of email address
|
||||
- Form - Adds a generic Django form for creating Accounts from the web
|
||||
- Characters
|
||||
- Create - Authenticated users can create new characters from the website (requires associated form)
|
||||
- Detail - Authenticated and authorized users can view select details about characters
|
||||
- List - Authenticated and authorized users can browse a list of all characters
|
||||
- Manage - Authenticated users can edit or delete owned characters from the web
|
||||
- Form - Adds a generic Django form for creating characters from the web
|
||||
- Channels
|
||||
- Detail - Authorized users can view channel logs from the web
|
||||
- List - Authorized users can browse a list of all channels
|
||||
- Help Entries
|
||||
- Detail - Authorized users can view help entries from the web
|
||||
- List - Authorized users can browse a list of all help entries from the web
|
||||
- Navbar changes
|
||||
- Characters - Link to character list
|
||||
- Channels - Link to channel list
|
||||
- Help - Link to help entry list
|
||||
- Puppeting
|
||||
- Users can puppet their own characters within the context of the website
|
||||
- Dropdown
|
||||
- Link to create characters
|
||||
- Link to manage characters
|
||||
- Link to quick-select puppets
|
||||
- Link to password change workflow
|
||||
- Functions
|
||||
- Updates Bootstrap to v4 stable
|
||||
- Enables use of Django Messages framework to communicate with users in browser
|
||||
- Implements webclient/website `_shared_login` functionality as Django middleware
|
||||
- 'account' and 'puppet' are added to all request contexts for authenticated users
|
||||
- Adds unit tests for all web views
|
||||
- Cosmetic
|
||||
- Prettifies Django 'forgot password' workflow (requires SMTP to actually function)
|
||||
- Prettifies Django 'change password' workflow
|
||||
- Bugfixes
|
||||
- Fixes bug on login page where error messages were not being displayed
|
||||
- Remove strvalue field from admin; it made no sense to have here, being an optimization field
|
||||
for internal use.
|
||||
|
||||
### Prototypes
|
||||
|
||||
- `evennia.prototypes.save_prototype` now takes the prototype as a normal
|
||||
argument (`prototype`) instead of having to give it as `**prototype`.
|
||||
- `evennia.prototypes.search_prototype` has a new kwarg `require_single=False` that
|
||||
raises a KeyError exception if query gave 0 or >1 results.
|
||||
- `evennia.prototypes.spawner` can now spawn by passing a `prototype_key`
|
||||
|
||||
### Typeclasses
|
||||
|
||||
- Add new methods on all typeclasses, useful specifically for object handling from the website/admin:
|
||||
+ `web_get_admin_url()`: Returns the path to the object detail page in the Admin backend.
|
||||
+ `web_get_create_url()`: Returns the path to the typeclass' creation page on the website, if implemented.
|
||||
+ `web_get_absolute_url()`: Returns the path to the object's detail page on the website, if implemented.
|
||||
+ `web_get_update_url()`: Returns the path to the object's update page on the website, if implemented.
|
||||
+ `web_get_delete_url()`: Returns the path to the object's delete page on the website, if implemented.
|
||||
- All typeclasses have new helper class method `create`, which encompasses useful functionality
|
||||
that used to be embedded for example in the respective `@create` or `@connect` commands.
|
||||
- DefaultAccount now has new class methods implementing many things that used to be in unloggedin
|
||||
commands (these can now be customized on the class instead):
|
||||
+ `is_banned()`: Checks if a given username or IP is banned.
|
||||
+ `get_username_validators`: Return list of validators for username validation (see
|
||||
`settings.AUTH_USERNAME_VALIDATORS`)
|
||||
+ `authenticate`: Method to check given username/password.
|
||||
+ `normalize_username`: Normalizes names so (for Unicode environments) users cannot mimic existing usernames by replacing select characters with visually-similar Unicode chars.
|
||||
+ `validate_username`: Mechanism for validating a username based on predefined Django validators.
|
||||
+ `validate_password`: Mechanism for validating a password based on predefined Django validators.
|
||||
+ `set_password`: Apply password to account, using validation checks.
|
||||
- `AttributeHandler.remove` and `TagHandler.remove` can now be used to delete by-category. If neither
|
||||
key nor category is given, they now work the same as .clear().
|
||||
|
||||
### Protocols
|
||||
|
||||
- Support for `Grapevine` MUD-chat network ("channels" supported)
|
||||
|
||||
### Server
|
||||
|
||||
- Convert ServerConf model to store its values as a Picklefield (same as
|
||||
Attributes) instead of using a custom solution.
|
||||
- OOB: Add support for MSDP LIST, REPORT, UNREPORT commands (re-mapped to `msdp_list`,
|
||||
`msdp_report`, `msdp_unreport`, inlinefuncs)
|
||||
- Added `evennia.ANSIString` to flat API.
|
||||
- Server/Portal log files now cycle to names on the form `server_.log_19_03_08_` instead of `server.log___19.3.8`, retaining
|
||||
unix file sorting order.
|
||||
- Django signals fire for important events: Puppet/Unpuppet, Object create/rename, Login,
|
||||
Logout, Login fail Disconnect, Account create/rename
|
||||
|
||||
### Settings
|
||||
|
||||
- `GLOBAL_SCRIPTS` - dict defining typeclasses of global scripts to store on the new
|
||||
`evennia.GLOBAL_SCRIPTS` container. These will auto-start when Evennia start and will always
|
||||
exist.
|
||||
- `OPTIONS_ACCOUNTS_DEFAULT` - option dict with option defaults and Option classes
|
||||
- `OPTION_CLASS_MODULES` - classes representing an on-Account Option, on special form
|
||||
- `VALIDATOR_FUNC_MODULES` - (general) text validator functions, for verifying an input
|
||||
is on a specific form.
|
||||
|
||||
### Utils
|
||||
|
||||
- `evennia` launcher now fully handles all django-admin commands, like running tests in parallel.
|
||||
- `evennia.utils.create.account` now also takes `tags` and `attrs` keywords.
|
||||
- `evennia.utils.interactive` decorator can now allow you to use yield(secs) to pause operation
|
||||
in any function, not just in Command.func. Likewise, response = yield(question) will work
|
||||
if the decorated function has an argument or kwarg `caller`.
|
||||
- Added many more unit tests.
|
||||
- Swap argument order of `evennia.set_trace` to `set_trace(term_size=(140, 40), debugger='auto')`
|
||||
since the size is more likely to be changed on the command line.
|
||||
- `utils.to_str(text, session=None)` now acts as the old `utils.to_unicode` (which was removed).
|
||||
This converts to the str() type (not to a byte-string as in Evennia 0.8), trying different
|
||||
encodings. This function will also force-convert any object passed to it into a string (so
|
||||
`force_string` flag was removed and assumed always set).
|
||||
- `utils.to_bytes(text, session=None)` replaces the old `utils.to_str()` functionality and converts
|
||||
str to bytes.
|
||||
- `evennia.MONITOR_HANDLER.all` now takes keyword argument `obj` to only retrieve monitors from that specific
|
||||
Object (rather than all monitors in the entire handler).
|
||||
- Support adding `\f` in command doc strings to force where EvMore puts page breaks.
|
||||
- Validation Functions now added with standard API to homogenize user input validation.
|
||||
- Option Classes added to make storing user-options easier and smoother.
|
||||
- `evennia.VALIDATOR_CONTAINER` and `evennia.OPTION_CONTAINER` added to load these.
|
||||
|
||||
### Contribs
|
||||
|
||||
- Evscaperoom - a full puzzle engine for making multiplayer escape rooms in Evennia. Used to make
|
||||
the entry for the MUD-Coder's Guild's 2019 Game Jam with the theme "One Room", where it ranked #1.
|
||||
- Evennia game-index client no longer a contrib - moved into server core and configured with new
|
||||
setting `GAME_INDEX_ENABLED`.
|
||||
- The `extended_room` contrib saw some backwards-incompatible refactoring:
|
||||
+ All commands now begin with `CmdExtendedRoom`. So before it was `CmdExtendedLook`, now
|
||||
it's `CmdExtendedRoomLook` etc.
|
||||
+ The `detail` command was broken out of the `desc` command and is now a new, stand-alone command
|
||||
`CmdExtendedRoomDetail`. This was done to make things easier to extend and to mimic how the detail
|
||||
command works in the tutorial-world.
|
||||
+ The `detail` command now also supports deleting details (like the tutorial-world version).
|
||||
+ The new `ExtendedRoomCmdSet` includes all the extended-room commands and is now the recommended way
|
||||
to install the extended-room contrib.
|
||||
- Reworked `menu_login` contrib to use latest EvMenu standards. Now also supports guest logins.
|
||||
- Mail contrib was refactored to have optional Command classes `CmdMail` for OOC+IC mail (added
|
||||
to the CharacterCmdSet and `CmdMailCharacter` for IC-only mailing between chars (added to CharacterCmdSet)
|
||||
|
||||
### Translations
|
||||
|
||||
- Simplified chinese, courtesy of user MaxAlex.
|
||||
|
||||
|
||||
## Evennia 0.8
|
||||
|
||||
> 2017-2018
|
||||
> Released Nov 2018
|
||||
|
||||
### Requirements
|
||||
|
||||
- Up requirements to Django 1.11.x, Twisted 18 and pillow 5.2.0
|
||||
- Add `inflect` dependency for automatic pluralization of object names.
|
||||
|
||||
### Server/Portal
|
||||
|
||||
- Removed `evennia_runner`, completely refactor `evennia_launcher.py` (the 'evennia' program)
|
||||
with different functionality).
|
||||
- Both Portal/Server are now stand-alone processes (easy to run as daemon)
|
||||
- Made Portal the AMP Server for starting/restarting the Server (the AMP client)
|
||||
- Dynamic logging now happens using `evennia -l` rather than by interactive mode.
|
||||
- Made AMP secure against erroneous HTTP requests on the wrong port (return error messages).
|
||||
- The `evennia istart` option will start/switch the Server in foreground (interactive) mode, where it logs
|
||||
to terminal and can be stopped with Ctrl-C. Using `evennia reload`, or reloading in-game, will
|
||||
return Server to normal daemon operation.
|
||||
- For validating passwords, use safe Django password-validation backend instead of custom Evennia one.
|
||||
- Alias `evennia restart` to mean the same as `evennia reload`.
|
||||
|
||||
### Prototype changes
|
||||
|
||||
- New OLC started from `olc` command for loading/saving/manipulating prototypes in a menu.
|
||||
- Moved evennia/utils/spawner.py into the new evennia/prototypes/ along with all new
|
||||
functionality around prototypes.
|
||||
- A new form of prototype - database-stored prototypes, editable from in-game, was added. The old,
|
||||
module-created prototypes remain as read-only prototypes.
|
||||
- All prototypes must have a key `prototype_key` identifying the prototype in listings. This is
|
||||
checked to be server-unique. Prototypes created in a module will use the global variable name they
|
||||
are assigned to if no `prototype_key` is given.
|
||||
- Prototype field `prototype` was renamed to `prototype_parent` to avoid mixing terms.
|
||||
- All prototypes must either have `typeclass` or `prototype_parent` defined. If using
|
||||
`prototype_parent`, `typeclass` must be defined somewhere in the inheritance chain. This is a
|
||||
change from Evennia 0.7 which allowed 'mixin' prototypes without `typeclass`/`prototype_key`. To
|
||||
make a mixin now, give it a default typeclass, like `evennia.objects.objects.DefaultObject` and just
|
||||
override in the child as needed.
|
||||
- Spawning an object using a prototype will automatically assign a new tag to it, named the same as
|
||||
the `prototype_key` and with the category `from_prototype`.
|
||||
- The spawn command was extended to accept a full prototype on one line.
|
||||
- The spawn command got the /save switch to save the defined prototype and its key
|
||||
- The command spawn/menu will now start an OLC (OnLine Creation) menu to load/save/edit/spawn prototypes.
|
||||
|
||||
### EvMenu
|
||||
|
||||
- Added `EvMenu.helptext_formatter(helptext)` to allow custom formatting of per-node help.
|
||||
- Added `evennia.utils.evmenu.list_node` decorator for turning an EvMenu node into a multi-page listing.
|
||||
- A `goto` option callable returning None (rather than the name of the next node) will now rerun the
|
||||
current node instead of failing.
|
||||
- Better error handling of in-node syntax errors.
|
||||
- Improve dedent of default text/helptext formatter. Right-strip whitespace.
|
||||
- Add `debug` option when creating menu - this turns off persistence and makes the `menudebug`
|
||||
command available for examining the current menu state.
|
||||
|
||||
|
||||
### Webclient
|
||||
|
||||
- Webclient now uses a plugin system to inject new components from the html file.
|
||||
- Split-windows - divide input field into any number of horizontal/vertical panes and
|
||||
assign different types of server messages to them.
|
||||
- Lots of cleanup and bug fixes.
|
||||
- Hot buttons plugin (friarzen) (disabled by default).
|
||||
|
||||
### Locks
|
||||
|
||||
- New function `evennia.locks.lockhandler.check_lockstring`. This allows for checking an object
|
||||
against an arbitrary lockstring without needing the lock to be stored on an object first.
|
||||
- New function `evennia.locks.lockhandler.validate_lockstring` allows for stand-alone validation
|
||||
of a lockstring.
|
||||
- New function `evennia.locks.lockhandler.get_all_lockfuncs` gives a dict {"name": lockfunc} for
|
||||
all available lock funcs. This is useful for dynamic listings.
|
||||
|
||||
|
||||
### Utils
|
||||
|
||||
- Added new `columnize` function for easily splitting text into multiple columns. At this point it
|
||||
is not working too well with ansi-colored text however.
|
||||
- Extend the `dedent` function with a new `baseline_index` kwarg. This allows to force all lines to
|
||||
the indentation given by the given line regardless of if other lines were already a 0 indentation.
|
||||
This removes a problem with the original `textwrap.dedent` which will only dedent to the least
|
||||
indented part of a text.
|
||||
- Added `exit_cmd` to EvMore pager, to allow for calling a command (e.g. 'look') when leaving the pager.
|
||||
- `get_all_typeclasses` will return dict `{"path": typeclass, ...}` for all typeclasses available
|
||||
in the system. This is used by the new `@typeclass/list` subcommand (useful for builders etc).
|
||||
- `evennia.utils.dbserialize.deserialize(obj)` is a new helper function to *completely* disconnect
|
||||
a mutable recovered from an Attribute from the database. This will convert all nested `_Saver*`
|
||||
classes to their plain-Python counterparts.
|
||||
|
||||
### General
|
||||
|
||||
- Start structuring the `CHANGELOG` to list features in more detail.
|
||||
- Docker image `evennia/evennia:develop` is now auto-built, tracking the develop branch.
|
||||
- Inflection and grouping of multiple objects in default room (an box, three boxes)
|
||||
- `evennia.set_trace()` is now a shortcut for launching pdb/pudb on a line in the Evennia event loop.
|
||||
- Removed the enforcing of `MAX_NR_CHARACTERS=1` for `MULTISESSION_MODE` `0` and `1` by default.
|
||||
- Add `evennia.utils.logger.log_sec` for logging security-related messages (marked SS in log).
|
||||
|
||||
### Contribs
|
||||
|
||||
- `Auditing` (Johnny): Log and filter server input/output for security purposes
|
||||
- `Build Menu` (vincent-lg): New @edit command to edit object properties in a menu.
|
||||
- `Field Fill` (Tim Ashley Jenkins): Wraps EvMenu for creating submittable forms.
|
||||
- `Health Bar` (Tim Ashley Jenkins): Easily create colorful bars/meters.
|
||||
- `Tree select` (Fluttersprite): Wrap EvMenu to create a common type of menu from a string.
|
||||
- `Turnbattle suite` (Tim Ashley Jenkins)- the old `turnbattle.py` was moved into its own
|
||||
`turnbattle/` package and reworked with many different flavors of combat systems:
|
||||
- `tb_basic` - The basic turnbattle system, with initiative/turn order attack/defense/damage.
|
||||
- `tb_equip` - Adds weapon and armor, wielding, accuracy modifiers.
|
||||
- `tb_items` - Extends `tb_equip` with item use with conditions/status effects.
|
||||
- `tb_magic` - Extends `tb_equip` with spellcasting.
|
||||
- `tb_range` - Adds system for abstract positioning and movement.
|
||||
- The `extended_room` contrib saw some backwards-incompatible refactoring:
|
||||
- All commands now begin with `CmdExtendedRoom`. So before it was `CmdExtendedLook`, now
|
||||
it's `CmdExtendedRoomLook` etc.
|
||||
- The `detail` command was broken out of the `desc` command and is now a new, stand-alone command
|
||||
`CmdExtendedRoomDetail`. This was done to make things easier to extend and to mimic how the detail
|
||||
command works in the tutorial-world.
|
||||
- The `detail` command now also supports deleting details (like the tutorial-world version).
|
||||
- The new `ExtendedRoomCmdSet` includes all the extended-room commands and is now the recommended way
|
||||
to install the extended-room contrib.
|
||||
- Updates and some cleanup of existing contribs.
|
||||
|
||||
|
||||
### Internationalization
|
||||
|
||||
- Polish translation by user ogotai
|
||||
|
||||
# Overview-Changelogs
|
||||
|
||||
> These are changelogs from a time before we used formal version numbers.
|
||||
|
||||
## Sept 2017:
|
||||
Release of Evennia 0.7; upgrade to Django 1.11, change 'Player' to
|
||||
'Account', rework the website template and a slew of other updates.
|
||||
Info on what changed and how to migrate is found here:
|
||||
https://groups.google.com/forum/#!msg/evennia/0JYYNGY-NfE/cDFaIwmPBAAJ
|
||||
|
||||
## Feb 2017:
|
||||
New devel branch created, to lead up to Evennia 0.7.
|
||||
|
||||
## Dec 2016:
|
||||
Lots of bugfixes and considerable uptick in contributors. Unittest coverage
|
||||
and PEP8 adoption and refactoring.
|
||||
|
||||
## May 2016:
|
||||
Evennia 0.6 with completely reworked Out-of-band system, making
|
||||
the message path completely flexible and built around input/outputfuncs.
|
||||
A completely new webclient, split into the evennia.js library and a
|
||||
gui library, making it easier to customize.
|
||||
|
||||
## Feb 2016:
|
||||
Added the new EvMenu and EvMore utilities, updated EvEdit and cleaned up
|
||||
a lot of the batchcommand functionality. Started work on new Devel branch.
|
||||
|
||||
## Sept 2015:
|
||||
Evennia 0.5. Merged devel branch, full library format implemented.
|
||||
|
||||
## Feb 2015:
|
||||
Development currently in devel/ branch. Moved typeclasses to use
|
||||
django's proxy functionality. Changed the Evennia folder layout to a
|
||||
library format with a stand-alone launcher, in preparation for making
|
||||
an 'evennia' pypy package and using versioning. The version we will
|
||||
merge with will likely be 0.5. There is also work with an expanded
|
||||
testing structure and the use of threading for saves. We also now
|
||||
use Travis for automatic build checking.
|
||||
|
||||
## Sept 2014:
|
||||
Updated to Django 1.7+ which means South dependency was dropped and
|
||||
minimum Python version upped to 2.7. MULTISESSION_MODE=3 was added
|
||||
and the web customization system was overhauled using the latest
|
||||
functionality of django. Otherwise, mostly bug-fixes and
|
||||
implementation of various smaller feature requests as we got used
|
||||
to github. Many new users have appeared.
|
||||
|
||||
## Jan 2014:
|
||||
Moved Evennia project from Google Code to github.com/evennia/evennia.
|
||||
|
||||
## Nov 2013:
|
||||
Moved the internal webserver into the Server and added support for
|
||||
out-of-band protocols (MSDP initially). This large development push
|
||||
also meant fixes and cleanups of the way attributes were handled.
|
||||
Tags were added, along with proper handlers for permissions, nicks
|
||||
and aliases.
|
||||
|
||||
## May 2013:
|
||||
Made players able to control more than one Character at the same
|
||||
time, through the MULTISESSION_MODE=2 addition. This lead to a lot
|
||||
of internal changes for the server.
|
||||
|
||||
## Oct 2012:
|
||||
Changed Evennia from the Modified Artistic 1.0 license to the more
|
||||
standard and permissive BSD license. Lots of updates and bug fixes as
|
||||
more people start to use it in new ways. Lots of new caching and
|
||||
speed-ups.
|
||||
|
||||
## March 2012:
|
||||
Evennia's API has changed and simplified slightly in that the
|
||||
base-modules where removed from game/gamesrc. Instead admins are
|
||||
encouraged to explicitly create new modules under game/gamesrc/ when
|
||||
they want to implement their game - gamesrc/ is empty by default
|
||||
except for the example folders that contain template files to use for
|
||||
this purpose. We also added the ev.py file, implementing a new, flat
|
||||
API. Work is ongoing to add support for mud-specific telnet
|
||||
extensions, notably the MSDP and GMCP out-of-band extensions. On the
|
||||
community side, evennia's dev blog was started and linked on planet
|
||||
Mud-dev aggregator.
|
||||
|
||||
## Nov 2011:
|
||||
After creating several different proof-of-concept game systems (in
|
||||
contrib and privately) as well testing lots of things to make sure the
|
||||
implementation is basically sound, we are declaring Evennia out of
|
||||
Alpha. This can mean as much or as little as you want, admittedly -
|
||||
development is still heavy but the issue list is at an all-time low
|
||||
and the server is slowly stabilizing as people try different things
|
||||
with it. So Beta it is!
|
||||
|
||||
## Aug 2011:
|
||||
Split Evennia into two processes: Portal and Server. After a lot of
|
||||
work trying to get in-memory code-reloading to work, it's clear this
|
||||
is not Python's forte - it's impossible to catch all exceptions,
|
||||
especially in asynchronous code like this. Trying to do so results in
|
||||
hackish, flakey and unstable code. With the Portal-Server split, the
|
||||
Server can simply be rebooted while players connected to the Portal
|
||||
remain connected. The two communicates over twisted's AMP protocol.
|
||||
|
||||
## May 2011:
|
||||
The new version of Evennia, originally hitting trunk in Aug2010, is
|
||||
maturing. All commands from the pre-Aug version, including IRC/IMC2
|
||||
support works again. An ajax web-client was added earlier in the year,
|
||||
including moving Evennia to be its own webserver (no more need for
|
||||
Apache or django-testserver). Contrib-folder added.
|
||||
|
||||
## Aug 2010:
|
||||
Evennia-griatch-branch is ready for merging with trunk. This marks a
|
||||
rather big change in the inner workings of the server, such as the
|
||||
introduction of TypeClasses and Scripts (as compared to the old
|
||||
ScriptParents and Events) but should hopefully bring everything
|
||||
together into one consistent package as code development continues.
|
||||
|
||||
## May 2010:
|
||||
Evennia is currently being heavily revised and cleaned from
|
||||
the years of gradual piecemeal development. It is thus in a very
|
||||
'Alpha' stage at the moment. This means that old code snippets
|
||||
will not be backwards compatabile. Changes touch almost all
|
||||
parts of Evennia's innards, from the way Objects are handled
|
||||
to Events, Commands and Permissions.
|
||||
|
||||
## April 2010:
|
||||
Griatch takes over Maintainership of the Evennia project from
|
||||
the original creator Greg Taylor.
|
||||
|
||||
# Older
|
||||
|
||||
Earlier revisions, with previous maintainer, used SVN on Google Code
|
||||
and have no changelogs.
|
||||
|
||||
First commit (Evennia's birthday) was November 20, 2006.
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
# Coding Introduction
|
||||
|
||||
Evennia allows for a lot of freedom when designing your game - but to code efficiently you still
|
||||
need to adopt some best practices as well as find a good place to start to learn.
|
||||
|
||||
Here are some pointers to get you going.
|
||||
|
||||
## Start with the tutorial
|
||||
|
||||
It's highly recommended that you jump in on the [Starting Tutorial](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Part1-Intro.md). Even if
|
||||
you only the beginning or some part of it, it covers much of the things needed to get started.
|
||||
|
||||
## Python
|
||||
|
||||
Evennia is developed using Python. Even if you are more of a designer than a coder, it is wise to
|
||||
learn how to read and understand basic Python code. If you are new to Python, or need a refresher,
|
||||
take a look at our [Python introduction](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Python-basic-introduction.md).
|
||||
|
||||
## Explore Evennia interactively
|
||||
|
||||
When new to Evennia it can be hard to find things or figure out what is available. Evennia offers a
|
||||
special interactive python shell that allows you to experiment and try out things. It's recommended
|
||||
to use [ipython](https://ipython.org/) for this since the vanilla python prompt is very limited. Here
|
||||
are some simple commands to get started:
|
||||
|
||||
# [open a new console/terminal]
|
||||
# [activate your evennia virtualenv in this console/terminal]
|
||||
pip install -r requirements_extra.txt # install ipython etc
|
||||
cd mygame
|
||||
evennia shell
|
||||
|
||||
This will open an Evennia-aware python shell (using ipython). From within this shell, try
|
||||
|
||||
import evennia
|
||||
evennia.<TAB>
|
||||
|
||||
That is, enter `evennia.` and press the `<TAB>` key. This will show you all the resources made
|
||||
available at the top level of Evennia's "flat API". See the [flat API](../Evennia-API.md) page for more
|
||||
info on how to explore it efficiently.
|
||||
|
||||
### Jupyter Notebook Support
|
||||
|
||||
You can also explore evennia interactively in a [Jupyter notebook](https://jupyter.readthedocs.io/en/latest/index.html#). This offers
|
||||
an in-browser view of your code similar to Matlab or similar programs. There are
|
||||
a few extra steps that must be taken in order for this to work:
|
||||
|
||||
# [open a new console/terminal]
|
||||
# [activate your evennia virtualenv in this console/terminal]
|
||||
cd evennia
|
||||
pip install -r requirements_extra.txt # if not done already above
|
||||
|
||||
Next, `cd` to your game folder. _It's important that you are in the _root_ of this folder for the next command_:
|
||||
|
||||
evennia shell_plus --notebook &
|
||||
|
||||
The `&` at the end starts the process as a background process on Linux/Unix.
|
||||
Skip it if your OS doesn't support this syntax. Your browser should now open
|
||||
with the Jupyter interface. If not, open a browser to the link given on the
|
||||
command line.
|
||||
|
||||
In the window, open the `new` menu in the top right and start a `Django Shell-Plus` notebook (or
|
||||
open an existing one if you had one from before). In the first cell you must initialize
|
||||
Evennia like so:
|
||||
|
||||
```python
|
||||
import evennia
|
||||
evennia._init()
|
||||
```
|
||||
|
||||
_Note that the above initialization must be run every time a new new notebook/kernel is started or restarted._
|
||||
|
||||
After this you can import and access all of the Evennia system, same as with `evennia shell`.
|
||||
|
||||
### More exploration
|
||||
|
||||
You can complement your exploration by peeking at the sections of the much more detailed
|
||||
[Evennia Component overview](../Components/Components-Overview.md). The [Tutorials](../Howtos/Howtos-Overview.md) section also contains a growing collection
|
||||
of system- or implementation-specific help.
|
||||
|
||||
## Use a python syntax checker
|
||||
|
||||
Evennia works by importing your own modules and running them as part of the server. Whereas Evennia
|
||||
should just gracefully tell you what errors it finds, it can nevertheless be a good idea for you to
|
||||
check your code for simple syntax errors *before* you load it into the running server. There are
|
||||
many python syntax checkers out there. A fast and easy one is
|
||||
[pyflakes](https://pypi.python.org/pypi/pyflakes), a more verbose one is
|
||||
[pylint](https://www.pylint.org/). You can also check so that your code looks up to snuff using
|
||||
[pep8](https://pypi.python.org/pypi/pep8). Even with a syntax checker you will not be able to catch
|
||||
every possible problem - some bugs or problems will only appear when you actually run the code. But
|
||||
using such a checker can be a good start to weed out the simple problems.
|
||||
|
||||
## Plan before you code
|
||||
|
||||
Before you start coding away at your dream game, take a look at our [Game Planning](../Howtos/Beginner-Tutorial/Part2/Beginner-Tutorial-Game-Planning.md)
|
||||
page. It might hopefully help you avoid some common pitfalls and time sinks.
|
||||
|
||||
## Code in your game folder, not in the evennia/ repository
|
||||
|
||||
As part of the Evennia setup you will create a game folder to host your game code. This is your
|
||||
home. You should *never* need to modify anything in the `evennia` library (anything you download
|
||||
from us, really). You import useful functionality from here and if you see code you like, copy&paste
|
||||
it out into your game folder and edit it there.
|
||||
|
||||
If you find that Evennia doesn't support some functionality you need, make a [Feature
|
||||
Request](github:issue) about it. Same goes for [bugs][bug]. If you add features or fix bugs
|
||||
yourself, please consider [Contributing](../Contributing.md) your changes upstream!
|
||||
|
||||
## Learn to read tracebacks
|
||||
|
||||
Python is very good at reporting when and where things go wrong. A *traceback* shows everything you
|
||||
need to know about crashing code. The text can be pretty long, but you usually are only interested
|
||||
in the last bit, where it says what the error is and at which module and line number it happened -
|
||||
armed with this info you can resolve most problems.
|
||||
|
||||
Evennia will usually not show the full traceback in-game though. Instead the server outputs errors
|
||||
to the terminal/console from which you started Evennia in the first place. If you want more to show
|
||||
in-game you can add `IN_GAME_ERRORS = True` to your settings file. This will echo most (but not all)
|
||||
tracebacks both in-game as well as to the terminal/console. This is a potential security problem
|
||||
though, so don't keep this active when your game goes into production.
|
||||
|
||||
> A common confusing error is finding that objects in-game are suddenly of the type `DefaultObject`
|
||||
rather than your custom typeclass. This happens when you introduce a critical Syntax error to the
|
||||
module holding your custom class. Since such a module is not valid Python, Evennia can't load it at
|
||||
all. Instead of crashing, Evennia will then print the full traceback to the terminal/console and
|
||||
temporarily fall back to the safe `DefaultObject` until you fix the problem and reload.
|
||||
|
||||
## Docs are here to help you
|
||||
|
||||
Some people find reading documentation extremely dull and shun it out of principle. That's your
|
||||
call, but reading docs really *does* help you, promise! Evennia's documentation is pretty thorough
|
||||
and knowing what is possible can often give you a lot of new cool game ideas. That said, if you
|
||||
can't find the answer in the docs, don't be shy to ask questions! The [discussion
|
||||
group](https://sites.google.com/site/evenniaserver/discussions) and the [irc
|
||||
chat](https://webchat.freenode.net/?channels=evennia) are also there for you.
|
||||
|
||||
## The most important point
|
||||
|
||||
And finally, of course, have fun!
|
||||
|
||||
[feature-request]: (https://github.com/evennia/evennia/issues/new?title=Feature+Request%3a+%3Cdescriptive+title+here%3E&body=%23%23%23%23+Description+of+the+suggested+feature+and+how+it+is+supposed+to+work+for+the+admin%2fend+user%3a%0D%0A%0D%0A%0D%0A%23%23%23%23+A+list+of+arguments+for+why+you+think+this+new+feature+should+be+included+in+Evennia%3a%0D%0A%0D%0A1.%0D%0A2.%0D%0A%0D%0A%23%23%23%23+Extra+information%2c+such+as+requirements+or+ideas+on+implementation%3a%0D%0A%0D%0A
|
||||
[bug](https://github.com/evennia/evennia/issues/new?title=Bug%3a+%3Cdescriptive+title+here%3E&body=%23%23%23%23+Steps+to+reproduce+the+issue%3a%0D%0A%0D%0A1.+%0D%0A2.+%0D%0A3.+%0D%0A%0D%0A%23%23%23%23+What+I+expect+to+see+and+what+I+actually+see+%28tracebacks%2c+error+messages+etc%29%3a%0D%0A%0D%0A%0D%0A%0D%0A%23%23%23%23+Extra+information%2c+such+as+Evennia+revision%2frepo%2fbranch%2c+operating+system+and+ideas+for+how+to+solve%3a%0D%0A%0D%0A)
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# Coding and development help
|
||||
|
||||
This documentation aims to help you set up a sane development environment to
|
||||
make your game, also if you never coded before. If you are an experienced coder, much of this will be familiar
|
||||
to you, but some things may still be useful.
|
||||
|
||||
|
||||
## Setting up a workflow
|
||||
|
||||
See also the [Beginner Tutorial](../Howtos/Beginner-Tutorial/Beginner-Tutorial-Intro.md).
|
||||
|
||||
```{toctree}
|
||||
:maxdepth: 2
|
||||
|
||||
Version-Control.md
|
||||
Updating-Your-Game.md
|
||||
|
||||
```
|
||||
|
||||
## Coding away
|
||||
|
||||
```{toctree}
|
||||
:maxdepth: 2
|
||||
|
||||
Coding-Introduction.md
|
||||
Debugging.md
|
||||
Unit-Testing.md
|
||||
Profiling.md
|
||||
Quirks.md
|
||||
Changelog.md
|
||||
|
||||
```
|
||||
|
||||
## Third-party integrations
|
||||
|
||||
```{toctree}
|
||||
:maxdepth: 2
|
||||
|
||||
Continuous-Integration.md
|
||||
Setting-up-PyCharm.md
|
||||
|
||||
```
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
# Continuous Integration - TeamCity (linux)
|
||||
|
||||
This sets up a TeamCity build integration environment on Linux.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Follow [TeamCity](https://www.jetbrains.com/teamcity/) 's in-depth
|
||||
[Setup Guide](https://confluence.jetbrains.com/display/TCD8/Installing+and+Configuring+the+TeamCity+Server).
|
||||
- You need to use [Version Control](./Version-Control.md).
|
||||
|
||||
After meeting the preparation steps for your specific environment, log on to your teamcity interface
|
||||
at `http://<your server>:8111/`.
|
||||
|
||||
Create a new project named "Evennia" and in it construct a new template called `continuous-integration`.
|
||||
|
||||
## A Quick Overview
|
||||
|
||||
_Templates_ are fancy objects in TeamCity that allow an administrator to define build steps that are
|
||||
shared between one or more build projects. Assigning a VCS Root (Source Control) is unnecessary at
|
||||
this stage, primarily you'll be worrying about the build steps and your default parameters (both
|
||||
visible on the tabs to the left.)
|
||||
|
||||
## Template Setup
|
||||
|
||||
In this template, you'll be outlining the steps necessary to build your specific game. (A number of
|
||||
sample scripts are provided under this section below!) Click Build Steps and prepare your general
|
||||
flow. For this example, we will be doing a few basic example steps:
|
||||
|
||||
* Transforming the Settings.py file - We do this to update ports or other information that make your production
|
||||
environment unique from your development environment.
|
||||
* Making migrations and migrating the game database.
|
||||
* Publishing the game files.
|
||||
* Reloading the server.
|
||||
|
||||
For each step we'll being use the "Command Line Runner" (a fancy name for a shell script executor).
|
||||
|
||||
Create a build step with the name: "Transform Configuration" and add the script:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Replaces the game configuration with one
|
||||
# appropriate for this deployment.
|
||||
|
||||
CONFIG="%system.teamcity.build.checkoutDir%/server/conf/settings.py"
|
||||
MYCONF="%system.teamcity.build.checkoutDir%/server/conf/my.cnf"
|
||||
|
||||
sed -e 's/TELNET_PORTS = [4000]/TELNET_PORTS = [%game.ports%]/g' "$CONFIG" > "$CONFIG".tmp && mv
|
||||
"$CONFIG".tmp "$CONFIG"
|
||||
sed -e 's/WEBSERVER_PORTS = [(4001, 4002)]/WEBSERVER_PORTS = [%game.webports%]/g' "$CONFIG" >
|
||||
"$CONFIG".tmp && mv "$CONFIG".tmp "$CONFIG"
|
||||
``````
|
||||
|
||||
```bash
|
||||
|
||||
# settings.py MySQL DB configuration
|
||||
echo Configuring Game Database...
|
||||
echo "" >> "$CONFIG"
|
||||
echo "######################################################################" >> "$CONFIG"
|
||||
echo "# MySQL Database Configuration" >> "$CONFIG"
|
||||
echo "######################################################################" >> "$CONFIG"
|
||||
|
||||
echo "DATABASES = {" >> "$CONFIG"
|
||||
echo " 'default': {" >> "$CONFIG"
|
||||
echo " 'ENGINE': 'django.db.backends.mysql'," >> "$CONFIG"
|
||||
echo " 'OPTIONS': {" >> "$CONFIG"
|
||||
echo " 'read_default_file': 'server/conf/my.cnf'," >> "$CONFIG"
|
||||
echo " }," >> "$CONFIG"
|
||||
echo " }" >> "$CONFIG"
|
||||
echo "}" >> "$CONFIG"
|
||||
|
||||
# Create the My.CNF file.
|
||||
echo "[client]" >> "$MYCONF"
|
||||
echo "database = %mysql.db%" >> "$MYCONF"
|
||||
echo "user = %mysql.user%" >> "$MYCONF"
|
||||
echo "password = %mysql.pass%" >> "$MYCONF"
|
||||
echo "default-character-set = utf8" >> "$MYCONF"
|
||||
|
||||
```
|
||||
|
||||
If you look at the parameters side of the page after saving this script, you'll notice that some new
|
||||
parameters have been populated for you. This is because we've included new teamcity configuration
|
||||
parameters that are populated when the build itself is ran. When creating projects that inherit this
|
||||
template, we'll be able to fill in or override those parameters for project-specific configuration.
|
||||
|
||||
Go ahead and create another build step called "Make Database Migration"
|
||||
If you're using Sqlite3 for your game (default database), it's prudent to change working directory on this
|
||||
step to your game dir.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Update the DB migration
|
||||
|
||||
LOGDIR="server/logs"
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
# Check that the logs directory exists.
|
||||
if [ ! -d "$LOGDIR" ]; then
|
||||
# Control will enter here if $LOGDIR doesn't exist.
|
||||
mkdir "$LOGDIR"
|
||||
fi
|
||||
|
||||
evennia makemigrations
|
||||
```
|
||||
|
||||
Create yet another build step, this time named: "Execute Database Migration":
|
||||
If you're using Sqlite3 for your game (default database), it's prudent to change working directory on this
|
||||
step to your game dir.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Apply the database migration.
|
||||
|
||||
LOGDIR="server/logs"
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
# Check that the logs directory exists.
|
||||
if [ ! -d "$LOGDIR" ]; then
|
||||
# Control will enter here if $LOGDIR doesn't exist.
|
||||
mkdir "$LOGDIR"
|
||||
fi
|
||||
|
||||
evennia migrate
|
||||
|
||||
```
|
||||
|
||||
Our next build step is where we actually publish our build. Up until now, all work on game has been
|
||||
done in a 'work' directory on TeamCity's build agent. From that directory we will now copy our files
|
||||
to where our game actually exists on the local server.
|
||||
|
||||
Create a new build step called "Publish Build". If you're using SQlite3 on your game, be sure to order this step ABOVE
|
||||
the Database Migration steps. The build order will matter!
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Publishes the build to the proper build directory.
|
||||
|
||||
DIRECTORY="<game_dir>"
|
||||
|
||||
if [ ! -d "$DIRECTORY" ]; then
|
||||
# Control will enter here if $DIRECTORY doesn't exist.
|
||||
mkdir "$DIRECTORY"
|
||||
fi
|
||||
|
||||
# Copy all the files.
|
||||
cp -ruv %teamcity.build.checkoutDir%/* "$DIRECTORY"
|
||||
chmod -R 775 "$DIRECTORY"
|
||||
|
||||
```
|
||||
|
||||
Finally the last script will reload our game for us.
|
||||
|
||||
Create a new script called "Reload Game":
|
||||
The working directory on this build step will be: `%game.dir%`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Apply the database migration.
|
||||
|
||||
LOGDIR="server/logs"
|
||||
PIDDIR="server/server.pid"
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
# Check that the logs directory exists.
|
||||
if [ ! -d "$LOGDIR" ]; then
|
||||
# Control will enter here if $LOGDIR doesn't exist.
|
||||
mkdir "$LOGDIR"
|
||||
fi
|
||||
|
||||
# Check that the server is running.
|
||||
if [ -d "$PIDDIR" ]; then
|
||||
# Control will enter here if the game is running.
|
||||
evennia reload
|
||||
fi
|
||||
```
|
||||
|
||||
Now the template is ready for use! It would be useful this time to revisit the parameters page and
|
||||
set the evenv parameter to the directory where your virtualenv exists: IE "/srv/mush/evenv".
|
||||
|
||||
### Creating the Project
|
||||
|
||||
Now it's time for the last few steps to set up a CI environment.
|
||||
|
||||
* Return to the Evennia Project overview/administration page.
|
||||
* Create a new Sub-Project called "Production". This will be the category that holds our actual game.
|
||||
* Create a new Build Configuration in Production with the name of your MUSH. Base this configuration off of the
|
||||
continuous-integration template we made earlier.
|
||||
* In the build configuration, enter VCS roots and create a new VCS root that points to the
|
||||
branch/version control that you are using.
|
||||
* Go to the parameters page and fill in the undefined parameters for your specific configuration.
|
||||
* If you wish for the CI to run every time a commit is made, go to the VCS triggers and add one for
|
||||
"On Every Commit".
|
||||
|
||||
And you're done! At this point, you can return to the project overview page and queue a new build
|
||||
for your game. If everything was set up correctly, the build will complete successfully. Additional
|
||||
build steps could be added or removed at this point, adding some features like Unit Testing or more!
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# Continuous integration with Travis
|
||||
|
||||
[Travis CI](https://travis-ci.org/) is an online service for checking, validating and potentially
|
||||
deploying code automatically. It can check that every commit is building successfully after every
|
||||
commit to its Github repository.
|
||||
|
||||
If your game is open source on Github you may use Travis for free.
|
||||
See [the Travis docs](https://docs.travis-ci.com/user/getting- started/) for how to get started.
|
||||
|
||||
After logging in you will get to point Travis to your repository on github. One further thing you
|
||||
need to set up yourself is a Travis config file named `.travis.yml` (note the initial period `.`).
|
||||
This should be created in the root of your game directory. The idea with this file is that it
|
||||
describes what Travis needs to import and build in order to create an instance of Evennia from
|
||||
scratch and then run validation tests on it. Here is an example:
|
||||
|
||||
``` yaml
|
||||
language: python
|
||||
python:
|
||||
- "3.10"
|
||||
install:
|
||||
- git clone https://github.com/evennia/evennia.git
|
||||
- cd evennia
|
||||
- pip install -e .
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
script:
|
||||
- evennia migrate
|
||||
- evennia test --settings settings.py .
|
||||
```
|
||||
|
||||
This will tell travis how to download Evennia, install it, set up a database and then run
|
||||
your own test suite (inside the game dir). Use `evennia test evennia` if you also want to
|
||||
run the Evennia full test suite.
|
||||
|
||||
You need to add this file to git (`git add .travis.yml`) and then commit your changes before Travis
|
||||
will be able to see it.
|
||||
|
||||
For properly testing your game you of course also need to write unittests.
|
||||
The [Unit testing](./Unit-Testing.md) doc page gives some ideas on how to set those up for Evennia.
|
||||
You should be able to refer to that for making tests fitting your game.
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
# Continuous Integration
|
||||
|
||||
One of the advantages of Evennia over traditional MU* development systems is that Evennia can
|
||||
integrate into enterprise-level integration environments and source control.
|
||||
|
||||
## What is Continuous Integration (CI)?
|
||||
|
||||
[Continuous Integration (CI)](https://www.thoughtworks.com/continuous-integration) is a development
|
||||
practice that requires developers to integrate code into a shared repository.
|
||||
Each check-in is then verified by an automated build, allowing teams to detect problems early. This
|
||||
can be set up to safely deploy data to a production server only after tests have passed, for example.
|
||||
|
||||
For Evennia, continuous integration allows an automated build process to:
|
||||
|
||||
* Pull down a latest build from Source Control.
|
||||
* Run migrations on the backing SQL database.
|
||||
* Automate additional unique tasks for that project.
|
||||
* Run unit tests.
|
||||
* Publish those files to the server directory
|
||||
* Reload the game.
|
||||
|
||||
## List of continuous integration tools
|
||||
|
||||
There are a lot of tools and services providing CI functionality. Here are a few that people have used
|
||||
with Evennia:
|
||||
|
||||
```{toctree}
|
||||
:maxdepth: 1
|
||||
|
||||
Continuous-Integration-Travis.md
|
||||
Continuous-Integration-TeamCity.md
|
||||
|
||||
```
|
||||
|
||||
[This is an overview of other tools](https://www.atlassian.com/continuous-delivery/continuous-integration/tools)
|
||||
(external link).
|
||||
|
|
@ -1,296 +0,0 @@
|
|||
# Debugging
|
||||
|
||||
|
||||
Sometimes, an error is not trivial to resolve. A few simple `print` statements is not enough to find
|
||||
the cause of the issue. Running a *debugger* can then be very helpful and save a lot of time.
|
||||
Debugging
|
||||
means running Evennia under control of a special *debugger* program. This allows you to stop the
|
||||
action at a given point, view the current state and step forward through the program to see how its
|
||||
logic works.
|
||||
|
||||
Evennia natively supports these debuggers:
|
||||
|
||||
- [Pdb](https://docs.python.org/2/library/pdb.html) is a part of the Python distribution and
|
||||
available out-of-the-box.
|
||||
- [PuDB](https://pypi.org/project/pudb/) is a third-party debugger that has a slightly more
|
||||
'graphical', curses-based user interface than pdb. It is installed with `pip install pudb`.
|
||||
|
||||
## Debugging Evennia
|
||||
|
||||
To run Evennia with the debugger, follow these steps:
|
||||
|
||||
1. Find the point in the code where you want to have more insight. Add the following line at that
|
||||
point.
|
||||
```python
|
||||
from evennia import set_trace;set_trace()
|
||||
```
|
||||
2. (Re-)start Evennia in interactive (foreground) mode with `evennia istart`. This is important -
|
||||
without this step the debugger will not start correctly - it will start in this interactive
|
||||
terminal.
|
||||
3. Perform the steps that will trigger the line where you added the `set_trace()` call. The debugger
|
||||
will start in the terminal from which Evennia was interactively started.
|
||||
|
||||
The `evennia.set_trace` function takes the following arguments:
|
||||
|
||||
|
||||
```python
|
||||
evennia.set_trace(debugger='auto', term_size=(140, 40))
|
||||
```
|
||||
|
||||
Here, `debugger` is one of `pdb`, `pudb` or `auto`. If `auto`, use `pudb` if available, otherwise
|
||||
use `pdb`. The `term_size` tuple sets the viewport size for `pudb` only (it's ignored by `pdb`).
|
||||
|
||||
|
||||
## A simple example using pdb
|
||||
|
||||
The debugger is useful in different cases, but to begin with, let's see it working in a command.
|
||||
Add the following test command (which has a range of deliberate errors) and also add it to your
|
||||
default cmdset. Then restart Evennia in interactive mode with `evennia istart`.
|
||||
|
||||
|
||||
```python
|
||||
# In file commands/command.py
|
||||
|
||||
|
||||
class CmdTest(Command):
|
||||
|
||||
"""
|
||||
A test command just to test pdb.
|
||||
|
||||
Usage:
|
||||
test
|
||||
|
||||
"""
|
||||
|
||||
key = "test"
|
||||
|
||||
def func(self):
|
||||
from evennia import set_trace; set_trace() # <--- start of debugger
|
||||
obj = self.search(self.args)
|
||||
self.msg("You've found {}.".format(obj.get_display_name()))
|
||||
|
||||
```
|
||||
|
||||
If you type `test` in your game, everything will freeze. You won't get any feedback from the game,
|
||||
and you won't be able to enter any command (nor anyone else). It's because the debugger has started
|
||||
in your console, and you will find it here. Below is an example with `pdb`.
|
||||
|
||||
```
|
||||
...
|
||||
> .../mygame/commands/command.py(79)func()
|
||||
-> obj = self.search(self.args)
|
||||
(Pdb)
|
||||
|
||||
```
|
||||
|
||||
`pdb` notes where it has stopped execution and, what line is about to be executed (in our case, `obj
|
||||
= self.search(self.args)`), and ask what you would like to do.
|
||||
|
||||
### Listing surrounding lines of code
|
||||
|
||||
When you have the `pdb` prompt `(Pdb)`, you can type in different commands to explore the code. The
|
||||
first one you should know is `list` (you can type `l` for short):
|
||||
|
||||
```
|
||||
(Pdb) l
|
||||
43
|
||||
44 key = "test"
|
||||
45
|
||||
46 def func(self):
|
||||
47 from evennia import set_trace; set_trace() # <--- start of debugger
|
||||
48 -> obj = self.search(self.args)
|
||||
49 self.msg("You've found {}.".format(obj.get_display_name()))
|
||||
50
|
||||
51 # -------------------------------------------------------------
|
||||
52 #
|
||||
53 # The default commands inherit from
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
Okay, this didn't do anything spectacular, but when you become more confident with `pdb` and find
|
||||
yourself in lots of different files, you sometimes need to see what's around in code. Notice that
|
||||
there is a little arrow (`->`) before the line that is about to be executed.
|
||||
|
||||
This is important: **about to be**, not **has just been**. You need to tell `pdb` to go on (we'll
|
||||
soon see how).
|
||||
|
||||
### Examining variables
|
||||
|
||||
`pdb` allows you to examine variables (or really, to run any Python instruction). It is very useful
|
||||
to know the values of variables at a specific line. To see a variable, just type its name (as if
|
||||
you were in the Python interpreter:
|
||||
|
||||
```
|
||||
(Pdb) self
|
||||
<commands.command.CmdTest object at 0x045A0990>
|
||||
(Pdb) self.args
|
||||
u''
|
||||
(Pdb) self.caller
|
||||
<Character: XXX>
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
If you try to see the variable `obj`, you'll get an error:
|
||||
|
||||
```
|
||||
(Pdb) obj
|
||||
*** NameError: name 'obj' is not defined
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
That figures, since at this point, we haven't created the variable yet.
|
||||
|
||||
> Examining variable in this way is quite powerful. You can even run Python code and keep on
|
||||
> executing, which can help to check that your fix is actually working when you have identified an
|
||||
> error. If you have variable names that will conflict with `pdb` commands (like a `list`
|
||||
> variable), you can prefix your variable with `!`, to tell `pdb` that what follows is Python code.
|
||||
|
||||
### Executing the current line
|
||||
|
||||
It's time we asked `pdb` to execute the current line. To do so, use the `next` command. You can
|
||||
shorten it by just typing `n`:
|
||||
|
||||
```
|
||||
(Pdb) n
|
||||
AttributeError: "'CmdTest' object has no attribute 'search'"
|
||||
> .../mygame/commands/command.py(79)func()
|
||||
-> obj = self.search(self.args)
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
`Pdb` is complaining that you try to call the `search` method on a command... whereas there's no
|
||||
`search` method on commands. The character executing the command is in `self.caller`, so we might
|
||||
change our line:
|
||||
|
||||
```python
|
||||
obj = self.caller.search(self.args)
|
||||
```
|
||||
|
||||
### Letting the program run
|
||||
|
||||
`pdb` is waiting to execute the same instruction... it provoked an error but it's ready to try
|
||||
again, just in case. We have fixed it in theory, but we need to reload, so we need to enter a
|
||||
command. To tell `pdb` to terminate and keep on running the program, use the `continue` (or `c`)
|
||||
command:
|
||||
|
||||
```
|
||||
(Pdb) c
|
||||
...
|
||||
```
|
||||
|
||||
You see an error being caught, that's the error we have fixed... or hope to have. Let's reload the
|
||||
game and try again. You need to run `evennia istart` again and then run `test` to get into the
|
||||
command again.
|
||||
|
||||
```
|
||||
> .../mygame/commands/command.py(79)func()
|
||||
-> obj = self.caller.search(self.args)
|
||||
(Pdb)
|
||||
|
||||
```
|
||||
|
||||
`pdb` is about to run the line again.
|
||||
|
||||
```
|
||||
(Pdb) n
|
||||
> .../mygame/commands/command.py(80)func()
|
||||
-> self.msg("You've found {}.".format(obj.get_display_name()))
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
This time the line ran without error. Let's see what is in the `obj` variable:
|
||||
|
||||
```
|
||||
(Pdb) obj
|
||||
(Pdb) print obj
|
||||
None
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
We have entered the `test` command without parameter, so no object could be found in the search
|
||||
(`self.args` is an empty string).
|
||||
|
||||
Let's allow the command to continue and try to use an object name as parameter (although, we should
|
||||
fix that bug too, it would be better):
|
||||
|
||||
```
|
||||
(Pdb) c
|
||||
...
|
||||
```
|
||||
|
||||
Notice that you'll have an error in the game this time. Let's try with a valid parameter. I have
|
||||
another character, `barkeep`, in this room:
|
||||
|
||||
```test barkeep```
|
||||
|
||||
And again, the command freezes, and we have the debugger opened in the console.
|
||||
|
||||
Let's execute this line right away:
|
||||
|
||||
```
|
||||
> .../mygame/commands/command.py(79)func()
|
||||
-> obj = self.caller.search(self.args)
|
||||
(Pdb) n
|
||||
> .../mygame/commands/command.py(80)func()
|
||||
-> self.msg("You've found {}.".format(obj.get_display_name()))
|
||||
(Pdb) obj
|
||||
<Character: barkeep>
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
At least this time we have found the object. Let's process...
|
||||
|
||||
```
|
||||
(Pdb) n
|
||||
TypeError: 'get_display_name() takes exactly 2 arguments (1 given)'
|
||||
> .../mygame/commands/command.py(80)func()
|
||||
-> self.msg("You've found {}.".format(obj.get_display_name()))
|
||||
(Pdb)
|
||||
```
|
||||
|
||||
As an exercise, fix this error, reload and run the debugger again. Nothing better than some
|
||||
experimenting!
|
||||
|
||||
Your debugging will often follow the same strategy:
|
||||
|
||||
1. Receive an error you don't understand.
|
||||
2. Put a breaking point **BEFORE** the error occurs.
|
||||
3. Run the code again and see the debugger open.
|
||||
4. Run the program line by line,examining variables, checking the logic of instructions.
|
||||
5. Continue and try again, each step a bit further toward the truth and the working feature.
|
||||
|
||||
### Stepping through a function
|
||||
|
||||
`n` is useful, but it will avoid stepping inside of functions if it can. But most of the time, when
|
||||
we have an error we don't understand, it's because we use functions or methods in a way that wasn't
|
||||
intended by the developer of the API. Perhaps using wrong arguments, or calling the function in a
|
||||
situation that would cause a bug. When we have a line in the debugger that calls a function or
|
||||
method, we can "step" to examine it further. For instance, in the previous example, when `pdb` was
|
||||
about to execute `obj = self.caller.search(self.args)`, we may want to see what happens inside of
|
||||
the `search` method.
|
||||
|
||||
To do so, use the `step` (or `s`) command. This command will show you the definition of the
|
||||
function/method and you can then use `n` as before to see it line-by-line. In our little example,
|
||||
stepping through a function or method isn't that useful, but when you have an impressive set of
|
||||
commands, functions and so on, it might really be handy to examine some feature and make sure they
|
||||
operate as planned.
|
||||
|
||||
## Cheat-sheet of pdb/pudb commands
|
||||
|
||||
PuDB and Pdb share the same commands. The only real difference is how it's presented. The `look`
|
||||
command is not needed much in `pudb` since it displays the code directly in its user interface.
|
||||
|
||||
| Pdb/PuDB command | To do what |
|
||||
| ----------- | ---------- |
|
||||
| list (or l) | List the lines around the point of execution (not needed for `pudb`, it will show
|
||||
this directly). |
|
||||
| print (or p) | Display one or several variables. |
|
||||
| `!` | Run Python code (using a `!` is often optional). |
|
||||
| continue (or c) | Continue execution and terminate the debugger for this time. |
|
||||
| next (or n) | Execute the current line and goes to the next one. |
|
||||
| step (or s) | Step inside of a function or method to examine it. |
|
||||
| `<RETURN>` | Repeat the last command (don't type `n` repeatedly, just type it once and then press
|
||||
`<RETURN>` to repeat it). |
|
||||
|
||||
If you want to learn more about debugging with Pdb, you will find an [interesting tutorial on that
|
||||
topic here](https://pymotw.com/3/pdb/).
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
# Profiling
|
||||
|
||||
*This is considered an advanced topic mainly of interest to server developers.*
|
||||
|
||||
## Introduction
|
||||
|
||||
Sometimes it can be useful to try to determine just how efficient a particular
|
||||
piece of code is, or to figure out if one could speed up things more than they
|
||||
are. There are many ways to test the performance of Python and the running
|
||||
server.
|
||||
|
||||
Before digging into this section, remember Donald Knuth's
|
||||
[words of wisdom](https://en.wikipedia.org/wiki/Program_optimization#When_to_optimize):
|
||||
|
||||
> *[...]about 97% of the time: Premature optimization is the root of all evil*.
|
||||
|
||||
That is, don't start to try to optimize your code until you have actually
|
||||
identified a need to do so. This means your code must actually be working before
|
||||
you start to consider optimization. Optimization will also often make your code
|
||||
more complex and harder to read. Consider readability and maintainability and
|
||||
you may find that a small gain in speed is just not worth it.
|
||||
|
||||
## Simple timer tests
|
||||
|
||||
Python's `timeit` module is very good for testing small things. For example, in
|
||||
order to test if it is faster to use a `for` loop or a list comprehension you
|
||||
could use the following code:
|
||||
|
||||
```python
|
||||
import timeit
|
||||
# Time to do 1000000 for loops
|
||||
timeit.timeit("for i in range(100):\n a.append(i)", setup="a = []")
|
||||
<<< 10.70982813835144
|
||||
# Time to do 1000000 list comprehensions
|
||||
timeit.timeit("a = [i for i in range(100)]")
|
||||
<<< 5.358283996582031
|
||||
```
|
||||
|
||||
The `setup` keyword is used to set up things that should not be included in the
|
||||
time measurement, like `a = []` in the first call.
|
||||
|
||||
By default the `timeit` function will re-run the given test 1000000 times and
|
||||
returns the *total time* to do so (so *not* the average per test). A hint is to
|
||||
not use this default for testing something that includes database writes - for
|
||||
that you may want to use a lower number of repeats (say 100 or 1000) using the
|
||||
`number=100` keyword.
|
||||
|
||||
## Using cProfile
|
||||
|
||||
Python comes with its own profiler, named cProfile (this is for cPython, no
|
||||
tests have been done with `pypy` at this point). Due to the way Evennia's
|
||||
processes are handled, there is no point in using the normal way to start the
|
||||
profiler (`python -m cProfile evennia.py`). Instead you start the profiler
|
||||
through the launcher:
|
||||
|
||||
evennia --profiler start
|
||||
|
||||
This will start Evennia with the Server component running (in daemon mode) under
|
||||
cProfile. You could instead try `--profile` with the `portal` argument to
|
||||
profile the Portal (you would then need to
|
||||
[start the Server separately](../Setup/Start-Stop-Reload.md)).
|
||||
|
||||
Please note that while the profiler is running, your process will use a lot more
|
||||
memory than usual. Memory usage is even likely to climb over time. So don't
|
||||
leave it running perpetually but monitor it carefully (for example using the
|
||||
`top` command on Linux or the Task Manager's memory display on Windows).
|
||||
|
||||
Once you have run the server for a while, you need to stop it so the profiler
|
||||
can give its report. Do *not* kill the program from your task manager or by
|
||||
sending it a kill signal - this will most likely also mess with the profiler.
|
||||
Instead either use `evennia.py stop` or (which may be even better), use
|
||||
`@shutdown` from inside the game.
|
||||
|
||||
Once the server has fully shut down (this may be a lot slower than usual) you
|
||||
will find that profiler has created a new file `mygame/server/logs/server.prof`.
|
||||
|
||||
### Analyzing the profile
|
||||
|
||||
The `server.prof` file is a binary file. There are many ways to analyze and
|
||||
display its contents, all of which has only been tested in Linux (If you are a
|
||||
Windows/Mac user, let us know what works).
|
||||
|
||||
You can look at the contents of the profile file with Python's in-built `pstats`
|
||||
module in the evennia shell (it's recommended you install `ipython` with `pip
|
||||
install ipython` in your virtualenv first, for prettier output):
|
||||
|
||||
evennia shell
|
||||
|
||||
Then in the shell
|
||||
|
||||
```python
|
||||
import pstats
|
||||
from pstats import SortKey
|
||||
|
||||
p = pstats.Stats('server/log/server.prof')
|
||||
p.strip_dirs().sort_stats(-1).print_stats()
|
||||
|
||||
```
|
||||
|
||||
See the
|
||||
[Python profiling documentation](https://docs.python.org/3/library/profile.html#instant-user-s-manual)
|
||||
for more information.
|
||||
|
||||
You can also visualize the data in various ways.
|
||||
- [Runsnake](https://pypi.org/project/RunSnakeRun/) visualizes the profile to
|
||||
give a good overview. Install with `pip install runsnakerun`. Note that this
|
||||
may require a C compiler and be quite slow to install.
|
||||
- For more detailed listing of usage time, you can use
|
||||
[KCachegrind](http://kcachegrind.sourceforge.net/html/Home.html). To make
|
||||
KCachegrind work with Python profiles you also need the wrapper script
|
||||
[pyprof2calltree](https://pypi.python.org/pypi/pyprof2calltree/). You can get
|
||||
`pyprof2calltree` via `pip` whereas KCacheGrind is something you need to get
|
||||
via your package manager or their homepage.
|
||||
|
||||
How to analyze and interpret profiling data is not a trivial issue and depends
|
||||
on what you are profiling for. Evennia being an asynchronous server can also
|
||||
confuse profiling. Ask on the mailing list if you need help and be ready to be
|
||||
able to supply your `server.prof` file for comparison, along with the exact
|
||||
conditions under which it was obtained.
|
||||
|
||||
## The Dummyrunner
|
||||
|
||||
It is difficult to test "actual" game performance without having players in your
|
||||
game. For this reason Evennia comes with the *Dummyrunner* system. The
|
||||
Dummyrunner is a stress-testing system: a separate program that logs into your
|
||||
game with simulated players (aka "bots" or "dummies"). Once connected, these
|
||||
dummies will semi-randomly perform various tasks from a list of possible
|
||||
actions. Use `Ctrl-C` to stop the Dummyrunner.
|
||||
|
||||
```{warning}
|
||||
|
||||
You should not run the Dummyrunner on a production database. It
|
||||
will spawn many objects and also needs to run with general permissions.
|
||||
|
||||
This is the recommended process for using the dummy runner:
|
||||
```
|
||||
|
||||
1. Stop your server completely with `evennia stop`.
|
||||
1. At _the end_ of your `mygame/server/conf.settings.py` file, add the line
|
||||
|
||||
from evennia.server.profiling.settings_mixin import *
|
||||
|
||||
This will override your settings and disable Evennia's rate limiters and
|
||||
DoS-protections, which would otherwise block mass-connecting clients from
|
||||
one IP. Notably, it will also change to a different (faster) password hasher.
|
||||
1. (recommended): Build a new database. If you use default Sqlite3 and want to
|
||||
keep your existing database, just rename `mygame/server/evennia.db3` to
|
||||
`mygame/server/evennia.db3_backup` and run `evennia migrate` and `evennia
|
||||
start` to create a new superuser as usual.
|
||||
1. (recommended) Log into the game as your superuser. This is just so you
|
||||
can manually check response. If you kept an old database, you will _not_
|
||||
be able to connect with an _existing_ user since the password hasher changed!
|
||||
1. Start the dummyrunner with 10 dummy users from the terminal with
|
||||
|
||||
evennia --dummyrunner 10
|
||||
|
||||
Use `Ctrl-C` (or `Cmd-C`) to stop it.
|
||||
|
||||
If you want to see what the dummies are actually doing you can run with a single
|
||||
dummy:
|
||||
|
||||
evennia --dummyrunner 1
|
||||
|
||||
The inputs/outputs from the dummy will then be printed. By default the runner
|
||||
uses the 'looker' profile, which just logs in and sends the 'look' command
|
||||
over and over. To change the settings, copy the file
|
||||
`evennia/server/profiling/dummyrunner_settings.py` to your `mygame/server/conf/`
|
||||
directory, then add this line to your settings file to use it in the new
|
||||
location:
|
||||
|
||||
DUMMYRUNNER_SETTINGS_MODULE = "server/conf/dummyrunner_settings.py"
|
||||
|
||||
The dummyrunner settings file is a python code module in its own right - it
|
||||
defines the actions available to the dummies. These are just tuples of command
|
||||
strings (like "look here") for the dummy to send to the server along with a
|
||||
probability of them happening. The dummyrunner looks for a global variable
|
||||
`ACTIONS`, a list of tuples, where the first two elements define the
|
||||
commands for logging in/out of the server.
|
||||
|
||||
Below is a simplified minimal setup (the default settings file adds a lot more
|
||||
functionality and info):
|
||||
|
||||
```python
|
||||
# minimal dummyrunner setup file
|
||||
|
||||
# Time between each dummyrunner "tick", in seconds. Each dummy will be called
|
||||
# with this frequency.
|
||||
TIMESTEP = 1
|
||||
|
||||
# Chance of a dummy actually performing an action on a given tick. This
|
||||
# spreads out usage randomly, like it would be in reality.
|
||||
CHANCE_OF_ACTION = 0.5
|
||||
|
||||
# Chance of a currently unlogged-in dummy performing its login action every
|
||||
# tick. This emulates not all accounts logging in at exactly the same time.
|
||||
CHANCE_OF_LOGIN = 0.01
|
||||
|
||||
# Which telnet port to connect to. If set to None, uses the first default
|
||||
# telnet port of the running server.
|
||||
TELNET_PORT = None
|
||||
|
||||
# actions
|
||||
|
||||
def c_login(client):
|
||||
name = f"Character-{client.gid}"
|
||||
pwd = f"23fwsf23sdfw23wef23"
|
||||
return (
|
||||
f"create {name} {pwd}"
|
||||
f"connect {name} {pwd}"
|
||||
)
|
||||
|
||||
def c_logout(client):
|
||||
return ("quit", )
|
||||
|
||||
def c_look(client):
|
||||
return ("look here", "look me")
|
||||
|
||||
# this is read by dummyrunner.
|
||||
ACTIONS = (
|
||||
c_login,
|
||||
c_logout,
|
||||
(1.0, c_look) # (probability, command-generator)
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
At the bottom of the default file are a few default profiles you can test out
|
||||
by just setting the `PROFILE` variable to one of the options.
|
||||
|
||||
### Dummyrunner hints
|
||||
|
||||
- Don't start with too many dummies. The Dummyrunner taxes the server much more
|
||||
than 'real' users tend to do. Start with 10-100 to begin with.
|
||||
- Stress-testing can be fun, but also consider what a 'realistic' number of
|
||||
users would be for your game.
|
||||
- Note in the dummyrunner output how many commands/s are being sent to the
|
||||
server by all dummies. This is usually a lot higher than what you'd
|
||||
realistically expect to see from the same number of users.
|
||||
- The default settings sets up a 'lag' measure to measaure the round-about
|
||||
message time. It updates with an average every 30 seconds. It can be worth to
|
||||
have this running for a small number of dummies in one terminal before adding
|
||||
more by starting another dummyrunner in another terminal - the first one will
|
||||
act as a measure of how lag changes with different loads. Also verify the
|
||||
lag-times by entering commands manually in-game.
|
||||
- Check the CPU usage of your server using `top/htop` (linux). In-game, use the
|
||||
`server` command.
|
||||
- You can run the server with `--profiler start` to test it with dummies. Note
|
||||
that the profiler will itself affect server performance, especially memory
|
||||
consumption.
|
||||
- Generally, the dummyrunner system makes for a decent test of general
|
||||
performance; but it is of course hard to actually mimic human user behavior.
|
||||
For this, actual real-game testing is required.
|
||||
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
# Quirks
|
||||
|
||||
|
||||
This is a list of various quirks or common stumbling blocks that people often ask about or report
|
||||
when using (or trying to use) Evennia. They are not bugs.
|
||||
|
||||
## Forgetting to use `reload` to see changes to your typeclasses
|
||||
|
||||
Firstly: Reloading the server is a safe and usually quick operation which will *not* disconnect any
|
||||
accounts.
|
||||
|
||||
New users tend to forget this step. When editing source code (such as when tweaking typeclasses and
|
||||
commands or adding new commands to command sets) you need to either use the in-game `@reload`
|
||||
command or, from the command line do `python evennia.py reload` before you see your changes.
|
||||
|
||||
## Web admin to create new Account
|
||||
|
||||
If you use the default login system and are trying to use the Web admin to create a new Player
|
||||
account, you need to consider which `MULTIACCOUNT_MODE` you are in. If you are in
|
||||
`MULTIACCOUNT_MODE` `0` or `1`, the login system expects each Account to also have a Character
|
||||
object named the same as the Account - there is no character creation screen by default. If using
|
||||
the normal mud login screen, a Character with the same name is automatically created and connected
|
||||
to your Account. From the web interface you must do this manually.
|
||||
|
||||
So, when creating the Account, make sure to also create the Character *from the same form* as you
|
||||
create the Account from. This should set everything up for you. Otherwise you need to manually set
|
||||
the "account" property on the Character and the "character" property on the Account to point to each
|
||||
other. You must also set the lockstring of the Character to allow the Account to "puppet" this
|
||||
particular character.
|
||||
|
||||
## Mutable attributes and their connection to the database
|
||||
|
||||
When storing a mutable object (usually a list or a dictionary) in an Attribute
|
||||
|
||||
```python
|
||||
object.db.mylist = [1,2,3]
|
||||
```
|
||||
|
||||
you should know that the connection to the database is retained also if you later extract that
|
||||
Attribute into another variable (what is stored and retrieved is actually a `PackedList` or a
|
||||
`PackedDict` that works just like their namesakes except they save themselves to the database when
|
||||
changed). So if you do
|
||||
|
||||
```python
|
||||
alist = object.db.mylist
|
||||
alist.append(4)
|
||||
```
|
||||
|
||||
this updates the database behind the scenes, so both `alist` and `object.db.mylist` are now
|
||||
`[1,2,3,4]`
|
||||
|
||||
If you don't want this, Evennia provides a way to stably disconnect the mutable from the database by
|
||||
use of `evennia.utils.dbserialize.deserialize`:
|
||||
|
||||
```python
|
||||
from evennia.utils.dbserialize import deserialize
|
||||
|
||||
blist = deserialize(object.db.mylist)
|
||||
blist.append(4)
|
||||
```
|
||||
|
||||
The property `blist` is now `[1,2,3,4]` whereas `object.db.mylist` remains unchanged. If you want to
|
||||
update the database you'd need to explicitly re-assign the updated data to the `mylist` Attribute.
|
||||
|
||||
## Commands are matched by name *or* alias
|
||||
|
||||
When merging [command sets](../Components/Commands.md) it's important to remember that command objects are identified
|
||||
*both* by key *or* alias. So if you have a command with a key `look` and an alias `ls`, introducing
|
||||
another command with a key `ls` will be assumed by the system to be *identical* to the first one.
|
||||
This usually means merging cmdsets will overload one of them depending on priority. Whereas this is
|
||||
logical once you know how command objects are handled, it may be confusing if you are just looking
|
||||
at the command strings thinking they are parsed as-is.
|
||||
|
||||
## Objects turning to `DefaultObject`
|
||||
|
||||
A common confusing error for new developers is finding that one or more objects in-game are suddenly
|
||||
of the type `DefaultObject` rather than the typeclass you wanted it to be. This happens when you
|
||||
introduce a critical Syntax error to the module holding your custom class. Since such a module is
|
||||
not valid Python, Evennia can't load it at all to get to the typeclasses within. To keep on running,
|
||||
Evennia will solve this by printing the full traceback to the terminal/console and temporarily fall
|
||||
back to the safe `DefaultObject` until you fix the problem and reload. Most errors of this kind will
|
||||
be caught by any good text editors. Keep an eye on the terminal/console during a reload to catch
|
||||
such errors - you may have to scroll up if your window is small.
|
||||
|
||||
## Overriding of magic methods
|
||||
|
||||
Python implements a system of [magic
|
||||
methods](https://docs.python.org/3/reference/datamodel.html#emulating-container-types), usually
|
||||
prefixed and suffixed by double-underscores (`__example__`) that allow object instances to have
|
||||
certain operations performed on them without needing to do things like turn them into strings or
|
||||
numbers first-- for example, is `obj1` greater than or equal to `obj2`?
|
||||
|
||||
Neither object is a number, but given `obj1.size == "small"` and `obj2.size == "large"`, how might
|
||||
one compare these two arbitrary English adjective strings to figure out which is greater than the
|
||||
other? By defining the `__ge__` (greater than or equal to) magic method on the object class in which
|
||||
you figure out which word has greater significance, perhaps through use of a mapping table
|
||||
(`{'small':0, 'large':10}`) or other lookup and comparing the numeric values of each.
|
||||
|
||||
Evennia extensively makes use of magic methods on typeclasses to do things like initialize objects,
|
||||
check object existence or iterate over objects in an inventory or container. If you override or
|
||||
interfere with the return values from the methods Evennia expects to be both present and working, it
|
||||
can result in very inconsistent and hard-to-diagnose errors.
|
||||
|
||||
The moral of the story-- it can be dangerous to tinker with magic methods on typeclassed objects.
|
||||
Try to avoid doing so.
|
||||
|
||||
## Things to remember about the flat API
|
||||
|
||||
The flat API is a series of 'shortcuts' on the `evennia` main library root (defined in
|
||||
`evennia/__init__.py`). Its componentas are documented [as part of the auto-documentation](../Evennia-API.md).
|
||||
|
||||
### To remember when importing from `evennia`
|
||||
|
||||
Properties on the root of the `evennia` package are *not* modules in their own right. They are just
|
||||
shortcut properties stored in the `evennia/__init__.py` module. That means that you cannot use dot-
|
||||
notation to `import` nested module-names over `evennia`. The rule of thumb is that you cannot use
|
||||
`import` for more than one level down. Hence you can do
|
||||
|
||||
```python
|
||||
import evennia
|
||||
print(evennia.default_cmds.CmdLook)
|
||||
```
|
||||
|
||||
or import one level down
|
||||
|
||||
```python
|
||||
from evennia import default_cmds
|
||||
print(default_cmds.CmdLook)
|
||||
```
|
||||
|
||||
but you *cannot* import two levels down
|
||||
|
||||
```python
|
||||
from evennia.default_cmds import CmdLook # error!
|
||||
```
|
||||
|
||||
This will give you an `ImportError` telling you that the module `default_cmds` cannot be found -
|
||||
this is becasue `default_cmds` is just a *variable* stored in `evennia.__init__.py`; this cannot be
|
||||
imported from. If you really want full control over which level of package you import you can always
|
||||
bypass the root package and import directly from from the real location. For example
|
||||
`evennia.DefaultObject` is a shortcut to `evennia.objects.objects.DefaultObject`. Using this full
|
||||
path will have the import mechanism work normally. See `evennia/__init__.py` to see where the
|
||||
package imports from.
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
# Setting up PyCharm with Evennia
|
||||
|
||||
[PyCharm](https://www.jetbrains.com/pycharm/) is a Python developer's IDE from Jetbrains available
|
||||
for Windows, Mac and Linux. It is a commercial product but offer free trials, a scaled-down
|
||||
community edition and also generous licenses for OSS projects like Evennia.
|
||||
|
||||
> This page was originally tested on Windows (so use Windows-style path examples), but should work
|
||||
the same for all platforms.
|
||||
|
||||
First, install Evennia on your local machine with [[Getting Started]]. If you're new to PyCharm,
|
||||
loading your project is as easy as selecting the `Open` option when PyCharm starts, and browsing to
|
||||
your game folder (the one created with `evennia --init`). We refer to it as `mygame` here.
|
||||
|
||||
If you want to be able to examine evennia's core code or the scripts inside your virtualenv, you'll
|
||||
need to add them to your project too:
|
||||
1. Go to `File > Open...`
|
||||
1. Select the folder (i.e. the `evennia` root)
|
||||
1. Select "Open in current window" and "Add to currently opened projects"
|
||||
|
||||
## Setting up the project interpreter
|
||||
|
||||
It's a good idea to do this before attempting anything further. The rest of this page assumes your
|
||||
project is already configured in PyCharm.
|
||||
|
||||
1. Go to `File > Settings... > Project: \<mygame\> > Project Interpreter`
|
||||
1. Click the Gear symbol `> Add local`
|
||||
1. Navigate to your `evenv/scripts directory`, and select Python.exe
|
||||
|
||||
Enjoy seeing all your imports checked properly, setting breakpoints, and live variable watching!
|
||||
|
||||
## Attaching PyCharm debugger to Evennia
|
||||
|
||||
1. Launch Evennia in your preferred way (usually from a console/terminal)
|
||||
1. Open your project in PyCharm
|
||||
1. In the PyCharm menu, select `Run > Attach to Local Process...`
|
||||
1. From the list, pick the `twistd` process with the `server.py` parameter (Example: `twistd.exe
|
||||
--nodaemon --logfile=\<mygame\>\server\logs\server.log --python=\<evennia
|
||||
repo\>\evennia\server\server.py`)
|
||||
|
||||
Of course you can attach to the `portal` process as well. If you want to debug the Evennia launcher
|
||||
or runner for some reason (or just learn how they work!), see Run Configuration below.
|
||||
|
||||
> NOTE: Whenever you reload Evennia, the old Server process will die and a new one start. So when
|
||||
you restart you have to detach from the old and then reattach to the new process that was created.
|
||||
|
||||
> To make the process less tedious you can apply a filter in settings to show only the server.py
|
||||
process in the list. To do that navigate to: `Settings/Preferences | Build, Execution, Deployment |
|
||||
Python Debugger` and then in `Attach to process` field put in: `twistd.exe" --nodaemon`. This is an
|
||||
example for windows, I don't have a working mac/linux box.
|
||||

|
||||
|
||||
## Setting up an Evennia run configuration
|
||||
|
||||
This configuration allows you to launch Evennia from inside PyCharm. Besides convenience, it also
|
||||
allows suspending and debugging the evennia_launcher or evennia_runner at points earlier than you
|
||||
could by running them externally and attaching. In fact by the time the server and/or portal are
|
||||
running the launcher will have exited already.
|
||||
|
||||
1. Go to `Run > Edit Configutations...`
|
||||
1. Click the plus-symbol to add a new configuration and choose Python
|
||||
1. Add the script: `\<yourrepo\>\evenv\Scripts\evennia_launcher.py` (substitute your virtualenv if
|
||||
it's not named `evenv`)
|
||||
1. Set script parameters to: `start -l` (-l enables console logging)
|
||||
1. Ensure the chosen interpreter is from your virtualenv
|
||||
1. Set Working directory to your `mygame` folder (not evenv nor evennia)
|
||||
1. You can refer to the PyCharm documentation for general info, but you'll want to set at least a
|
||||
config name (like "MyMUD start" or similar).
|
||||
|
||||
Now set up a "stop" configuration by following the same steps as above, but set your Script
|
||||
parameters to: stop (and name the configuration appropriately).
|
||||
|
||||
A dropdown box holding your new configurations should appear next to your PyCharm run button.
|
||||
Select MyMUD start and press the debug icon to begin debugging. Depending on how far you let the
|
||||
program run, you may need to run your "MyMUD stop" config to actually stop the server, before you'll
|
||||
be able start it again.
|
||||
|
||||
## Alternative run configuration - utilizing logfiles as source of data
|
||||
|
||||
This configuration takes a bit different approach as instead of focusing on getting the data back
|
||||
through logfiles. Reason for that is this way you can easily separate data streams, for example you
|
||||
rarely want to follow both server and portal at the same time, and this will allow it. This will
|
||||
also make sure to stop the evennia before starting it, essentially working as reload command (it
|
||||
will also include instructions how to disable that part of functionality). We will start by defining
|
||||
a configuration that will stop evennia. This assumes that `upfire` is your pycharm project name, and
|
||||
also the game name, hence the `upfire/upfire` path.
|
||||
|
||||
1. Go to `Run > Edit Configutations...`\
|
||||
1. Click the plus-symbol to add a new configuration and choose the python interpreter to use (should
|
||||
be project default)
|
||||
1. Name the configuration as "stop evennia" and fill rest of the fields accordingly to the image:
|
||||

|
||||
1. Press `Apply`
|
||||
|
||||
Now we will define the start/reload command that will make sure that evennia is not running already,
|
||||
and then start the server in one go.
|
||||
1. Go to `Run > Edit Configutations...`\
|
||||
1. Click the plus-symbol to add a new configuration and choose the python interpreter to use (should
|
||||
be project default)
|
||||
1. Name the configuration as "start evennia" and fill rest of the fields accordingly to the image:
|
||||

|
||||
1. Navigate to the `Logs` tab and add the log files you would like to follow. The picture shows
|
||||
adding `portal.log` which will show itself in `portal` tab when running:
|
||||

|
||||
1. Skip the following steps if you don't want the launcher to stop evennia before starting.
|
||||
1. Head back to `Configuration` tab and press the `+` sign at the bottom, under `Before launch....`
|
||||
and select `Run another configuration` from the submenu that will pop up.
|
||||
1. Click `stop evennia` and make sure that it's added to the list like on the image above.
|
||||
1. Click `Apply` and close the run configuration window.
|
||||
|
||||
You are now ready to go, and if you will fire up `start evennia` configuration you should see
|
||||
following in the bottom panel:
|
||||

|
||||
and you can click through the tabs to check appropriate logs, or even the console output as it is
|
||||
still running in interactive mode.
|
||||
|
|
@ -1,318 +0,0 @@
|
|||
# Unit Testing
|
||||
|
||||
*Unit testing* means testing components of a program in isolation from each other to make sure every
|
||||
part works on its own before using it with others. Extensive testing helps avoid new updates causing
|
||||
unexpected side effects as well as alleviates general code rot (a more comprehensive wikipedia
|
||||
article on unit testing can be found [here](https://en.wikipedia.org/wiki/Unit_test)).
|
||||
|
||||
A typical unit test set calls some function or method with a given input, looks at the result and
|
||||
makes sure that this result looks as expected. Rather than having lots of stand-alone test programs,
|
||||
Evennia makes use of a central *test runner*. This is a program that gathers all available tests all
|
||||
over the Evennia source code (called *test suites*) and runs them all in one go. Errors and
|
||||
tracebacks are reported.
|
||||
|
||||
By default Evennia only tests itself. But you can also add your own tests to your game code and have
|
||||
Evennia run those for you.
|
||||
|
||||
## Running the Evennia test suite
|
||||
|
||||
To run the full Evennia test suite, go to your game folder and issue the command
|
||||
|
||||
evennia test evennia
|
||||
|
||||
This will run all the evennia tests using the default settings. You could also run only a subset of
|
||||
all tests by specifying a subpackage of the library:
|
||||
|
||||
evennia test evennia.commands.default
|
||||
|
||||
A temporary database will be instantiated to manage the tests. If everything works out you will see
|
||||
how many tests were run and how long it took. If something went wrong you will get error messages.
|
||||
If you contribute to Evennia, this is a useful sanity check to see you haven't introduced an
|
||||
unexpected bug.
|
||||
|
||||
## Running tests for your game dir
|
||||
|
||||
If you have implemented your own tests for your game you can run them from your game dir
|
||||
with
|
||||
|
||||
evennia test --settings settings.py .
|
||||
|
||||
The period (`.`) means to run all tests found in the current directory and all subdirectories. You
|
||||
could also specify, say, `typeclasses` or `world` if you wanted to just run tests in those subdirs.
|
||||
|
||||
An important thing to note is that those tests will all be run using the _default Evennia settings_.
|
||||
To run the tests with your own settings file you must use the `--settings` option:
|
||||
|
||||
evennia test --settings settings.py .
|
||||
|
||||
The `--settings` option of Evennia takes a file name in the `mygame/server/conf` folder. It is
|
||||
normally used to swap settings files for testing and development. In combination with `test`, it
|
||||
forces Evennia to use this settings file over the default one.
|
||||
|
||||
You can also test specific things by giving their path
|
||||
|
||||
evennia test --settings settings.py .world.tests.YourTest
|
||||
|
||||
|
||||
## Writing new tests
|
||||
|
||||
Evennia's test suite makes use of Django unit test system, which in turn relies on Python's
|
||||
*unittest* module.
|
||||
|
||||
To make the test runner find the tests, they must be put in a module named `test*.py` (so `test.py`,
|
||||
`tests.py` etc). Such a test module will be found wherever it is in the package. It can be a good
|
||||
idea to look at some of Evennia's `tests.py` modules to see how they look.
|
||||
|
||||
Inside the module you need to put a class inheriting (at any distance) from `unittest.TestCase`. Each
|
||||
method on that class that starts with `test_` will be run separately as a unit test. There
|
||||
are two special, optional methods `setUp` and `tearDown` that will (if you define them) run before
|
||||
_every_ test. This can be useful for setting up and deleting things.
|
||||
|
||||
To actually test things, you use special `assert...` methods on the class. Most common on is
|
||||
`assertEqual`, which makes sure a result is what you expect it to be.
|
||||
|
||||
Here's an example of the principle. Let's assume you put this in `mygame/world/tests.py`
|
||||
and want to test a function in `mygame/world/myfunctions.py`
|
||||
|
||||
```python
|
||||
# in a module tests.py somewhere i your game dir
|
||||
import unittest
|
||||
|
||||
from evennia import create_object
|
||||
# the function we want to test
|
||||
from .myfunctions import myfunc
|
||||
|
||||
|
||||
class TestObj(unittest.TestCase):
|
||||
"This tests a function myfunc."
|
||||
|
||||
def setUp(self):
|
||||
"""done before every of the test_ * methods below"""
|
||||
self.obj = create_object("mytestobject")
|
||||
|
||||
def tearDown(self):
|
||||
"""done after every test_* method below """
|
||||
self.obj.delete()
|
||||
|
||||
def test_return_value(self):
|
||||
"""test method. Makes sure return value is as expected."""
|
||||
actual_return = myfunc(self.obj)
|
||||
expected_return = "This is the good object 'mytestobject'."
|
||||
# test
|
||||
self.assertEqual(expected_return, actual_return)
|
||||
def test_alternative_call(self):
|
||||
"""test method. Calls with a keyword argument."""
|
||||
actual_return = myfunc(self.obj, bad=True)
|
||||
expected_return = "This is the baaad object 'mytestobject'."
|
||||
# test
|
||||
self.assertEqual(expected_return, actual_return)
|
||||
```
|
||||
|
||||
To test this, run
|
||||
|
||||
evennia test --settings settings.py .
|
||||
|
||||
to run the entire test module
|
||||
|
||||
evennia test --settings setings.py .world.tests
|
||||
|
||||
or a specific class:
|
||||
|
||||
evennia test --settings settings.py .world.tests.TestObj
|
||||
|
||||
You can also run a specific test:
|
||||
|
||||
evennia test --settings settings.py .world.tests.TestObj.test_alternative_call
|
||||
|
||||
You might also want to read the [Python documentation for the unittest module](https://docs.python.org/library/unittest.html).
|
||||
|
||||
## Using the Evennia testing classes
|
||||
|
||||
Evennia offers many custom testing classes that helps with testing Evennia features.
|
||||
They are all found in [evennia.utils.test_resources](evennia.utils.test_resources). Note that
|
||||
these classes implement the `setUp` and `tearDown` already, so if you want to add stuff in them
|
||||
yourself you should remember to use e.g. `super().setUp()` in your code.
|
||||
|
||||
### Classes for testing your game dir
|
||||
|
||||
These all use whatever setting you pass to them and works well for testing code in your game dir.
|
||||
|
||||
- `EvenniaTest` - this sets up a full object environment for your test. All the created entities
|
||||
can be accesses as properties on the class:
|
||||
- `.account` - A fake [Account](evennia.accounts.accounts.DefaultAccount) named "TestAccount".
|
||||
- `.account2` - Another account named "TestAccount2"
|
||||
- `char1` - A [Character](evennia.objects.objects.DefaultCharacter) linked to `.account`, named `Char`.
|
||||
This has 'Developer' permissions but is not a superuser.
|
||||
- `.char2` - Another character linked to `account`, named `Char2`. This has base permissions (player).
|
||||
- `.obj1` - A regular [Object](evennia.objects.objects.DefaultObject) named "Obj".
|
||||
- `.obj2` - Another object named "Obj2".
|
||||
- `.room1` - A [Room](evennia.objects.objects.DefaultRoom) named "Room". Both characters and both
|
||||
objects are located inside this room. It has a description of "room_desc".
|
||||
- `.room2` - Another room named "Room2". It is empty and has no set description.
|
||||
- `.exit` - An exit named "out" that leads from `.room1` to `.room2`.
|
||||
- `.script` - A [Script](evennia.scripts.scripts.DefaultScript) named "Script". It's an inert script
|
||||
without a timing component.
|
||||
- `.session` - A fake [Session](evennia.server.serversession.ServerSession) that mimics a player
|
||||
connecting to the game. It is used by `.account1` and has a sessid of 1.
|
||||
- `EvenniaCommandTest` - has the same environment like `EvenniaTest` but also adds a special
|
||||
[.call()](evennia.utils.test_resources.EvenniaCommandTestMixin.call) method specifically for
|
||||
testing Evennia [Commands](../Components/Commands.md). It allows you to compare what the command _actually_
|
||||
returns to the player with what you expect. Read the `call` api doc for more info.
|
||||
- `EvenniaTestCase` - This is identical to the regular Python `TestCase` class, it's
|
||||
just there for naming symmetry with `BaseEvenniaTestCase` below.
|
||||
|
||||
Here's an example of using `EvenniaTest`
|
||||
|
||||
```python
|
||||
# in a test module
|
||||
|
||||
from evennia.utils.test_resources import EvenniaTest
|
||||
|
||||
class TestObject(EvenniaTest):
|
||||
"""Remember that the testing class creates char1 and char2 inside room1 ..."""
|
||||
def test_object_search_character(self):
|
||||
"""Check that char1 can search for char2 by name"""
|
||||
self.assertEqual(self.char1.search(self.char2.key), self.char2)
|
||||
|
||||
def test_location_search(self):
|
||||
"""Check so that char1 can find the current location by name"""
|
||||
self.assertEqual(self.char1.search(self.char1.location.key), self.char1.location)
|
||||
# ...
|
||||
```
|
||||
|
||||
This example tests a custom command.
|
||||
|
||||
```python
|
||||
from evennia.commands.default.tests import EvenniaCommandTest
|
||||
from commands import command as mycommand
|
||||
|
||||
|
||||
class TestSet(EvenniaCommandTest):
|
||||
"tests the look command by simple call, using Char2 as a target"
|
||||
|
||||
def test_mycmd_char(self):
|
||||
self.call(mycommand.CmdMyLook(), "Char2", "Char2(#7)")
|
||||
|
||||
def test_mycmd_room(self):
|
||||
"tests the look command by simple call, with target as room"
|
||||
self.call(mycommand.CmdMyLook(), "Room",
|
||||
"Room(#1)\nroom_desc\nExits: out(#3)\n"
|
||||
"You see: Obj(#4), Obj2(#5), Char2(#7)")
|
||||
```
|
||||
|
||||
When using `.call`, you don't need to specify the entire string; you can just give the beginning
|
||||
of it and if it matches, that's enough. Use `\n` to denote line breaks and (this is a special for
|
||||
the `.call` helper), `||` to indicate multiple uses of `.msg()` in the Command. The `.call` helper
|
||||
has a lot of arguments for mimicing different ways of calling a Command, so make sure to
|
||||
[read the API docs for .call()](evennia.utils.test_resources.EvenniaCommandTestMixin.call).
|
||||
|
||||
### Classes for testing Evennia core
|
||||
|
||||
These are used for testing Evennia itself. They provide the same resources as the classes
|
||||
above but enforce Evennias default settings found in `evennia/settings_default.py`, ignoring
|
||||
any settings changes in your game dir.
|
||||
|
||||
- `BaseEvenniaTest` - all the default objects above but with enforced default settings
|
||||
- `BaseEvenniaCommandTest` - for testing Commands, but with enforced default settings
|
||||
- `BaseEvenniaTestCase` - no default objects, only enforced default settings
|
||||
|
||||
There are also two special 'mixin' classes. These are uses in the classes above, but may also
|
||||
be useful if you want to mix your own testing classes:
|
||||
|
||||
- `EvenniaTestMixin` - A class mixin that creates all test environment objects.
|
||||
- `EvenniaCommandMixin` - A class mixin that adds the `.call()` Command-tester helper.
|
||||
|
||||
If you want to help out writing unittests for Evennia, take a look at Evennia's [coveralls.io
|
||||
page](https://coveralls.io/github/evennia/evennia). There you see which modules have any form of
|
||||
test coverage and which does not. All help is appreciated!
|
||||
|
||||
## Unit testing contribs with custom models
|
||||
|
||||
A special case is if you were to create a contribution to go to the `evennia/contrib` folder that
|
||||
uses its [own database models](../Concepts/New-Models.md). The problem with this is that Evennia (and Django) will
|
||||
only recognize models in `settings.INSTALLED_APPS`. If a user wants to use your contrib, they will
|
||||
be required to add your models to their settings file. But since contribs are optional you cannot
|
||||
add the model to Evennia's central `settings_default.py` file - this would always create your
|
||||
optional models regardless of if the user wants them. But at the same time a contribution is a part
|
||||
of the Evennia distribution and its unit tests should be run with all other Evennia tests using
|
||||
`evennia test evennia`.
|
||||
|
||||
The way to do this is to only temporarily add your models to the `INSTALLED_APPS` directory when the
|
||||
test runs. here is an example of how to do it.
|
||||
|
||||
> Note that this solution, derived from this [stackexchange
|
||||
answer](http://stackoverflow.com/questions/502916/django-how-to-create-a-model-dynamically-just-for-
|
||||
testing#503435) is currently untested! Please report your findings.
|
||||
|
||||
```python
|
||||
# a file contrib/mycontrib/tests.py
|
||||
|
||||
from django.conf import settings
|
||||
import django
|
||||
from evennia.utils.test_resources import BaseEvenniaTest
|
||||
|
||||
OLD_DEFAULT_SETTINGS = settings.INSTALLED_APPS
|
||||
DEFAULT_SETTINGS = dict(
|
||||
INSTALLED_APPS=(
|
||||
'contrib.mycontrib.tests',
|
||||
),
|
||||
DATABASES={
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3"
|
||||
}
|
||||
},
|
||||
SILENCED_SYSTEM_CHECKS=["1_7.W001"],
|
||||
)
|
||||
|
||||
|
||||
class TestMyModel(BaseEvenniaTest):
|
||||
def setUp(self):
|
||||
if not settings.configured:
|
||||
settings.configure(**DEFAULT_SETTINGS)
|
||||
django.setup()
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.db.models import loading
|
||||
loading.cache.loaded = False
|
||||
call_command('syncdb', verbosity=0)
|
||||
|
||||
def tearDown(self):
|
||||
settings.configure(**OLD_DEFAULT_SETTINGS)
|
||||
django.setup()
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.db.models import loading
|
||||
loading.cache.loaded = False
|
||||
call_command('syncdb', verbosity=0)
|
||||
|
||||
# test cases below ...
|
||||
|
||||
def test_case(self):
|
||||
# test case here
|
||||
```
|
||||
|
||||
|
||||
## A note on making the test runner faster
|
||||
|
||||
If you have custom models with a large number of migrations, creating the test database can take a
|
||||
very long time. If you don't require migrations to run for your tests, you can disable them with the
|
||||
django-test-without-migrations package. To install it, simply:
|
||||
|
||||
```
|
||||
$ pip install django-test-without-migrations
|
||||
```
|
||||
|
||||
Then add it to your `INSTALLED_APPS` in your `server.conf.settings.py`:
|
||||
|
||||
```python
|
||||
INSTALLED_APPS = (
|
||||
# ...
|
||||
'test_without_migrations',
|
||||
)
|
||||
```
|
||||
|
||||
After doing so, you can then run tests without migrations by adding the `--nomigrations` argument:
|
||||
|
||||
```
|
||||
evennia test --settings settings.py --nomigrations .
|
||||
```
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
# Updating Your Game
|
||||
|
||||
|
||||
Fortunately, it's extremely easy to keep your Evennia server up-to-date. If you haven't already, see
|
||||
the [Getting Started guide](../Setup/Installation.md) and get everything running.
|
||||
|
||||
## Updating with the latest Evennia code changes
|
||||
|
||||
Very commonly we make changes to the Evennia code to improve things. There are many ways to get told
|
||||
when to update: You can subscribe to the RSS feed or manually check up on the feeds from
|
||||
https://www.evennia.com. You can also simply fetch the latest regularly.
|
||||
|
||||
When you're wanting to apply updates, simply `cd` to your cloned `evennia` root directory and type:
|
||||
|
||||
git pull
|
||||
|
||||
assuming you've got the command line client. If you're using a graphical client, you will probably
|
||||
want to navigate to the `evennia` directory and either right click and find your client's pull
|
||||
function, or use one of the menus (if applicable).
|
||||
|
||||
You can review the latest changes with
|
||||
|
||||
git log
|
||||
|
||||
or the equivalent in the graphical client. You can also see the latest changes online
|
||||
[here](https://github.com/evennia/evennia/blob/master/CHANGELOG.md).
|
||||
|
||||
You will always need to do `evennia reload` (or `reload` from -in-game) from your game-dir to have
|
||||
the new code affect your game. If you want to be really sure you should run a full `evennia reboot`
|
||||
so that both Server and Portal can restart (this will disconnect everyone though, so if you know the
|
||||
Portal has had no updates you don't have to do that).
|
||||
|
||||
## Upgrading Evennia dependencies
|
||||
|
||||
On occasion we update the versions of third-party libraries Evennia depend on (or we may add a new
|
||||
dependency). This will be announced on the mailing list/forum. If you run into errors when starting
|
||||
Evennia, always make sure you have the latest versions of everything. In some cases, like for
|
||||
Django, starting the server may also give warning saying that you are using a working, but too-old
|
||||
version that should not be used in production.
|
||||
|
||||
Upgrading `evennia` will automatically fetch all the latest packages that it now need. First `cd` to
|
||||
your cloned `evennia` folder. Make sure your `virtualenv` is active and use
|
||||
|
||||
pip install --upgrade -e .
|
||||
|
||||
Remember the period (`.`) at the end - that applies the upgrade to the current location (your
|
||||
`evennia` dir).
|
||||
|
||||
> The `-e` means that we are _linking_ the evennia sources rather than copying them into the
|
||||
environment. This means we can most of the time just update the sources (with `git pull`) and see
|
||||
those changes directly applied to our installed `evennia` package. Without installing/upgrading the
|
||||
package with `-e`, we would have to remember to upgrade the package every time we downloaded any new
|
||||
source-code changes.
|
||||
|
||||
Follow the upgrade output to make sure it finishes without errors. To check what packages are
|
||||
currently available in your python environment after the upgrade, use
|
||||
|
||||
pip list
|
||||
|
||||
This will show you the version of all installed packages. The `evennia` package will also show the
|
||||
location of its source code.
|
||||
|
||||
## Migrating the Database Schema
|
||||
|
||||
Whenever we change the database layout of Evennia upstream (such as when we add new features) you
|
||||
will need to *migrate* your existing database. When this happens it will be clearly noted in the
|
||||
`git log` (it will say something to the effect of "Run migrations"). Database changes will also be
|
||||
announced on the Evennia [mailing list](https://groups.google.com/forum/#!forum/evennia).
|
||||
|
||||
When the database schema changes, you just go to your game folder and run
|
||||
|
||||
evennia migrate
|
||||
|
||||
> Hint: If the `evennia` command is not found, you most likely need to activate your
|
||||
[virtualenv](../Glossary.md#virtualenv).
|
||||
|
||||
## Resetting your database
|
||||
|
||||
Should you ever want to start over completely from scratch, there is no need to re-download Evennia
|
||||
or anything like that. You just need to clear your database. Once you are done, you just rebuild it
|
||||
from scratch by running
|
||||
|
||||
evennia migrate
|
||||
|
||||
The first step in wiping your database is to stop Evennia completely with
|
||||
|
||||
evennia stop
|
||||
|
||||
If you run the default `SQlite3` database (to change this you need to edit your `settings.py` file),
|
||||
the database is actually just a normal file in `mygame/server/` called `evennia.db3`. *Simply delete
|
||||
that file* - that's it. Now run `evennia migrate` to recreate a new, fresh one.
|
||||
|
||||
If you run some other database system you can instead flush the database:
|
||||
|
||||
evennia flush
|
||||
|
||||
This will empty the database. However, it will not reset the internal counters of the database, so
|
||||
you will start with higher dbref values. If this is okay, this is all you need.
|
||||
|
||||
Django also offers an easy way to start the database's own management should we want more direct
|
||||
control:
|
||||
|
||||
evennia dbshell
|
||||
|
||||
In e.g. MySQL you can then do something like this (assuming your MySQL database is named "Evennia":
|
||||
|
||||
mysql> DROP DATABASE Evennia;
|
||||
mysql> exit
|
||||
|
||||
> NOTE: Under Windows OS, in order to access SQLite dbshell you need to [download the SQLite
|
||||
command-line shell program](https://www.sqlite.org/download.html). It's a single executable file
|
||||
(sqlite3.exe) that you should place in the root of either your MUD folder or Evennia's (it's the
|
||||
same, in both cases Django will find it).
|
||||
|
||||
## More about schema migrations
|
||||
|
||||
If and when an Evennia update modifies the database *schema* (that is, the under-the-hood details as
|
||||
to how data is stored in the database), you must update your existing database correspondingly to
|
||||
match the change. If you don't, the updated Evennia will complain that it cannot read the database
|
||||
properly. Whereas schema changes should become more and more rare as Evennia matures, it may still
|
||||
happen from time to time.
|
||||
|
||||
One way one could handle this is to apply the changes manually to your database using the database's
|
||||
command line. This often means adding/removing new tables or fields as well as possibly convert
|
||||
existing data to match what the new Evennia version expects. It should be quite obvious that this
|
||||
quickly becomes cumbersome and error-prone. If your database doesn't contain anything critical yet
|
||||
it's probably easiest to simply reset it and start over rather than to bother converting.
|
||||
|
||||
Enter *migrations*. Migrations keeps track of changes in the database schema and applies them
|
||||
automatically for you. Basically, whenever the schema changes we distribute small files called
|
||||
"migrations" with the source. Those tell the system exactly how to implement the change so you don't
|
||||
have to do so manually. When a migration has been added we will tell you so on Evennia's mailing
|
||||
lists and in commit messages -
|
||||
you then just run `evennia migrate` to be up-to-date again.
|
||||
|
|
@ -1,469 +0,0 @@
|
|||
# Version Control
|
||||
|
||||
Version control software allows you to track the changes you make to your code, as well as being
|
||||
able to easily backtrack these changes, share your development efforts and more.
|
||||
|
||||
It's strongly recommended that you put your game code under version control. Version
|
||||
control is also the way to contribue to Evennia itself.
|
||||
|
||||
For an introduction to the concept, start with the Wikipedia article
|
||||
[here](https://en.wikipedia.org/wiki/Version_control). Evennia uses the version
|
||||
control system [Git](https://git-scm.com/) and this is what will be covered
|
||||
henceforth. Note that this page primarily shows commands for Linux, but the
|
||||
syntax should be the same for Windows and Mac.
|
||||
|
||||
For more help on using Git, please refer to the [Official GitHub
|
||||
documentation](https://help.github.com/articles/set-up-git#platform-all).
|
||||
|
||||
## Setting up Git
|
||||
|
||||
You can find expanded instructions for
|
||||
installation [here](https://git-scm.com/book/en/Getting-Started-Installing-Git).
|
||||
|
||||
### Step 1: Install Git
|
||||
|
||||
- **Fedora Linux**
|
||||
|
||||
yum install git-core
|
||||
|
||||
- **Debian Linux** _(Ubuntu, Linux Mint, etc.)_
|
||||
|
||||
apt-get install git
|
||||
|
||||
- **Windows**: It is recommended to use [Git for Windows](https://gitforwindows.org/).
|
||||
- **Mac**: Mac platforms offer two methods for installation, one via MacPorts, which you can find
|
||||
out about [here](https://git-scm.com/book/en/Getting-Started-Installing-Git#Installing-on-Mac), or
|
||||
you can use the [Git OSX Installer](https://sourceforge.net/projects/git-osx-installer/).
|
||||
|
||||
### Step 2: Define user/e-mail Settings for Git
|
||||
|
||||
To avoid a common issue later, you will need to set a couple of settings; first you will need to
|
||||
tell Git your username, followed by your e-mail address, so that when you commit code later you will
|
||||
be properly credited.
|
||||
|
||||
> Note that your commit information will be visible to everyone if you ever contribute to Evennia or
|
||||
use an online service like github to host your code. So if you are not comfortable with using your
|
||||
real, full name online, put a nickname here.
|
||||
|
||||
1. Set the default name for git to use when you commit:
|
||||
|
||||
git config --global user.name "Your Name Here"
|
||||
|
||||
2. Set the default email for git to use when you commit:
|
||||
|
||||
git config --global user.email "your_email@example.com"
|
||||
|
||||
|
||||
## Putting your game folder under version control
|
||||
|
||||
> Note: The game folder's version control is completely separate from Evennia's repository.
|
||||
|
||||
After you have set up your game you will have created a new folder to host your particular game
|
||||
(let's call this folder `mygame` for now).
|
||||
|
||||
This folder is *not* under version control at this point.
|
||||
|
||||
git init mygame
|
||||
|
||||
Your mygame folder is now ready for version control! Add all the content and make a first
|
||||
commit:
|
||||
|
||||
cd mygame
|
||||
git add *
|
||||
git commit -a -m "Initial commit"
|
||||
|
||||
In turn these commands:
|
||||
- Move us into the `mygame` folder
|
||||
- Tell `git` that everything `*` means everything) in this folder should be put
|
||||
under version control.
|
||||
- _Commit_ all (`-a`) those newly added files to git and add a message `-m` so you remember
|
||||
what you did at this point. Doing a commit is like saving a snapshot of the
|
||||
current state of everything.
|
||||
|
||||
Read on for details!
|
||||
|
||||
### Tracking files
|
||||
|
||||
When working on your code or fix bugs in your local branches you may end up creating new files. If
|
||||
you do you must tell Git to track them by using the add command.
|
||||
|
||||
git add <filename>
|
||||
|
||||
You only need to do this once per file.
|
||||
|
||||
git status
|
||||
|
||||
will show if you have any modified, added or otherwise changed files. Some
|
||||
files, like database files, logs and temporary PID files are usually *not*
|
||||
tracked in version control. These should either not show up or have a question
|
||||
mark in front of them.
|
||||
|
||||
```{note}
|
||||
You will notice that some files are not covered by your git version control,
|
||||
notably your settings file (`mygame/server/conf/settings.py`) and your sqlite3
|
||||
database file `mygame/server/evennia.db3`. What is auto-ignored by is controlled
|
||||
by the hidden file `mygame/.gitignore`. Evennia creates this file as part of
|
||||
the creation of your game directory. Everything matched in this file will be
|
||||
ignored by git. If you want to, for example, include your settings file for
|
||||
collaborators to access, remove that entry in `.gitignore`.
|
||||
```
|
||||
|
||||
```{warning}
|
||||
You should *never* put your sqlite3 database file into git by removing its entry
|
||||
in `.gitignore`. GIT is for backing up your code, not your database. That way
|
||||
lies madness and a good chance you'll confuse yourself so that after a few
|
||||
commits and reverts don't know what is in your database or not. If you want to
|
||||
backup your database, do so by simply copying the file on your hard drive to a
|
||||
backup-name.
|
||||
```
|
||||
|
||||
### Committing your Code
|
||||
|
||||
_Committing_ your code means storing the current snapshot of your code within
|
||||
git. This creates a "save point" or "history" of your development process. You
|
||||
can later jump back and forth in your history, for example to figure out just
|
||||
when a bug was introduced or see what results the code used to produce compared
|
||||
to now. Or just wiping everything since the last commit, if you did something
|
||||
stupid.
|
||||
|
||||
It's usually a good idea to commit your changes often. Committing is fast and
|
||||
local only - you will never commit anything online at this point. To commit your
|
||||
changes, use
|
||||
|
||||
git commit --all
|
||||
|
||||
Also `-a` works. This will open a text editor for you to describe your change.
|
||||
Be brief but informative in your message - you'll appreciate it later. When you
|
||||
save and close the editor, the commit will be saved. You can create the message
|
||||
directly with
|
||||
|
||||
git commit -a -m "This fixes a bug in the combat code."
|
||||
|
||||
|
||||
### Changing your mind
|
||||
|
||||
If you have non-committed changes that you realize you want to throw away, you
|
||||
'check out' the file you want - this will re-load it from the last committed
|
||||
state:
|
||||
|
||||
git checkout <file_to_revert>
|
||||
git checkout foo/bar/dummy.py
|
||||
|
||||
If you want to revert _all_ changes you did since last commit, do
|
||||
|
||||
git checkout .
|
||||
|
||||
(that is, add a single `.` at the end).
|
||||
|
||||
### Pushing your code online
|
||||
|
||||
So far your code is only located on your private machine. A good idea is to back
|
||||
it up online. The easiest way to do this is to push it to your own remote
|
||||
repository on GitHub.
|
||||
|
||||
```{important}
|
||||
Just to avoid confusion, be aware that Github's documentation has changed to
|
||||
calling the primary branch 'main' rather than 'master'. While Evennia still
|
||||
uses 'master' branch (and this is what we refer to below), you can use either
|
||||
name for your personal primary branch - they are equivalent.
|
||||
```
|
||||
|
||||
1. Make sure you have your game directory setup under git version control as
|
||||
described in the previous section. Make sure to commit any changes you did.
|
||||
2. Create a new, empty repository on Github. Github explains how
|
||||
[here](https://help.github.com/articles/create-a-repo/) (do *not* "Initialize
|
||||
the repository with a README" or else you'll create unrelated histories).
|
||||
3. From your local game dir, do `git remote add origin <github URL>` where
|
||||
`<github URL>` is the URL to your online repo. This tells your game dir that
|
||||
it should be pushing to the remote online dir.
|
||||
4. `git remote -v` to verify the online dir.
|
||||
5. `git push origin master` (or `git push origin main`) now pushes your game dir
|
||||
online so you can see it on github.com.
|
||||
|
||||
You can commit your work locally (`git commit --all -m "Make a change that
|
||||
..."`) as many times as you want. When you want to push those changes to your
|
||||
online repo, you do `git push`. You can also `git clone <url_to_online_repo>`
|
||||
from your online repo to somewhere else (like your production server) and
|
||||
henceforth do `git pull` to update that to the latest thing you pushed.
|
||||
|
||||
Note that GitHub's repos are, by default publicly visible by all. Creating a
|
||||
publicly visible online clone might not be what you want for all parts of your
|
||||
development process - you may prefer a more private venue when sharing your
|
||||
revolutionary work with your team. If that's the case you can change your
|
||||
repository to "Private" in the github settings. Then your code will only be
|
||||
visible to those you specifically grant access.
|
||||
|
||||
|
||||
## Forking Evennia
|
||||
|
||||
This helps you set up an online *fork* of the main Evennia repository so you can
|
||||
easily commit fixes and help with upstream development. You can do this step
|
||||
also if you _didn't_ put your game dir under version control like in the
|
||||
previous section - the evennia repo and your game dir repo are completely
|
||||
separate.
|
||||
|
||||
### Step 1: Fork the evennia/master repository
|
||||
|
||||
> Before proceeding with the following step, make sure you have registered and
|
||||
> created an account on [GitHub.com](https://github.com/). This is necessary in order to create a fork
|
||||
of Evennia's master repository, and to push your commits to your fork either for
|
||||
yourself or for contributing to
|
||||
Evennia.
|
||||
|
||||
A _fork_ is a clone of the master repository that you can make your own commits
|
||||
and changes to. At the top of [this page](https://github.com/evennia/evennia),
|
||||
click the "Fork" button, as it appears below.
|
||||

|
||||
|
||||
### Step 2: Clone your online fork of Evennia
|
||||
|
||||
The fork only exists online as of yet. In a terminal, change your directory to
|
||||
the folder you wish to develop in. From this directory run the following
|
||||
command:
|
||||
|
||||
git clone https://github.com/yourusername/evennia.git
|
||||
|
||||
This will download your fork to your computer. It creates a new folder
|
||||
`evennia/` at your current location.
|
||||
|
||||
### Step 3: Configure remotes
|
||||
|
||||
Your Evennia-fork is now separate from upstream, 'official' Evennia. You will
|
||||
want to set it up so that you can easily sync our updates and changes to your
|
||||
fork.
|
||||
|
||||
We do this by setting up a new _remote_. We actually already have one remote,
|
||||
that is our own github form of Evennia. This got created when you cloned the
|
||||
repo and defaults to being called `origin`.
|
||||
|
||||
We will now create a new remote called `upstream`.
|
||||
|
||||
cd evennia
|
||||
git remote add upstream https://github.com/evennia/evennia.git
|
||||
|
||||
This adds a remote to the main evennia repo.
|
||||
|
||||
If you also want to access Evennia's `develop` branch (the bleeding edge
|
||||
development) do the following:
|
||||
|
||||
git fetch upstream develop
|
||||
git checkout develop
|
||||
|
||||
Use
|
||||
git checkout master
|
||||
git checkout develop
|
||||
|
||||
to switch between the branches. If you want to contribute a fix, ask first which
|
||||
branch to use. Normally `master` is for bug fixes and `develop` is for new
|
||||
features, but late in the development of a new Evennia version, all changes
|
||||
often go into `develop`.
|
||||
|
||||
|
||||
## Working with your Evennia fork
|
||||
|
||||
_Branches_ are stand-alone editions of the same code. You make a commit to a
|
||||
branch. Switching to a branch will change the code on-disk. You can easily
|
||||
make a new branch off a parent branch, and then merge it back into the same
|
||||
branch later (or throw it away). This is a very common way to work on new
|
||||
features in safety and isolation.
|
||||
|
||||
### Updating to latest Evennia
|
||||
|
||||
When Evennia's official repository updates, first make sure to commit all your
|
||||
changes to your branch and then checkout the "clean" master branch:
|
||||
|
||||
git checkout master
|
||||
git pull upstream master
|
||||
|
||||
Or, if you are working against Evennia's development branch:
|
||||
|
||||
git checkout develop
|
||||
git pull upstream develop
|
||||
|
||||
The `pull` command will fetch all the changes from the "upstream" remote and
|
||||
merge it into your local master/develop branch. It should now be a perfect copy
|
||||
of the latest Evennia changes.
|
||||
|
||||
### Making changes
|
||||
|
||||
As a rule of thumb you should _never_ work directly in Evennia's `master` or
|
||||
`develop` branches. Instead you make a _new_ branch off the branch you want
|
||||
and change _that_.
|
||||
|
||||
git checkout master (or develop)
|
||||
check checkout -b strange_bug
|
||||
|
||||
You now have a new branch `strange_bug` that is an exact replica of the branch you
|
||||
had checked out when you created it. Here you can now make your own
|
||||
modifications.
|
||||
|
||||
git branches
|
||||
|
||||
will show you which branches are available and which one you are currently
|
||||
using. Use `git checkout <branch>` to move between them, but remember to commit
|
||||
your changes before you do.
|
||||
|
||||
You often want to make sure also your work-branch has the latest upstream
|
||||
changes. To do this, you need to first update your copy of the
|
||||
`master`/`develop` branch and then _merge_ those changes into your work branch.
|
||||
Make sure you have committed everything first!
|
||||
|
||||
git commit -a -m "My latest changes ..." # on your strange_bug branch
|
||||
git checkout master (or develop)
|
||||
git pull upstream develop
|
||||
git checkout strange_bug
|
||||
git merge master (or develop)
|
||||
|
||||
If everything went well, your `strange_bug` branch will now have the latest version
|
||||
of Evennia merged with whatever changes you have done.
|
||||
|
||||
Now work away on your code and commit with reasonable commit messages
|
||||
|
||||
git commit -a -m "Fixed the issue in ..."
|
||||
git commit -a -m "Adding unit tests. This resolves #123."
|
||||
|
||||
Use
|
||||
|
||||
git diff
|
||||
|
||||
to see what you changed since last commit, and
|
||||
|
||||
git log
|
||||
|
||||
to see past commits (including those made by Evennia upstream, remember that
|
||||
your branch is a copy of the upstream one, including its history!)
|
||||
|
||||
## Sharing your Evennia fixes on Github
|
||||
|
||||
Up to this point your `strange_bug` branch only exists on your local computer. No
|
||||
one else can see it. If you want a copy of this branch to also appear in your
|
||||
online fork on GitHub, make sure to have checked out your "myfixes" branch and
|
||||
then run the following:
|
||||
|
||||
git push -u origin strange_bug
|
||||
|
||||
You only need to do this once, the `-u` makes this the default push-location. In
|
||||
the future, you can just push things online like this:
|
||||
|
||||
git push
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If you hadn't setup a public key on GitHub or aren't asked for a
|
||||
username/password, you might get an error `403: Forbidden Access` at this stage.
|
||||
In that case, some users have reported that the workaround is to create a file
|
||||
`.netrc` under your home directory and add your github credentials there:
|
||||
|
||||
```bash
|
||||
machine github.com
|
||||
login <my_github_username>
|
||||
password <my_github_password>
|
||||
```
|
||||
|
||||
## Making an Evennia Pull Request
|
||||
|
||||
If you think that the fixes you did in your `strange_bug` branch should be a
|
||||
part of the regular Evennia, you should create a _Pull Request_ (PR). This is a
|
||||
call for the Evennia maintainer to pull your change into an upstream branch.
|
||||
|
||||
> It is wise to make separate branches for every fix or series of fixes you want
|
||||
to contribute.
|
||||
|
||||
Assuming you have followed the instructions above and have pushed your changes
|
||||
online, [create a pull request](https://github.com/evennia/evennia/pulls) and
|
||||
follow the instructions. Make sure to specifically select your `strange_bug`
|
||||
branch to be the source of the merge and use the branch you based that branch
|
||||
off (`master` or `develop`) as the target.
|
||||
|
||||
Evennia developers will then be able to examine your request and merge it if
|
||||
it's deemed suitable. They may also come back with feedback and request you do
|
||||
some changes.
|
||||
|
||||
Once approved and merged, your change will now be available in the upstream
|
||||
branch:
|
||||
|
||||
git checkout master (or develope)
|
||||
git pull upstream master (or develop)
|
||||
|
||||
Since your changes are now in upstream, your local `strange_bug` branch is now
|
||||
superfluous and should be deleted:
|
||||
|
||||
git branch -D strange_bug
|
||||
|
||||
You can also safely delete your online `strange_bug` branch in your fork
|
||||
(you can do this from the PR page on github).
|
||||
|
||||
|
||||
## GIT tips and tricks
|
||||
|
||||
Some of the GIT commands can feel a little long and clunky if you need to do them often. Luckily you
|
||||
can create aliases for those. Here are some useful commands to run:
|
||||
|
||||
|
||||
```
|
||||
# git st
|
||||
# - view brief status info
|
||||
git config --global alias.st 'status -s'
|
||||
```
|
||||
|
||||
Above, you only need to ever enter the `git config ...` command once - you have then added the new
|
||||
alias. Afterwards, just do `git st` to get status info. All the examples below follow the same
|
||||
template.
|
||||
|
||||
```
|
||||
# git cl
|
||||
# - clone a repository
|
||||
git config --global alias.cl clone
|
||||
```
|
||||
|
||||
```
|
||||
# git cma "commit message"
|
||||
# - commit all changes without opening editor for message
|
||||
git config --global alias.cma 'commit -a -m'
|
||||
```
|
||||
|
||||
```
|
||||
# git ca
|
||||
# - amend text to your latest commit message
|
||||
git config --global alias.ca 'commit --amend'
|
||||
```
|
||||
|
||||
```
|
||||
# git fl
|
||||
# - file log; shows diffs of files in latest commits
|
||||
git config --global alias.fl 'log -u'
|
||||
```
|
||||
|
||||
```
|
||||
# git co [branchname]
|
||||
# - checkout
|
||||
git config --global alias.co checkout
|
||||
```
|
||||
|
||||
```
|
||||
# git br <branchname>
|
||||
# - create branch
|
||||
git config --global alias.br branch
|
||||
```
|
||||
|
||||
```
|
||||
# git ls
|
||||
# - view log tree
|
||||
git config --global alias.ls 'log --pretty=format:"%C(green)%h\ %C(yellow)[%ad]%Cred%d\
|
||||
%Creset%s%Cblue\ [%cn]" --decorate --date=relative --graph'
|
||||
```
|
||||
|
||||
```
|
||||
# git diff
|
||||
# - show current uncommitted changes
|
||||
git config --global alias.diff 'diff --word-diff'
|
||||
```
|
||||
|
||||
```
|
||||
# git grep <query>
|
||||
# - search (grep) codebase for a search criterion
|
||||
git config --global alias.grep 'grep -Ii'
|
||||
```
|
||||
|
||||
To get a further feel for GIT there is also [a good YouTube talk about it](https://www.youtube.com/watch?v=1ffBJ4sVUb4#t=1m58s) - it's a bit long but it will help you understand the underlying ideas behind GIT
|
||||
(which in turn makes it a lot more intuitive to use).
|
||||
Loading…
Add table
Add a link
Reference in a new issue