|
1 |
| -# Version 0.2.0 |
| 1 | +# Version 0.2.1 |
2 | 2 |
|
3 |
| -Version 0.2.0 is a major update that focuses primarily on underground generation and features. |
4 |
| -Other notable changes include pickblock, block selection, better particles and profiling. |
| 3 | +0.2.1 is a minor update following 0.2.0 that focuses more on bug fixes, optimizations, code improvements, and expandability changes. |
5 | 4 |
|
6 |
| -## Additions |
7 |
| - |
8 |
| -### New blocks |
9 |
| - |
10 |
| -- Bedrock |
11 |
| -- Granite |
12 |
| -- Diorite |
13 |
| -- Andesite |
14 |
| -- Coal ore |
15 |
| -- Iron ore |
16 |
| -- Gold ore |
17 |
| -- Lapis ore |
18 |
| -- Redstone ore |
19 |
| -- Diamond ore |
20 |
| -- Emerald ore |
21 |
| -- Deepslate |
22 |
| -- Cobbled deepslate |
23 |
| -- Deepslate coal ore |
24 |
| -- Deepslate iron ore |
25 |
| -- Deepslate gold ore |
26 |
| -- Deepslate lapis ore |
27 |
| -- Deepslate redstone ore |
28 |
| -- Deepslate diamond ore |
29 |
| -- Deepslate emerald ore |
30 |
| - |
31 |
| -### Caves |
32 |
| - |
33 |
| -- Generated with Perlin Noise |
34 |
| -- You will sometimes find grass and dirt getting cut off without any actual cave generating, that is a quirk of cave generation |
35 |
| -- Caves will not be able to cut through bedrock |
36 |
| - |
37 |
| -Example: |
38 |
| - |
39 |
| - |
40 |
| -### Stone Types |
41 |
| - |
42 |
| -- There are 4 new stone types: |
43 |
| - - Granite |
44 |
| - - Diorite |
45 |
| - - Andesite |
46 |
| - - Tuff |
47 |
| -- Granite, diorite, and andesite generate anywhere above deepslate level ( < chunk-y 64) |
48 |
| -- Tuff only generates below deepslate level ( > chunk-y 64) |
49 |
| -- Their shapes are determined by a Cellular Automata algorithm |
50 |
| -- They will not generate overlapping with ore veins, neither will they replace dirt, ores, nor bedrock |
51 |
| - |
52 |
| -### Bedrock + World Height |
53 |
| - |
54 |
| -- Bedrock generates from y 1024+ |
55 |
| -- There is a blend between stone and bedrock, generated the same as stone -> deepslate |
56 |
| -- The player cannot break bedrock |
57 |
| - |
58 |
| -### Ore Veins |
59 |
| - |
60 |
| -- Ore vein shapes are determined by a Cellular Automata algorithm. |
61 |
| -- They will turn into deepslate variants of the ores if they generate replacing deepslate |
62 |
| -- Ores will not replace bedrock or dirt |
63 |
| - |
64 |
| -#### Distribution |
65 |
| - |
66 |
| -- They generate underground with the following distribution (all percentages represent the chance of generation per chunk): |
67 |
| - - Coal ore (2 attempts per chunk) starts generating with a 16% chance at the top of the world, decreases until it reaches chunk-y 64, gets more common going down until chunk-y 96 with a 3% chance, then gets rarer until chunk-y 128 |
68 |
| - - Iron ore (2 attempts per chunk) starts generating at the top of the world rarely, quickly goes to 10% chance at chunk-y 8, then gets rarer as chunk-y goes down to 72 |
69 |
| - - Lapis ore (1 attempt per chunk) starts generating at chunk-y 32, gets more common until chunk-y 64 with a 6% chance, then gets rarer until chunk-y 96 |
70 |
| - - Gold ore (1 attempt per chunk) starts generating at chunk-y 56, gets more common until chunk-y 88 with a 7% chance, then gets rarer until chunk-y 120 |
71 |
| - - Redstone ore (2 attempts per chunk) starts generating at chunk-y 56, gets more common until chunk-y 120, then quickly gets rarer until chunk-y 128 |
72 |
| - - Diamond ore (1 attempt per chunk) starts generating at chunk-y 56, maintains a 1% chance of generating until chunk-y 96, then gets more common until chunk-y 128 with a 5% chance |
73 |
| - - Emerald ore (1 attempt per chunk) starts generating at chunk-y 56, maintains a 1% chance of generating until chunk-y 72, then gets more common until chunk-y 96 with a 3% chance, then gets rarer until chunk-y 120 |
74 |
| - |
75 |
| -Ore distribution map: |
76 |
| - |
| 5 | +--- |
77 | 6 |
|
78 |
| -#### Best y-level for mining |
| 7 | +## Additions |
79 | 8 |
|
80 |
| -- The best chunk-y to mine for each ore, the attempts per chunk, and the chance per attempt: |
81 |
| - - Coal: 2 (not 1 because a large portion of chunk-y 1 is made up of dirt), 16%, 2 |
82 |
| - - Iron: 8, 10%, 2 |
83 |
| - - Lapis: 64, 6%, 1 |
84 |
| - - Gold: 88, 7%, 1 |
85 |
| - - Redstone: 120, 15%, 2 |
86 |
| - - Diamond: 126 (not 128 or 127 because a large portion of them are made up of bedrock), 5%, 1 |
87 |
| - - Emerald: 96, 3%, 1 |
| 9 | +### Screenshot |
88 | 10 |
|
89 |
| -### Particles |
| 11 | +- Press F2 to screenshot |
| 12 | +- The screenshot image will be stored in a folder named "screenshots" in the same directory as main.py |
| 13 | +- The image will be the same resolution as the resolution of the game (1200 x 600) |
90 | 14 |
|
91 |
| -#### Void Fog Particles |
| 15 | +### Cinematic Modes |
92 | 16 |
|
93 |
| -- Void fog particles start to spawn below y 896 |
94 |
| -- The lower down the player is: |
95 |
| - - The more particles spawn |
96 |
| - - The bigger the particles on average |
97 |
| -- Void fog particles will be deleted if they either move behind a block or move outside the screen |
| 17 | +- To toggle cinematic modes, press F3 |
| 18 | +- There are 4 option to toggle through in order: |
| 19 | + - Show both the hotbar and crosshair |
| 20 | + - Hide both |
| 21 | + - Show crosshair but hide hotbar |
| 22 | + - Show hotbar but hide crosshair |
| 23 | +- The current cinematic mode state will be shown by a popup displayed on the top-right |
98 | 24 |
|
99 |
| -#### Player Fall Particles |
| 25 | +### Hand Held Blocks |
100 | 26 |
|
101 |
| -- Player fall particles will be spawned when the player falls for more than or equal to 4 blocks and lands |
102 |
| -- The longer the player falls for, the most particles are spawned, to a maximum of 15 blocks |
103 |
| -- The particles will take the color of a random pixel of the block that the player fell onto |
| 27 | +- Blocks will now physically appear in the player's hand when the player is holding an item |
104 | 28 |
|
105 |
| -### Block Selection Box |
| 29 | +### Walking particles |
106 | 30 |
|
107 |
| -- Added a selection box around the block that the crosshair is hovering over |
108 |
| -- It is 2 pixels thick, and is offset towards the topleft corner by 2 pixels to fit the selected block entirely within the box |
| 31 | +- When the player walks at over 3 blocks per second, block particles would be spawned underneath its feet |
109 | 32 |
|
110 |
| -### Sky Gradient |
111 |
| - |
112 |
| -- The background colour now has a gradient between the default blue (y = 0-) and black (y = 1024) |
| 33 | +### 2DMC logo |
113 | 34 |
|
114 |
| -### Pick-block |
| 35 | +- 2DMC now has... a logo! It will be shown on the top left corner of the game window and in Alt + Tab menu! |
| 36 | +- You can see it below: |
115 | 37 |
|
116 |
| -- Press the MMB (middle mouse button) to pick the block the crosshair is hovering over |
117 |
| -- Some blocks cannot be pick-blocked, like bedrock, tall grass top, and leafed oak log |
118 |
| -- Pick-blocking will move the targeted block to the slot that you are selecting, no matter if it is on the hotbar or in the inventory |
| 38 | + |
119 | 39 |
|
120 | 40 | ## Changes
|
121 | 41 |
|
122 |
| -- Crosshair now fades between colors instead of instantly changing |
123 |
| -- Added "Block position" to the debug menu, which shows the coordinates of the block the crosshair is hovering over |
124 |
| -- Added "Particles" to the debug menu, which shows the number of particles that is being calculated |
125 |
| -- Added a transparent white overlay on the inventory slot that is being hovered over |
126 |
| - |
127 |
| -## Bug fixes |
128 |
| - |
129 |
| -- Fixed floating tall grass on chunk borders |
130 |
| -- Particles float upwards when inside a block, now they just fall out |
131 |
| -- Fixed tall grass being cut off by a tree on chunk borders |
132 |
| - |
133 |
| -## Technical changes |
| 42 | +- Optimized particles with conditional collision testing |
| 43 | +- Text boxes now show their outer border / rect whilst in debug mode |
| 44 | +- Velocity now shows up as BPS (blocks per second) in debug |
| 45 | +- Paperdoll no longer covers held item when in inventory |
| 46 | +- Optimized chunk loading and structure generation |
| 47 | + |
| 48 | +## Bug Fixes |
| 49 | + |
| 50 | +- Fixed particles occasionally falling into solid blocks |
| 51 | +- Fixed void fog particles spawning in extremely large numbers when the player enters the upper threshold of void fog particles |
| 52 | +- Fixed player being able to tunnel through blocks as FPS gets extremely low |
| 53 | +- Fixed player tunnelling when the window is moved, now, the game will just pause with dt being set to 0 |
| 54 | + |
| 55 | +## Licensing |
| 56 | + |
| 57 | +- 2DMC is now an officially Open Source project! |
| 58 | +- It is licensed with the GNU General Public License v3 |
| 59 | +- You can view the full license [here](LICENSE.md)! |
| 60 | +- All src/ files now have a short header to reflect this. |
| 61 | + |
| 62 | +## Technical Changes |
| 63 | + |
| 64 | +- Reworked the sprite system to allow better control over draw order, and to make the sprites easier to work with! |
| 65 | + - We now have a custom defined sprite class |
| 66 | + - This sprite class serves as a superclass for all other sprites, and provides a constructor and a number of methods that make all sprites compatible with our SpriteManager |
| 67 | + - We have a SpriteManager class that manages draw order, updates and other useful management functions |
| 68 | + - Draw order is defined in an automatic enumeration |
| 69 | + - Sprites can have a custom debug layer (debug information is rendered on a different layer to the sprite) or a regular debug layer (debug information is rendered on the same layer as the sprite) |
| 70 | + - If you want to get a better understanding of this system then you are best off looking at the code (particuarly [sprite.py](src/sprite.py)), be warned the code is kinda gross >.< |
| 71 | + |
| 72 | +- Velocity is now set and calculated with BPS (blocks per second) |
| 73 | +- We have implemented a Single Instance Superclass. This class ensures any subclasses can only have 1 instance of themselves at a time. |
| 74 | + - This is useful, for example for the inventory labels, where whenever you move the mouse a new label will spawn. However, we only want one label to spawn at a time. Previously this required a very complicated and extremely ugly system of kill methods and class attributes and conditional checks which was, in short, [gross](https://github.com/DaNubCoding/2DMC/commit/21970ed4f93699bfecfa0e321f33f127ece247e4?diff=split#r70245084). |
| 75 | + - This system removes the need for this. Any sprite that inherits from SingleInstance and calls it's constructor will have this handled automatically |
| 76 | + - Demo (because the constructor is slightly confusing): |
| 77 | + |
| 78 | + ```python |
| 79 | + class Foo(Sprite, SingleInstance): |
| 80 | + def __init__(self, layer: int | LayersEnum) -> None: |
| 81 | + Sprite.__init__(self, layer) |
| 82 | + SingleInstance.__init__(self, self) # The second self call passes the instance to SingleInstance, the first is just a __init__ thing ¯\_(ツ)_/¯ |
| 83 | + ``` |
134 | 84 |
|
135 |
| -- Grouped code into different files in the "src" folder |
136 |
| -- Added comments, docstrings and type annotations explaining the code |
137 |
| -- Separated collision detection from camera because that is just very bad |
138 |
| -- Improved particle performance |
139 |
| -- Greatly improved chunk loading performance considering the new terrain features that have been added |
140 |
| -- The system by which we create, update and draw particles has been completely reworked. |
141 |
| - - We are now using OOP in the inheritance tree: |
| 85 | +- We have implemented a new system called "Information Labels" |
| 86 | + - These labels can be defined as "anything non-permanent that conveys information or any other content". |
| 87 | + - This includes images, popups, labels, toasts, ect. |
| 88 | + - Made a [information label class](src/information_label.py) to better how these labels are handled. Labels are considered sprites internally, and so can be given different layers |
| 89 | + - Labels are designed with OOP in mind. As of 0.2.1 the inheritance tree is as follows: |
142 | 90 |
|
143 | 91 | ```InheritanceTree
|
144 |
| - Particle |
145 |
| - ├── PhysicsParticle |
146 |
| - │ ├── BlockParticle |
147 |
| - │ └── PlayerFallParticle |
148 |
| - └── EnviromentalParticle |
149 |
| - └──VoidFogParticle |
| 92 | + InformationLabel |
| 93 | + └── GenericTextBox |
| 94 | + ├── InventoryLabelTextBox |
| 95 | + └── HotbarLabelTextBox |
150 | 96 | ```
|
151 | 97 |
|
152 |
| -### Profiling |
153 |
| - |
154 |
| -- To make a profile for a function, pass the callable into src.utils.profile, along with its parameters |
155 |
| -- It will create a .prof file in build/profiles on the function that has been passed when F9 is pressed |
156 |
| -- The file will have the time of creation in its file name |
157 |
| - |
158 |
| -In game you can presss F9 and it will generate a profile of `<callable>` in build/profiles. |
159 |
| - |
160 |
| -```python |
161 |
| -# variable = <callable>(<*args>) |
162 |
| -import src.utils as utils |
163 |
| -variable = utils.profile(<callable>, <*args>) |
164 |
| -``` |
165 |
| - |
166 |
| -For instance, to time the loading of chunks, you could do the following: |
167 |
| - |
168 |
| -```python |
169 |
| -# self.rendered_chunks = load_chunks(self.player.camera) |
170 |
| -import src.utils as utils |
171 |
| -self.rendered_chunks = utils.profile(load_chunks, self.player.camera) |
172 |
| -``` |
173 |
| - |
174 |
| -If you want to generate a profile without you having to press a key (for example, |
175 |
| -if you want to time a function if a certain condition is met), you could do the following: |
176 |
| - |
177 |
| -```python |
178 |
| -import src.utils as utils |
179 |
| -if <condition>: |
180 |
| - utils.do_profile = True |
181 |
| -profile(<callable>, <*args>) |
182 |
| -``` |
183 |
| - |
184 |
| -For instance, to time the loading time of a certain chunk at (x, y), you could do the following: |
| 98 | + - NOTE: GenericTextBox also inherits from SingleInstance but this is hard to show on an inheritance tree. |
185 | 99 |
|
186 |
| -```python |
187 |
| -import src.utils as utils |
188 |
| -if chunk == (x, y): |
189 |
| - utils.do_profile = True |
190 |
| -profile(Chunk, chunk) |
191 |
| -``` |
| 100 | +- Structure generation and chunk loading is now done slightly differently |
| 101 | + - Structure that extend into already existing chunks will simply place down the extra blocks directly into the neighboring chunk |
| 102 | + - Base block generation is now cached by position |
| 103 | + - Since perlin noise (which is used for cave generation) is very slow, it is now done once per loop instead of 64 times at once |
| 104 | + - The cave heighmap will be generate block by block while chunks are not loading, so that when chunks load, the heightmap values have already been cached |
0 commit comments