public void AddSpecialFeature(
        Hex hex,
        Vector3 position,
        float hexOuterRadius,
        int wrapSize
    ) {
        Transform instance = Instantiate(special[hex.SpecialIndex - 1]);

        instance.localPosition = HexagonPoint.Perturb(
            position,
            hexOuterRadius,
            wrapSize
        );

        RandomHash rootHash = HexagonPoint.SampleHashGrid(position);
        float e = rootHash.GetValue(4);

        instance.localRotation = Quaternion.Euler(0f, 360f * e, 0f);
        instance.SetParent(_container, false);
    }
    private void AddWallSegment (
        Vector3 pivot, Hex pivotHex,
        Vector3 left, Hex leftHex,
        Vector3 right, Hex rightHex,
        float hexOuterRadius,
        int wrapSize
    ) {
        if (pivotHex.IsUnderwater) {
            return;
        }

        bool hasLeftWall = !leftHex.IsUnderwater &&
                            pivotHex.GetEdgeType(leftHex) != ElevationEdgeTypes.Cliff;

        bool hasRightWall = !rightHex.IsUnderwater &&
                            pivotHex.GetEdgeType(rightHex) != ElevationEdgeTypes.Cliff;

        if (hasLeftWall) {
            if (hasRightWall) {
                bool hasTower = false;

                if (leftHex.elevation == rightHex.elevation) {
                    RandomHash rootHash = HexagonPoint.SampleHashGrid (
                        (pivot + left + right) * 1f / 3f
                    );

                    float e = rootHash.GetValue(4);

                    hasTower = e < HexagonPoint.wallTowerThreshold;
                }

                AddWallSegment(
                    pivot,
                    left,
                    pivot,
                    right,
                    hexOuterRadius,
                    wrapSize,
                    hasTower
                );
            }
            else if (leftHex.elevation < rightHex.elevation) {
                AddWallWedge(
                    pivot,
                    left,
                    right,
                    hexOuterRadius,
                    wrapSize
                );
            }
            else {
                AddWallCap(
                    pivot,
                    left,
                    hexOuterRadius,
                    wrapSize
                );
            }
        }
        else if (hasRightWall) {
            if (rightHex.elevation < leftHex.elevation) {
                AddWallWedge(
                    right,
                    pivot,
                    left,
                    hexOuterRadius,
                    wrapSize
                );
            }
            else
            {
                AddWallCap(
                    right,
                    pivot,
                    hexOuterRadius,
                    wrapSize
                );
            }
        }
    }
    public void AddFeature(
        Hex hex,
        Vector3 position,
        float hexOuterRadius,
        int wrapSize
    ) {

        if (hex.IsSpecial) {
            return;
        }

/* Randomness of rotation is obtained by sampling a Hash
* World rather than using Random, so the rotation of objects
* will not be changed when the hex is refreshed.
*/

        RandomHash randomHash = HexagonPoint.SampleHashGrid(position);
        float a = randomHash.GetValue(0);
        float b = randomHash.GetValue(1);
        float c = randomHash.GetValue(2);
        float d = randomHash.GetValue(3);
        float e = randomHash.GetValue(4);

        Transform prefab = PickPrefab(
            urbanCollections, hex.UrbanLevel, a, d
        );

        Transform otherPrefab = PickPrefab(
            farmCollections, hex.FarmLevel, b, d
        );

        float usedHash = randomHash.GetValue(0);
        if (prefab) {
            if (otherPrefab && b < a) {
                prefab = otherPrefab;
                usedHash = b;
            }
        }
        else if (otherPrefab) {
            prefab = otherPrefab;
            usedHash = b;
        }

        otherPrefab = PickPrefab (
            plantCollections, hex.PlantLevel, c, d
        );

        if (prefab) {
            if (otherPrefab && c < usedHash) {
                prefab = otherPrefab;
            }
        }
        else if (otherPrefab) {
            prefab = otherPrefab;
        }
        else {
            return;
        }

        if (!prefab) {
            return;
        }

        Transform instance = Instantiate(prefab);

        instance.localPosition = HexagonPoint.Perturb(
            position,
            hexOuterRadius,
            wrapSize
        );
        
        instance.localRotation = Quaternion.Euler(0f, 360f * e, 0f);

        instance.SetParent(_container, false);
    }