21 May 2019

feedDjango community aggregator: Community blog posts

The Best Animation and Prototyping Tools for Designers in 2019

Prototyping is a great way to showcase your product before embarking on a long development process. It gives you the opportunity to make changes prior to development. It also saves you significant time and money. The post The Best Animation and Prototyping Tools for Designers in 2019 appeared first on Distillery.

21 May 2019 9:42pm GMT

18 May 2019

feedDjango community aggregator: Community blog posts

Creating Evscaperoom, part 1

Over the last month (April-May 2019) I have taken part in the Mud Coder's Guild Game Jam "Enter the (Multi-User) Dungeon". This year the theme for the jam was One Room.

The result was Evscaperoom, an text-based multi-player "escape-room" written in Python using the Evennia MU* creation system. You can play it from that link in your browser or MU*-client of choice. If you are so inclined, you can also vote for it here in the jam (don't forget to check out the other entries while you're at it).

This little series of (likely two) dev-blog entries will try to recount the planning and technical aspects of the Evscaperoom. This is also for myself - I'd better write stuff down now while it's still fresh in my mind!

Inception

When I first heard about the upcoming game-jam's theme of One Room, an 'escape room' was the first thing that came to mind, not the least because I just recently got to solve my my own first real-world escape-room as a gift on my birthday.

If you are not familiar with escape-rooms, the premise is simple - you are locked into a room and have to figure out a way to get out of it by solving practical puzzles and finding hidden clues in the room.

While you could create such a thing in your own bedroom (and there are also some one-use board game variants), most escape-rooms are managed by companies selling this as an experience for small groups. You usually have one hour to escape and if you get stuck you can press a button (or similar) to get a hint.

I thought making a computer escape-room. Not only can you do things in the computer that you cannot do in the real world, restricting the game to a single room limits so that it's conceivable to actually finish the damned thing in a month.

A concern I had was that everyone else in the jam surely must have went for the same obvious idea. In the end that was not an issue at all though.


Basic premises

I was pretty confident that I would technically be able to create the game in time (not only is Python and Evennia perfect for this kind of fast experimentation and prototyping, I know the engine very well). But that's not enough; I had to first decide on how the thing should actually play. Here are the questions I had to consider:

Room State

An escape room can be seen as going through multiple states as puzzles are solved. For example, you may open a cabinet and that may open up new puzzles to solve. This is fine in a single-player game, but how to handle it in a multi-player environment?

My first thought was that each object may have multiple states and that players could co-exist in the same room, seeing different states at the same time. I really started planning for this. It would certainly be possible to implement.

But in the end I considered how a real-world escape-room works - people in the same room solves it together. For there to be any meaning with multi-player, they must share the room state.

So what I went with was a solution where players can create their own room or join an existing one. Each such room is generated on the fly (and filled with objects etc) and will change as players solve it. Once complete and/or everyone leaves, the room is deleted along with all objects in it. Clean and tidy.

So how to describe these states? I pictured that these would be described as normal Python modules with a start- and end function that initialized each state and cleaned it up when a new state was started. In the beginning I pictured these states as being pretty small (like one state to change one thing in the room). In the end though, the entire Evscaperoom fits in 12 state modules. I'll describe them in more detail in the second part of this post.

Accessibility and "pixel-hunting" in text

When I first started writing descriptions I didn't always note which objects where interactive. It's a very simple and tempting puzzle to add - mention an object as part of a larger description and let the player figure out that it's something they can interact with. This practice is sort-of equivalent to pixel-hunting in graphical games - sweeping with the mouse across the screen until you find that little spot on the screen that you can do something with.

Problem is, pixel-hunting's not really fun. You easily get stuck and when you eventually find out what was blocking you, you don't really feel clever but only frustrated. So I decided that I should clearly mark every object that people could interact with and focus puzzles on better things.


In fact, in the end I made it an option:

Option menu ('quit' to return) 1: ( ) No item markings (hard mode) 2: ( ) Items marked as item (with color) 3: (*) Items are marked as [item] (screenreader friendly) 4: ( ) Screenreader mode


As part of this I had to remind myself never to use colors only when marking important information: Visually impaired people with screen readers will simply miss that. Not to mention that some just disable colors in their clients.

So while I personally think option 2 above is the most visually pleasing, Evscaperoom defaults to the third option. It should should start everyone off on equal footing. Evennia has a screen-reader mode out of the box, but I moved it into the menu here for easy access.

Inventory and collaboration

In a puzzle-game, you often find objects and combine them with other things. Again, this is simple to do in a single-player game: Players just pick things up and use them later.

But in a multi-player game this offers a huge risk: players that pick up something important and then log off. The remaining players in that room would then be stuck in an unsolvable room - and it would be very hard for them to know this.

In principle you could try to 'clean' player inventories when they leave, but not only does it add complexity, there is another issue with players picking things up: It means that the person first to find/pick up the item is the only one that can use it and look at it. Others won't have access until the first player gives it up. Trusting that to anonymous players online is not a good idea.

So in the end I arrived at the following conclusions:

As a side-effect of this I also set a limit to the kind of puzzles I would allow:


Focusing on objects

So without inventory system, how do you interact with objects? A trademark of any puzzle is using one object with another and also to explore things closer to find clues. I turned to graphical adventure games for inspiration:

Hovering with mouse over lens object offers action "look at lens"
Secret of Monkey Island ©1990 LucasArts. Image from old-games.com


A common way to operate on an object in traditional adventure games is to hover the mouse over it and then select the action you want to apply to it. In later (3D) games you might even zoom in of the object and rotate it around with your mouse to see if there are some clues to be had.

While Evennia and modern UI clients may allow you to use the mouse to select objects, I wanted this to work the traditional MUD-way, by inserting commands. So I decided that you as a player would be in one of two states:

A small stone fireplace sits in the middle of the wall opposite the [door]. On the chimney hangs a small oil [painting] of a man. Hanging over the hearth is a black [cauldron]. The piles of [ashes] below are cold. (It looks like fireplace may be suitable to [climb].)


In the example above, the fireplace points out other objects you could also focus on, whereas the last parenthesis includes one or more "actions" that you can perform on the fireplace only when you have it focused.

This ends up pretty different from most traditional MUD-style inputs. When I first released this to the public, I found people logged off after their first examine. It turned out that they couldn't figure out how to leave the focus mode. So they just assumed the thing was buggy and quit instead. Of course it's mentioned if you care to write help, but this is clearly one step too many for such an important UI concept.

So I ended up adding the header above that always reminds you. And since then I've not seen any confusion over how the focus mode works.

For making it easy to focus on things, I also decided that each room would only ever have one object named a particular thing. So there is for example only one single object in the game named "key" that you can focus on.

Communication

I wanted players to co-exist in the same room so that they could collaborate on solving it. This meant communication must be possible. I pictured people would want to point things out and talk to each other.

In my first round of revisions I had a truckload of individual emotes; you could

point at target

for example. In the end I just limited it to

say/shout/whisper <message>

and

emote <whatever>

And seeing what people actually use, this is more than enough (say alone is probably 99% of what people need, really). I had a notion that the shout/whisper could be used in a puzzle later but in the end I decided that communication commands should be strictly between players and not have anything to do with the puzzles.

I removed all other interaction: There is no fighting and without an inventory or requirement to collaborate on puzzles, there is no need for other interactions than to communicate.

First version you didn't even see what the others did, but eventually I added so that you at least saw what other players were focusing on at the moment (and of course if some major thing was solved/found).

In the end I don't even list characters as objects in the room (you have to use the who command to see who's in there with you).

Listing of commands available in the Evscaperoom (output of the help-command in game)
The main help command output.

Story

It's very common for this type of game to have a dangerous or scary theme. Things like "get out before the bomb explodes", "save the space ship before the engines overheat", "flee the axe murderer before he comes back" etc). I'm no stranger to dark themes, but for this I wanted something friendlier and brighter, maybe with a some dark undercurrents here and there.

My Jester character is someone I've not only depicted in art, but she's also an old RP character and literary protagonist of mine. Who else would find it funny to lock someone into a room only to provide crazy puzzles and hints for them to get out again? So my flimsy 'premise' was this:

The village Jester wants to win the pie eating contest. You are one of her most dangerous opponents. She tricked you to her cabin and now you are locked in! If you don't get out in time, she'll get to eat all those pies on her own and surely win!


That's it - this became the premise from which the entire game flowed. I quickly decided that it to be a very "small-scale" story: no life-or-death situation, no saving of the world. The drama takes place in a small village with an "adversary" that doesn't really want to hurt you, but only to eat more pies than you.

From this, the way to offer hints came naturally - just eat a slice of "hintberry pie" the jester made (she even encourage you to eat it). It gives you a hint but is also very filling. So if you eat too much, how will you beat her in the contest later, even if you do get out?

To further the rustic and friendly tone I made sure the story took place on a warm summer day. Many descriptions describe sunshine, chirping birds and the smell of pie. I aimed at letting the text point out quirky and slightly comedic tone of the puzzles the Jester left behind. The player also sometimes gets teased by the game when doing things that does not make sense.

I won't go into the story further here - it's best if you experience it yourself. Let's just say that the village has some old secrets. And and the Jester has her own ways of doing things and of telling a story. The game has multiple endings and so far people have drawn very different conclusions in the end.

Scoring

Most often in escape rooms, final score is determined by the time and the number of hints used. I do keep the latter - for every pie you eat, you get a penalty on your final score.

As for time - this background story would fit very well with a time limit (get out in X time, after which the pie-eating contest will start!). But from experience with other online text-based games I decided against this. Not only should a player be able to take a break, they may also want to wait for a friend to leave and come back etc.

But more importantly, I want players to explore and read all my carefully crafted descriptions! So I'd much rather prefer they take their time and reward them for being thorough.

So in the end I give specific scores for actions throughout the game instead. Most points are for doing things that drive the story forward, such as using something or solving a puzzle. But a significant portion of the score comes from turning every stone and trying everything out. The nice side-effect of this is that even if you know exactly how to solve everything and rush through the game you will still not end up with a perfect score.

The final score, adjusted by hints is then used to determine if you make it in time to the contest and how you fare. This means that if you explore carefully you have a "buffer" of points so eating a few pies may still land you a good result in the end.


First sketch

I really entered the game 'building' aspect with no real notion of how the Jester's cabin should look nor which puzzles should be in it. I tried to write things down beforehand but it didn't really work for me.

So in the end I decided "let's just put a lot of interesting stuff in the room and then I'll figure out how they interact with each other". I'm sure this is different from game-maker to game-maker. But for me, this process worked perfectly.

Scribbles on my notebook, sketching up the room's main items
My first, very rough, sketch of the Jester's cabin


The above, first sketch ended up being what I used, although many of the objects mentioned never ended up in the final game and some things switched places. I did some other sketches too, but they'd be spoilers so I won't show them here ...


The actual game logic

The Evscaperoom principles outlined above deviate quite a bit from the traditional MU* style of game play.

While Evennia provides everything for database management, in-game objects, commands, networking and other resources, the specifics of your game is something you need to make yourself - and you have the full power of Python to do it!

So for the first three days of the jam I used Evennia to build the custom game logic needed to provide the evscaperoom style of game play. I also made the tools I needed to quickly create the game content (which then took me the rest of the jam to make).

In part 2 of this blog post I will cover the technical details of the Evscaperoom I built. I'll also go through some issues I ran into and conclusions I drew. I'll link to that from here when it's available!

18 May 2019 11:50pm GMT

17 May 2019

feedDjango community aggregator: Community blog posts

New features planned for Python 4.0

With the release of Python 3.8 coming soon, the core development team has asked me to summarize our latest discussions on the new features planned for Python 4.0, codename "ouroboros: the snake will eat itself". This will be an exciting release and a significant milestone, many thanks to the hard work of over 100 contributors.

Notably absent from 4.0, with much sadness, the following features did not make the cut:

We look forward to this release, and will do everything in our power to ensure it takes us several minor versions before it is even remotely usable.

photos/deadsnakes.png

17 May 2019 3:41pm GMT

django-debug-toolbar 2.0a1 is now available on PyPI. Please help with testing or with success stori

django-debug-toolbar 2.0a1 is now available on PyPI. Please help with testing or with success stories or with bug reporting & squashing.

17 May 2019 3:25pm GMT

15 May 2019

feedDjango community aggregator: Community blog posts

The Price of the Hallway Track

There are many good reasons to not go to every talk possible when attending conferences. However increasingly it became hip to boast with not going to talks at all - encouraging others to follow suit. As a speaker, that rubs me the wrong way and I'll try to explain why.

15 May 2019 11:00pm GMT

5 Ways Software Outsourcing Helps FinTech Startups Compete and Win

As many FinTech startups have already learned, the right development partner is a massive competitive advantage. Don't get left behind. Instead, let outsourcing help you accelerate. The post 5 Ways Software Outsourcing Helps FinTech Startups Compete and Win appeared first on Distillery.

15 May 2019 12:57am GMT

14 May 2019

feedDjango community aggregator: Community blog posts

Django + Tailwind CSS = ❤️

If you use Tailwind CSS and want to integrate it easily with Django, check out a package I created about a month ago.

Surprisingly it's called Django-Tailwind. You can find it here on GitHub: https://github.com/timonweb/django-tailwind.

If you don't know what Tailwind CSS is, then ...

Read now

14 May 2019 8:57am GMT

10 May 2019

feedDjango community aggregator: Community blog posts

Django Search Tutorial

Add basic search functionality to any Django website.

10 May 2019 3:28pm GMT

PyGrunn: testing your infrastructure code - Ruben Homs

(One of my summaries of a talk at the 2019 PyGrunn conference).

Servers used to be managed by proper wizards. But even wizards can be killed by a balrog. So... what happens when your sysadmin leaves?

  • The point of failure is the sysadmin.
  • Knowledge about infrastructure is centralised.
  • It is non-reproducible.

A solution is configuration management. Chef, ansible, saltstack, puppet. Configuration that's in source control instead of information in a sysadmin's head.

  • It is a reproducible way to build your infrastructure.
  • Source code, so everyone can see how a system works.
  • You can even version your infrastructure.

He'll use saltstack as an example, that's what they're using in his company. It is a master/minion system. So a central master pushes out commands to the minion systems.

For testing, he uses a tool called "kitchen", originally intended for puppet, which can however also be used with saltstack: https://kitchen.saltstack.com/ . He showed a demo where he created a couple of virtualbox machines and automatically ran the salt scripts on them.

You can then ssh to those boxes and check if they're OK.

But... that's manual work. So he started using testinfra and pytest. Testinfra helps you test infrastructure. There are build-in tests for checking if a package has been installed, for instance:

def test_emacs_installed(host):
    assert host.package("emacs").is_installed

You can run those tests via "kitchen". They use that to test their infrastructure setup from travis-ci.com.

10 May 2019 4:00am GMT

PyGrunn: python as a scientist's playground - Peter Kroon

(One of my summaries of a talk at the 2019 PyGrunn conference).

He's a scientist. Quite often, he searches for python packages.

  • If you're writing python packages, you can learn how someone might search for your package.
  • If you don't write python packages, you can learn how to investigate.

Scientists try to solve unsolved problems. When doing it with computers, you basically do three things.

  • Perform simulations.
  • Set up simulations.
  • Analyze results.

Newton said something about "standing on the shoulders of giants". So basically he predicted the python package index! So much libraries to build upon!

A problem is that there is so much software. There are multiple libraries that can handle graphs (directed graphs, not diagrams). He's going to use that as an example.

Rule one: PR is important. If you don't know a package exists, it won't come on the list. Google, github discovery, stackoverflow, scientific liberature, friends, pygrunn talks, etc.

A README is critical. Without a good readme: forget it.

The five he found: graph-tool, networkx, igraph, python-graph scipy.sparse.csgraph.

Rule two: documentation is very important. Docs should showcase the capabilities. This goes beyond explaining it, it should show it.

I must be able to learn how to use your package from the docs. Just some API documentation is not enough, you need examples.

Watch out with technical jargon and terms. On the one hand: as a scientist you're often from a different field and you might not know your way around the terms. On the other hand, you do want to mention those terms to help with further investigation.

Bonus points for references to scientific literature.

Documentation gold standard: scikit-learn!

python-graph has no online docs, so that one's off the shortlist. The other four are pretty OK.

Rule three: it must be python3 compatible. On 1 january 2020 he's going to wipe python2 from all the machines that he has write access to.

All four packages are OK.

Rule four: it must be easy to install. So pypi (or a conda channel). You want to let pip/coda deal with your dependencies. If not, at least list them.

Pure python is desirable. If you need compilation of c/c++/fortran, you need all the build dependencies. This also applies to your dependencies.

He himself is a computer scientist, so he can compile stuff. But most scientists can't really do.

He himself actually wants to do research: he doesn't want to solve packaging problems.

graph-tool is not on pypi, networkx is pure python. scipy is fortran/c, but provides wheels. igraph is C core and not on pypi.

So scipy and networkx are left.

Rule five: it must be versatile. Your package must do everything. If your package does a lot, there are fewer dependencies in the future. And I have to learn fewer packages.

If it doesn't do everything, it might still be ok if it is extendable. He might even open a pull request to add the functionality that he needs.

Note: small projects that solve one project and solve it well are OK, too.

networkx: does too much to count. Nice. scipy.sparse.csgraph has six functions. So for now, networkx is the package of choice.

The first and third rules are hard rules: if it is a python2-only package it is out and if you can't find a package, you can't find it, period.

Conclusions

  • You need to invest effort to make ME try your package.
  • "My software is so amazing, so you should invest time and effort to use it": NO :-)
  • If it doesn't work in 15 minutes: next candidate.

10 May 2019 4:00am GMT

PyGrunn: embedding the python interpreter - Mark Boer

(One of my summaries of a talk at the 2019 PyGrunn conference).

Writing scripts inside applications is often hard. Some of them luckily have an embedded version of python, but not all of them.

Two important terms: extending and embedding. Lots of scientific software is made available via extending: a python wrapper. Numpy and tensorflow, for instance.

The other way around is embedding: you put python inside your application. Useful for plugins, scripting. He doesn't know if jupyter notebooks are a good example of embedding, but in any case, jupyter is doing funny things with the python interpreter.

CPython, which is the version of python we're talking about, consists of three parts:

  • Bytecode compiler
  • Python virtual machine (the one running the compiled bytecode).
  • Python's C API, which allows other programs to call python. The C API is the opposite of python: it is hard to read and write :-) Oh, and the error messages are horrendous.

But... starting python from C and sending lines to the REPL, that's quite easy. PyRun-SimpleString(). He showed a 10-line C program that reads from stdin and lets python execute it.

He then expanded it to run in a separate thread. But soon his program crashed. The solution was to explicitly acquire and release the GIL ("global interpreter lock").

A problem: multiprocessing doesn't work. At least on windows. Starting another process from within python opens another version of the whole program you're in...

A suggestion: pybind11, a handy library for helping you embed python into c++. It especially helps with managing the GIL and for embedding python modules.

Something he sees often, is that it is used to parallellize code for the benefit of python:

  • Convert python types to c/c++ types
  • release GIL
  • Perform computation
  • acquire GIL
  • Convert c/c++ types to return type.

A note on deployment: just include python in your installer.

10 May 2019 4:00am GMT

PyGrunn: data processing and visualisation of tractor data - Erik-Jan Blanksma

(One of my summaries of a talk at the 2019 PyGrunn conference).

He works for Dacom, a firm that writes software to help farmers be more effective. Precision farming is a bit of a buzzword nowadays. You can get public elevation data, you can let someone fly over your fields to take measurements or a cart can do automatic ground samples. This way you can make a "prescription map" where to apply more fertilizer and where less will do.

Another source of data is the equipment the farmer uses to drive over his field. As an example, the presentation looks at a potato harvester.

  • Which route did the harvester take through the field?
  • What was the yield (in potatoes per hectare) in all the various spots?

Some tools and libraries that they use:

  • Numpy: very efficient numerical processing. Arrays.
  • Pandas: dataseries.
  • Matplotlib: graph plotting library.
  • Postgis: geographical extension to the postgres databases.

Pandas is handy for reading in data, from csv for instance. It integrates nicely with matplotlib. With a one-liner you can let it create a histogram from the data.

With the .describe() function, you get basic statistics about your data.

Another example: a map (actually a graph, but it looks like a map) with color codes for the yield. The locations where the yields are lower are immediately clear this way.

When converting data, watch out with your performance. What can be done by pandas itself is much quicker than if it has to ask python to do it. For instance, creating a datetime from a year field, a month field, etc, that takes a long time as it basically happens per row. It is way quicker to let pandas concatenate the yyyy/mm/dd + time info into one string and then convert that one string to a datetime.

He showed the same example for creating a geometric point. It is quickest to create a textual POINT(1.234,8.234) string from two x/y fields and only then to convert it to a point.

Use the best tool for the job. Once he had massaged the data in pandas, he exported it to a postgis database table. Postgis has lots of geographical functions, like ST_CENTROID, ST_BUFFER, and ST_MAKELINE, which he used to do the heavy geographical lifting.

He then used the "geopandas" extension to let pandas read the resulting postgis query's result. Which could again be plotted with matplotlib.

Nice!

10 May 2019 4:00am GMT

PyGrunn: advanced pytest - Òscar Vilaplana

(One of my summaries of a talk at the 2019 PyGrunn conference).

Imagine being a developer being woken up at night because your latest commit broke the website. You fix the issue, run the tests of your part of the code (which passes) and push to github. That runs all the tests and it fails in a completely unrelated piece of the code. But what is happening? Is the test wrong? Is your code wrong? "3 is not 90": what does that mean?

What does it mean that this fails? What is the test's promise? If a test you wrote fails, it should fail beautifully. It should tell exactly what's wrong:

assert num_something == 2, "The number should match the number of added items"

You can use pytest fixtures to at least make the data the test is working with clearer.

You can make fixtures that work as context managers:

@pytest.fixture
def test_with_teardown():
    thing = create_something()  # setup
    yield thing
    thing.destroy()  # teardown

A tip: have fixtures per subsystem. Assuming you have multiple test directories, one per subsystem. Give every subsystem its own conftest.py. Different subsystems might get different fixtures even though using the same name ("product" for instance). This way you can tweak your main fixture items per subsystem.

  • Disadvantage: it is implicit instead of explicit...
  • Advantage: the fixtures can stay minimal. Otherwise your fixture has to support all use cases.

You can parametrize fixtures:

@pytest.fixture(params=["no-user", "disabled-user", "read-only-user"])
def unauthorized_user():
    if param == ...
        return ...
    if param == ...
        ...

Tests using that fixture are run three times, once for every possible kind of unauthorized user!

You can do it even more elaborate. You can make a kind of a "build matrix" and use @pytest.mark.parametrize.

If every test needs a temporary database or a temporary something, you can pass auto_use=True to the fixture, that'll apply it automatically.

Pytest can help you with mocking, but sometimes you're better off setting up dependency injection. So adding a parameter to the method you're testing to accept some mocked item instead of its regular default.

If you think regular code is more important than the tests: he pro-tests :-)

You need tests because they give you a feeling of safety. If you feel safe, you dare to try things. Tests are a bit of a shared goal inside a team: you and your code want to belong. You want interaction: make sure your tests are communicative and helpful.

10 May 2019 4:00am GMT

PyGrunn: a day has only 24 ± 1 hours - Miroslav Šedivý

(One of my summaries of a talk at the 2019 PyGrunn conference).

Time zones... If you do datatime.datetime.now() you'll get a date+time without timezone information. You can get different results on your laptop (set to local time) and a server (that might be set to UTC).

You can use datetime.datetime.utcnow() that returns UTC time. But... without a timezone attached. Best is to request the time in a specific timezone.

There are gotchas regarding time. Check your time only once in a calculation. If you call .utcnow() multiple times, you can get different dates when your code runs around 0:00.

Same with time.time(): if the "ntp" daemon adjusts your system clock in the mean time you get weird results. For that, there is time.monotonic().

The original source for all time zone information is the time zone database (tzdata). You can download it and look at all the files per timezone. Interesting reading! Look at Istanbul's timezone. Daylight savings time being delayed by a day in a specific year because of a nationwide school exam. It was anounced a few weeks before. That's all in the time zone database.

So if you make a Docker now and still use it in two years' time, you might run into problems because summer time might have been abolished by the EU by then. So make sure you keep your time zone libary up to date.

10 May 2019 4:00am GMT

Django Pony GIF's

Camera

I discovered GIFCities recently. It's a project by the Internet Archive for browsing GIF's extracted from their Geocities archive.

I spent a bit of time searching it for pegasus gifs, to represent the unofficial Django mascot, the Django Pony. Here are the best I found!

Running django-admin.py startproject

Baby pegasus hatching from an egg

Mentoring a New Django Developer

Pegasus caring for a young pegasus

Code Review

Pegasus shaking head

Code Review Complete

Pegasi caring for each other

Your Pet Project

Unicorn in a sparkly heart

When You Have One View

Mini flying pegasus

Deploy Goes Perfectly

Gliding pegasus

Deploy Goes Bad and Roll Back

Pegasus flying in and taking off again

Maximum Requests Per Second

Pegasus flapping its wings incredibly fast

Serving a Slow Admin Page

Pegasus rearing

How You Describe Your Project

Pegasus in the stars

How Your Project Actually Works

Pegasus in a starry snowglobe

Fin

Enjoy the GIFt,

-Adam

10 May 2019 4:00am GMT

09 May 2019

feedDjango community aggregator: Community blog posts

Podcast about Evennia

I was interviewed on the (pretty grandiosely named) podcast Titans of Text the other day.

In the interview, which are run by people from the MUD Coder's Guild (a great initiative!), I talk a bit about the history of Evennia, the text-based multiplayer game engine I'm working on, and go into some various technical aspects of the engine as well. Check it out and support the podcast!

https://www.titansoftext.com/4

09 May 2019 6:38pm GMT