Thursday, May 16, 2019

Project Status Update

Progress on Wayfarer is much slower than it was before switching to Evennia. A lot of this is due to my unfamiliarity with Evennia; I'm spending far more time researching what the 'Evennian' way of doing X is versus just implementing it and moving on. I'm still hopeful that this switch will be a net time savings due to not having to re-implement a lot of Evennia's existing features, but it'll be slow going for a while more.

As a note to future users of the Wilderness contrib, I'm finding that some of the design decisions don't make sense in the original contrib. For instance, map generators are responsible for dictating whether or not a given coordinate set is valid, but the code for updating coordinates via movement is a standalone function outside of the map generator class. I've moved it inside to allow map generators to dictate their own coordinate-change behaviors (wrapping worlds, etc).

Current work list:
- Design method of generating and saving playfields out-of-band to avoid loading the server during exploration.
- Design method of saving and loading alterations to playfields (sector/biome evolution, clear-cutting, etc).
- Re-implement work from custom codebase re: procedural generation.

Saturday, May 4, 2019

Ways to represent coordinate-based worlds in Evennia

I've been talking with Griatch (Evennia's principal developer) in the MUD Coders Guild's public Slack server, and he noted several ways of getting Evennia to work with a coordinate system. I'll summarize the information I gleaned here; any errors, omissions, or bad visualizations should be assumed to be my own.

1) It's possible to use a global script (i.e. an OOC object in Evennia lingo) to hold a 2D array of room objects directly. Evennia's Attributes system supports this kind of storage natively and efficiently, although cacheing the array is also advisable.

2) Alternatively, tags can be used on objects to represent their axial coordinates (example: tag="xcoord 3", tag="ycoord 4"). Tags can be shared between objects, meaning that to tag anything within a 10x10 coordinate grid you'd only need to create 20 tags in the database (10 for X, 10 for Y). Less optimally, attributes can be used to store coordinate pairs, but these cannot be shared between objects and would need one attribute per object (10x10 = 100 attributes just for the rooms). Tagging is the approach described in Evennia's Coordinates writeup.

3) Finally, for very large grids, it's advised to use the wilderness contrib which uses one room per player. As the player moves around, the room moves with them, a bit like a giant hamster ball rolling across the world. The wilderness keeps track of the things inside it, and when you move it checks to see if anything occupies the same space as you; if it finds things, it adds them to your room (or merges your room with theirs if they are a player). This keeps room memory usage light and allows for large spaces.

I was originally considering very large playing fields (500x500, or even 1000x1000), but after looking back at this post on Wayfar 1444's chargen system, it's clear that I was vastly over-estimating the size of the original planets. Restricting the playing fields to 100x100 may be advisable to ensure that players run into each other more frequently. This will also naturally lessen the amount of work the procedural generators have to do.

Friday, May 3, 2019

Biome Generation Completed - Testing Evennia

I've finished biome generation including temperature and moisture maps. This took more work than the original height generation process, as I had to design my own linear gradient to apply temperature such that it was warm across the equator and cool at the poles. Height, temperature, and moisture now all play a role in generating terrain, leading to something like this:


Seen above is a map with a north and south polar ice cap, and desert banding in the middle. This is perhaps a little too warm at the equator for my tastes. Subsequent rebalancing is planned, but not a priority-- it's just tweaking constants in the generator at this point.

Of potentially greater impact is the fact that I'm currently evaluating Evennia as a potential codebase for the game. I'm not familiar with MOO design in general, but Evennia has a lot of functionality that I'd otherwise have to self-implement in my bare-bones codebase-- things like seamless copyovers, persistence, character inventories, etc that are all taken for granted in modern games but represent a significant amount of dev time. I'm currently experimenting with recreating the terrain generator work there to see how feasible a game in this style would be in that codebase.

Wednesday, May 1, 2019

Rough Draft Terrain Implemented

It was much quicker than I thought it'd be to get this pulled together.

Generated with frequency set at 1.0 (see below)

This initial version uses OpenSimplex and a custom octaving flow to generate believable terrain masses. Each pixel in that image represents one tile. For next steps, I'm looking to up the complexity so that the playing space is more varied-- the current large areas of similar terrain are somewhat realistic, but not fun to trudge across.

Currently, tile type is generated solely from height. Next steps after tweaking the noise for complexity will be adding in temperature (derived partially from height) and rainfall maps so we can establish proper biomes. I'd also like to run rivers.

So far, I'm finding this GamaSutra article to be very helpful in getting my head around the various concepts involved in proc-gen terrain. I highly recommend it; the explanations are great even if you're not using Unity (which I'm not for this project).


Edit to add: Increasing terrain complexity was a simple matter of increasing the frequency value when octaving.

Frequency 1.25

Frequency 1.5


Frequency 1.5 with tweaked height-to-sector mapping

Bare-Bones Server Online

I've gotten the barest of bones of a server built, thanks in large part to mud-pi which currently provides the backend. Much of the dev time so far has been spent re-vamping the server to use a more developed concept of a character, and to discard rooms and use Wayfarer's current data structure.

Succinctly, the game is comprised on an arbitrary number of space fields, which contain an arbitrary number of play fields (planets, moons, etc). Play fields are wrapped 2D maps that contain a list of their occupants (players, NPCs, vehicles, etc) and have a tile object for each coordinate pair. Tiles contain information about what is built on them, and also track their sector type. Sector types are the terrain type of the tile.

The game currently contains a 100x100 playfield, upon which sector types are randomly generated. Coordinates wrap, and resources are displayed (currently all tiles have placeholder resources).


I've used tkinter to output a bare-bones representation of what the map looks like. Colors are based on height, which is currently randomly generated.


Upcoming development work will center on the implementation of procedural terrain generation. This is expected to take some time.

Of future development interest is the question of whether tiles should track buildings, or whether buildings should be tracked at the field level. The original thinking with using tiles was that if playfields are sufficiently large and developed, it will be slow iterating through every building to see which ones are in range of a given player; however, if they playfields don't get this developed, then iterating over every tile in range of the player to check them for buildings will be more expensive. This will need some thought.

Monday, April 29, 2019

An Introduction to Wayfarer

Welcome to the development blog for Wayfarer, an open-world survival and crafting MUD named in homage to the late MUD Wayfar 1444.

Wayfarer is a MUD that incorporates many of the same thematic and design elements as Wayfar 1444 did (a drop-pod start, a crafting/researching/resource-gathering centric gameplay loop, fun combat mechanics), but also adds new twists and tweaks to enhance the player's experience. Engine details are still being worked over, but Wayfarer will tentatively be built on a custom Python engine implementing common telnet features.

Current development work is focusing on drafting the telnet server and implementing necessary aspects of the related RFPs so Mudlet can connect to it. Next steps will focus on building the data model to contain multiple procedurally-generated playing fields in an efficient and usable manner.