Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411576 Posts in 69386 Topics- by 58444 Members - Latest Member: darkcitien

May 04, 2024, 11:40:01 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsForced 2 - A rogue-like with deckbuilding! (A few keys in the newest post)
Pages: [1]
Print
Author Topic: Forced 2 - A rogue-like with deckbuilding! (A few keys in the newest post)  (Read 1054 times)
Xul_solar
Level 0
*



View Profile WWW
« on: May 27, 2015, 08:46:23 AM »




Forced 2: The Rush is a rogue-like deckbuilding game that combines the best of skill-based action gameplay with tactical deckbuilding.

Sounds weird? It's pretty awesome. You smash bosses, upgrade your character, fight with a companion at your side and select between a variety of characters. The game can be played very casually or be perfected by the nerdiest of tacticians. Though I'll admit... Right now it is very very difficult!

                                                                                       
What the heck is Forced 2? Forced 2 is a randomly generated rogue-like. What we want to achieve with this game is a combination of awesome tactical deckbuilding gameplay and fast-paced action gameplay. We have a range of heroes (though currently only two are in, with one coming very soon) that all differ a lot in playstyle. This fact combined with the deckbuilding and randomly generated levels and skill trees means that there basically is an endless amount of ways to play and experience the game. Currently the game flow is: Build a deck for your champion > Enter a campaign with a champion > Beat as many matches as you can (each match consists of 8 arenas with random events) > earn gold > buy upgrades in your randomly generated skill tree > complete the campaign or die > gain profile progression (xp/quests) and unlock new cards > rinse and repeat with your improved cards.

So what's next? Right now, we are working super hard on making Forced 2 awesome. We don't want this game to be great. We want it to be amazing. Like, really, really, REALLY good. Currently we are in alpha on Steam, and the input we get from our community is a huge help to us. We are working super agile, so we are patching new updates to the game every single week. This week it will be alpha 20! This way of developing is fantastic, because it allows us to implement the feedback from our community on what's almost a day-to-day basis.


Why a devlog? Basically the intention with this devlog is to share our development, and to get input from awesome people. It is super important to us to be a transparent company, and you can follow our day-to-day Trello right here if you'd really like the nitty-gritty details of how we work. Currently we are a team of 18 people, and if there is something specific that you think would be awesome to have us post about (3D art, lighting, programming, design processes, our thoughts on extra-terrestrials or something else), just ask and I will try to find the right guy or girl to do a post here!

Forced 2? What's Forced 1? well, thank you for asking! Forced 1 was a tactical co-op game for up to four players that we released back in 2013. This might be a good time to introduce you to the team as well! We have a pretty weird story, and the first game was made with blood, sweat and tears. See the picture below:



Screenshots below are already a bit outdated, but I hope they will give you an impression of the visual style of the game:




If you want some updated visuals check out this video:

https://youtu.be/9D9-Pq0SKgc?list=PLVmM0UVcquYLAE5schkE_c_TpciAN-wHt

Some of the cards


Some characters and enemies

« Last Edit: May 28, 2015, 06:53:44 AM by Xul_solar » Logged

Xul_solar
Level 0
*



View Profile WWW
« Reply #1 on: May 28, 2015, 06:53:07 AM »

We just released Patch A20, which features hero number 3, Stormbringer.



You can find the notes here.

Also, if someone wants to try out the game, you can find 3 keys below. Please only take one, so the keys goes to people that reads this post. Also, please write which key you grab, so other people won't try in vain. Thank you  Gentleman

E354V-IXYXC-28BPQ
5734A-H67RB-000AB
AETK2-INMK0-9E8B5

In not so long we will do a post about how we are handling branches and sharing in our team, using Plastic SCM.

Thank you for reading : )
Logged

Bambino2012
Level 0
***



View Profile
« Reply #2 on: May 28, 2015, 07:10:07 AM »

Impressive story you have here Smiley
I got the first key E354V-IXYXC-28BPQ.

Good luck guys !
Logged

Xul_solar
Level 0
*



View Profile WWW
« Reply #3 on: May 29, 2015, 12:47:15 AM »

I know that a lot of games on here are small projects, so I’m hoping we can pitch in with some of the solutions we have used to make game development work in a bigger team.

Today's post is about one of the tools that we use that allows us to keep track of our code and assets in our projects, Plastic SCM. Version control systems are an integral part of game or any software development process. They allow many users to work on the same project at the same time, with minimal conflicts. There are many options available for version control in the world and it can be hard to figure out which is the best to use.

Before we picked up Plastic SCM we were using a private git system, with the freely available software SourceTree. While git is a great version control system for text files (code files), it struggles greatly with binary files, such as models or textures. While using git our project was around 25 GB, and a full download of the project from git could easily take a few hours. Aside from issues with handling binary, managing a private git repository often proved painful, with many hours of troubleshooting when the repository became corrupt, for one reason or another. We also had numerous stability and usability issues with SourceTree.


A screenshot of the Plastic SCM branch explorer, here you can see our latest patch branch.

When the problems with git finally became too much we started to look elsewhere for version control systems, thankfully we stumbled over Plastic SCM. We have found Plastic to be extremely user friendly, fast and stable. The user interface for Plastic SCM is fantastic and it is much more user friendly and feature extensive than SourceTree was. Updates from an empty repository takes half an hour or so for our over 40 GB project. While I would often fight with git for hours in a day when problems arose, Plastic has more or less run without server interaction for over 8 months. Plastic is also very good at merging conflicting changes between team members, we mainly use this for text files and the three way merge supported by Plastic has been rather good to us. Plastics branching system is great, and works very similar to git, so we were right at home with the system with minimal introduction.


A screenshot of the Plastic SCM recent changeset query, we are at over 6000 commits and going strong!

All in all Plastic SCM has allowed us to not have to worry much about version control, and instead focus on making a great game. As source control is used all the time by all members this is quite a blessing. So if you are working on game projects out there, it would be worth checking out Plastic SCM, as it handles the day to day of game development much better than git.
Logged

panbake
TIGBaby
*


View Profile
« Reply #4 on: June 01, 2015, 05:50:09 AM »

Rune: BetaDwarf's Visual Scripting Language for Unity3D

Everyone at BetaDwarf is hard at work producing Forced 2 : The Rush, which is currently in alpha. In the debut title Forced a visual scripting language was created to allow designers to set up world events for in game actions such as creatures spawning, or cutscenes. Based on the usefulness of this tool, it was decided early on in Forced 2 that a visual scripting language was needed. These types of tools are great in that they allow designers and other non programmer members of the team to rapidly create logical content. We primarily use the system to allow designers to create abilities that players and enemies can use to battle each other with, however it's utility can extend far beyond that, as we have attempted to build a very open ended system that allows content creators to add new functionality (with a little programmer help of course) to the system.


Graphs, nodes, pins and variables oh my!

When researching the field of visual scripting for games, we looked at one of the best around, Blueprint for Unreal Engine 4. This gave us some great inspiration and helped formulate the basic system we constructed. All of the logic for an ability, or simply an assembly of logic is represented by a Graph. Inside a graph we have a collection of Nodes, each node is comprised of Pins, which can either be of Flow or Variable type. Flow pins connect to other flow pins and drive the logic forward, variable pins are used for variable passing and are essentially the parameters to the method calls represented by the flow pins. We also have variables in the graphs, these can be Graph Variables, which are local to the graph, and each variable pin has a backing variable which stores the intermediate values, which could be used anywhere by the graph.

Below you can see an example of a (section of) graph



The above graph is a section of our Boomer Boom ability. This ability causes an explosion to go off right before the death of the enemy. As you can see we have an event system that we hook into, so OnStart is called when the graph is ready to go, similar to the Start method in MonoBehaviours. When this event fires, we receive a call and spawn an explosion Subgraph, of type Instantiated Subgraph, which is an object that is instantiated and immediately after a graph is applied to it. We have two other type of subgraphs as well, one is called Function Subgraph, which is a graph that is run inside the current graph. The other is a Target Subgraph, which is a graph applied to a specific target, we generally use these for buffs in Forced 2.

I've also included another, slightly more complex graph that shows off our GetterNodes, these are not called by flow, instead they are called at the point they are used by a flow. You can see this graph below, for our Earth Elemental Boss' Level 2 Shard Blast. As our graphs and nodes are often changing you can see one result of this in the graph, the red nodes indicate nodes which have been rendered obsolete in code, and therefore should be changed to use the most up to date versions. However the old versions usually work fine as the graph was initially made with them in mind.



How it's put together

Something that we found was possible early one was the ability to hot load code. We write all of our code in C#, which with a little trickery can be compiled dynamically in Unity using CodeDomProvider. To do this we write all of our code dynamically for the graphs. When a user has reached a point of completeness they are satisfied with they can call for a graph build. When the graph builds we write out code corresponding to each node. This can be done while a game is playing, and you can reload an assembly at runtime. However this is not done for finished abilities, these are written out to a .cs file and included in the project. This has the benefit of being extremely fast, as the generated classes themselves are relatively simple assembly of method calls invoking other C# scripts. I believe this is a benefit to using our system over perhaps a Lua based approach, and we have access to all of C#'s great features.

To give some insight into how we write code see the class definition below. This definition is for one of our node classes, of the type FlowNode. We use attributes to mark up input calls, and output calls. Input calls are always a function, which can return either void or an IEnumerator (to be handled as a coroutine). Output calls are always of type Action or Action<T1...>, in this way we can have the flows connect using callbacks attached to the actions. This is our way of activating the next node in the flow chain. When the graph is set up, we register the input method call in the graph code with the output Action of the method invoked by the previous node's graph method.

Code:
using System;

namespace BetaDwarf.Rune.Runtime.Nodes
{
    [DisplayName("Flow Utility Nodes/Debug Log")]
    [FlowNode]
    public class DebugLogNode
    {
        [OutputFlow(0)]
        public Action Complete { get; set; }

        [InputFlow(0)]
        public void Print([DefaultValue("Default Debug Log Text")] string text)
        {
            UnityEngine.Debug.Log(text);

            if (Complete != null)
            {
                Complete();
            }
        }
    }
}

With these definitions it is very easy to write out the code, when you know how the nodes are connected and where variable values can be found (as outputs from other nodes or from graph variables). We use reflection at design time to generate the node structure. When a new node is placed in a graph, we reflect the attributes for the selected node type, for example the DebugLogNode seen above. These fill out simple referential data structures, where nodes contain pins, which possibly contain variables. When the code is generated from the in memory node structure, we write calls into the node classes, such as the one seen above.

Below you can see how the flow of the system is constructed in a very abbreviated form. An event is fired by external systems and our listeners cause the event to be sent into a graph, which invokes an input method call. This input method call invokes the InputFlow designated by the node, once this happens it is up to the node class to call an Action which in turn invokes a callback that has been registered with that Action.



An interesting note about variables is that while we can handle most types with normal C# serialization (we tried lots of things here, and this by far worked the best as many other serialization frameworks don't serialize data in the exact type it is, or handle System.Object..Json/Protobuf .NET you disappoint me!) Unity types are impossible to serialize in this way. We circumvent this by maintaining a ScriptableObject instance in a resource folder to serialize any UnityEngine.Object reference used by the graph. It is then simply a matter of loading these resources when the graph is started. The graphs are all MonoBehaviour parented classes, inheriting from a number of interfaces we use to interact with them.

Rune has proven to be an amazing asset for the team, and while it's had it's usability issues, it has allowed the programmers to handle large systems while designers can create content like cards and enemies. We currently build graphs for many things, including our events, giving out cards after arenas are completed even directing game flow. I hope some of you find this interesting and I'm always happy to talk about some of the implementation details if someone is curious!
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic