The development blog dedicated to the Unity based 3D adaptation of Space Station 13 project.
Don't wanna be here? Send us removal request.
Text
Tiny Update
Busy as shit with work. No progress lately, but not forgotten.
1 note
·
View note
Text
Map Editor Cont.
The last few nights I’ve managed to put in 1-1.5 hours. I’ve been working on solidifying the map editor, which is still plenty buggy, but been fixing problems and adding abilities.
It’s now possible to edit individual faces of the blocks, so while a block may be of type “Hull” the interior face may get a different sprite.
The red plane represents the face editor, and will snap to the block, while the red block is used to add/remove the actual blocks. I’m not great at shaders, so while I was hoping for translucent + self illumination, it sometimes makes the block completely transparent. It has no effect on the actual data, just momentarily while using the tool.
Map loading and map saving is working. I’ve decided to change sprites, block types and their ID types from a uint to ushort to save space. The changes each block from 30 bytes to 16 bytes. That may still increase as more data is squeezed in (I’m still not sure 1 byte will hold all the pipe/wiring related data), but it’s already quite a size difference. For instance, 200x5x200 is 200,000 blocks, making 6,000,000 B vs 3,200,000 B for the difference sizes. It’ll definitely payoff down the road.
I guess lighting is back up as the next task. I’ve also got to strip out several thousands of lines of code as a bunch of classes have been reinvented from the ground up. The longer it lingers, the harder it’ll be to keep organized. Not the most fun.
2 notes
·
View notes
Text
Map Editor
It’s been a busy week. Tonight was the first chance I’ve had to sit down and do some work. I picked up with the map. Can’t have stuff to do until you have a place to do it in/under/around/above/through. With the recent decision switch to a more 3D-ized world and map, comes a change to the map format and the map renderer.
In order get a map in a working order, and to make it not super tedious to edit, I’ve been working on the map editor. This currently runs in Unity, is missing tons of features, lots of stuff is broken and currently can’t save or load map data. But the basics are there.
What works right now is the ability to import color coded pngs, one image for each y-block in the map. As can be seen in the screenshots below is a very primitive adaptation of the “mini station” map as converted into an approximate 3D version. To give a sense of scale, player’s eye level will still be (for a normal height person) at 0.6 units, slightly above the mid line of the doors. That means two block height is pretty roomy. Maintenance shafts can be more claustrophobic for one block height, and larger areas like arrival could be half a dozen or more blocks high.
With the imported images, basic block types can be assigned. This will be block types like “Nothing” (aka atmosphere/vacuum), Scaffold--which like it’s counterpart in SS13 will be the foundation of any block, Hull, Reinforced Hull, and Door. Other types like Glass, Reinforced Glass and Porous--to allow vents and screens--will come soon enough.
Once imported and generated, you can fly the camera in and add/remove blocks. Currently you can only remove blocks and add Scaffold, so one of the next immediate steps if you allow picking of block type.
Furthermore each block face will be editable to allow different art. That can manifest as a Hull block having five faces of default Hull (as defined by the templates) but the normally visible face is checker floor or something. It also means blocks that form corners that say, transition from a hallway to medbay, can have appropriate art on each face, depending on which room that face is in. That will be editable.
Furthermore, each block can have the possibility to having up to eight “pipes” running through it. This should cover most of the atmospherics, as well as water and electricity. As I write this I realize I’ve forgotten about potential for waste water and trash. Might have to change something...
Anyways, map editor isn’t glamorous, and it’s getting written really quickly and not too cleanly. But it works, and I figure as long as it can read/write map data for the game, and do the other thing an editor needs to do, it can always be improved later. Maybe I’ll regret those words some day.
Level 0 - Aka the floor
Level 1 - Aka player level wall
Level 2 - Aka higher wall
Level 3 - Aka ceiling
Screen shots are a bit dark as I’ve turned the ambient light down, and without lighting it’s not quite there yet. But hopefully the difference in tiles and the presence of doors are discernible.
I have a busy next few weeks, so progress will be slow. However, for future reference incase I forget, next on the list is
Reimplement template base block types and add editor support
Rethink how best to do resources moving through blocks (might have to change a byte to a short)
Add loading/saving
Reimplement lighting
1 note
·
View note
Text
TL;DR -- This reply became a bit longer than I originally planned for, but I feel it’s important information to questions that’ll pop up often.
For clarification, in this 3D context we’d be talking about the Y-axis “Up/Down”. Z-axis is considered “Forward/Backward” and X-Axis “Right/Left”.
There will be a concept of Up/Down. There will be a difference between floor and ceiling. I am expecting and planning for situations where gravity is disabled or unavailable that there will be up/down movement within the constraints. Rooms will be of varying heights.
The axis will always be there, it’ll be a fundamental part of the engine. Whether or not someone fully utilizes it in the future will always be a possibility. Whether or not that someone is me, is a smaller possibility but I won’t rule it out. But the code will be available on github for anyone who wishes to tackle it.
My two main issues with the third dimension--and why not to embrace it fully--is the impact on gameplay, and the demand on art.
GamePlay
Part of the fun is learning the maps, and it should be something that requires some time and repeated play to do. That means a map, within its self, needs to be constant--BoxStation needs to be BoxStation--barring any temporary destruction. And it needs to be in a format that the game can adequately portray the map to players who are attempting to learn. By constraining things to essentially two dimensions, you’re now able to reproduce the station as a single layer, or a single image. Making the third dimension too important makes it that much harder to comprehend, and, in my opinion, it’s a step too far.
An additional part of the “impact on gameplay” is map density. A block voxel approach is nice because it’s uniform. A block voxel approach also is limiting because it’s uniform. IRL, a house’s wall, atleast in the USA/Canada, is typically about 5in/12cm. A ground floor wall of a skyscraper might be 12in/30cm. The wall of a concrete military bunker might be several feet/meters thick. There’s variation. Now, reproduce any of those structures in blocks. Everything is at least one block thick including the thinnest of wall partitions. The same with a space station. Rooms that should be small become quite big. A sleeping cabin or office that could exist with an 18in/46cm gap around furniture has to become either a 39in/100cm or none at all. It throws off all the sizes of things. That ultimately requires padding out spaces with extra blocks to have a better feeling and layout.
However, now with extra padding, and a fully destructible environment, you introduce a bunch of dead space. What do you do with it? What’s to keep players from hiding in it or placing a round ending bomb in it? The more area that consists of just filler, the more dead space it is, and there’s nothing to keep players out of it. I want wall/bulkhead destruction to be special--exceptions, not the rule. It is possible to pull off, but it just makes things that much harder to put together and there’s more important challenges to conquer first.
Art
The second issue I have with it is a very practical one: art. Since the goal is to utilize as much already available art as possible and the fact that non-map-geography objects use a 2D sprite, we lack the entire up/down view of objects. For instance, take the Clown. You can look at the clown from front, back, left and right. But what does the clown look like when looking down on it? What about when looking up at it? Those are all angles that’d have to be made. And now multiply it by every character and every object that’d require it. It’s certainly do-able, but it really raises the threshold. And in a volunteer, unpaid environment like this development will be, I know what my interests, skills and willingness can do. I cannot however count on anyone else to be equally motivated--to be fair there are individuals who are capable and far more motivated than I. However, I don’t want the project to stall out because its missing a bunch of art for things that are otherwise are good to go.
Should a set of dedicated people decide to add it, it should be very possible to do.
Fundamental Changes
As I started working with the netcode, I began to think about restructuring the project to better support a separation between client and server. That led to actually doing it. Keeping one single Unity project, as two projects would be too much a pain in the butt to maintain, as well as decrease the ability to play.
So, root code folders became Client, Common and Server. But as I was sitting there, I kept looking at the older screenshots–the screenshots of no ceilings. That made me think more about what capabilities were required. Which led me to restarting the map format…
I’ve decided to stick with a cube voxel format, basically identical in appearance to the existing format, but with added height. I don’t want to expand the game out into a full 3D map format, as it is my opinion it will make the game too difficult to learn and play, and having ladders and elevator shafts will needlessly complicate things without really adding to the gameplay. There are already fully suitable games out there like Space Engineers that do have full freedom in all three dimensions, but the fact no SS13 gameplay has really sprung up around Space Engineers I’ll use as evidence to support my argument.
And that produces this:
It’s pretty dark at the moment without lights, which need to be re-added. I plan to use the same lighting, but with the added dimension, shouldn’t have too much effect.
I should also add that the maps, while chunks will be larger, will be limited to four blocks. That means doing things like repairs and station construction won’t require crazy climbing, or removing whole wall panels in order to access adjacent, hidden blocks. Basically, if you can stand on/under or immediately adjacent to the block in question, you will be able to repair/construct/deconstruct like you can now in the 2D Byond version.
That also means things like explosions will work as cylinders (circles with height) as opposed to spheres. Players outside the station in a suit will not be able to climb over and under the station either.
So there it is.
6 notes
·
View notes
Text
Fundamental Changes
As I started working with the netcode, I began to think about restructuring the project to better support a separation between client and server. That led to actually doing it. Keeping one single Unity project, as two projects would be too much a pain in the butt to maintain, as well as decrease the ability to play.
So, root code folders became Client, Common and Server. But as I was sitting there, I kept looking at the older screenshots--the screenshots of no ceilings. That made me think more about what capabilities were required. Which led me to restarting the map format...
I’ve decided to stick with a cube voxel format, basically identical in appearance to the existing format, but with added height. I don’t want to expand the game out into a full 3D map format, as it is my opinion it will make the game too difficult to learn and play, and having ladders and elevator shafts will needlessly complicate things without really adding to the gameplay. There are already fully suitable games out there like Space Engineers that do have full freedom in all three dimensions, but the fact no SS13 gameplay has really sprung up around Space Engineers I’ll use as evidence to support my argument.
And that produces this:
It’s pretty dark at the moment without lights, which need to be re-added. I plan to use the same lighting, but with the added dimension, shouldn’t have too much effect.
I should also add that the maps, while chunks will be larger, will be limited to four blocks. That means doing things like repairs and station construction won’t require crazy climbing, or removing whole wall panels in order to access adjacent, hidden blocks. Basically, if you can stand on/under or immediately adjacent to the block in question, you will be able to repair/construct/deconstruct like you can now in the 2D Byond version.
That also means things like explosions will work as cylinders (circles with height) as opposed to spheres. Players outside the station in a suit will not be able to climb over and under the station either.
So there it is.
6 notes
·
View notes
Text
Networking - The Start
It’s a bit of departure from what I was previously working on, but as I was working on the lockers (and storage in general) I kept thinking about whether what I was working now vs would it would work in a multiplayer environment with a server.
One strategy could be to just make the game all work in a single player, non networked setup. That is often the most satisfying as you see your results quickly. However what often works in single player doesn’t work when you have to now network it. That’d mean redoing a lot of stuff. I have enough experience from past projects to also know that is a great way to kill enthusiasm and cause abandonment.
That’s not a great idea. So I’ve spent the last week or so, working on a network implementation. It’s adapted from some previous attempts at networking, as well as tutorials.
It’s TCP based, so it means connections are established and data streamed back and forth. Before the question of “Why TCP? Why not UDP?!”, this is my preemptive answer. UDP is great, and often the best choice for shooters and other things which generate a lot of temporary or inconsequential data (positions, actions often at 30 updates per second). But what makes UDP fast (lack of followup) is also the hinderance when you need to be sure a message arrives.
EveryDay Space Station as a close adaption of SS13 requires a lot of permanence. That means things like doors open, objects being placed and most importantly, whole sections of walls/floor/other being moved, destroyed and otherwise altered meant that there HAS to be some reliability. So in order to do that with UDP you now have to add your own controls to check if data was received, resend it if it’s need, and so on.
That made UDP much less palatable, and meant more work, to recreate basically a simplified TCP. And EDSS, much like SS13, isn’t really twitchy. I think things like position updates and combat can be kept at rates slower than a game like Counter-Strike or Call of Duty, and still provide a better experience than SS13 currently supplies, and all on top of TCP.
There are additional supporting reasons, but that’s really what it comes down to. Either way, I’ll be sure that it’s not going down the “easy-now-difficult-later” path that many SS13 remakes do, as from the get go, the client/server setup will exist.
0 notes
Text
Lockers
The UML layout for the door worked great, and got all the Json redone much faster. I’m leaving the doors alone for the time being until some of the systems are included, like power and atmosphere.
That means I’ve moved onto lockers. Lockers are a new type of entity, since they include storage, have a toggle state (open and closed) as well as restrictions (security lockers). I think I’ve got the basics of it down, and have been experimenting with best ways to do the locker door, but still haven’t settled on a choice yet.
Lockers are also multi angle viewable, so like chairs, they change their sprite based on player viewing orientation. Of course, art doesn’t exist for those angles, so had to put something together quickly. Not the best, not the worst, but didn’t want to spend too much time on it.
Until next time
2 notes
·
View notes
Text
Doors Cont. 3
Continued on doors tonight. I’ve been working to finish the rests of the states (Malfunctioning, Access Panel Open when Powered/UnPowered). The json is getting extremely difficult to navigate, most in terms of finding the right UIDs to reference. So I decided to sink some time into making a UML diagram for reference. It took about two hours, but I think will make things about 100 times easier to verify and implement.
So, as unsexy as it is, here’s the UML laying out the door states, and the transitions between states.
0 notes
Text
Doors Cont. 2
Been busy the last few days so haven’t had a chance to add new features. Tonight got a chance to sit down and continue on the doors.
There is now support for the door to change power states and toggle between welded/unwelded. Most of the work has just been plodding through the json files. The single door json is 722 lines--admittedly with lots of line returns--and is becoming a bit tedious to keep organized. I’d love a visual node based editor that produces json right now as it’s only going to get worse...
If you should try it out, “Q” toggles weld state and “R” cycles power state. If you select the door component in the editor, you’ll see the states change. I think I might continue tonight and add in the “access denied” state.
0 notes
Text
Doors Cont.
It may be New Years Eve, but that doesn’t mean I have to actually go outside. With the holidays ramping down, I had a few hours last night and tonight to continue working on the doors. These are data driven with pretty good flexibility. That does mean they’re pretty easy to mess up if the json data is bad, though runtime errors should be kept to a minimum and instead data errors will merely present themselves as behavior “misadventures”.
Currently doors are on a 20 second timer, but can be opened when in a closed state, or closed when in an open state.
The next step will be adding modifiers like hacked state, welded state, various power states.
After that, I think I’ll tackle storage containers.
1 note
·
View note
Text
Doors
I’ve added a simple highlighting scheme and colliders to entities. The next step has been adding interaction, which starts with doors.
They’re a complicated beast, a single door is already at 150 lines of json and that’s only covering a few situations. Doors will be able to be locked, opened, hacked, pryed open and built. The entity spawning is in, as is drawing and collision. What comes next is interaction, state change, and animation.
Also added a simple minecraft style crosshair where colors within the white section will be inverted. Entities that are highlighted get a green-ish coloration. Not sure that’ll be permanent though.
1 note
·
View note
Text
Chairs!
I’ve continued on the implementation of entities. I’ve added chairs.
Where chairs different from lights, is that chairs consist of multiple sprites that will display based on entity orientation in world space, and relative angle to player camera.
I also discovered that the billboard shader was being dynamically batched by Unity since all instances of the object use different meshs/verts/uvs but the same material and texture. Turning off dynamic batching was necessary in order to prevent it from breaking. It looks appropriate and along the lines I was hoping for.
Next step is going to be adding colliders to entities so you can see things when mousing over them, as well as doors.
However, between Star Wars and the holidays, the next two weeks is going to be pretty quiet.
Don’t forget, the latest code is available on GitHub --> https://github.com/casualsimpleton/EveryDaySpaceStation
1 note
·
View note
Text
Entities and Optimizations
Not a lot of pretty things to show, but did a lot of work on organization and parsing of entities. The goal is to provide as much, or even more (if possible) flexibility than the current BYOND version of SS13. That’s a damn high bar. So I spent a lot of time trying to come up with suitable json layout and component structures to allow it. Loading time is currently about 600ms, with loading 4 512x512 textures, and about 120kb of json files. 75% of that 600ms is directly from the json deserialize calls, but not much that can be done about that.
There are 10 lights present, covering essentially 256 tiles (16x16) and at a cost of 2ms. Drawcalls range between 44 and 64, but that’s partly because it’s not culling the scaffolding which is present, but not obviously visible. Drawcalls will go up significantly as players and other entities appear on screen, but should be about 1 drawcall per object, so we’ve got a pretty breathing room still, especially with better culling as the camera moves about.
I think it’s a good start, but we’ll have to see how it goes as more stuff gets added.
For some numerical comparisons: Ministation is about 115x116 tiles as far as I can measure, and much of that is empty space. The longest hallway is about 52 tiles long, and at 8 tiles per chunk (in one dim.) that’s 7 chunks. Double that if you want, in the case that it falls on a chunk line, and you’ve got 14 chunks. As it stands right now, just by duplicating the running scene 5x times (for a total of 4 * 6 = 24 chunks) drawcalls are ~240 without scaffolding or other chunks being culled. I know drawcalls aren’t the end-all-be-all for performance measuring, but I want to make sure the game runs well on older hardware for the types of people playing SS13 on old crap PCs.
There was also much obsessing over garbage generated via the lighting algorithm. Previously a bunch of stuff was stored in dictionaries and hashsets, as they needed to be collected, but also unique entries. This would cause GC to kick in every few seconds, and while not “bad”, 4-5ms every ~5 seconds isn’t that desirable either. So I replaced the dictionary with a paired list class, and even went as far as making a dedicated key uint declaration to eliminate the generic’s need for object.Equals() when adding or retrieving values. The HashSet was replaced with a simple List that does loop to check if the value already exists. Not super efficient on add/removes but those are really only done at start up, and the list should never exceed ~6 items.
The result is 0 KB of garbage generated now, and the lighting updates at 100ms for now.
I did break the light that the player carries as can seen in previous shots, but it should be easy enough to fix.
Next step I think will be to get some basic furniture in. Then doors, which will require state toggling.
0 notes
Text
Oh No, It’s the Clown
Instead of going to bed, I started in on entity sprites to liven things up a bit. I added a billboard shader for when needed, so it’ll give a nice Wolfenstein 3D style of look. The graphics will always be facing you, however depending on its relative orientation, different sides of the art will be show (front, back, side etc).
I do need to give some attention to scaffolding and wiring though, but the entities will be nice to have in place so levels aren’t so empty. Will have to also expand the level json format to accommodate world entities.
1 note
·
View note
Text
More Sophisticated Light Cont.
Just added the tile lighting for neighbor tiles, so things like the walls will be lit up at the same intensity as its adjacent flooring.
1 note
·
View note
Text
More Sophisticated Lighting
I rewrote the lighting fill algorithm to be a smidge faster, and react properly to walls and other light blocking objects. At the same time, things marked as Transparent, will allow light through.
Next step is have tiles cast their light level on neighbor walls.
1 note
·
View note
Text
Basic collision and lighting
So my plans for Monday night fell through so I decided to begin on collision and lighting.
I also extracted the chunk rendering from the chunk itself, and made it flexible down to the specific sprite. This means that there should be no real problem in performance when using multiple sprite sheets. The fewer the better of course, but each one is a drawcall and a mesh of about 3k triangles and 6k verts, so not too bad. There might be a few bugs, but in the screenshots you can see the chrome sprite from a 2nd sheet.
I was originally going to use pooled colliders to fill in the walls. But that left a question of how to do the floor collision, and then I figured I’d try out mesh colliders. And that works pretty well. I still need to verify it’ll scale appropriately, since block building isn’t too fast/often (outside of singularity mishaps) the performance should be consistent.
I also managed to do a first attempt at tile based lighting. This functions similar to how Minecraft did their old lighting (back it Alpha/Early Beta before smoothing) and is consistent with Space Station 13′s look. Also did a test case where the player camera is carrying a light and so you can see it update dynamically.
The exact system in use is each MapTile contains a light value. The SceneLevelManager keeps a bounds for visible chunks, and then 10x a second, updates those chunks lighting by iterating all registered lights in that chunk.
This system is not without its flaws. It’ll make blending between two lights a bit more difficult, and it requires constantly pushing vert colors and updating the mesh assignments. But it does allow for completely custom color lighting (any RGB value is fine). I’m going to be trying out a different system where instead of pushing colors, to push uvs for a pre-created “tint” texture which is combined in the shader to produced colored looks.
Some technical details: a Color32 (which Unity suggests if you’re performance minded) is a 4 byte struct. A Vector2, which is used for UVs, is 2x floats, which are 4 bytes each, for a total of 8 bytes per vector2. There’d have to be same number, which is equal to the number of verts present in the mesh. As far as I know, there’s not much difference in pushing a Vector2[] vs a Color32[]. So there’s a few options (let’s use 6k verts for sake of math):
Get rid of vert colors altogether, and maintain two sets of UVs (one for main texture, one for tint). This would mean completely flexible light colors are out, but depending on the tint texture--each color only needs 1 pixel--it’d could still be pretty diverse (will people see the difference between 50% dark rose and 50% dark red?). So very simple memory math, that’d be 2 floats * 4 bytes/float * 2 arrays * 6k verts = 96,000B bytes
Keep vert colors, and add the 2nd uv tint color. This gives the most flexibility, as the tints can be kept simple. This also uses the most memory. 2 floats * 4 bytes/float * 2 array * 6k verts = 96,000B. 4 bytes/color * 6k verts = 24,000B. A total of 120,000B.
Keep vert colors, and don’t use tint texture. Which is 2 floats * 4 bytes/float * 1 array * 6k verts = 48,000B. And then 24,000B for the colors. Total 72,000B.
Multiple all that for, let’s say, 100 chunks, that’d be 9.6MB, 12MB and 7.2MB. And in retrospect... doesn’t really matter in this day and age. Most memory in the game will ultimately be used by either the textures (as the game grows), the network (for a server networking 50+ players won’t be too cheap even with proper pooling). So I’ll probably go for #2.
Whatever the decision, I need to add correct face lighting, as it’s currently per box, as opposed to lighting the opposing faces, as well as add blocking (so light doesn’t go through blocks) and add in support for transparency.
That’s about it for now. Not sure when next post will be. Don’t forget, this is all available on https://github.com/casualsimpleton/EveryDaySpaceStation
0 notes