• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

SyncViews

Members
  • Content count

    217
  • Joined

  • Last visited

Community Reputation

734 Good

About SyncViews

  • Rank
    Member
  1. I dont understand how you get the noise peak at a desired location? I did consider using just noise for the entire thing (instead of a specified x,y,size) but had issues avoiding lots of "low yield" patches (I somewhat worked around it by a fairly expensive second pass that eliminated any patches with less than a certain total, or less than a certain cell average) but then had even more trouble making it interact well with other map features (e.g. in a flat desert plenty of ore spawned, but in mountain, water, etc. areas many areas are blocked)
  2. I spent some time trying to implement this. Ran into a problem with borders between "seams" as you described it, which I partially solved by considering all lines (weighted sum), rather than just the nearest, but the lines still really stand out. Maybe I did fully understand. [attachment=35243:gd-near.png] [attachment=35242:gd-segments.png] Using a sum of multiple lines instead to get a weight. But wondering how to hide the circle and line edge gradients. [attachment=35244:gd-sum.png]     Still working on the perturb idea to see if I get anything good. But as I understand it, instead of doing something like "cellWeight = f(distanceToCenter(x,y)) * noise(x,y)" you are suggesting to do like "cellWeight = f(distanceToCenter(x + noise(x,y), y + noise(x,y))" where "f" is some simple function to map a weight to an ore value (including cutoffs for full-ore and no-ore cells).
  3. I am trying to generate an ore deposit centred approximately on a specific location with an approximate size and ore values (in the central area of the deposit). The game is a 2D tile game and id be looking for the deposits to be roughly areas from 20x20 up to 50x50. Each ore tile has its own quantity (say up to 5000, or some patch specific "quality") for more variation and smoother transitions, but I want most of the falloff from around the fields peak to 0 to be around the edge. void generateOrePatch(World world, int x, int y, int size, int quantity) { ? } The problem I am having is how to effectively generate these ore tiles without some obvious geometric shape.   For example I tried multiplying some noise (e.g. Simplex) with a linear weight from the edge to the centre of my desired deposit. But of course the result is that while I get some variation within the deposit, the circle itself is obvious. [attachment=35170:ore-values-simplex.png]   Ideally id like to generate with a lot of variety things like this one I did manually. [attachment=35171:ore-values-paint.png]
  4.   I've also worked on some projects that set a 150 character line length and then made use of it almost every line, which I found way more annoying than a "short" length, since the seemingly ever longer names for things meant most lines did in fact use that length and then still wrap, to the '(', '=' or other "alignment" symbol half way across the screen.   The people I joined there just had a single code window on a 1080p screen. I on the other hand generally have the solution explorer (or similar) panel, wide enough to fit whatever deep folder structure there was, then to have 2 side by side code windows (e.g. the cpp + hpp, or the structure + builder, and such like). I found that extremely disruptive as it messed up my entire workflow.   Id go for a short length any day.           The formatting or the need for a doc comment that stated nothing useful?   I've taken a disliking for coding styles that then require a large amount of additional code/text to not tell me anything a couple of words could have. Even if the basic starting point was an OK formatting (e.g. doxygen, javadoc, etc. for comments, always use braces, description names, etc.).   The idea of a formatted documentation block that stands out I quite like, its just when there these massive blocks repeating the same thing (and who even reads those later anyway?).   There also often a source of doing 3 or 4 (slow) rebuilds because the style checker found a full stop in a comment out of place. I then very frequently see simple things with just plain wrong comments and names because someone copy pasted to avoid typing so much.   e.g. builders that just set simple fields because of an immutable object rule, and 4 parameter constructor rule. Maybe OK so far if dont have C++ "const" in most languages, but then the field in the actual object, the getter in the object, the field in the builder, the getter in the builder, and the setter in the builder all get full doc comments fully describing the field. /**Set the name value used to build MyObject. * @param value fieldWithLongName value to set. Must not be null and be at least MyObject.MIN_FIELD_WITH_LONG_NAME_LEN and ... and ... * @return This MyObjectBuilder instance for chaining. Not null. * @throws NullPointerException if the name was null. * @throws IllegalArgumentException If the name did not meet one of the other requirements. */ public @NotNull MyObjectWithAReallyLongNameBuilder withFieldWithLongName(@NotNull final String value) throws NullPointerException, IllegalArgumentException { Preconditions.checkNotNull(value); Preconditions.check... this.namefieldWithLongName = value; return this; } And generally such strict rules just seem to be a massive waste of time. I still come across lots of horrible code that was written to the letter of the style guide / checker. e.g. the ability to combine long repetitive names and lambda/stream features to "avoid branches" for the complexity checker to make a 10 line by 100 column solid block, then repeated 10 times for each of the different fields/arrays being processed.
  5. I am working on creating some C++ templates to ease bind functions and member functions to a dynamic system (Lua/Python/console/CLI/etc.), avoiding large numbers of hand coded wrappers / specs.   In the past I have either just gone with doing it by hand, or some sort of code gen. Which always seems to end up being a pain, since I still had a separate "specification" file, and it added build requirements like having a recent version of Ruby/Python/whatever+libs and poor/nonexistent IDE support.   So want to see if its possible in pure C++ now with variadic templates.   e.g. in the simple case of just dealing with strings (e.g. for a command console), to be able to do something such as this: typedef std::vector<std::string> Args; std::string to_string(float x); //plus normal and custom overloads template<class T> T from_string(const std::string &str); //with specialisations float add(float a, float b); float mul(float a, float b); void kill(Entity *entity); FunctionTable functions = { {"add", &add}, {"mul", &mul}, {"kill", &kill} }; I came up with a solution to have a template function that can call another function pointer type, although that results in me storing both pointers, and for member function pointers I cant safely cast them to/from void*/anything, so ended up using memcpy.   I understand that it is possible to pass a function pointer, member function pointer, or member variable pointer directly as a template argument, thus becoming part of the template itself. But can this be made to work with a pointer of unknown type? It seemed the template had to declare each component explicitly, e.g.: template<MyReturn (MyClass::*Func)(int, float)> Method wrapper(); wrapper<&McClass::foo>(); //OK, but not generic template<typename Func> Method wrapper(); wrapper<&McClass::foo>(); //invalid template argument for 'Func', type expected Prototype code: //This was only way I found to unpack each element of an array-like container into a normal function call //Its just to give a parameter pack such as "0, 1, 2, 3" for a 4-arg function template<size_t...> struct Indices {}; template<size_t N, size_t... Is> struct BuildIndices : BuildIndices<N - 1, N - 1, Is...> {}; template<size_t... Is> struct BuildIndices<0, Is...> : Indices<Is...> {}; template<class... Args, class Func, size_t ...indices> std::string do_call_inner(Func func, const std::vector<std::string> &args, Indices<indices...>) { //call by unpacking args and converting each from a from_string specialisation return to_string(func(from_string<Args>(args[indices])...)); } //Another wrapper to add in BuildIndices, since needed Args separated in the function signature template<class RetType, class ...Args> std::string do_call(RetType(*func)(Args...), const std::vector<std::string> &args) { if (args.size() != sizeof...(Args)) throw std::runtime_error("Invalid argument count"); return do_call_inner<Args...>(func, args, BuildIndices<sizeof...(Args)>{}); } template<class Func> std::string wrapped_call(void *storage, const std::vector<std::string> &args) { return do_call((Func)storage, args); } struct Method { template<class Func> Method(Func f) : storage(f), caller(&wrapped_call<decltype(f)>) {} std::string operator ()(const std::vector<std::string> &args)const { return caller(storage, args); } void *storage; Caller caller; }; And of course overloaded functions wont work with this approach. But is there any reasonable solution for that? I am thinking ill just carry on hand-coding the overload resolution for those.
  6. Well tried a few things to have chunks with a level of detail based on distance (merging 2x2, 4x4, etc. tiles into a single tile), but avoiding visible seams is proving an issue. Solved it to an extent by adding vertical edge pieces going down to the lowest height, so at least no gaps to see through. Seems like a bit of a hack though.
  7. Well yes, hadn't really though about the size maths since each vertex is small lol. Well guess the low-end and laptop GPU's wouldn't be able to render so much in detail anyway.   The heights can be changed slightly at runtime though. e.g. to flatten a bunch of tiles for a building or road. But I guess maybe for such things its OK to just create a brand new buffer and throw out the old one, more or less what I expected a write-only map/unmap to do behind the scenes.     But still, is such a triangle list really the normal approach all these games took/take? Found lots on the things various FPS/third-person games take for indoor areas or comparatively small outdoor areas (to only render the rooms the player can see, and simply lower detail meshes with distance for independent objects/entities), but not so much for large outdoor areas, even though games have been doing it for years while keeping pretty good detail for close terrain.   Is the "100x100 chunks but keeping the borders full detail" a suitable idea, or should I have a better look at algorithms to deal with borders, since I don't really need full detail "lines" joining distant regions? Obviously putting a low-res region directly next to a high-res one while doing nothing else is liable to leave gaps along the edges where the gradient changes.
  8. Not right now, although its not an immutable buffer, maybe I need to play with the creation flags. At some point id want to update sections where the world gets changed, but all I did in my test was Map/Unmap the constants buffers to take an update camera matrix, cleared the render target, a few Set* calls and the single DrawIndexed. Not even got textures in play there yet.   CPU usage was around 0.5% in task manager (i7-4790K), although didn't run the profiler on it.   EDIT: Actually changing the usage flag was a lot faster, guess the driver put it somewhere the GPU cant access efficiently before, even though i never made it CPU readable. I also only just realized that such a vertex buffer is still 100's of megabytes, depending on how much data I need in a Vertex, so I guess that is not a particularly good thing either.
  9. You can translate all the drag and drop parts directly to GML pretty easily. This means you can teach all the important concepts (objects/classes, events, variables, conditionals, inheritance, etc.) within the "simple" drag and drop environment.   GML is however able to go far beyond what those drag and drop actions can do practically. You can also combine both, create reusable scripts, or even create custom drag and drop components which can make for a good middle ground, and a good introduction to GML.   Personally many years ago I found that a really useful feature, because I was able to basically learn GML that way. e.g. I had a space invaders like game in pure drag and drop.   But then I wanted more complex logic like intelligent turrets that could select the best target, and have some chance of hitting fast targets. Or particle effects for explosions, impacts, etc. rather than simple pre-made animated sprites. Or the ability to load, edit and save levels using text files, not just pre-made game maker rooms, so started to include GML scripts. In the end I had nearly the entire game in GML.   This wasn't out of some drive to learn GML specifically, but as a means to add the features I desired to my game, and not be limited because no drag and drop item existed to do what I wanted.
  10. Seems to be the vertex shader limiting it. If i intentionally transform it out of view, so nothing for the pixel shader, the frame rate is the same. The 1000x1000 test mesh I created is already in world space. The vertex shader just multiplies the vertex position with the camera matrix and copies the rest of the fields over (normal vector + colour for now). Also occurred to me that making a triangle strip is a lot harder than on first consideration since differnt tile types have different textures/uvs, and the edge tiles are multiple textures. Smaller chunks with culling is something I intend to do, along with fog, for larger map areas , but was hoping with modern gpu's could have somthing near this in view at once. Could maybe do a level of detail thing by having say 100x100 chunks but keeping the borders full detail? Not sure how hard that is to create along the edges. Seems fairly complex along with optimising flatish, single texture regions. Will have to see what tessellation can do. Not something I have used. Not sure how instancing is meant to work? Seems unlikely and hard to determine tiles with the same textures and geometry even if i restrict the height map to 8bits? Still feeling this is getting overly complex though and missing a simple solution, or at least a well known one to implement that has already gone through the process of figuring out the ideal approach, and what optimidations are worthwhile. I can think of many older games that did this predating modern GPU's and features.   edit: shader is just this right now. //vertex shader Output main(Input input) { Output output; output.pos = mul(input.pos, viewProj); output.normal = input.normal; output.colour = input.colour; return output; } //pixel shader float4 main(Input input) : SV_TARGET { float lightIntensity = saturate(dot(input.normal, lightDirection)); float4 colour = saturate(input.colour * diffuseColour * lightIntensity); return colour;// * texture2d.Sample(samplerState, input.uv); }
  11. I am looking from moving from a pure 2D map to making it 3D with a height map, currently using D3D11. My initial goal being something like Stronghold or Railroad Tycoon 2, keeping my existing 2D assets, but I want the scope to replace those with 3D ones and full camera movement later (shallow camera angles being the main issue, due to the resulting long view distance).   The problem I am having is determining the best/correct approach to render this terrain. A quick test showed me that just having a 1000x1000 tile 2xtriangle quad list doesn't perform (4 million vertices, 6 million indices, and about 50fps on my AMD 7870 with just that one DrawIndexed D3D11 call).   I have various ideas for enhancing this, of various complexity, but don't really have any idea which is a suitable one, or if I am missing something simple on this matter.   Convert the list to a strip. I expect this to be a fairly good gain, with around half as many vertices for the vertex shader, and will likely do it. Need to work around some complexities (e.g. Stronghold style cliffs, and vertex texture fields), and it doesn't really seem enough by itself, would only expect at most that 2x performance boost.   At longer distances from the camera, only render a single quad for multiple tiles (average height, most common tile texture, etc.). This however seems to force me to re-create the mesh each frame, and need a way to deal with the edges between detail levels (to support a shallow camera angle, since some tiles are very close, and others distant)? Done/seen this in plenty of games/engines with independent meshes, but not encountered this single mesh issue before (in all of them I did technical stuff with, I found they used pre-made low detail versions of the models to just swap between).   For larger maps, making sure to only ask D3D to draw ranges I know are in the view area, either with a dynamic mesh, or just making multiple Draw calls for the needed subsets. Essentially this is what I have always done in 2D with a dynamic vertex buffer, but there I only had at most maybe 100x100 on-screen tiles so only a small per-frame buffer, and its trivial to determine the viewable area (x/y tile rect for a simple for loop).
  12. Yes, so while in that project we do have schema's and one of the Java things to validate and load an XML into a generated class, nearly every element and attribute is "optional" in the schema, and there is no effective validation of file inheritance/extension related things.       Wasn't aware of XmlPlus. I suppose may be able to get LGPL to work, if it is practical to make it into a self contained DLL without any inclusion of the main code. I think a commercial licence would be a hard sell in most of the cases I have run into this issue though, since only a small number of custom data files/schemas. Also doesn't look like they solve the inheritance/extension issue.       Is there any compelling reason to use SQL as the primary data definition format? I have used SQL in many context's, but only as something for the software to manipulate. It seems a big ask for people (often non-programmers) to define content directly in SQL, especially since you end up with a fairly nasty foreign key structure for when things contain any kind of list/collection.
  13. And also remember that especially outside games, many users are not able to elevate. Software will be installed by IT admins (possibly in some bulk capacity, I am not up to speed with the Window's domain admin stuff) and after that it needs to work correctly in a multi-user environment. They really dislike having to do special installs for software that does not quiet work like that, and only developers can get local admin.   I suspect there are other requirements they have, like not being able to put pwned.exe/dll in some directory using a visitor/guest/contractor login and have your piece of software execute it next time someone tries to use that conference room.
  14. So what aspect exactly?   Normally when there is many levels,  I see stats implemented via some sort of formulas, which you can play with to get the results you want. Some stats may be linear, others exponential.   e.g.:   You can apply such things to both players and NPC's, and to randomly generated weapons/items. NPC level is selected based on player level, possibly with some random variation, and possibly including difficulty setting.   When there is fairly few levels (e.g. specific skills you spend skill points on, rather than or in addition to a "level" that buffs everything), I tend to see games just explicitly pick values for each level. Sometimes a skill level will have an entirely new effect compared to the one before it.     It mostly just a question of deciding what you want level's/skills to do, then playing it a lot to try and make it balanced/fair.
  15.   Well, you would still have a simple interface with a memory pool approach. I can't remember the exact steps off hand, but it should be possible to make new/delete directly use your custom allocator. If you do that you even get rid of this "recycleEvent" thing and can just let the default delete keyword, constructors and destructors take care of it. In some places you might even find you can just put the event on the stack if it is not queued and handled asynchronously, so you can do "MyEvent evt(...); handler->handleNow(&evt);"   EDIT: From a quick looked based on memory and some searches, you should be able to do something like this if you want a global allocator. If you don't want a global allocator, I think you can do some clever things with how you have the new/delete, or you could just make the alloc/free part of that EventHandler class, and use a small header template with argument forwarding and placement new/delete to construct and destruct the actual objects. You either would not be able to do "delete p; delete[] arr", or would need to insert a pointer back to the EventHandler in the memory layout for operator new to use.    I am hoping this code is mostly correct, but it also mostly from memory You can still put events directly on the stack, as globals, inside other classes etc. They will be allocated/deallocated according to the normal rules in that case. I found on MSVC 2015 that for new[], delete[], that while new[] was given the total size of memory, that delete[] seemed to get given what looked like sizeof(T). Not very helpful... As a result I had that bit of logic to track the actual allocation size. If you are using multiple threads, the alloc/free methods need to be thread safe. This may be possible using the available atomic operations, I have no thought about it. The alloc function may choose to allocate lots of internal memory at once. e.g. instead of allocating say 32byte objects one at a time to pool, it might opt to get take a 4KB page from the OS and use that, instead of making lots of small long-lived allocations that may fragment the C++ heap. The alloc function may also decide to group different sizes into "buckets". Eg. everything from 65 to 128 bytes might just use a single 128 byte pool. Objects/Events of the size naturally use the same pool regardless. It should be possible to avoid the use of std::map/std::unordered_map. If you implement with a small number of buckets, a simple integer search is very fast. If you choose the bucket size carefully, you might be able to "jump" directly to the right one using simple arthritic. /**@brief Minimal base for all event types.*/ class Event { public: static void* operator new(size_t size) { return genericPoolAllocator.alloc(size); } static void operator delete(void *p, size_t size) { genericPoolAllocator.free(p, size); } static void* operator new[](size_t size) { auto realSize = size + sizeof(size_t); auto tmp = (char*)genericPoolAllocator.alloc(realSize); *(size_t*)tmp = realSize; return tmp + sizeof(size_t); } static void operator delete[](void *p, size_t size) { auto realP = ((char*)p) - sizeof(size_t); auto realSize = *(size_t*)realP; genericPoolAllocator.free(realP, realSize); } Event() {} virtual ~Event() {} private: }; class KeyEvent : public Event { ... }; class Nested : public Event { Event a, b; }; struct Container { Event a, b; }; int main() { { std::cout << "Event" << std::endl; Event *evt = new Event(); delete evt; } { std::cout << "KeyEvent" << std::endl; KeyEvent *evt2 = new KeyEvent(); delete evt2; } { std::cout << "Event array" << std::endl; Event *evt = new Event[100]; delete[] evt; } { std::cout << "Nested" << std::endl; Nested *evt2 = new Nested(); //single custom allocation for outter object delete evt2; } { std::cout << "Container" << std::endl; Container *evt2 = new Container(); //doesnt use custom allocator, because container does not delete evt2; } { std::cout << "KeyEvent stack/auto" << std::endl; KeyEvent stack; //just lives on the stack } }