Giter Club home page Giter Club logo

gm_voxelate's Introduction

gm_voxelate

forthebadge

Welcome to the home of gm_voxelate, the configurable voxel module for Garrysmod.

Links

NO EXTERNAL LINKS RIGHT NOW. A NEW FACEPUNCH THREAD WILL BE CREATED FOR VERSION 0.3.0.

Documentation

See the wiki in the sidebar.

DOCS ARE CURRENTLY OUTDATED. API SUBJECT TO CHANGE AND WILL BE STABILIZED IN VERSION 0.4.0.

Support

  • Windows: ✔️ Works.
  • Linux: ❓ Shaders not tested.
  • Mac: ❓ Shaders not tested.

Bugs

Please report bugs on this repository's issues page!

Building

This is designed to be built with MetaMan's Garry's Mod and Source SDK headers.

It requires a compiler/runtime that supports C++11, which can cause problems on older linux systems.

YOU SHOULD PROBABLY JUST DEBUG ON RELEASE BUILDS BECAUSE THE DEBUG SETTINGS ARE A BIT AGGRESSIVE AND MAKE THIS RUN SLOW AS BALLS AND I HAVN'T BOTHERED TO FIX IT.

Quick Start

THIS GUIDE IS WINDOWS-ONLY. SETTINGS IN THIS GUIDE ARE NOT IDEAL FOR RELEASES.

  1. Clone this, garrysmod_common, and sourcesdk-minimal into the same directory.
  2. Get a recent build of premake5 and put it in your path. Official builds may not be new enough. Contact us if you have issues with this...
  3. Run "gm_voxelate/projects/setup.bat". If you want to use something other than VS2017, just change that part of the command.
  4. Run the shader install script in the repo's root directory.

At this point you should have working VS projects to build the modules with. Upon build, modules will automatically be copied to your garrysmod directory, assuming it is in the default place on the C drive.

If you want lua hotloading, make a .vox_hotloading file as described in that section.

Auto Install

The --autoinstall flag can be passed to premake to automatically copy binaries to the garrysmod directory on each build. Only supported on windows. Assumes the gmod directory is "C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod".

Shaders

This module needs to load custom shaders. Fortunately, compiled shaders are shipped with the module. Unfortunately, they still need to be copied to the garrysmod directory. You can either run "install_shaders.bat", which assumes that the gmod directory is the same as above, or manually copy the shaders from "source/shaders/shaders" to "Garrysmod/garrysmod/shaders".

If you actually want to build shaders, follow the instructions in "source/shaders/readme.txt".

Lua Hotloading

Right now, the Lua portion of gm_voxelate is compiled into the DLL, and is unmodifiable at runtime. This can get quite annoying during extended sessions of modifying the Lua portion of gm_voxelate exclusively. As such, you may enable lua hotloading to ease the burden of development and debugging, which directly reads files from the OS filesystem and loads them into Lua.

Hotloading can be enabled by creating a file in GarrysMod/garrysmod/data with the name .vox_hotloading, whose contents is the path to the lua folder in this repo. NO NEWLINES, NO TRAILING SPACES!

Secondly, you will either:

  1. install gm_luaiox (kindly provided by MetaMan)
  2. compile gm_voxelate with the premake trigger --luahotloading, which will add a dangerous function that can read any file without restrictions

Enjoy!

P.S. fair word of warning: warning

Technical details for using this in a gamemode

IGNORE THIS.

Required libraries/dependencies

We generally don't depend on garryFuncs:tm: You should be good to completely override includes/init.lua, as long as the stock luajit 5.1 funcs aren't modified, and a version of the hook and timer libraries is available for use.

Sub entities

Voxelate engine based

use gm_voxelate:RegisterSubEntity(className,classObj) and it will internally extend the VoxelEntity class

Source engine based

extend voxel_entity

note: both the voxelate engine and source engine entities are mutually exclusive: you may only use one type at a time.

Used In

gm_f1atgrass - Testbed for the module

gm_voxelate's People

Contributors

bmwalters avatar mdfl64 avatar swadicalrag avatar

Stargazers

 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

gm_voxelate's Issues

Config/API Improvements PT 2

  • Change default scale to 40 (Seems like the most sane default.)
  • Push defaults back down into config object on parse, so we don't have to substitute defaults in on the lua side.
  • UpperCamelCase for methods.
  • Improve block type parsing.

Make sure compression buffers are large enough

Compression lib doc says compression buffers need to be at least 5% larger than input. IIRC this is not the case right now. I vote for a good round 9000 byte static buffer but we're going to want to keep track of this in case the chunk size changes.

World generation

Perlin noise?

what do bois

how are we going to handle biomes?

VoxelWorld save format 2

0xmagic header: 0xB00B1352 (boobies 2)

needs to be saved across a bunch of files and needs to be corruption resistant.

Ideas?

World Repeater Part 1: The Misner Cube

The first step is to make a simplified world repeater that only wraps the world back on itself.

This functionality is for testing the more advanced system and will probably not be kept.

Merge Hell

@SwadicalRag I've merged my changes into your branch. No clue if shit works, but it compiles.

In future can we try to coordinate large scale refactors better? In your defense, I had a lot of smaller renames, but the massive amount of changes in vox_voxelworld.cpp paired with the file rename made git angry.

If it's really fucked up I have most of tomorrow free, but I also really want to work on some of my other projects.

Block extra data

This means that each block will occupy more than 2 bytes (when we implement this)

kind of like damage values to store extra data in blocks??? how do we implement this???

how do we implement chests, for example?

Get working loonix build

Guurgle tried this morning and had some mad issues with the sourcenet files. I can probably get shit set up on my server if nobody else wants to do this.

document code better

Currently the Lua API is documented pretty well, but a lot of the module code is terrible.

Finish rewriting the Lua portion of this module

  • Basic lua framework
  • Voxelate networking wrapper
  • VoxelWorld entity
  • Voxel config networking
  • VoxelWorld initial chunk networking
  • VoxelWorld chunk updates networking
  • Other stuff I've missed

Networking Discussion

Old Version

  • Client requests voxel config once it sees a voxel entity.
  • Server sends the config and adds an init task for the client.
  • Chunks are sent in order.
  • Every tick, send up 2kb (maybe a little more) worth of compressed chunks.
  • Once all chunks are sent, send voxelate_init_finish. This tells the client it can start building chunks.

What Needs Changing

  • Do as little shit in Lua as possible. Just make sure chunk data stays away from lua.
  • Just send all configs on player join. Store them in a table so the entities dont need to be initialized. Init voxels when we get the entity or when we get the config, whichever happens later.
  • Don't let the server tell us when we can and can't build chunks. Either set up our own timer to start generation, or only generate chunks with at least 3 neighbors (Need exceptions for very small voxel maps!)
  • Keep a table of which chunks have been networked to each client. Alternate: Track the chunk the player/viewer entity is in and track which changes need to be networked to clients.
  • For finite maps, just keep networking all the chunks, but possibly use one of the two systems above to accomplish it.
  • For infinite maps, only network chunks in a certain range. We can probably just have client render all the chunks it knows about to simplify things.

New Version

Terminology:

  • PUID: A security key used by the handshake.
  • PeerID: ENet client identifier.
  • Router: Singleton that handles all the networking for a given state.
  • Channel: A single message 'type', can be named.
    • Is this part of ENet or something we've defined ourselves?
    • Can we just define these all in one spot? Currently the Auth and init channels are defined in two different spots.
    • Is the channel class even used? Side snark: Shoehorning excessive amounts of class-based OO into lua makes me want to go on a killing spree. If we wanted to make a better minecraft then why the hell are we writing this in Java?

Process:

  • Client sends gmod_vox_sync, server responds with gmod_vox_sync containing the player's PUID.
    • Can we add the client's module version to the request? I don't think we have any version checking logic in the new version yet?
    • There's a separate Lua version. Okay. Why?
  • Server listens for AuthHandshake, which contains the PUID.
    • Do we want to just boot the client if they fail?
  • Configs are still requested.
    • I'd rather just send them indiscriminately unless you have a real good reason not to.
    • Is there any good reason to start adding sub-message types within individual channels? Seems like it kinda defeats the point of having channels.
  • How exactly do we want to handle cases where the client loses connection in ENet but not source? Boot them?
  • Also probably boot the client if they don't sync within a certain timeframe.

revamp texturing

Options for Reducing Artifacts

  1. Just use point sampled atlases. Gives it a pixelated, minecraft-like look which may not always be desirable.
  2. Use padded atlases. Takes up 4x the space of normal atlases.
  3. Generate mipmaps that don't bleed.
  4. Texture arrays. Not supported by DX9, even if we did hack into it.
  5. 3D textures. Supported by DX9 but mipmapped in 3 dimensions, which is probably terrible.
  6. Make the atlas a narrow strip. Takes up the same amount of space as a normal atlas but probably reduces our available space to the square root of whatever it normally is.

Options (4) (5) and (6) would allow greedy meshing. Honestly none of them really seem viable. Option (6) would probably still require some form of (2) and (3).

Old System

You have to specify a texture atlas, provide its dimensions, and use indices into the atlas whenever you want to use a texture. Attempts to use a combination of (2) and (3) above. You have to use my atlas generator if you want padded atlases with good mipmaps.

Proposed System

Let user code specify a base directory filled with pngs. Use the name of the png in place of an atlas index. Auto-magically generate the atlas with correct padding and mipmaps. Essentially this would probably just involve merging the texturing utility into the main codebase. The only problem I can forsee is that it could take a while to generate the atlas, so it might be a good idea to cache it.

Update?

Swad wanted to do a thing. Not sure if still wants to do thing, and I still have some shit on my plate, but here's a list potential features for UPDATE.

Possible Goals:

  • Add support for sparse / arbitrary sized voxel maps.
  • Add a way to trace through arbitrary sized maps.
  • Add some kind of rendering support for arbitrary sized maps.
  • Move all the lua shit to actual Lua files. The way the lua portion is loaded now is jank as fuck.
  • TRY TO improve traces and deal with precision errors.
  • Just flat out disable smooth texturing until...
  • Try to get array textures working, either on source's terms or via graphics API hackery.
  • Make networking work without dipping into the Lua context. Need to ask my nerds how2do.

There's a lot of other crap that COULD BE useful later, but I think this is a good list to start with.

Non-Goals:

  • Getting actual physics to work on arbitrary sized maps. Traces should be fine.
  • Any kind of inventory bullshit
  • Javascript support.
  • For now I probably won't bother with any kind of linux or OSX support.

Remove state determining logic

The old module did a lot of wonky shit. Which included testing the Lua state to see if it was running on the server or on the client. I'll get rid of this ASAP.

Tie up Texturing

  • Add a batch script to install shaders for developers.
  • Document shadershit + other platform shit in readme.
  • Re-enable physical mesh generation.
  • Improve atlas generator.
    • Get perms to the repo.
    • Always pad, use a simpler padding method compatible with the 4tap shader.
    • Allow input textures of different sizes.
    • Force explicit specification of dimensions.
  • Rename CubeFace -> SliceFace
  • Only read atlas dimensions from material, not config.
  • Remake gm_f1atgrass atlas with gooder textures.
  • Make shader detour work under Mac and Linux.

Heap corruption in VoxelChunk::meshStop

Exception thrown at 0x503E1F87 (AcLayers.dll) in hl2.exe: 0xC0000374: A heap has been corrupted (parameters: 0x00000000).
Unhandled exception at 0x503E1F87 (AcLayers.dll) in hl2.exe: 0xC0000374: A heap has been corrupted (parameters: 0x00000000).

call stack

		if (verts_remaining == BUILD_MAX_VERTS) {
			CMatRenderContextPtr pRenderContext(IFACE_CL_MATERIALS);
			pRenderContext->DestroyStaticMesh(current_mesh);
		}
		else {
			meshes.push_back(current_mesh);
		}

it appears to occur when pRenderContext->DestroyStaticMesh is called

Improve config parsing + General module API improvements

  • Make exterior mesh generation option shared (Serverside physical mesh garbage probably wants to know whether it should generate external faces.)
  • Just read everything regardless of state.
  • Make bounds in voxels, not chunks? Add option for huge worlds?
  • Move generator func into config, there's no reason this re-init logic should be necessary. (Partly done, but not well.)
  • Require system init to have a config. This removes the two step process and a lot of fuckuppery.
  • Just stick the config struct inside voxelworld instead of using a stoopid pointer.
  • Remove all the shit dealing with checking if we're allowed to render/generate. Remove code that allows us to re-flag everything.
  • Remove getdata, remove data from chunk init, probably remove chunk init all together?
  • Add mesh generation logic consistent with bounds in blocks.
  • Actually make shit work on the lua side.
  • Call VoxelWorld:_initMisc directly. (Done on server, not done on client.)
  • Call generator on chunk init.

Shader loads, but does nothing.

Compiled the voxelate shader and installed it properly, but it doesn't seem to be doing anything when I apply it to an object.

I had the same issue when I added my very own vertex shader to a pixel shader.

Project Management Apps

Submit yer ballots

  • Trello - Currently used. I'd rather switch to something else. 👍
  • Waffle.io - I'm a fan, basically a fancy UI over github issues. 😄
  • Github Project - Never used before. Anyone have an opinion? 🎉
  • Some Other Hipster Shit 👎

fix naming conventions

The exposed C++<->Lua api is fairly consistent, but the pure Lua API is messy as fuck.

Here's how I'm doing it:

  • local vars are simpleCaseCamelCased
  • global vars are UpperCaseCamelCased, with the exception of gm_voxelate
  • class methods are UpperCaseCamelCased
  • avoid using snake_case because it looks weird af tbh

Thoughts @birdbrainswagtrain ?

the infinite world can of worms

seasonal greetings from glua.team!

With the hiatus gone, and development well underway on voxelate, I feel that it is important that we talk about how to tackle an arbitrary, infinite world with gm_voxelate.

In the past, we've been avoiding this due to the sheer complexity of introducing an infinite or arbitrary world system into a game like Garry's Mod that uses a static, limited world size (which, frankly, is quite tiny!).

However, now that an infinite world is definitely on our to do list, it is time to open that can of worms. So, how do we do it?

In the past we’ve seen some pure Lua implementations (and I’ve made one before too, before shortly giving up on my efforts) that divide the world into chunks and repeat a central chunk serverside and create an illusion of an infinite world clientside. This was one of our considerations for gm_voxelate, but from personal experience I heavily disagree.

The world repeater

Pros

  • Re-use gmod’s data structures

Cons

  • SUPER HACKY
  • Extremely difficult to maintain compatibility with gmod
  • Re-using gmod’s datastructures will also mean that we have to deal with some of gmod’s limitations, like the global entity limit
  • Floating point math being wildly wrong on a large scale infinite map

My proposal: our own world system

Now, now it seems like packaging our own physics engine and writing the logic to a world management system may be too hard, but I feel that this is the right way to go.

Firstly and importantly, we won’t have to go through the worry of figuring out how to interface with some of gmod’s shittiest libraries. Given that we’re already including a binary module both clientside AND serverside, I think that it’s only appropriate that we use the binary module’s capabilities to its fullest and include whatever libraries we need, rather than depending on or hacking a shitty one within gmod.

So, summarised:

Pros

  • Our own system, and the freedom that comes with designing our own system
  • We can use our own data types for the system
  • Less hacky since we won’t have to repeat a map
  • Possible performance improvements due to using our own custom designed world system

Cons

  • The engineering and planning effort behind getting such a system working
  • Perceived lack of functionality when comparing a custom designed system to the plethora of functions Garry’s Mod already provides us with (since we’ll have to redesign an entity system, and won’t be able to use gmod’s entity system)

So, what now? I believe that we shouldn’t rush into the implementation phase of this world management system just yet. Careful planning is key to pulling off such an engineering effort.

In the next few posts I’ll outline some concepts and ideas that we’ll have to take into account when designing this system.

-- SWAD OUT

Memory Leek (Probably?)

Pretty sure my crashes were due to a memory leek.

Chunks weren't being deleted on the server so that may have been an issue.

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.