Code Monkey home page Code Monkey logo

agony-engine's People

Contributors

fossabot avatar scionaltera avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

agony-engine's Issues

Implement GET from container

As a player I would like to retrieve an item from a container that I have placed it in so that it is not lost to me forever. The container must be in my inventory.

Syntax:
GET <item> <container>

Try out AWS Code*

Investigate leaving Codeship for AWS CodeBuild, CodeDeploy and CodePipeline so that there is a complete continuous delivery pipeline that will automatically push freshly baked Docker containers to the ECS cluster.

Create wilderness tiles in forest tileset

The map generator will need a selection of a few "regular" tiles to choose from when it flood fills the map. In this case, something like this should work:

  • Clearing - very sparse trees here
  • Light - a few trees, but movement is easy
  • Medium - a good selection of trees
  • Dense - many trees, movement is slowed

Create impassable tile in forest tileset

Create a tile flagged as IMPASSABLE. These will be generated around the edges of the map to make it feel less square. Description doesn't matter since nobody will ever see it.

Configure name of MUD in application.yml

The name of the MUD should be configurable in application.yml.

All places that show the MUD's name, such as the FTL templates, need to be updated to pull a value from the configuration.

ReaperService can't reap link dead players

It used to work before I added inventories... 🙄

Now when it tries to delete the Actor it's still associated with a GameMap and can't be deleted. This relates to #91 and the solution to that issue should also solve this one.

Basic audit trail for Actors

Add some fields to Actor to be able to track changes more easily.

  • creation time
  • last modified time <-- PostgreSQL should auto-update this, don't rely on code
  • who created it <-- "System" or the account name of who created it

All these fields should be NOT NULL, so the migration will have to fill in values for existing rows.

Framework for communication channels

Right now SAY is the only channel for communication and it's kind of hacked in. What we really need is channels as a first class thing with options for how messages are distributed. The set of channels I have in mind is:

SAY -> send to everyone in the same room as you
SHOUT -> send to everyone within a radius of 5(?) rooms
GOSSIP -> send to everyone in the game
TELL -> private message to one other person
ADMIN -> jury is out on the name, but only send to other admins (when there is such a thing)

Ideally the channels should be configurable somehow. Doesn't necessarily need to be via commands inside the game at this point, but through Spring config or a repeatable Flyway migration would be fine.

Idle timeout

Somewhere in the production infrastructure there's an idle timeout. Not sure what is doing it yet, but after about 10 minutes the client's connection to the broker gets disconnected. :(

Implement PUT command

As a player I would like to put an item into a container so that I can better organize my inventory. The container must be in my inventory.

Syntax:
PUT <item> <container>

Block TAB on client

I keep hitting tab accidentally because I'm so used to tab completion in the shell, and it ends up kicking me back to the account screen. Not sure if it's possible, but it would be good to block the TAB key and just swallow it for now so you don't accidentally get out of the input box. (In the future I'd like to implement tab completion for commands, but that's out of scope for now.)

Implement VERSION command

A simple command that displays the current software version and possibly the server start date, which you can get from ApplicationConfiguration. Would be helpful to tell whether your change has been deployed yet on the server you are connected to.

Implement GIVE command

As a player I would like a way to give an item directly to another player so I don't have to drop it on the ground, which could give an unintended player the opportunity to grab it.

Usage:
GIVE <item> <target>

Message notification in browser tab

It would be really handy if the title in your browser tab would update when you receive messages while the tab is out of focus. That way if someone logs into the game and talks to you while you're looking at something else you'd have a quick notification to let you know to check the game.

Need a play button

When you create an account or just log in the workflow takes you inside the game at the end. If you close your browser and come back, your session will recognize you and keep you authenticated but there is no way to get back in the game. There ought to be a "Play" button next to the "Logout" button that takes you back in, since you're already authenticated.

Save your inventory when you QUIT

As a player I want the items in my inventory to be there after I quit and return to the game so I don't lose my stuff.

The game currently makes you drop all the items in your inventory on the floor before you leave the game, because the GameMap that represents your inventory is cascade-deleted from the database when your Actor is deleted. Instead, it would be great to be able to keep your inventory around and reattach it when you come back to the game.

Fuzz generated map edges

"Fuzz" the edges of generated maps by filling in some random IMPASSABLE rooms to obscure the square shape of the map for players. Don't create any inaccessible pockets and don't block off too much of the map.

Connection to ActiveMQ closes unexpectedly

This seems to happen a lot, both on the real game and locally, and it's pretty annoying. The client is good about reconnecting automatically but I'd like to actually get it fixed. I suspect it's actually a bug in ActiveMQ or SocksJS rather than something wrong with the MUD's code. There might be something I can fix through configuration in ActiveMQ, or something like that though.

I'm opening this issue to track any information leading to an answer.

Refactor Bitfields to EnumSets

It turns out that Java has a mechanism to handle flag values, and I didn't have to roll my own. Here are the various pieces that need to be addressed:

  • WearLocation and BodyPartCapability are already enums but the places where we're using my Bitfield need to have that replaced with EnumSet.
  • Storage to the database can be achieved by storing long values (as we already do) and Apache commons EnumUtils in an AttributeConverter. The Apache EnumUtils appear to use the enum's ordinal which is not a great idea, but my current implementation is doing that too. Best case would be to move to a new solution that doesn't use ordinals. Instead, the enums could possibly define their own integer constants between 0 and 63.

ChRoNoN's answer on this SO question is a pretty interesting approach.
See also KeaganFouche's answer here.

Bind players as noun tokens

The second word in a sentence must be a noun (until we add modifiers). Refactor the command interface to accept the noun binding result rather than a list of tokens.

Since we don't have items or NPCs yet, nouns must refer to players. So... try to bind the nouns to players.

  • The binding result should tell us whether the player is currently logged in or not.
  • The search algorithm should prefer logged in players over players that are not logged in.
  • It's not possible now, but in the future it will need to be able to prefer players that are in the same room over those that are elsewhere. Be sure to design the code with that future enhancement in mind.

Now the game will support very simple commands like: LOOK SCION

Consider the following situation carefully: it would be very cool if a command could specify as part of its contract what it wants as arguments. What if the HIT command could specify HIT <logged in player in same room> instead of only HIT <player> as its valid syntax? Then the command parser could not even bother invoking the command if the noun didn't match precisely, and still generate a useful message like "Sorry, that player isn't in this room." instead of building all the error cases into every command. Doing this right will eliminate the need to write thousands of lines of boilerplate error checking.

Command binding

Bind the first token in each input sentence to a command. Once the binding is complete, the command executor should pass the remaining tokens into the command to be executed. If the binding fails to look up a command, show the user a helpful error message.

If a user's input has been broken up into multiple sentences, each of those sentences should begin with a verb: GET SWORD THEN EQUIP SWORD THEN KILL GOBLIN -> GET SWORD. EQUIP SWORD. KILL GOBLIN.

The output from binding should be a new object that either contains or copies the value of the original token and contains a mapping to the command that should be executed. Later on, binding for nouns will also generate result objects (mapping tokens to the various objects in the game world) so when designing these objects, consider extensibility as an important factor.

Prevent characters from entering the game twice

It is currently possible to log two sessions in using the same Actor.

The desired behavior is that logging a character in from a second session will "reconnect" it, closing any prior sessions. That way if your session does become disconnected you can connect back to it, but you shouldn't ever be able to get your character into the game more than once or control the same character from more than one client.

CloudFormation templates for AWS

Note to myself to rewrite my AWS infrastructure for the ECS cluster that runs The Agony Engine in CloudFormation, and make it available with the project.

Create command infrastructure

Commands have two parts:

  • An interface with a method that is called when a command is invoked.
  • A metadata class that maps a name to a command executable.

The interface should, for now, accept a list of tokens as arguments. We have a little bit of a bootstrapping process we have to undertake here. The current interpreter tokenizes and does some basic sanitization of input. A later stage will map the tokens to parts of speech (verb, noun, modifier, etc.) and attempt to validate against a simple grammar. Then (still before the command has seen it) it will bind each token to an object. Verbs map to commands, nouns to objects in the game. Modifiers help guide the object lookup for nouns (i.e. "GET BLUE GEM" or "GET BEST SWORD"). The binding process will have to either wrap the tokens or convert them into different objects and the result of that is what would eventually be passed into the command. We don't have any of that yet, so for now we'll just take the tokens directly and refactor later.

The metadata allows for multiple names to be mapped to the same executable code. A good example for this would be the movement commands (N, E, S, W, U, D). There are a bunch of these commands but the code that runs could be exactly the same, just with a parameter to specify which direction the command moves you in. There's no reason to copy/paste six different classes for this. Another example could be HIT vs. KILL vs. ATTACK and any other synonyms for "try to kill the target". We probably want to map all those words to run the same code but we don't want to duplicate the code; just the pointer to the code.

Metadata should also let us sort the commands, first by "priority" and then alphabetically. We want "n" to map to NORTH, not to NOD or NAP. Eventually it will also be nice to have those mappings be configurable by admins inside the game at runtime, but that's out of scope for this ticket.

Update to dependency checker v3.3.1

The build now has a message saying the dependency checker is out of date. Need to update the version and verify that the build still works with the new version.

Annotation for commands to check capabilities

In MoveCommand the first thing it needs to do is check the Actor to see if it is capable of walking. This check is going to be repeated frequently for all sorts of things as more and more capabilities are added. It would make a lot of sense to turn it into an annotation on the command's invoke() method. That way the InvokerService could perform the check in a generic way before ever invoking the command method.

Bind string tokens

Make a token representation of a quoted string so that a command may implement invoke(QuotedString) instead of just invoke(). This will work toward supporting commands like SAY, TELL and GOSSIP.

Impose order on invoke() selection

You can see this happen with PURGE: there are two implementations of invoke() and it's supposed to try binding your arguments to each implementation, find the best match and run that.

What actually happens is it tries to run both and displays both an error message and the successful output from the command. Less than ideal.

Another more subtle issue here is that there's no way to tell PURGE that (for example) you'd prefer it try to bind to items in your inventory before items on the floor. What if there were items that match your argument in both places? Which one is it going to choose first? The answer right now is that it's completely arbitrary and up to Java reflection to decide!

So there are two acceptance criteria for this issue:

  • Invoking a command should never produce two distinct sets of output (e.g. an error message and a success message glued together). Only show an error message to the user if none of the invoke() implementations could successfully bind.
  • There needs to be a way for the programmer to specify which order the implementations are tried. Some commands will have variations based on whether a target is worn, in your inventory, on the ground, or possibly somewhere else in the game. You will almost always want the command to do the smallest-scoped search first and progress to the largest scope last - both for efficiency and because that's what would generally make the most sense to the player.

Better error reporting

Currently if a command throws an exception there is no feedback to the user about it. They don't even see a new prompt, so it's unclear what happened or why. We probably don't want to show the text of the exception, but we should at least show a message saying something like "Oops! Something went wrong!" and give them a new prompt so they know they can still type commands.

Create start location markers

Create a new entity StartLocation to mark a room where players may enter the game. Alter the code that puts players into the game so that it finds a usable StartLocation and puts the player there rather than using (0, 0) on the default map.

Duplicate players in world

During development I have noticed that when I kill the MUD, recompile and start it back up I can get duplicates of my character in the world pretty reliably.

I believe this is due to a problem with the code in WebSocketResource.onSubscribe() that tries to determine whether an Actor is already in the game or not. It tries to match the STOMP username and session ID, but when the game has been stopped and restarted the STOMP session will have been recreated.

Without taking a closer look I'm not sure what the exact remedy is for this, but I suspect it will involve storing a little more information somewhere so we can find our Actor in the world more reliably. Maybe keeping the ID from the PlayerActorTemplate on the Actor would do the trick.

Command list on website

It would be nice to have a dynamically generated list of all the commands on the website so that visitors could have a reference they can look at in a second window rather than having to type HELP all the time in the game.

What could be really nice is to make every command object implement an interface that specified some methods like getDescription() that the website and the HELP command could use to generate helpful documentation for each command. That way the text of the documentation for every command would live right there with the code and it would be easy to keep up to date. It would also be the same inside the game as it is on the website, and only ever need to be updated in one place.

Update gradle version

I've only been using Java 8 so far for this project, but @jayyargh reports that the gradle version doesn't like Java 10. Looks like the problem can be solved by updating to the latest version of gradle.

To do that, we just need to change the version number in gradle/wrapper/gradle.properties to the latest version. However, once that is changed the build needs to be tested thoroughly to make sure it still works reliably and that none of the gradle plugins become broken.

Create basic map generator

Create a simple map generator that will generate a map of random size, between 5 and 30 rooms in width. Flood fill all the rooms with a randomly selected WILDERNESS tile from the map's tileset.

Account screen should indicate in-game characters

The account screen right now just has a Play button for every character. When you have an active session open and you look at the account screen from another browser it should change the Play button to an orange Reconnect button.

Website traffic tracking injection

As a MUD operator I need a clean, configurable way to inject some HTML or Javascript to collect metrics about who visits my site so I can tell whether I'm getting visitors or not.

For example, a lot of people will want to use Google Analytics on their front page. AddThis is also very popular, and there are many other options. Some MUDs will want to use more than one provider.

Implement AFK command

Running the "AFK" command will toggle a flag true or false, stored on your Connection object.

When the flag is false, everything is normal.

When it's true, you'll see a flag in LOOK and WHO that says [AFK], very similar to the [LINK DEAD] flag. It's just there to show other people that you probably aren't looking at the game right now. For the time being it has no other effects, but in the future it could be used to protect you from unexpected combat or other dangers while you're away from the keyboard.

CI/CD Webhooks

My "production" deployment of The Agony Engine lives in an AWS ECS cluster, is automatically built by CodeBuild and deployed by CodePipeline. Every time a PR is merged into master it triggers a build and deploy. The current behavior is that when the container you are connected to is brought down in the rolling deploy you get disconnected (that could potentially be resolved in the future) and it happens very suddenly, without any warning.

What if there were REST endpoints exposed on the game that GitHub and AWS could hit to produce notifications? "Code has been merged." "A build is starting." "A rolling deploy is starting." etc. So that inside the game you'd get messages to indicate that you may be disconnected soon and that new features are inbound.

Certainly not a big deal right now when there aren't any players and there isn't any game, but even if the disconnections got fixed it might be cool as a player to know when new features are being deployed.

ArgumentBindings should understand color tags and other punctuation

If you put a color tag in an Actor name it makes it very hard to interact with that object. The command interpreter should be smart enough to ignore color tags so you can still interact despite all the colors.

Some permutations to consider:

[red]red balloon
red [red]balloon
[dred]red [red]balloon
colorful [red]b[dyellow]a[yellow]l[green]l[blue]o[dmagenta]o[cyan]n

Other punctuation, symbols and emoji should get filtered out as well since the command interpreter will filter them out of the input tokens. For your consideration:

> l
(0, 2) Armory
Weapon and armor racks line the walls, and a practice dummy stands forlornly in the
corner.
Exits: east south
"armor" is here.
 
> get arm
No "target in same room" found for word: ARM
 
> get "&quot
You get "armor".

Deploy with a real message broker

Using the in-memory message broker we are limited to running only a single copy of the game at a time. With multiple copies they would each have their own in-memory simple message brokers that don't talk to one another and would be unable to route messages between the instances.

To get multiple instances to talk to one another we need a stand-alone message broker such as ActiveMQ or RabbitMQ (not sure if SQS will work?) that all instances can register with and route messages through.

Some additional key points:

  • It must be possible to use the simple in-memory message broker for local development and simple deployments of the MUD. Configuration profiles maybe?
  • Using AWS "native" products would be preferable to standing up a message broker in ECS, but that may not be possible.
  • Fully document how to configure both in-memory and stand-alone message brokers on the wiki.

Multiple tabs reconnect as the wrong characters

If you are connected with two different characters in two browser tabs and restart the server, both tabs will automatically reconnect but they will both reconnect as the same character. The first tab in will be in a broken, un-playable state.

The expected behavior is that each of the tabs reconnects to the character it was originally connected as.

I have not yet verified that the behavior is the same on the public version of the game, but I would expect it to do the same thing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.