GithubHelp home page GithubHelp logo

chris3606 / gorogue Goto Github PK

View Code? Open in Web Editor NEW
489.0 489.0 30.0 7.86 MB

.NET Standard roguelike library in C#. Features many algorithms and data structures pertinent to roguelike/2D game developers, specifically designed to be minimally intrusive upon the developer's architecture.

License: MIT License

C# 98.38% Batchfile 0.01% Shell 1.18% Python 0.16% PowerShell 0.27%

gorogue's People

Contributors

arxae avatar chris3606 avatar davidfidge avatar fcheadle avatar masonwheeler avatar thraka avatar

Stargazers

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

Watchers

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

gorogue's Issues

Split TranslationMap and LambdaTranslationMap

Currently, TranslationMap and LambdaTranslationMap require specifying both "get" and "set" methods. In many GoRogue algorithms, including pathing, fov, and sense-mapping, "set" functionality is not required, rather only "get" functionality. In these cases it would be convenient to specify translation methods as lambda methods, but only specify the needed "get" functionality, rather than writing unnecessary set functionality (particularly since set functionality may be difficult or lengthy to implement in certain map architectures).

Thus, I propose that it may be beneficial to split TranslationMap into two classes, TranslationMap and SettableTranslationMap. TranslationMap would implement IMapView and require only the "get" function to be specified, whereas SettableTranslationMap would extend that to implement ISettableMapView and require the "set" functionality. Similarly, split LambdaTranslationMap into LambdaTranslationMap and SettableLambdaTranslationMap. These would more closely mirror the IMapView vs. ISettableMapView distinction made in GoRogue, and prevent the need to specify both "get" and "set" functionality to take advantage of the convenience of lambda functions.

Any feedback is welcome! :)

Change Rectangle Naming Conventions

Properties in rectangle currently expose some very poorly named values, that can lead to confusing code. See issue #43 for one example. Proposal is as follows to correct:

  • Rename MinCorner to Position, since it represents the "position" of the rectangle (we define rectangle position by its minimum extent)
    • Add MinExtent/MinExtentX/MinExtentY properties that are identical to Position/PositionX/PositionY, to be consistent with below convention
  • Rename MaxCorner to MaxExtent, since it is talking about max extent of rectangle.
    • Rename MaxX/MaxY to MaxExtentX/MaxExtentY.
  • Add Coord size Property that returns (Width, Height)
  • Remove Rectangle.NewWith... functions, as the names are long and do not cover plausible use cases accurately. Replace them with with the following functions, all of which return new Rectangles with the specified changes made:
    • Move(int, int)/MoveTo(Coord) to move position
    • MoveX(int) to change X-value of position
    • MoveY(int) to change Y-value of position
    • Translate(int, int)/Translate(Coord) to move by given dx/dy
    • TranslateX(int) to move by given dx
    • TranslateY(int) to move by given dy
    • CenterOn(int, int)/CenterOn(Coord) to move center point
    • SetMinExtent(int, int)/SetMinExtent(Coord) to expand/shrink the rectangle to have the given MinExtent.
    • SetMinExtentX(int)/SetMinExtentY(int) to change the min extent values separately.
    • SetMaxExtent(int, int)/SetMaxExtent(Coord) to expand/shrink the rectangle to have the given MaxExtent.
    • SetMaxExtentX(int)/SetMaxExtentY(int) to change max extent values separately.
    • SetSize(int, int)/SetSize(Coord) to change the width/height of the rectangle to the specified values.
    • SetWidth(int)/SetHeight(int) to set the width/height separately to the specified values
    • ChangeSize(int, int)/ChangeSize(Coord) to change size by given dx/dy values
    • ChangeWidth(int)/ChangeHeight(int) co change height by given delta-values

RadiusAreaProvider Feedback

I have no problem with the technical workings of RAP - in fact it seems to work great, and it's significantly faster than I expected. There is an issue with communicating the intent and design of the class, and there is an important (or at least it seems to me) missing element in the library that would grease the wheels of this class and provide that extra boost of utility for many of the other functions.

The documentation for RAP recommends holding onto a single instance of the class for as long as possible due to heavy costs under the hood. However, it's not really clear why that is unless you glance over the source of Positions(). When you're in the editor, Positions() looks a lot like the kind of property that just returns a field. Even the documentation only just barely hints that it is the main workhorse of the class. A simple renaming to CalculatePositions() or similar would be a good start. The documentation should not be expanded, really, but it should be adjusted. Specific recommendations would be mentioning the current radius and how that would differ from a new radius. There's a consideration to moving some of the comments from class heading into the method heading.

Again, it's just about communicating the design and intent of the class. Renaming the function and/or splashing a few adjectives around in the documentation would make it a lot more clear. Having a few unusual things like Coord.Get() and RAP.Positions() is not a problem at all if you put them front and center, with respect to documentation.

As for other related feedback, one thing that I've found myself doing with high frequency, particularly in relation to RAP, is dealing with the issue of unique Coords. I was just looking at my overall code today and found that a surprising amount of it was devoted to carrying around containers of Coords and doing lots of checks on them, particularly whether a Coord was already present in the container. You can imagine the relation here to RAP.

In some instances, this has actually caused fairly extensive utility-work where I'm hunting for C# solutions to dealing with uniqueness. All experienced C# developers have probably run into List.Contains( item) eating up every CPU cycle in the western hemisphere, but it was a new thing for me. I eventually settled on a "good enough for now" HashSet solution and will probably have to revisit that in the future when the demand for cycles expands.

It didn't occur to me until today that avoiding this type of distraction is exactly the reason I favor this library so much. I'm not sure whether this fits with your vision, but it seems to me that a container optimized specifically to carry around and manipulate Coords could provide a lot of leverage to the library.

Thanks very much for all your work on this library; I find myself eagerly anticipating upcoming features and docs.

Method parameters with map generation

If you do a map with the cellular automata, you pass map, then the rnd gen as the second parameter, but if you use the room generator, the first parameter is the map, but the rnd gen is the last one.

I understand that since you can omit the random number generator, it has to be the last parameter.
What about adding several method signatures (with and without the rnd gen) to try to keep the parameters in the same order?

Add LambdaMapView and SettableLambdaMapView

Currently, we have LambdaTranslationMap, which allows translation function(s) to be specified as delegates/lambdas. Since many translations to values GoRogue algorithms want to deal with are extremely simple, this can provide much convenience. However, the obvious use predicates on the user's map architecture consisting of something like an array of Cell instances, where there exists a single type representing each specific location. If a map is represented in a different way, for example as an array of terrain and spatial maps containing other entities, defining a Cell type of some sort that is constructed in demand may not be difficult, but it may be preferable to define a custom IMapView implementation.

In these general cases, I propose the addition of LambdaMapView, which would simply take a Function<Coord, T> parameter, that would take a location and produce the corresponding value of type T. This functions similarly to LambdaTranslationMap but doesn't take the extra type, and therefore could be used to gain the convenience of lambdas in those situations where that extra type is not conveniently available.

Wiki Updates/Modifications

This issue is largely a staging area for discussing wiki updates/completions as work is being done.

Currently, we have the following list of things to be completed.

  • Bugfixes
    • Dealing With Directions: Image in Standard Mathematical Coordinates section displays incorrect coordinates in bottom row
    • Missing Table of Contents on numerous pages
    • Rectangles page inaccurate after major refactor.
  • Completions
    • Line Creation - Incomplete.
    • Effects System - Partially incomplete, not linked -- Need to add OnExpire event setup
    • Field of View - Incomplete
    • Map Generation - Incomplete
    • Map View System - Incomplete
    • Pathfinding - Incomplete, potentially pending merge of PR #25
    • Random Number Generation - Mostly incomplete, unlinked. What does exist needs to be rewritten to reflect RNG rewrite.
    • Sense Mapping - Incomplete
    • Spatial Map - Incomplete
    • Utility/Miscellaneous - Incomplete.
  • Structural Changes/Additional Updates
    • RLNET Project Setup may stay but isn't used (and may not be at all) in wiki demos, unlike what is on the wiki at the current time. If it ends up being used everything works -- if not, page needs to be updated.
    • BoundedRectangle should be added to the coordinate plane docs, and can be referenced from MapView
    • A SadConsole Project Setup page should also be included, since SadConsole is commonly used.

To Fix:

  • Updates for new map gen syntax
  • Broken images in getting started (?)

A-Star Ties and Weights/Penalties

I'm unable to make sense of the Pathing/Astar.cs tie-breaker (i.e. how it chooses between nodes of equal weight). There are some remarks in the comments, but they are fairly vague. In cases like this, a full explanation often will not fit snugly into a method comment (I can definitely understand that). Nonetheless the tie-breaker plays a significant role in the macro-level behavior of entities following A* paths, so it's a consideration for something to mention on the wiki in the future.

The A* implementation seems very optimized as far as performance goes, so I would guess that it is in a finalized or near-finalized state. I'm wondering if there is something in it that prevents a weight map in addition to the walkability map as an input. Glancing over the code, at line 130:

nodes[index].F = (float)_distanceMeasurement.Calculate(start, end); // Completely heuristic for first node

You could seemingly just add an indexed weight from an ArrayMap to this line and it would carry on none the wiser. I could be missing something or there could be other considerations I haven't thought about.

Just for 100% clarity, in this implementation weights would instead be more like fixed penalties (i.e. instead of multiplying anything, they would be additive). So if you have a tile type that is weighted '0', the implementation would carry on as usual. But if you have a tile type that is weighted '2' or '11', then those values would be conceptually added to the distance away from the starting point.

/edit - I was just refreshing myself on the various documentation available and noticed that weighted A* is planned on the roadmap.

Split RNG into Generators and Distributions

Currently, GaussianRandom simply uses a System.Random instance to generate random numbers, even though it is in fact a distribution that could use any rng as its source.

Thus, distributions could potentially be separated from random number sources themselves -- Sources, such as .NET Random, would implement an IGenerator interface. Distributions, would take an IGenerator instance to operate on, and would implement an IDistribution interface.

There may be significant overlap, however, between IGenerator and IDistribution, in terms of functions defined -- another option is both distributions and sources implement a single IRandom interface, just distributions take sources in the constructor. However this could create some confusion and lead to difficulty implementing custom distributions and/or generators. Furthermore, serialization (a future feature) doesn't make sense for distributions, only generators.

Documentation for Rectangle.Center is misleading

Documentation states that center will be rounded down to the nearest integer in the case that there is not an exact integer center point, however the current formula rounds up. This may actually be desirable, as it produces mathematically correct rounding results without actually calling Math.Round, however in this case the documentation needs to be modified. Otherwise, the formula should be modified to (MaxExtent-MinExtent)/2.

RandomRoomsGenerator is generating rooms that are too small

Try running RandomRoomsGenerator.Generate on a decently-large map, with a large maximum number of rooms and a roomMinSize value of 4, and then have a look at the output that gets produced. You'll see a lot of rooms that are only 2 or 3 cells wide/tall.

With larger minimum sizes, the effect can still be seen, with rooms frequently being produced up to 2 cells below the minimum in one or both dimensions.

This appears to be happening inside the createRoom method, where a 1-cell border on all sides is being excluded from the generated room. Presumably this is to give rooms a wall, so you don't end up with one room pressed directly against another with nothing to separate them, but since a bool has no way to distinguish between a room wall and the dungeon interior, there is no way to make this distinction apparent, and instead you just end up with rooms that are smaller than the minimum for no easily-apparent reason.

If establishing the border wall is necessary, the internal logic should add 2 to the randomly-generated dimensions in order to account for it, rather than producing rooms that are too small.

Add missing Coord overloads in LOS

Most functions that take a position take either x and y, or a Coord to represent the position. LOS function take only x and y, not a coord.

AStar ShortestPath Exception

if the map have open borders (Walkability = true), ShortestPath try to find neighbours on the edges and raise an out of bound exception.
I dont know if it is intended so you force to use a map with borders or if it is a bug in the find neighbours methods that should test the bounds
Or maybe I dont use it the good way ;)
Thanks

Add Missing ToString Functions to Data Structures

Some data structures, to include Coord, Direction, and Rectangle provided ToString functions that allow printing the data structure and retrieving a sensible value -- however, many, to include AdjacencyRule, Distance, Radius, MapArea, and SpatialMap, and potentially others do not. These should be provided for consistency in many cases.

Implement (Customizable) Key Bindings and Action Abstraction

Methods here will depend drastically on how we want to handle UI navigation, etc. However, eventually we will likely want to make key bindings for things customization. Tied to this, particularly if menus use similar navigation (up/down/left/right) as options, it might be useful to use InputStack as a "translator" that translates keys into "actions", eg. NumPad8 OR K = Action.UP. Already there is a good bit of duplicate code between targeting and player movement to this effect.

Switch FOV/SenseMapping ResistanceMap Values?

Currently, SenseMap/FOV take as a parameter an IMapOf, where the values range from 0.0 to 1.0.
A value of 0.0 represents 0 resistance to light (a fully transparent cell), and 1.0 represents full resistance to light (a fully opaque cell). Would this make more sense the other way around, where 1.0 is full transparency (100% of light gets through), and 0.0 is fully opaque (0% of light gets through)?

Rectangle.Positions returning wrong positions

Rectangle.Positions is returning positions in range (0, 0) -> (Width - 1, Height - 1), instead of range (X, Y) -> (MaxX, MaxY).

This is unintentional, as it should return all positions it actually represents, not positions "relative" to the rectangle.

Bounded Rectangle Area Doesn't Resize by -1

Tested extensively. Area will not resize by -1 if using MaxCorner arg. Any other value will result in a resize however.
Example code:

 public void UpdateCameraSize(int dx, int dy)
        {
            Camera.Area = Camera.Area.NewWithMaxCorner(Coord.Get(dx + Camera.Area.Width, dy + Camera.Area.Height));
        }

Differentiation of Coord as position vs Coord as vector.

In most functions provided by the library, Coords are treated as a positions. However in some (Coord math operations, some bearing functions), a Coord is treated as if it is a vector (eg, a measure of magnitude of X and Y values).

While the core data of a vector and coord are the same (x and y value), the way they are interpreted is different, and as such it may be prudent to attempt to differentiate between the two use cases.

One possible solution is to create a class Vector that does nothing more than inherit from Coord to act as a "typedef" for those functions that intend a Coord to be interpreted as a vector, eg.

class Vector : Coord { }

This would allow vector values (which are still generally fairly likely to fall within the range of pooled Coords) to take advantage of Coord pooling, however would allow a potentially confusing implicit conversion from Vec to Coord, and allow a Vec to be used anywhere a Coord can be used (not intentionally desireable behavior).

Numerous other solutions exist, from separate classes that define implicit/explicit conversion operators, to attempting to utilize a base class, or simply ensuring documentation explicitly states what the Coord is being interpreted as.

Any feedback/suggestions are welcome.

Walkable start and end locations during AStar pathing?

Would GoRogue's AStar pathing benefit from a flag that paths with the assumption that the two endpoints (start and end) are walkable, regardless of what the walkability map reports?

This is something I have seen in other pathing algorithms, that is currently only possible in GoRogue by manipulating the walkability map given to the algorithm.

Add Viewport/SettableViewport

This would effectively be a wrapper around an IMapView/ISettableMapView, that represents a sub-section of the original map, and does relative to absolute coordinate translation when accessed.

This could be useful for representing a camera, or for things like GoalMaps where calculating a GoalMap on a large map can be expensive.

Add angle-restricted light sources to SenseMap

Angle-restricted shadowcasting is implemented already in FOV, and RIPPLE is possible. Thus, adding angle-restricted light sources (directional lights) to SenseMap should be fairly simple.

Provide RNG overloads

Because a default rng cannot be a compile-time constant, overloads should be provided of all functions that take RNG's that default to the default RNG. Furthermore, since this has to be the case anyway it might be useful to allow the default RNG to be set by the user, although it definately should still default to its current value.

Unit Test Non-Manual Output Tests

Many of the complex algorithms/data structures, have unit tests marked "Manual", meaning there are no assert statements, and the output is meant to be observed manually. This could be remedied if nothing else by observing correct output, recording it in a file, and reading back in and comparing for unit tests, to ensure they are all automatic.

Rectangle should be immutable

Rectangle is a struct (value-type), and therefore should be immutable to avoid accidentally modifying temporary boxed values.

Convenience functions such as Rectangle.ChangeCenter could be provided that take a center point and return a new rectangle modified to have that center, to allow for convenient modification.

Add type conversion from Rectangle to MapArea

Add a conversion that converts a Rectangle to a MapArea instance. This would also allow providing an "exact union" function returns a map area containing exactly the locations in either of the two rectangles. (Effectively GetUnion but returns exact MapArea as opposed to a rectangle that is a bounding box).

Add more ways to create Rectangles

Although a rectangle can be defined in a number of ways, the number of constructors for Rectangle is somewhat limited. This is due to the fact that many ways of defining a rectangle have overlapping function parameter prototypes; for instance, a rectangle could be defined as 4 integers; these 4 integers could represent (x, y, width, height), or (minExtentX, minExtentY, maxExtentX, maxExtentY). Because there is no way to differentiate between these methods in the constructor, currently Rectangle "chooses" one (x, y, width, height), and allows the other to be defined by specifying 2 Coords (maxExtent, minExtent).

While this certainly is functional, in certain cases it could be undesirable. From a "clean-code" standpoint, being forced to create Coords in-line with function calls can make code harder to read (and is in general something the library tries to prevent requiring). In addition, using Coords in general outside the pre-allocated range of Coords, if done very frequently, could cause performance degradation due to constant garbage collection/reallocation. Obviously one could be careful not to use a constructor for a Rectangle that requires a Coord in this case, however the math involved, while simple, could prove inconvenient.

Therefore, I propose the addition of either static functions of the Rectangle class, or static functions of some other class RectangleCreators or some such, that simply take parameters and create an appropriate rectangle. These are effectively constructors, with the advantage of being able to change names of functions to differentiate between identical prototypes CreateWithSize(int x, int y, int width, int height) vs CreateWithExtents(int minX, int minY, int maxX, int maxY).

This would require no modification of existing constructors (since they do cover many common cases), and would allow some convenience in cases where the parameter specification method doesn't precisely match an available constructor prototype.

Change Direction functions to return Coords representing neighbors instead of directions

Currently, we have functions like CardinalsClockwise, DirectionsClockwise, etc. that return 4 or 8 directions in a particular order. The most common/main use for such a function is presumably to visit all neighbors of a given Coord:

Coord start = Coord.Get(1, 2);
foreach (Direction dir in Direction.DirectionsClockwise())
{
    Coord neighbor = start + dir;
    // Do things with the neighbor.
}

Under these circumstances, it would seem to be more beneficial to instead have functions that take a Coord and return neighbors of that Cood:

Coord start = Coord.Get(1, 2);
foreach (Coord neighbor in Directions.Neighbors(start))
{
    /// Do things with neighbor
}

In this case, perhaps such a series of function would also be more logically located in the Coord class, rather than the Direction class.

Any thoughts, or possible cases where functionality might be removed by making this change, are welcome in the comments.

Pull neighbor-related functionality into its own class structure AdjacencyRule

Functionality pertaining to neighbors, iterating through directions/coordinates of neighbors, etc. is currently spread out over many overloads of functions in Coord and Direction. Considering it is possible (and frequent, in internal GoRogue implementations) to map Distance and/or radius types to their appropriate neighbor functions, it would be beneficial to pull this functionality out into its own class structure, similar to Distance. In this manner, function code could be consolidated, and much clutter and unnecessary spread removed.

This also makes a case for conversions from Radius to Distance, Radius to AdjacencyRule, and Distance to AdjacencyRule implicit, reducing many confusing overloads from these types of functions.

Add missing overloads to functions taking Coord

Most functions, if they take a Coord as a parameter, also provide an overload taking an x/y integer value. Some do not follow this convention. Rectangle does not for reasons of conflicting overloads, however other have them simply missing, including ITunnelCreator, SenseSource constructor, many functions in Coord, Direction.GetCardinalDirection/Direction.GetDirection, most SpatialMap functions, RadiusAreaProvider constructors, and Rectangle functions (contains).

These should be added to ensure interface consistency.

Add Read-only interfaces for classes where they are missing

Many classes, such as SpatialMap, offer the AsReadOnly() function, that returns an interface declaring only the read-only functions/properties of the class. This can be useful for exposing it, even if modification is encapsulated. Other classes do not include it. Some implement IMapViews which can serve this purpose, but in the case of FOV for example, this doesn't work because FOV exposes things such as NewlyUnseen, NewlySeen, etc. Such classes should certain expose AsReadOnly functions.

IEnumerable<T>.ToList() Duplicated from System.Linq.Enumerable

GoRogue's extension method ToList performs the same function with the same name as the function in System.Linq's method, and thus should be removed.

Likely to be modified in the 1.3 release to avoid breaking backwards compatibility, particularly during 7drl timeframe.

BearingOfLine produces values without respect for Direction.YIncreasesUpwards flag

Documentation is worded in such a way that it implies that UP is to be considered 0 degrees. If this is the case, this would imply that results should be in-line with what is considered an upwards direction. Since the dx/dy definition of the Direction UP changes based on the value of Direction.YIncreasesUpwards, by definition the direction that is considered to be UP by BearingOfLine should match the UP Direction instance, however it does not.

BearingOfLine should be modified to account for the YIncreasesUpwards flag.

Consider upgrade to .NET Standard 2.1 (C# 8.0)

This could lead to efficiency improvements, particularly in Rectangle by using the new in keyword from C# 7.2. In addition, default interface implementations and the potential for things other than extension methods in C# 8.0 would be a godsend for the IMapView interface and other similar interfaces.

Unity has already stated that they will be updating to a .NET Standard version that will support C# 8.0 (see here), as will most other platforms.

Unfortunately, this excludes .NET Framework, although since virtually every graphics-related library that I'm aware of that supports .NET Framework currently either has moved or is moving to .NET Core. See link above for subset of features that could be used in .NET Framework.

This couldn't happen until the full release of C# 8.0 in 2019 anyway, so consequences involving support for .NET Framework can be re-evaluated at that time.

.NET Core Support

Hi,

I just learned about your project yesterday so apologies if this is a dumb/answered question.

I'm working with .NET core, and the wiki page for RLNET project setup suggests:

Furthermore, although it is possible to recompile RLNET to work with a .NET Core project, [...]

This seems a little misleading. It looks like RLNET (aside from being a "dead" project with the last commit circa 2016) depends on OpenTK. From what I can surmise from this issue regarding OpenTK support of .NET Core, this is something that will happen in the upcoming (OpenTK 4.0?) release.

Meanwhile, some generous person created an OpenTK .NET Core nuget package here. While not official in any way, I'm guessing it works.

Piecing this all together, I can assume that someone tested GoRogue with a custom build of RLNET that uses the above-mentioned package of OpenTK on .NET Core.

Assuming that's true, would it be possible to put together some sort of package (eg. zip file, starter project) that links all these things together? I really don't want to build RLNET from scratch (especially since it looks abandoned), and if I can link some version of GoRogue that uses the homebrew version of OpenTK on .NET Core today, but switches to the official OpenTK 4.0 once it's released and stable (without having to recompile by hand), that would save a lot of effort.

Or is my entire premise wrong, and .NET Core isn't really supported with GoRogue today?

How to generate multiple distinct paths between rooms?

If you generate a set of rooms with the RandomRoomsGenerator, and then use a standard connector to connect them, you'll end up with a system where, if understood as a graph where each room is a node and each corridor is an edge, the graph is purely acyclic. (ie. there's only one path between any two given rooms, and if you .)

If you try to run a connector again, it will detect that the entire area is one big region and there's nothing that needs to be connected.

In popular roguelikes such as ADOM and NetHack, the room graph is not acyclic; most levels contain multiple ways to get between certain rooms. This makes the levels generated here look weird.

Is there any simple way to create cyclic paths among the rooms generated? Right now, the only good alternatives I can think of involves something convoluted like generating a room set, cloning it, applying a different corridor generator to each copy, and then ORing them together, and that just seems messy...

Error installing the package on Linux x64.

Morning.

I am a Linux user and when I try to install the package on Linux through NutGet I get the following output per console.

Could not install package 'GoRogue 1.0.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

I have also tried to install the package in Mono. Net 2.0 as Mono. Net 4.7.1 and I still get the same error.

Lines

The list of coords returned by Lines.Get(start, end) should be ordered from start to end instead of ordered in ascending order or maybe it could be an option
thanks

Unification of return interfaces.

We have some classes returning List, some returning IEnumerable -- particularly with respect to Coord. These should be unified to likely use IEnumerable whenenver possible.

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.