-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeed.xml
346 lines (247 loc) · 45.9 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.3">Jekyll</generator><link href="https://bluerope.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://bluerope.org/" rel="alternate" type="text/html" /><updated>2018-09-09T07:08:59-05:00</updated><id>https://bluerope.org/</id><title type="html">Blue Rope</title><subtitle>A blog about nothing of consequence.</subtitle><entry><title type="html">Simple Systems</title><link href="https://bluerope.org/2018/09/07/simple-systems.html" rel="alternate" type="text/html" title="Simple Systems" /><published>2018-09-07T00:00:00-05:00</published><updated>2018-09-07T00:00:00-05:00</updated><id>https://bluerope.org/2018/09/07/simple-systems</id><content type="html" xml:base="https://bluerope.org/2018/09/07/simple-systems.html"><p>One of the main reasons I decided to include a game example while documenting the ECS development is
that I found that much of it is about the pattern that I use with it rather than the actual code itself.</p>
<p>The basic idea of a system in ECS is that it handles any changes needed by components for each game loop.
So it your game has components with velocity, a system is responsible for moving those components the appropriate amount.</p>
<p>In my first attempts an an ECS before this, I equated a system to the list of components that it needed to deal with.
So a <code class="highlighter-rouge">MovementSystem</code> would have a container of <code class="highlighter-rouge">Movement</code> components that it processes.</p>
<p>The problem with that is that 2 different systems might share components. A <code class="highlighter-rouge">Location</code> component would be needed by
a system handling physics and a system that was making decisions for computer controlled entities.</p>
<p>So, the top level <code class="highlighter-rouge">EntityScene</code> will have all of the component containers. Each system will declare what components it needs
and the scene will pass those into the system each game loop.</p>
<h1 id="example-system">Example System</h1>
<p>That’s still kind of abstract so here’s an example from the game for the <code class="highlighter-rouge">MovementSystem</code>. The implementations are left out
here because</p>
<h2 id="components">Components</h2>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="c1">/// Describes how an entity moves</span>
<span class="kd">struct</span> <span class="kt">Movable</span> <span class="p">:</span> <span class="kt">Component</span> <span class="p">{</span>
<span class="p">}</span>
<span class="kd">protocol</span> <span class="kt">MovableComponents</span> <span class="p">{</span>
<span class="kd">associatedtype</span> <span class="kt">MovableContainerType</span><span class="p">:</span> <span class="kt">ComponentContainer</span> <span class="k">where</span> <span class="kt">MovableContainerType</span><span class="o">.</span><span class="kt">ComponentType</span> <span class="o">==</span> <span class="kt">Movable</span>
<span class="k">var</span> <span class="nv">movables</span><span class="p">:</span> <span class="kt">MovableContainerType</span> <span class="p">{</span><span class="k">get</span><span class="p">}</span>
<span class="p">}</span>
<span class="c1">/// Describes the physical body and location of an entity</span>
<span class="kd">struct</span> <span class="kt">Body</span> <span class="p">:</span> <span class="kt">Component</span> <span class="p">{</span>
<span class="p">}</span>
<span class="kd">protocol</span> <span class="kt">BodyComponents</span> <span class="p">{</span>
<span class="kd">associatedtype</span> <span class="kt">BodyContainerType</span><span class="p">:</span> <span class="kt">ComponentContainer</span> <span class="k">where</span> <span class="kt">BodyContainerType</span><span class="o">.</span><span class="kt">ComponentType</span> <span class="o">==</span> <span class="kt">Body</span>
<span class="k">var</span> <span class="nv">bodies</span><span class="p">:</span> <span class="kt">BodyContainerType</span> <span class="p">{</span><span class="k">get</span><span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>The important parts of this are the <code class="highlighter-rouge">MovableComponents</code> and <code class="highlighter-rouge">BodyComponents</code> protocols. These will be used for a system to declare what kind of components
it is dependent on.</p>
<p>A similar pattern will be followed for each component in the game. So for every component, there will be an additional protocol for systems to declare
their dependencies.</p>
<p>I tried playing around with Xcode snippets a bit to see if I could make adding them a bit easier, but that seems insufficient. I think an Xcode template will work.</p>
<h2 id="system">System</h2>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="cm">/**
The movement system depends on the following components
- Movables: determine how the entity moves
- Bodies: the location of the entity
*/</span>
<span class="kd">protocol</span> <span class="kt">MovementScene</span><span class="p">:</span> <span class="kt">EntityScene</span><span class="p">,</span> <span class="kt">MovableComponents</span><span class="p">,</span> <span class="kt">BodyComponents</span> <span class="p">{</span>
<span class="p">}</span>
<span class="cm">/**
Moves all of the components that need to be
*/</span>
<span class="kd">class</span> <span class="kt">MovementSystem</span><span class="o">&lt;</span><span class="kt">SceneType</span><span class="p">:</span> <span class="kt">MovementScene</span><span class="o">&gt;</span><span class="p">:</span> <span class="kt">System</span> <span class="p">{</span>
<span class="kd">func</span> <span class="n">update</span><span class="o">&lt;</span><span class="kt">SceneType</span><span class="p">:</span> <span class="kt">MovementScene</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">scene</span><span class="p">:</span> <span class="kt">SceneType</span><span class="p">,</span> <span class="nv">timeDelta</span><span class="p">:</span> <span class="kt">TimeInterval</span><span class="p">)</span> <span class="p">{</span>
<span class="n">scene</span><span class="o">.</span><span class="n">movables</span><span class="o">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">scene</span><span class="o">.</span><span class="n">bodies</span><span class="p">)</span> <span class="p">{</span> <span class="n">entity</span><span class="p">,</span> <span class="n">movable</span><span class="p">,</span> <span class="n">body</span> <span class="k">in</span>
<span class="c1">// move the entity</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>The <code class="highlighter-rouge">MovementScene</code> protocol is how we declare what the <code class="highlighter-rouge">MovementSystem</code> is dependent on. The <code class="highlighter-rouge">EntityScene</code> protocol is just the base protocol
for scenes and includes a property for the <code class="highlighter-rouge">EntityBuilder</code> so entities can be added and removed.</p>
<p>Then it’s dependent on the two protocols we just declared. So when it’s time to update (each game loop),
the MovementSystem can update any scene that has both <code class="highlighter-rouge">Movable</code> and <code class="highlighter-rouge">Body</code> components.</p>
<p>The <code class="highlighter-rouge">MovementSystem</code> itself, will iterate over all entities that have <code class="highlighter-rouge">Movable</code> and <code class="highlighter-rouge">Body</code> components and move them the appropriate amount.</p>
<p>The <code class="highlighter-rouge">forEach</code> function is an extension on a <code class="highlighter-rouge">ComponentContainer</code> that simplifies iterating entities when multiple components are required.</p>
<h2 id="scene">Scene</h2>
<p>Finally there’s the scene itself.</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">class</span> <span class="kt">BreakoutScene</span><span class="p">:</span> <span class="kt">EntityScene</span><span class="p">,</span> <span class="kt">MovementScene</span><span class="p">,</span> <span class="kt">CollisionScene</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">builder</span> <span class="o">=</span> <span class="kt">EntityBuilder</span><span class="p">()</span>
<span class="c1">// all components</span>
<span class="k">let</span> <span class="nv">bodies</span> <span class="o">=</span> <span class="kt">DenseComponentContainer</span><span class="o">&lt;</span><span class="kt">Body</span><span class="o">&gt;</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">movables</span> <span class="o">=</span> <span class="kt">SparseComponentContainer</span><span class="o">&lt;</span><span class="kt">Movable</span><span class="o">&gt;</span><span class="p">()</span>
<span class="c1">// all systems</span>
<span class="k">let</span> <span class="nv">movementSystem</span> <span class="o">=</span> <span class="kt">MovementSystem</span><span class="o">&lt;</span><span class="kt">BreakoutScene</span><span class="o">&gt;</span><span class="p">()</span>
<span class="kd">func</span> <span class="nf">update</span><span class="p">(</span><span class="n">_</span> <span class="nv">timeDelta</span><span class="p">:</span> <span class="kt">TimeInterval</span><span class="p">)</span> <span class="p">{</span>
<span class="n">movementSystem</span><span class="o">.</span><span class="nf">update</span><span class="p">(</span><span class="nv">scene</span><span class="p">:</span> <span class="k">self</span><span class="p">,</span> <span class="nv">timeDelta</span><span class="p">:</span> <span class="n">timeDelta</span><span class="p">)</span>
<span class="c1">// update the other systems</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>The <code class="highlighter-rouge">BreakoutScene</code> class is pretty much an analog for the <code class="highlighter-rouge">SKScene</code> subclass that would be in a SpriteKit
game. I’ve chosen to keep it separate just to keep a bit of extra separation from the SpriteKit specific code.</p>
<h1 id="git-repositories">Git repositories</h1>
<p>I’ve put up a repository for the Breakout game and SwiftECS</p>
<ul>
<li><a href="https://github.com/njallain/SwiftECS">SwiftECS</a></li>
<li><a href="https://github.com/njallain/Breakout">Breakout</a></li>
</ul>
<h1 id="previously">Previously</h1>
<ul>
<li><a href="/2018/08/11/journey-to-ecs.html">Journey to Swift ECS</a></li>
<li><a href="/2018/08/23/the-e-in-ecs.html">The E in ECS</a></li>
<li><a href="/2018/08/28/components.html">C comes after E?</a></li>
<li><a href="/2018/09/04/ecs-breakout.html">ECS Breakout</a></li>
</ul>
<h1 id="next-up">Next up</h1>
<p>We’ll get back into actually implementing this and see the basic patterns for a system.</p>
<h1 id="history">History</h1>
<p>All posts about the development of SwiftECS can be found <a href="https://bluerope.org/ecs">here</a></p>
<p>:computer:</p></content><author><name></name></author><category term="swift" /><category term="ecs" /><summary type="html">One of the main reasons I decided to include a game example while documenting the ECS development is that I found that much of it is about the pattern that I use with it rather than the actual code itself.</summary></entry><entry><title type="html">ECS Breakout</title><link href="https://bluerope.org/2018/09/04/ecs-breakout.html" rel="alternate" type="text/html" title="ECS Breakout" /><published>2018-09-04T00:00:00-05:00</published><updated>2018-09-04T00:00:00-05:00</updated><id>https://bluerope.org/2018/09/04/ecs-breakout</id><content type="html" xml:base="https://bluerope.org/2018/09/04/ecs-breakout.html"><p>Like I mentioned last time, properly designing and explaining an ECS is best if done in the context of a game.
I am actually designing a game while doing it, but for explaining it I want a very simple game.</p>
<p>Breakout is very simple (and is one of the first games I’ve ever owned back on my Atari 2600), so I’m satisfied
that it’s a good choice.</p>
<p>I will, however, expand a bit on simple breakout in order to use a bit more functionality out of ECS. Instead
of single player Breakout, I’ll make Breakout Deathmatch!</p>
<p>Instead of just one player, there will be two. Here’s the basic design:</p>
<p><img src="/assets/images/breakout_design.png" alt="Break design" /></p>
<p>Please excuse the horrendous drawing. Another benefit of doing Breakout is that
it won’t require anymore of my art.</p>
<h1 id="the-rules">The Rules</h1>
<ul>
<li>The bricks will be colored differently on each side.</li>
<li>Each ball will be ‘owned’ by the last player that hit it with their paddle.</li>
<li>When a brick is broken by a ball, the player that owns that ball will get points.</li>
<li>When a ball breaks an opposing brick, it will give more points than a same side brick.</li>
</ul>
<h1 id="previously">Previously</h1>
<ul>
<li><a href="/2018/08/11/journey-to-ecs.html">Journey to Swift ECS</a></li>
<li><a href="/2018/08/23/the-e-in-ecs.html">The E in ECS</a></li>
<li><a href="/2018/08/28/components.html">C comes after E?</a></li>
</ul>
<h1 id="next-up">Next up</h1>
<p>We’ll get back into actually implementing this and see the basic patterns for a system.</p>
<h1 id="history">History</h1>
<p>All posts about the development of SwiftECS can be found <a href="https://bluerope.org/ecs">here</a></p>
<p>:computer:</p></content><author><name></name></author><category term="swift" /><category term="ecs" /><summary type="html">Like I mentioned last time, properly designing and explaining an ECS is best if done in the context of a game. I am actually designing a game while doing it, but for explaining it I want a very simple game.</summary></entry><entry><title type="html">Another Vuelta Win for King</title><link href="https://bluerope.org/2018/09/02/another-vuelta-win.html" rel="alternate" type="text/html" title="Another Vuelta Win for King" /><published>2018-09-02T00:00:00-05:00</published><updated>2018-09-02T00:00:00-05:00</updated><id>https://bluerope.org/2018/09/02/another-vuelta-win</id><content type="html" xml:base="https://bluerope.org/2018/09/02/another-vuelta-win.html"><p>Can’t believe he got another win in the Vuelta. He looked absolutely trashed after the stage.
Luckily tomorrow is a rest day.</p>
<p>Once again, he posted his ride to <a href="https://www.strava.com/activities/1815212662/overview">Strava</a>.
I like how left the activity title as “Lunch Ride”.</p>
<p>:bicyclist:</p></content><author><name></name></author><category term="cycling" /><summary type="html">Can’t believe he got another win in the Vuelta. He looked absolutely trashed after the stage. Luckily tomorrow is a rest day.</summary></entry><entry><title type="html">Huge win for Ben King!</title><link href="https://bluerope.org/2018/08/29/vuelta-stage-4.html" rel="alternate" type="text/html" title="Huge win for Ben King!" /><published>2018-08-29T00:00:00-05:00</published><updated>2018-08-29T00:00:00-05:00</updated><id>https://bluerope.org/2018/08/29/vuelta-stage-4</id><content type="html" xml:base="https://bluerope.org/2018/08/29/vuelta-stage-4.html"><p>I’m so excited to see Ben King win a stage in this year’s Vuelta. A truly epic ride.</p>
<p>And he posted his full ride to <a href="https://www.strava.com/activities/1803622527">Strava</a>, so geeks like me can be amazed.</p>
<p>:bicyclist:</p></content><author><name></name></author><category term="cycling" /><summary type="html">I’m so excited to see Ben King win a stage in this year’s Vuelta. A truly epic ride.</summary></entry><entry><title type="html">C comes after E?</title><link href="https://bluerope.org/2018/08/28/components.html" rel="alternate" type="text/html" title="C comes after E?" /><published>2018-08-28T00:00:00-05:00</published><updated>2018-08-28T00:00:00-05:00</updated><id>https://bluerope.org/2018/08/28/components</id><content type="html" xml:base="https://bluerope.org/2018/08/28/components.html"><p>On the surface components are fairly simple. In ECS, a component, is basically a set of properties that an entity has. So if the entity is located somewhere, it might have a Location component with x and y coordinates. In fact, even though I’m add a protocol for <code class="highlighter-rouge">Component</code>, there’s nothing in it.</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">protocol</span> <span class="kt">Component</span> <span class="p">{</span>
<span class="p">}</span></code></pre></figure>
<p>I added it just in case I ever do need anything on the base component and to add a bit of clarity to the purpose of anything that’s used as a component.</p>
<h1 id="componentcontainer">ComponentContainer</h1>
<p>The slightly more complicated part of components is how they’re stored and associated to an entity.</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">protocol</span> <span class="kt">ComponentContainer</span> <span class="p">:</span> <span class="kt">EntityContainer</span> <span class="p">{</span>
<span class="kd">associatedtype</span> <span class="kt">ComponentType</span> <span class="k">where</span> <span class="kt">ComponentType</span> <span class="p">:</span> <span class="kt">Component</span>
<span class="kd">func</span> <span class="nf">get</span><span class="p">(</span><span class="nv">entity</span><span class="p">:</span> <span class="kt">Entity</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">ComponentType</span><span class="p">?</span>
<span class="kd">func</span> <span class="nf">update</span><span class="p">(</span><span class="nv">entity</span><span class="p">:</span> <span class="kt">Entity</span><span class="p">,</span> <span class="nv">component</span><span class="p">:</span> <span class="kt">ComponentType</span><span class="p">)</span>
<span class="k">var</span> <span class="nv">entities</span><span class="p">:</span> <span class="kt">AnySequence</span><span class="o">&lt;</span><span class="p">(</span><span class="kt">Entity</span><span class="p">,</span> <span class="kt">ComponentType</span><span class="p">)</span><span class="o">&gt;</span> <span class="p">{</span><span class="k">get</span><span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>At first I tried to allow the component container able to be a struct, but it ended up really not working well for reasons that’ll be covered later.</p>
<p>Right now I think there are 2 types of component containers:</p>
<ul>
<li>Dense where the majority of entities have the component</li>
<li>Sparse where only a few entities have the component</li>
</ul>
<p>The dense container will internally use an array to store components and the sparse container will use a dictionary instead. While the implementations are pretty short, I’ll leave them out for now for reasons below.</p>
<h1 id="next-up">Next up</h1>
<p>I’ve come to realize that talking about ECS in isolation doesn’t really work well. I’ve been implementing it while working on a game which drives what I need it to do, but that isn’t really shown in these posts.</p>
<p>To fix that, I’ll write a simple game to go along with it. It won’t be anywhere near complicated enough to really justify using an ECS (I’m thinking Breakout), but hopefully it’ll be enough to illustrate how it’s used.</p>
<p>Once I have enough of it in place, I’ll add a github repository with the ECS implementation and the sample game.</p>
<h1 id="history">History</h1>
<p>All posts about the development of SwiftECS can be found <a href="https://bluerope.org/ecs">here</a></p>
<p>:computer:</p></content><author><name></name></author><category term="swift" /><category term="ecs" /><summary type="html">On the surface components are fairly simple. In ECS, a component, is basically a set of properties that an entity has. So if the entity is located somewhere, it might have a Location component with x and y coordinates. In fact, even though I’m add a protocol for Component, there’s nothing in it.</summary></entry><entry><title type="html">VUELTA BEGINS!</title><link href="https://bluerope.org/2018/08/25/vuelta-starts.html" rel="alternate" type="text/html" title="VUELTA BEGINS!" /><published>2018-08-25T00:00:00-05:00</published><updated>2018-08-25T00:00:00-05:00</updated><id>https://bluerope.org/2018/08/25/vuelta-starts</id><content type="html" xml:base="https://bluerope.org/2018/08/25/vuelta-starts.html"><p>Vuelta Espana started today.</p>
<p>An 8k TT with a surprisingly bad performance from Richie Porte. Did I miss some news about him being sick or something? I wouldn’t expect him to beat Rohan Dennis, but to lose 21 seconds on Quintana is pretty shocking.</p>
<p>Will Kwiatkowski go for GC even though de la Cruz is technically their GC leader? I don’t know, but I’d love for him to win a grand tour.</p>
<p>:bicyclist:</p></content><author><name></name></author><category term="cycling" /><summary type="html">Vuelta Espana started today.</summary></entry><entry><title type="html">The ‘E’ in ECS</title><link href="https://bluerope.org/2018/08/23/the-e-in-ecs.html" rel="alternate" type="text/html" title="The 'E' in ECS" /><published>2018-08-23T00:00:00-05:00</published><updated>2018-08-23T00:00:00-05:00</updated><id>https://bluerope.org/2018/08/23/the-e-in-ecs</id><content type="html" xml:base="https://bluerope.org/2018/08/23/the-e-in-ecs.html"><p>In ECS, entities are just an identifier which components will be attached to, usually just an integer.</p>
<p>Rather than just a typedef for Int, I decided to make Entity a struct to provide a bit more type safety. I’m trusting in the swift compiler to make this reasonably efficient.</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">struct</span> <span class="kt">Entity</span> <span class="p">:</span> <span class="kt">Hashable</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span>
<span class="p">}</span></code></pre></figure>
<h1 id="entitybuilder">EntityBuilder</h1>
<p>Unique ids need to be assigned to each new entity. In addition, when entities are created, we’re going to need to usually add components to them. So there’s an <code class="highlighter-rouge">EntityBuilder</code> class that will create and assign ids to new entities.</p>
<p>Also, when entities are destroyed, we’ll want to reclaim those ids and notify anyone interested that the entities are gone.</p>
<p>We’ll come back to <code class="highlighter-rouge">EntityBuilder</code> to help us add components to an entity</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">class</span> <span class="kt">EntityBuilder</span> <span class="p">{</span>
<span class="cm">/***
* Builds an entity with the next available id
*/</span>
<span class="kd">func</span> <span class="nf">build</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Entity</span> <span class="p">{</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">freeId</span> <span class="o">=</span> <span class="n">_freeIds</span><span class="o">.</span><span class="n">last</span> <span class="p">{</span>
<span class="n">_freeIds</span><span class="o">.</span><span class="nf">removeLast</span><span class="p">()</span>
<span class="k">return</span> <span class="kt">Entity</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="n">freeId</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="p">{</span> <span class="n">_nextId</span> <span class="o">+=</span> <span class="mi">1</span> <span class="p">}</span>
<span class="k">return</span> <span class="kt">Entity</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="n">_nextId</span><span class="p">)</span>
<span class="p">}</span>
<span class="cm">/***
* Destroys an entity, returning it's id to the pool and notifies any registered entity container that it's been destroyed.
*/</span>
<span class="kd">func</span> <span class="nf">destroy</span><span class="p">(</span><span class="nv">entity</span><span class="p">:</span> <span class="kt">Entity</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="n">list</span> <span class="k">in</span> <span class="n">_lists</span> <span class="p">{</span>
<span class="n">list</span><span class="o">.</span><span class="nf">remove</span><span class="p">(</span><span class="nv">entity</span><span class="p">:</span> <span class="n">entity</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">_freeIds</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">entity</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="p">}</span>
<span class="cm">/***
* Destroys all entities
*/</span>
<span class="kd">func</span> <span class="nf">destroyAll</span><span class="p">()</span> <span class="p">{</span>
<span class="n">_nextId</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">_freeIds</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">list</span> <span class="k">in</span> <span class="n">_lists</span> <span class="p">{</span>
<span class="n">list</span><span class="o">.</span><span class="nf">removeAll</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cm">/***
* Registers a container with the builder that will be notified when an entity is destroyed.
* This allows the container to clean up any resources associated with the entity
*/</span>
<span class="kd">func</span> <span class="nf">register</span><span class="p">(</span><span class="nv">componentList</span><span class="p">:</span> <span class="kt">EntityContainer</span><span class="p">)</span> <span class="p">{</span>
<span class="n">_lists</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">componentList</span><span class="p">)</span>
<span class="p">}</span>
<span class="cm">/***
* Registers multiple containers with the builder.
*/</span>
<span class="kd">func</span> <span class="nf">register</span><span class="p">(</span><span class="nv">lists</span><span class="p">:</span> <span class="p">[</span><span class="kt">EntityContainer</span><span class="p">])</span> <span class="p">{</span>
<span class="n">_lists</span> <span class="o">+=</span> <span class="n">lists</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nv">_nextId</span> <span class="o">=</span> <span class="mi">0</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nv">_freeIds</span> <span class="o">=</span> <span class="p">[</span><span class="kt">Int</span><span class="p">]()</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nv">_lists</span> <span class="o">=</span> <span class="p">[</span><span class="kt">EntityContainer</span><span class="p">]()</span>
<span class="p">}</span></code></pre></figure>
<p>The protocol for EntityContainer is fairly straight forward</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="cm">/***
* Protocol for anything that needs to be notified when an entity is destroyed
*/</span>
<span class="kd">protocol</span> <span class="kt">EntityContainer</span> <span class="p">{</span>
<span class="kd">func</span> <span class="nf">remove</span><span class="p">(</span><span class="nv">entity</span><span class="p">:</span> <span class="kt">Entity</span><span class="p">)</span>
<span class="kd">func</span> <span class="nf">removeAll</span><span class="p">()</span>
<span class="kd">func</span> <span class="nf">register</span><span class="p">(</span><span class="n">with</span> <span class="nv">builder</span><span class="p">:</span> <span class="kt">EntityBuilder</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="k">Self</span>
<span class="p">}</span></code></pre></figure>
<p>So we end up with an entity builder that can create entities and destroy them, then notify anything interested when entities are destroyed (purely for cleaning up any resources).</p>
<h1 id="next-up">Next up</h1>
<p>Components and component containers</p>
<p>All posts about the development of SwiftECS can be found <a href="https://bluerope.org/ecs">here</a></p>
<p>:computer:</p></content><author><name></name></author><category term="swift" /><category term="ecs" /><summary type="html">In ECS, entities are just an identifier which components will be attached to, usually just an integer.</summary></entry><entry><title type="html">Eat. Race. Win.</title><link href="https://bluerope.org/2018/08/13/eat-race-win.html" rel="alternate" type="text/html" title="Eat. Race. Win." /><published>2018-08-13T00:00:00-05:00</published><updated>2018-08-13T00:00:00-05:00</updated><id>https://bluerope.org/2018/08/13/eat-race-win</id><content type="html" xml:base="https://bluerope.org/2018/08/13/eat-race-win.html"><p>I’m almost through watching this on Amazon Prime. It’s coverving the 2017 Tour de France with Orica Scott, and focusing on how their chef feeds them for 3 weeks.</p>
<p>It combines 2 of the things I love: cycling and eating. Very enjoyable so far.</p>
<p>The biggest negative is that the racing commentary seems to be a voice over. It clashes with the rest of it.</p>
<p>:bicyclist:</p></content><author><name></name></author><category term="cycling" /><summary type="html">I’m almost through watching this on Amazon Prime. It’s coverving the 2017 Tour de France with Orica Scott, and focusing on how their chef feeds them for 3 weeks.</summary></entry><entry><title type="html">Journey to Swift ECS</title><link href="https://bluerope.org/2018/08/11/journey-to-ecs.html" rel="alternate" type="text/html" title="Journey to Swift ECS" /><published>2018-08-11T00:00:00-05:00</published><updated>2018-08-11T00:00:00-05:00</updated><id>https://bluerope.org/2018/08/11/journey-to-ecs</id><content type="html" xml:base="https://bluerope.org/2018/08/11/journey-to-ecs.html"><p>While I’m a developer by day, I don’t do much iOS development anymore and certainly no game development.</p>
<p>I’ve had many ideas for games in the past and have toyed with them, but I’ve finally started working a bit more on a particular idea. Part of this is to improve my swift knowledge (I work mostly in C# and Typescript), but mostly it’s just for fun.</p>
<p>To begin with, I looked at using iOS’s GameplayKit ECS (entity component system, for those who are unfamiliar with the pattern), but I decided quickly that isn’t very ‘swifty’ and, more importantly, I’d enjoy implementing this kind of thing myself.</p>
<p><strong>Important note:</strong> As I’ve mentioned before, I’m not a game developer (I was one long, long ago before ECS became a popular pattern used in game development). I’m also not a swift expert. So, I freely admit that anything I come up with here might be scoffed at by a real game developer. Also anyone that really just wants to make a game should probably just use an existing tool (Unity, Unreal, etc.)</p>
<h1 id="what-is-an-ecs">What is an ECS</h1>
<p>There are plenty of places you can read about the basics of ECS. Rather than attempting to explain it (poorly), I’ll just provide a few links.</p>
<ul>
<li><a href="https://en.m.wikipedia.org/wiki/Entity–component–system">Wikipedia Description</a></li>
<li><a href="https://en.m.wikipedia.org/wiki/Entity–component–system">gamedev.net Description</a></li>
</ul>
<h1 id="goals">Goals</h1>
<p>I want the ECS to end up with the following qualities in rough order of priority</p>
<ul>
<li>Easy to use and read</li>
<li>Typesafe</li>
<li>Reasonable performance</li>
</ul>
<p>I don’t really need blistering performance, but I definitely don’t want it to suck.</p>
<p>This is already way longer than I intended. I want to try and keep posts short so I can post more often. We’ll see how it goes.</p>
<h1 id="history">History</h1>
<p>All posts about the development of SwiftECS can be found <a href="https://bluerope.org/ecs">here</a></p>
<p>:computer:</p></content><author><name></name></author><category term="swift" /><category term="ecs" /><summary type="html">While I’m a developer by day, I don’t do much iOS development anymore and certainly no game development.</summary></entry><entry><title type="html">Back to Blogging</title><link href="https://bluerope.org/2018/08/08/back-to-blogging.html" rel="alternate" type="text/html" title="Back to Blogging" /><published>2018-08-08T00:00:00-05:00</published><updated>2018-08-08T00:00:00-05:00</updated><id>https://bluerope.org/2018/08/08/back-to-blogging</id><content type="html" xml:base="https://bluerope.org/2018/08/08/back-to-blogging.html"><p>It’s been a long time since I’ve blogged, and I never really good about keeping it consistent before anyway. I’m going to give it another shot to see it I can provide anything useful to anyone else.</p>
<p>In general I’ll be writing mostly about software development, but also some about games (tabletop and video) and cycling (I’m no fitness guru but I’m a cyclist and runner, so I do like talking about it sometimes)</p></content><author><name></name></author><summary type="html">It’s been a long time since I’ve blogged, and I never really good about keeping it consistent before anyway. I’m going to give it another shot to see it I can provide anything useful to anyone else.</summary></entry></feed>