Code Monkey home page Code Monkey logo

td's Introduction

Bearded.TD

Build & test GitHub release

Bearded.TD is a tower defence game developed by paulcscharf and tomrijnbeek.

Screenshot of the game

The game

Systemic

TD offers an abstract level of simulation of various systems. By cleverly using the features each of the six elements offer, players are able to use the interactions to their benefit... or their detriment if they are not careful.

Procedurally generated

No game in TD is the same, as both the map and the enemy waves are fully procedurally generated.

Multiplayer friendly

TD was built with multiplayer front of mind. The game can be played in co-op mode with multiple players controlling the same faction. Other game modes are planned for the future to allow for a wide variety of gameplay experiences when playing together with your friends.

Moddable

The content for TD is defined in an extensible way, allowing you to design new combinations of behaviours for towers, enemies, or even entire game modes. Just create your own mod folder and start modding.

Built in custom engine

The game is built on top of a custom game engine, using OpenTK for basic windowing and OpenGL/OpenAL bindings. Much of the common code can be found in the MIT licensed open source libraries under the beardgame organisation on GitHub.

Development

The game is still under heavy development, and features should not be considered final or representative of the final game. A new release is published roughly each month, and the latest version can be downloaded from the GitHub releases page. Feel free to open issues with any feedback.

td's People

Contributors

dependabot[bot] avatar paulcscharf avatar tomrijnbeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

bubdm

td's Issues

Make mod loading not depend on file io

Instead, the mod loading context or something similar should return data streams for all content 'files'. This way mods can be stored as archives.

To enable reloadable shaders, mods would also be able to return 'file watchers' that could detect the change in a file. An archived version could create a dummy that never changed.

Interestingly, this could allow for changing shader code directly inside the game as well by having a mod loaded out of memory instead.

Unload mods when shutting down GameRunner

Most of the resources are managed and we don't care, but we do have to clean up all the OpenGL stuff:

  • surfaces (includes index and vertex buffers)
  • textures (not actually stored anywhere right now, so this needs some more thinking)

Probably have to turn the PackedSpriteSet into an interface so that we can hide more stuff in them, like the cleanup itself perhaps. Then we could also remove the funny IHasSurface interface (in place of maybe another one that serves the same purpose but does it better.

Automatically generate network serializers for readonly structs

We have a couple of places where we want to pass a set of parameters over the network. So far we have GameSettings, and now we're adding WaveScript as well. We want to pass the entire object across the network. We have wanted to avoid just passing in the struct and letting the network layer figure it out, so we tend to copy all the properties of the struct into a serializer. This leads to a lot of duplication, and we may forget to sync a newly added property.

My suggestion would be to automatically generate serializer classes. For example:

[GenerateNetSerializer]
readonly struct WaveScript {
  public Instant Start { get; }
  public instant End { get; }

  [DoNotSerialize]
  public TimeSpan Duration => End - Start;
}

Could generate something along the lines of:

sealed class WaveScriptSerializer {
  private Instant start;
  private Instant end;

  public void WaveScriptSerializer() {}
  public void WaveScriptSerializer(WaveScript original) {
    start = original.Start;
    end = original.End;
  }

  public void Serialize(INetBufferStream stream) {
    stream.Serialize(ref start);
    stream.Serialize(ref end);
  }
}

The easiest would be to wait for Rider to support generated classes so it doesn't show up as a compile error if you reference them in code. That way, you could just manually instantiate the serializer where you need it. It should work in my EAP version of Rider though, but I think it currently also needs a very specific combination of .NET frameworks so... I will stuck to doing this manually for now, and we can move it to codegen later.

FinishBuildingConstruction command does not find building

Happened on client. I think the building was destroyed by an enemy while building clientside and not server side? Or maybe I'm imagining it.

   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Bearded.TD.Game.GameState.Find[T](Id`1 id)
   at Bearded.TD.Game.Commands.FinishBuildingConstruction.Serializer.GetCommand(GameInstance game)
   at Bearded.TD.Commands.Serialization.SerializerExtensions.Read[TObject](ICommandSerializer`1 me, NetBufferReader stream, TObject context)
   at Bearded.TD.Game.ClientDataMessageHandler.Handle(NetIncomingMessage msg)
   at Bearded.TD.Networking.NetworkInterface.ConsumeMessages()
   at Bearded.TD.Game.GameRunner.Update(UpdateEventArgs args)
   at Bearded.TD.UI.Controls.GameUI.Update(UpdateEventArgs args)
   at Bearded.TD.UI.UIUpdater.Update(UpdateEventArgs args)
   at Bearded.TD.TheGame.OnUpdate(UpdateEventArgs e)
   at amulware.Graphics.Program.run(Double targetUpdatesPerSecond, Double targetDrawsPerSecond, Double maximumFrameTimeFactor, Boolean dontOverrideFps) in C:\Users\amulware\git\td\libs\awgraphics\src\amulware.Graphics\Window\Program.cs:line 279
   at amulware.Graphics.Program.<>c__DisplayClass22_0.<Run>b__0() in C:\Users\amulware\git\td\libs\awgraphics\src\amulware.Graphics\Window\Program.cs:line 211
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Fix lobby concurrency crash

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: index
at at System.Collections.Immutable.Requires.FailRange(String parameterName, String message)
at at System.Collections.Immutable.Requires.Range(Boolean condition, String parameterName, String message)
at at System.Collections.Immutable.ImmutableList1.Node.ItemRef(Int32 index) at at System.Collections.Immutable.ImmutableList1.get_Item(Int32 index)
at at Bearded.TD.UI.Controls.LobbyControl.LoadingBlueprintsListSource.CreateItemControlFor(Int32 index)
at at Bearded.UI.Controls.ListControl.createCellControl(Int32 index, Double top, Double bottom)
at at Bearded.UI.Controls.ListControl.createCellIfVisible(Int32 index, Double bottom, Double top, Double height)
at at Bearded.UI.Controls.ListControl.addCellAbove(Int32 index, Double bottom)
at at Bearded.UI.Controls.ListControl.addCellsUpwards()
at at Bearded.UI.Controls.ListControl.Reload()
at at Beard

Broken pathfinding

Pathfinding doesn't always propagate correctly. Cause as of yet unknown.

It is reproducible at 5b223df using game seed: 138415339 on a perlin map generated at size 42. For the map position check below.

For the full debug info in this case, check below.

Water rendering improvements

8476c61 adds a pretty good start at a proper water shader.

Here's a list of things that can be improved:

  • remove hardcoded surface light
    • either replace by rendering water surface to same normal map (will have to see how this looks) or by a second normal map (that'll make rendering lights a lot more expensive, but the same could be used to light smoke and similar effects!)
  • consider actual geometry surface normal
    • this isn't even passed into the shader right now, by considering this, larger-scale waves would look better
  • consider flow
    • also not passed into the shader yet. once we do that, we'll have to smoothly transition from a regular surface to a flowing one, and back without strange artifacts
    • this might require even more texture samples, but hopefully not too many
    • also, since we project caustics onto the terrain below, we might run into issues having properly flowing caustics at shallower angles, this needs testing
    • alternatively, if flow adds foam or a generally more turbulent surface, maybe the caustics will hardly be visible and they can remain non-flowing
  • sort out tile edges
    • this is a big problem with deeper drops, if the difference is too high, we gotta make a clear cut in the geometry and use a different effect/shader for the flow (or maybe.. we can just use the same shader, where flowing 'down' is the final interpolated form of regular flow, or some not-too-special case)
    • using more detailed geometry, or tesselation might be needed
  • handle shallow water better
    • prevent flickering, maybe even update flow to not spread as fast and thin (add min flow?)
  • check on performance of generating geometry on the GPU
    • consider geometry shader, or tesselation, or a static mesh where only the actual fluid data is injected

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.